Added support to update flows for induvidual security rule add/remove ,
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / PortSecurityHandler.java
index 26379b4b8b767b6de3b2ac8811e4353f808225b4..646693cd263950310ad51f608b252d49f9366816 100644 (file)
@@ -1,32 +1,41 @@
 /*
- * Copyright (C) 2013 Red Hat, Inc.
+ * Copyright (c) 2013, 2015 Red Hat, Inc. and others. All rights reserved.
  *
  * This program and the accompanying materials are made available under the
  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
  * and is available at http://www.eclipse.org/legal/epl-v10.html
- *
- * Authors : Brent Salisbury, Madhu Venugopal
  */
 
 package org.opendaylight.ovsdb.openstack.netvirt;
 
-import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityGroupAware;
-import org.opendaylight.controller.networkconfig.neutron.INeutronSecurityRuleAware;
-import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityGroup;
-import org.opendaylight.controller.networkconfig.neutron.NeutronSecurityRule;
-
+import java.net.HttpURLConnection;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronPort;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityGroup;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.NeutronSecurityRule;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.Neutron_IPs;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.crud.INeutronPortCRUD;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityGroupAware;
+import org.opendaylight.ovsdb.openstack.netvirt.translator.iaware.INeutronSecurityRuleAware;
+import org.opendaylight.ovsdb.openstack.netvirt.api.Action;
+import org.opendaylight.ovsdb.openstack.netvirt.api.EventDispatcher;
+import org.opendaylight.ovsdb.openstack.netvirt.api.SecurityServicesManager;
+import org.opendaylight.ovsdb.utils.servicehelper.ServiceHelper;
+import org.osgi.framework.ServiceReference;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.net.HttpURLConnection;
-
 /**
  * Handle requests for OpenStack Neutron v2.0 Port Security API calls.
  */
 public class PortSecurityHandler extends AbstractHandler
-        implements INeutronSecurityGroupAware, INeutronSecurityRuleAware{
+        implements INeutronSecurityGroupAware, INeutronSecurityRuleAware, ConfigInterface {
 
-    static final Logger logger = LoggerFactory.getLogger(PortSecurityHandler.class);
+    private static final Logger LOG = LoggerFactory.getLogger(PortSecurityHandler.class);
+    private volatile INeutronPortCRUD neutronPortCache;
+    private volatile SecurityServicesManager securityServicesManager;
 
     @Override
     public int canCreateNeutronSecurityGroup(NeutronSecurityGroup neutronSecurityGroup) {
@@ -35,12 +44,9 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityGroupCreated(NeutronSecurityGroup neutronSecurityGroup) {
-        int result = HttpURLConnection.HTTP_BAD_REQUEST;
-
-        result = canCreateNeutronSecurityGroup(neutronSecurityGroup);
+        int result = canCreateNeutronSecurityGroup(neutronSecurityGroup);
         if (result != HttpURLConnection.HTTP_CREATED) {
-            logger.debug("Neutron Security Group creation failed {} ", result);
-            return;
+            LOG.debug("Neutron Security Group creation failed {} ", result);
         }
     }
 
@@ -51,7 +57,7 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityGroupUpdated(NeutronSecurityGroup neutronSecurityGroup) {
-        return;
+        // Nothing to do
     }
 
     @Override
@@ -64,8 +70,7 @@ public class PortSecurityHandler extends AbstractHandler
         //TODO: Trigger flowmod removals
         int result = canDeleteNeutronSecurityGroup(neutronSecurityGroup);
         if  (result != HttpURLConnection.HTTP_OK) {
-            logger.error(" delete Neutron Security Rule validation failed for result - {} ", result);
-            return;
+            LOG.error(" delete Neutron Security Rule validation failed for result - {} ", result);
         }
     }
 
@@ -84,13 +89,7 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityRuleCreated(NeutronSecurityRule neutronSecurityRule) {
-        int result = HttpURLConnection.HTTP_BAD_REQUEST;
-
-        result = canCreateNeutronSecurityRule(neutronSecurityRule);
-        if (result != HttpURLConnection.HTTP_CREATED) {
-            logger.debug("Neutron Security Group creation failed {} ", result);
-            return;
-        }
+        enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.ADD));
     }
 
     @Override
@@ -100,7 +99,7 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityRuleUpdated(NeutronSecurityRule neutronSecurityRule) {
-        return;
+        // Nothing to do
     }
 
     @Override
@@ -110,11 +109,7 @@ public class PortSecurityHandler extends AbstractHandler
 
     @Override
     public void neutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
-        int result = canDeleteNeutronSecurityRule(neutronSecurityRule);
-        if  (result != HttpURLConnection.HTTP_OK) {
-            logger.error(" delete Neutron Security Rule validation failed for result - {} ", result);
-            return;
-        }
+        enqueueEvent(new NorthboundEvent(neutronSecurityRule, Action.DELETE));
     }
 
     /**
@@ -126,17 +121,78 @@ public class PortSecurityHandler extends AbstractHandler
     @Override
     public void processEvent(AbstractEvent abstractEvent) {
         if (!(abstractEvent instanceof NorthboundEvent)) {
-            logger.error("Unable to process abstract event " + abstractEvent);
+            LOG.error("Unable to process abstract event {}", abstractEvent);
             return;
         }
         NorthboundEvent ev = (NorthboundEvent) abstractEvent;
         switch (ev.getAction()) {
-            // TODO: add handling of events here, once callbacks do something
-            //       other than logging.
+            case ADD:
+                processNeutronSecurityRuleAdded(ev.getNeutronSecurityRule());
+                break;
+            case DELETE:
+                processNeutronSecurityRuleDeleted(ev.getNeutronSecurityRule());
+                break;
             default:
-                logger.warn("Unable to process event action " + ev.getAction());
+                LOG.warn("Unable to process event action {}", ev.getAction());
                 break;
         }
     }
 
+    private void processNeutronSecurityRuleAdded(NeutronSecurityRule neutronSecurityRule) {
+        List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
+        for (NeutronPort port:portList) {
+            syncSecurityGroup(neutronSecurityRule,port,neutronSecurityRule.getSecurityRuleGroupID(),true);
+        }
+    }
+
+    private void processNeutronSecurityRuleDeleted(NeutronSecurityRule neutronSecurityRule) {
+        List<NeutronPort> portList = getPortWithSecurityGroup(neutronSecurityRule.getSecurityRuleGroupID());
+        for (NeutronPort port:portList) {
+            syncSecurityGroup(neutronSecurityRule,port,neutronSecurityRule.getSecurityRuleGroupID(),false);
+        }
+    }
+
+    private void syncSecurityGroup(NeutronSecurityRule  securityRule,NeutronPort port,
+                                   String neutronSecurityGroupId,boolean write) {
+
+        if (null != securityRule.getSecurityRemoteGroupID()) {
+            List<Neutron_IPs> vmIpList  = securityServicesManager
+                    .getVmListForSecurityGroup(port.getID(), neutronSecurityGroupId);
+            for (Neutron_IPs vmIp :vmIpList ) {
+                securityServicesManager.syncSecurityRule(port, securityRule, vmIp, write);
+            }
+        } else {
+            securityServicesManager.syncSecurityRule(port, securityRule, null, write);
+        }
+    }
+
+    private List<NeutronPort> getPortWithSecurityGroup(String securityGroupUuid) {
+
+        List<NeutronPort> neutronPortList = neutronPortCache.getAllPorts();
+        List<NeutronPort> neutronPortInSG = new ArrayList<NeutronPort>();
+        for (NeutronPort neutronPort:neutronPortList) {
+            List<NeutronSecurityGroup> securityGroupList = neutronPort.getSecurityGroups();
+            for (NeutronSecurityGroup neutronSecurityGroup:securityGroupList) {
+                if (neutronSecurityGroup.getID().equals(securityGroupUuid)) {
+                    neutronPortInSG.add(neutronPort);
+                    break;
+                }
+            }
+        }
+        return neutronPortInSG;
+    }
+
+    @Override
+    public void setDependencies(ServiceReference serviceReference) {
+        eventDispatcher =
+                (EventDispatcher) ServiceHelper.getGlobalInstance(EventDispatcher.class, this);
+        eventDispatcher.eventHandlerAdded(serviceReference, this);
+        neutronPortCache =
+                (INeutronPortCRUD) ServiceHelper.getGlobalInstance(INeutronPortCRUD.class, this);
+        securityServicesManager =
+                (SecurityServicesManager) ServiceHelper.getGlobalInstance(SecurityServicesManager.class, this);
+    }
+
+    @Override
+    public void setDependencies(Object impl) {}
 }
\ No newline at end of file