Bug 5010: NeutronVpn: Internal VPN delete/recreate redesign + related fixes 90/32990/2
authorAbhinav Gupta <abhinav.gupta@ericsson.com>
Tue, 19 Jan 2016 09:42:59 +0000 (15:12 +0530)
committerAbhinav Gupta <abhinav.gupta@ericsson.com>
Tue, 19 Jan 2016 13:45:48 +0000 (19:15 +0530)
1. Eliminated deletion and recreation of internal vpn on
association/dissociation with vpn
2. Fixed router deletion - earlier internal vpn wasn't getting deleted
3. Updated getVpnForRouter to handle multiple VPNs after change (1), for
querying for either of internal/external vpn
4. Router deletion not recreating interfaces for internal vpn and clearing
from vpnmaps in multiple steps - cleaned for efficiency purposes
5. Updated to not fetching Neutron Router DS for interfaces once router is
deleted, using DCN input instead
6. Cleaned up yang imports to not use entire package, earlier done due to
conflicting packages

Change-Id: I4aa6568ac6c724cf9f361534e7df9e0807d2b5a9
Signed-off-by: Abhinav Gupta <abhinav.gupta@ericsson.com>
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java
neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java

index 826f9f839b52a35c0082c336f631031fe79ff456..4cd576e2ac9355f95cde2d4153c3f2b962bd646b 100644 (file)
@@ -18,7 +18,6 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.router
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router.Interfaces;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
 import org.opendaylight.yangtools.concepts.ListenerRegistration;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
@@ -83,21 +82,16 @@ public class NeutronRouterChangeListener extends AbstractDataChangeListener<Rout
         if (LOG.isTraceEnabled()) {
             LOG.trace("Removing router : key: " + identifier + ", value=" + input);
         }
-        // check if this router has internal-VPN
         Uuid routerId = input.getUuid();
-        VpnMap vpnmap = NeutronvpnUtils.getVpnMap(broker, routerId);
-        if (vpnmap != null) {
-            // if yes, remove corresponding internal vpn
-            LOG.trace("removing internal-vpn for router {}", routerId);
-            nvpnManager.removeL3Vpn(routerId);
-        } else {
-            // if not, it is associated with some VPN
-            // remove VPN-router association
-            Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId);
-            LOG.trace("dissociating router {} from vpn {}", routerId, vpnId);
-            nvpnManager.dissociateRouterFromVpn(vpnId, routerId);
+        // fetch subnets associated to router
+        List<Interfaces> routerInterfaces = input.getInterfaces();
+        List<Uuid> routerSubnetIds = new ArrayList<Uuid>();
+        if (routerInterfaces != null) {
+            for (Interfaces rtrIf : routerInterfaces) {
+                routerSubnetIds.add(rtrIf.getSubnetId());
+            }
         }
-
+        nvpnManager.handleNeutronRouterDeleted(routerId, routerSubnetIds);
     }
 
     @Override
@@ -107,7 +101,11 @@ public class NeutronRouterChangeListener extends AbstractDataChangeListener<Rout
                     update);
         }
         Uuid routerId = update.getUuid();
-        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId);
+        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+        // internal vpn always present in case external vpn not found
+        if (vpnId == null) {
+            vpnId = routerId;
+        }
         List<Interfaces> oldInterfaces = (original.getInterfaces() != null) ? original.getInterfaces() : new
                 ArrayList<Interfaces>();
         List<Interfaces> newInterfaces = (update.getInterfaces() != null) ? update.getInterfaces() : new
index a94101d0fb0328d15fb59cb7794d6eb09319c486..505d128a215506837909732f8dee23a0e2b488e3 100644 (file)
@@ -758,7 +758,7 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
     }
 
     protected void removeL3Vpn(Uuid id) {
-        // read VPN networks
+        // read VPNMaps
         VpnMap vpnMap = NeutronvpnUtils.getVpnMap(broker, id);
         Uuid router = vpnMap.getRouterId();
         // dissociate router
@@ -800,39 +800,40 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         }
     }
 
-    protected void associateRouterToVpn(Uuid vpn, Uuid router) {
+    protected void associateRouterToVpn(Uuid vpnId, Uuid routerId) {
 
-        // remove existing Router-VPN
-        if (!vpn.equals(router)) {
-            removeL3Vpn(router);
-        }
-        updateVpnMaps(vpn, null, router, null, null);
+        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
 
-        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
-        logger.debug("Adding subnets...");
+        if (!vpnId.equals(routerId)) {
+            logger.debug("Removing subnets from internal vpn {}", routerId.getValue());
+            if (routerSubnets != null) {
+                for (Uuid subnet : routerSubnets) {
+                    removeSubnetFromVpn(routerId, subnet);
+                }
+            }
+        }
+        logger.debug("Adding subnets to vpn {}", vpnId.getValue());
         for (Uuid subnet : routerSubnets) {
-            addSubnetToVpn(vpn, subnet);
+            addSubnetToVpn(vpnId, subnet);
         }
+
+        updateVpnMaps(vpnId, null, routerId, null, null);
     }
 
-    protected void dissociateRouterFromVpn(Uuid vpn, Uuid router) {
-        clearFromVpnMaps(vpn, router, null);
+    protected void dissociateRouterFromVpn(Uuid vpnId, Uuid routerId) {
 
-        // fetching sn from SubnetmapDS for internal VPN because sn already deleted from RouterIf DS on router deletion
-        List<Uuid> routerSubnets = (vpn.equals(router)) ? getSubnetsforVpn(vpn) :
-                NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router);
+        // remove existing external vpn interfaces
+        List<Uuid> routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId);
 
-        logger.debug("dissociateRouter vpn {} router {} Removing subnets...", vpn.getValue(), router.getValue());
         if (routerSubnets != null) {
             for (Uuid subnet : routerSubnets) {
-                removeSubnetFromVpn(vpn, subnet);
+                logger.debug("Removing subnets from external vpn {}", vpnId.getValue());
+                removeSubnetFromVpn(vpnId, subnet);
+                logger.debug("Adding subnets to internal vpn {}", routerId.getValue());
+                addSubnetToVpn(routerId, subnet);
             }
         }
-        // create Router-VPN for this router
-        if (!vpn.equals(router)) {
-            logger.debug("Re-creating vpn-router...");
-            createL3Vpn(router, null, null, null, null, null, router, null);
-        }
+        clearFromVpnMaps(vpnId, routerId, null);
     }
 
     protected List<String> associateNetworksToVpn(Uuid vpn, List<Uuid> networks) {
@@ -1056,6 +1057,28 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable {
         return result;
     }
 
+    protected void handleNeutronRouterDeleted(Uuid routerId, List<Uuid> routerSubnetIds) {
+        // check if the router is associated to some VPN
+        Uuid vpnId = NeutronvpnUtils.getVpnForRouter(broker, routerId, true);
+        if (vpnId != null) {
+            // remove existing external vpn interfaces
+            for (Uuid subnetId : routerSubnetIds) {
+                removeSubnetFromVpn(vpnId, subnetId);
+            }
+            clearFromVpnMaps(vpnId, routerId, null);
+        } else {
+            // remove existing internal vpn interfaces
+            for (Uuid subnetId : routerSubnetIds) {
+                removeSubnetFromVpn(routerId, subnetId);
+            }
+        }
+        // delete entire vpnMaps node for internal VPN
+        deleteVpnMapsNode(routerId);
+
+        // delete vpn-instance for internal VPN
+        deleteVpnInstance(routerId);
+    }
+
     protected Subnet getNeutronSubnet(Uuid subnetId) {
         InstanceIdentifier<Subnet> inst = InstanceIdentifier.create(Neutron.class).
                 child(Subnets.class).child(Subnet.class, new SubnetKey(subnetId));
index 042b0ea19f28dd22f0e400f892d715692b59c79b..a74a34b62a65303df327f79c57c79bd82a3b2635 100644 (file)
@@ -25,6 +25,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TimeUnits;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInput;
@@ -104,16 +107,26 @@ public class NeutronvpnUtils {
         return null;
     }
 
-    protected static Uuid getVpnForRouter(DataBroker broker, Uuid router) {
+    // true for external vpn, false for internal vpn
+    protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
-        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
+        Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
+                vpnMapsIdentifier);
         if (optionalVpnMaps.isPresent()) {
             VpnMaps vpnNets = optionalVpnMaps.get();
             List<VpnMap> allMaps = vpnNets.getVpnMap();
-            if (router != null) {
+            if (routerId != null) {
                 for (VpnMap vpnMap : allMaps) {
-                    if (router.equals(vpnMap.getRouterId())) {
-                        return vpnMap.getVpnId();
+                    if (routerId.equals(vpnMap.getRouterId())) {
+                        if (externalVpn == true) {
+                            if (!routerId.equals(vpnMap.getVpnId())) {
+                                return vpnMap.getVpnId();
+                            }
+                        } else {
+                            if (routerId.equals(vpnMap.getVpnId())) {
+                                return vpnMap.getVpnId();
+                            }
+                        }
                     }
                 }
             }
@@ -201,20 +214,20 @@ public class NeutronvpnUtils {
     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
         logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
 
-        List<Uuid> subnetNames = new ArrayList<Uuid>();
+        List<Uuid> subnetIdList = new ArrayList<Uuid>();
         Router router = getNeutronRouter(broker, routerId);
         if (router != null) {
             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
-                    .Interfaces> ifs = router.getInterfaces();
-            if (!ifs.isEmpty()) {
+                    .Interfaces> interfacesList = router.getInterfaces();
+            if (!interfacesList.isEmpty()) {
                 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
-                        .router.Interfaces iff : ifs) {
-                    subnetNames.add(iff.getSubnetId());
+                        .router.Interfaces interfaces : interfacesList) {
+                    subnetIdList.add(interfaces.getSubnetId());
                 }
             }
         }
         logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
-        return subnetNames;
+        return subnetIdList;
     }
 
     protected static String uuidToTapPortName(Uuid id) {
@@ -261,17 +274,10 @@ public class NeutronvpnUtils {
         try {
             Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
 
-            org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets
-                    .SubnetKey subnetkey = new org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets
-                    .rev150712.subnets.attributes.subnets.SubnetKey(subnetUUID);
-            InstanceIdentifier<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets
-                    .attributes.subnets.Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(org
-                    .opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets
-                    .class).child(org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets
-                    .attributes.subnets.Subnet.class, subnetkey);
-            Optional<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes
-                    .subnets.Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION, subnetidentifier);
-
+            SubnetKey subnetkey = new SubnetKey(subnetUUID);
+            InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
+                    .class).child(Subnet.class, subnetkey);
+            Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier);
             if (subnet.isPresent()) {
                 cidr = subnet.get().getCidr();
                 // Extract the prefix length from cidr