From c103ce9e5b1e4acfb3320f245503e46332593e43 Mon Sep 17 00:00:00 2001 From: Abhinav Gupta Date: Tue, 19 Jan 2016 15:12:59 +0530 Subject: [PATCH] Bug 5010: NeutronVpn: Internal VPN delete/recreate redesign + related fixes 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 --- .../NeutronRouterChangeListener.java | 28 ++++---- .../neutronvpn/NeutronvpnManager.java | 67 +++++++++++++------ .../neutronvpn/NeutronvpnUtils.java | 50 ++++++++------ 3 files changed, 86 insertions(+), 59 deletions(-) diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java index 826f9f83..4cd576e2 100644 --- a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java +++ b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronRouterChangeListener.java @@ -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 routerInterfaces = input.getInterfaces(); + List routerSubnetIds = new ArrayList(); + 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 oldInterfaces = (original.getInterfaces() != null) ? original.getInterfaces() : new ArrayList(); List newInterfaces = (update.getInterfaces() != null) ? update.getInterfaces() : new diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java index a94101d0..505d128a 100644 --- a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java +++ b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnManager.java @@ -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 routerSubnets = NeutronvpnUtils.getNeutronRouterSubnetIds(broker, routerId); - List 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 routerSubnets = (vpn.equals(router)) ? getSubnetsforVpn(vpn) : - NeutronvpnUtils.getNeutronRouterSubnetIds(broker, router); + // remove existing external vpn interfaces + List 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 associateNetworksToVpn(Uuid vpn, List networks) { @@ -1056,6 +1057,28 @@ public class NeutronvpnManager implements NeutronvpnService, AutoCloseable { return result; } + protected void handleNeutronRouterDeleted(Uuid routerId, List 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 inst = InstanceIdentifier.create(Neutron.class). child(Subnets.class).child(Subnet.class, new SubnetKey(subnetId)); diff --git a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java index 042b0ea1..a74a34b6 100644 --- a/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java +++ b/neutronvpn/neutronvpn-impl/src/main/java/org/opendaylight/vpnservice/neutronvpn/NeutronvpnUtils.java @@ -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 vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build(); - Optional optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier); + Optional optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, + vpnMapsIdentifier); if (optionalVpnMaps.isPresent()) { VpnMaps vpnNets = optionalVpnMaps.get(); List 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 getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) { logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue()); - List subnetNames = new ArrayList(); + List subnetIdList = new ArrayList(); Router router = getNeutronRouter(broker, routerId); if (router != null) { List 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 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 subnet = read(broker, LogicalDatastoreType.CONFIGURATION, subnetidentifier); - + SubnetKey subnetkey = new SubnetKey(subnetUUID); + InstanceIdentifier subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets + .class).child(Subnet.class, subnetkey); + Optional subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier); if (subnet.isPresent()) { cidr = subnet.get().getCidr(); // Extract the prefix length from cidr -- 2.36.6