Merge "Added isPortSecurityEnabled check to enable/disable SG."
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / netvirt / openstack / netvirt / PortSecurityHandler.java
1 /*
2  * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.netvirt.openstack.netvirt;
10
11 import java.net.HttpURLConnection;
12 import java.util.ArrayList;
13 import java.util.List;
14
15 import org.opendaylight.netvirt.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
16 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronPort;
17 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityGroup;
18 import org.opendaylight.netvirt.openstack.netvirt.translator.NeutronSecurityRule;
19 import org.opendaylight.netvirt.openstack.netvirt.translator.Neutron_IPs;
20 import org.opendaylight.netvirt.openstack.netvirt.translator.crud.INeutronPortCRUD;
21 import org.opendaylight.netvirt.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
22 import org.opendaylight.netvirt.openstack.netvirt.api.Action;
23 import org.opendaylight.netvirt.openstack.netvirt.api.EventDispatcher;
24 import org.opendaylight.netvirt.openstack.netvirt.api.SecurityServicesManager;
25 import org.opendaylight.netvirt.utils.servicehelper.ServiceHelper;
26 import org.osgi.framework.ServiceReference;
27 import org.slf4j.Logger;
28 import org.slf4j.LoggerFactory;
29
30 /**
31  * Handle requests for OpenStack Neutron v2.0 Port Security API calls.
32  */
33 public class PortSecurityHandler extends AbstractHandler
34         implements INeutronSecurityGroupAware, INeutronSecurityRuleAware, ConfigInterface {
35
36     private static final Logger LOG = LoggerFactory.getLogger(PortSecurityHandler.class);
37     private volatile INeutronPortCRUD neutronPortCache;
38     private volatile SecurityServicesManager securityServicesManager;
39
40     @Override
41     public int canCreateNeutronSecurityGroup(NeutronSecurityGroup neutronSecurityGroup) {
42         return HttpURLConnection.HTTP_CREATED;
43     }
44
45     @Override
46     public void neutronSecurityGroupCreated(NeutronSecurityGroup neutronSecurityGroup) {
47         int result = canCreateNeutronSecurityGroup(neutronSecurityGroup);
48         if (result != HttpURLConnection.HTTP_CREATED) {
49             LOG.debug("Neutron Security Group creation failed {} ", result);
50         }
51     }
52
53     @Override
54     public int canUpdateNeutronSecurityGroup(NeutronSecurityGroup delta, NeutronSecurityGroup original) {
55         return HttpURLConnection.HTTP_OK;
56     }
57
58     @Override
59     public void neutronSecurityGroupUpdated(NeutronSecurityGroup neutronSecurityGroup) {
60         // Nothing to do
61     }
62
63     @Override
64     public int canDeleteNeutronSecurityGroup(NeutronSecurityGroup neutronSecurityGroup) {
65         return HttpURLConnection.HTTP_OK;
66     }
67
68     @Override
69     public void neutronSecurityGroupDeleted(NeutronSecurityGroup neutronSecurityGroup) {
70         //TODO: Trigger flowmod removals
71         int result = canDeleteNeutronSecurityGroup(neutronSecurityGroup);
72         if  (result != HttpURLConnection.HTTP_OK) {
73             LOG.error(" delete Neutron Security Rule validation failed for result - {} ", result);
74         }
75     }
76
77     /**
78      * Invoked when a Security Rules creation is requested
79      * to indicate if the specified Rule can be created.
80      *
81      * @param neutronSecurityRule  An instance of proposed new Neutron Security Rule object.
82      * @return A HTTP status code to the creation request.
83      */
84
85     @Override
86     public int canCreateNeutronSecurityRule(NeutronSecurityRule neutronSecurityRule) {
87         return HttpURLConnection.HTTP_CREATED;
88     }
89
90     @Override
91     public void neutronSecurityRuleCreated(NeutronSecurityRule neutronSecurityRule) {
92         enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.ADD));
93     }
94
95     @Override
96     public int canUpdateNeutronSecurityRule(NeutronSecurityRule delta, NeutronSecurityRule original) {
97         return HttpURLConnection.HTTP_OK;
98     }
99
100     @Override
101     public void neutronSecurityRuleUpdated(NeutronSecurityRule neutronSecurityRule) {
102         // Nothing to do
103     }
104
105     @Override
106     public int canDeleteNeutronSecurityRule(NeutronSecurityRule neutronSecurityRule) {
107         return HttpURLConnection.HTTP_OK;
108     }
109
110     @Override
111     public void neutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
112         enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.DELETE));
113     }
114
115     /**
116      * Process the event.
117      *
118      * @param abstractEvent the {@link AbstractEvent} event to be handled.
119      * @see EventDispatcher
120      */
121     @Override
122     public void processEvent(AbstractEvent abstractEvent) {
123         if (!(abstractEvent instanceof NorthboundEvent)) {
124             LOG.error("Unable to process abstract event {}", abstractEvent);
125             return;
126         }
127         NorthboundEvent ev = (NorthboundEvent) abstractEvent;
128         switch (ev.getAction()) {
129             case ADD:
130                 processNeutronSecurityRuleAdded(ev.getNeutronSecurityRule());
131                 break;
132             case DELETE:
133                 processNeutronSecurityRuleDeleted(ev.getNeutronSecurityRule());
134                 break;
135             default:
136                 LOG.warn("Unable to process event action {}", ev.getAction());
137                 break;
138         }
139     }
140
141     private void processNeutronSecurityRuleAdded(NeutronSecurityRule neutronSecurityRule) {
142         List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
143         for (NeutronPort port:portList) {
144             syncSecurityGroup(neutronSecurityRule,port,true);
145         }
146     }
147
148     private void processNeutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
149         List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
150         for (NeutronPort port:portList) {
151             syncSecurityGroup(neutronSecurityRule,port,false);
152         }
153     }
154
155     private void syncSecurityGroup(NeutronSecurityRule  securityRule,NeutronPort port,
156                                    boolean write) {
157         if (!port.getPortSecurityEnabled()) {
158             LOG.info("Port security not enabled port", port);
159             return;
160         }
161         if (null != securityRule.getSecurityRemoteGroupID()) {
162             List<Neutron_IPs> vmIpList  = securityServicesManager
163                     .getVmListForSecurityGroup(port.getID(), securityRule.getSecurityRemoteGroupID());
164             for (Neutron_IPs vmIp :vmIpList ) {
165                 securityServicesManager.syncSecurityRule(port, securityRule, vmIp, write);
166             }
167         } else {
168             securityServicesManager.syncSecurityRule(port, securityRule, null, write);
169         }
170     }
171
172     private List<NeutronPort> getPortWithSecurityGroup(String securityGroupUuid) {
173
174         List<NeutronPort> neutronPortList = neutronPortCache.getAllPorts();
175         List<NeutronPort> neutronPortInSg = new ArrayList<NeutronPort>();
176         for (NeutronPort neutronPort:neutronPortList) {
177             List<NeutronSecurityGroup> securityGroupList = neutronPort.getSecurityGroups();
178             for (NeutronSecurityGroup neutronSecurityGroup:securityGroupList) {
179                 if (neutronSecurityGroup.getID().equals(securityGroupUuid)) {
180                     neutronPortInSg.add(neutronPort);
181                     break;
182                 }
183             }
184         }
185         return neutronPortInSg;
186     }
187
188     @Override
189     public void setDependencies(ServiceReference serviceReference) {
190         eventDispatcher =
191                 (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
192         eventDispatcher.eventHandlerAdded(serviceReference, this);
193         neutronPortCache =
194                 (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
195         securityServicesManager =
196                 (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
197     }
198
199     @Override
200     public void setDependencies(Object impl) {}
201 }