Neutron port removal fixed
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronPortAware.java
index da1ab83b6fae18b2b67b832926c589498abeae8d..07a0129a81c9dcd1d3042f2fa58794e87cd08972 100644 (file)
@@ -15,6 +15,7 @@ import java.util.Set;
 
 import javax.annotation.Nullable;
 
+import com.sun.jndi.cosnaming.IiopUrl;
 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
@@ -74,6 +75,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gb
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.ports.by.endpoints.PortByEndpoint;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
@@ -99,8 +101,11 @@ public class NeutronPortAware implements NeutronAware<Port> {
         this.epRegistrator = checkNotNull(epRegistrator);
     }
 
-    @Override
-    public void onCreated(Port port, Neutron neutron) {
+    @Override public void onCreated(Port createdItem, Neutron neutron) {
+        onCreated(createdItem, neutron, true);
+    }
+
+    public void onCreated(Port port, Neutron neutron, boolean addBaseEpMapping) {
         LOG.trace("created port - {}", port);
         if (PortUtils.isRouterInterfacePort(port)) {
             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
@@ -113,6 +118,45 @@ public class NeutronPortAware implements NeutronAware<Port> {
             }
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             ContextId routerL3Context = new ContextId(port.getDeviceId());
+            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
+
+            AddressEndpointKey addrEpKey = new AddressEndpointKey(port.getMacAddress().getValue(),
+                MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
+            UniqueId portId = new UniqueId(port.getUuid().getValue());
+            addBaseEndpointMappings(addrEpKey, portId, rwTx);
+
+            // Add Qrouter and VPProuter port as Endpoint
+            if (port.getAugmentation(PortBindingExtension.class) != null &&
+                PortUtils.DEVICE_VIF_TYPE.equals(port.getAugmentation(PortBindingExtension.class).getVifType())) {
+                LOG.trace("Port is QRouter port: {}", port.getUuid().getValue());
+                Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(port);
+                if (!firstFixedIps.isPresent()) {
+                    LOG.warn("QRouter port does not have an IP address. {}", port);
+                    return;
+                }
+
+                FixedIps ipWithSubnet = firstFixedIps.get();
+                NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue());
+                List<EndpointGroupId> epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups());
+                epgsFromSecGroups.add(NetworkService.EPG_ID);
+
+                // BUILD BASE ENDPOINT
+                AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment,
+                    epgsFromSecGroups);
+                AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(port, networkContainment,
+                    epgsFromSecGroups, neutron);
+                setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp);
+
+                // BUILD ENDPOINT
+                org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder
+                    epInBuilder =
+                    createEndpointRegFromPort(
+                        port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron);
+                registerBaseEndpointAndStoreMapping(
+                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx, addBaseEpMapping);
+                registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
+            }
+
             // change L3Context for all EPs with same subnet as router port
             changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), neutron);
             // set L3Context as parent for bridge domain which is parent of subnet
@@ -124,7 +168,6 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 return;
             }
             Subnet routerPortSubnet = potentialRouterPortSubnet.get();
-            ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             ContextId l2BdId = new ContextId(routerPortSubnet.getNetworkId().getValue());
             ForwardingContext l2Bd = new ForwardingContextBuilder().setContextId(l2BdId)
                 .setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
@@ -136,11 +179,6 @@ public class NeutronPortAware implements NeutronAware<Port> {
                     routerPortSubnet, portIpWithSubnet.getIpAddress());
             rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain);
 
-            AddressEndpointKey addrEpKey = new AddressEndpointKey(port.getMacAddress().getValue(),
-                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
-            UniqueId portId = new UniqueId(port.getUuid().getValue());
-            addBaseEndpointMappings(addrEpKey, portId, rwTx);
-
             // does the same for tenant forwarding domains
             processTenantForwarding(routerPortSubnet, routerL3Context, portIpWithSubnet, tenantId, rwTx);
 
@@ -171,7 +209,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
 
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             registerBaseEndpointAndStoreMapping(
-                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx);
+                    ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx, addBaseEpMapping);
             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
@@ -202,7 +240,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
                 baseEpRegs.add(l3BaseEp.build());
             }
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
-            registerBaseEndpointAndStoreMapping(baseEpRegs, port, rwTx);
+            registerBaseEndpointAndStoreMapping(baseEpRegs, port, rwTx, addBaseEpMapping);
             registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isRouterGatewayPort(port)) {
@@ -256,14 +294,15 @@ public class NeutronPortAware implements NeutronAware<Port> {
     private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Neutron neutron) {
         Set<Port> portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts());
         for (Port portInSameSubnet : portsInSameSubnet) {
-            if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)) {
+            if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet)
+                || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
                 // endpoints are created only from neutron normal port or DHCP port
                 Optional<FixedIps> firstFixedIps = PortUtils.resolveFirstFixedIps(portInSameSubnet);
                 if (firstFixedIps.isPresent()) {
                     // endpoint has only one network containment therefore only first IP is used
                     FixedIps ipWithSubnet = firstFixedIps.get();
                     List<EndpointGroupId> endpointGroupIds = new ArrayList<>();
-                    if (PortUtils.isDhcpPort(portInSameSubnet)) {
+                    if (PortUtils.isDhcpPort(portInSameSubnet) || PortUtils.isQrouterOrVppRouterPort(portInSameSubnet)) {
                         endpointGroupIds.add(NetworkService.EPG_ID);
                     } else if (PortUtils.isNormalPort(portInSameSubnet)) {
                         endpointGroupIds.add(NetworkClient.EPG_ID);
@@ -280,7 +319,9 @@ public class NeutronPortAware implements NeutronAware<Port> {
                         .setContextType(l3BaseEp.getContextType())
                         .build();
                     epRegistrator.unregisterEndpoint(addrEpUnreg);
-                    epRegistrator.registerEndpoint(l3BaseEp.build());
+                    RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder()
+                        .setAddressEndpointReg(ImmutableList.of(l2BaseEp.build(), l3BaseEp.build())).build();
+                    epRegistrator.registerEndpoint(regBaseEpInput);
 
                     modifyL3ContextForEndpoints(portInSameSubnet, ipWithSubnet, l3BaseEp.getContextId());
                 }
@@ -448,7 +489,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
     }
 
     private void registerBaseEndpointAndStoreMapping(List<AddressEndpointReg> addrEpRegs, Port port,
-            WriteTransaction wTx) {
+            WriteTransaction wTx, boolean addBaseEpMappings) {
         RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder().setAddressEndpointReg(addrEpRegs)
             .build();
 
@@ -458,7 +499,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
             return;
         }
         for (AddressEndpointReg addrEpReg : addrEpRegs) {
-            if (MappingUtils.L2_BRDIGE_DOMAIN.equals(addrEpReg.getContextType())) {
+            if (MappingUtils.L2_BRDIGE_DOMAIN.equals(addrEpReg.getContextType()) && addBaseEpMappings) {
                 UniqueId portId = new UniqueId(port.getUuid().getValue());
                 LOG.trace("Adding Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
                         port.getUuid());
@@ -480,7 +521,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
     }
 
     private void unregisterEndpointAndRemoveMapping(UnregisterEndpointInput baseEpUnreg, Port port,
-            ReadWriteTransaction rwTx) {
+            ReadWriteTransaction rwTx, boolean removeBaseEpMappings) {
         boolean isUnregisteredBaseEndpoint = epRegistrator.unregisterEndpoint(baseEpUnreg);
         if (isUnregisteredBaseEndpoint) {
             UniqueId portId = new UniqueId(port.getUuid().getValue());
@@ -488,7 +529,9 @@ public class NeutronPortAware implements NeutronAware<Port> {
                     MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
             LOG.trace("Removing Port-BaseEndpoint mapping for port {} (device owner {}) and endpoint {}",
                     port.getUuid().getValue(), port.getDeviceOwner(), portByBaseEndpointKey);
-            removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
+            if (removeBaseEpMappings) {
+                removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
+            }
         }
     }
 
@@ -502,12 +545,15 @@ public class NeutronPortAware implements NeutronAware<Port> {
     @Override
     public void onUpdated(Port oldPort, Port newPort, Neutron oldNeutron, Neutron newNeutron) {
         LOG.trace("updated port - OLD: {}\nNEW: {}", oldPort, newPort);
-        onDeleted(oldPort, oldNeutron, newNeutron);
-        onCreated(newPort, newNeutron);
+        onDeleted(oldPort, oldNeutron, newNeutron, false);
+        onCreated(newPort, newNeutron, false);
     }
 
-    @Override
-    public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron) {
+    @Override public void onDeleted(Port deletedItem, Neutron oldNeutron, Neutron newNeutron) {
+        onDeleted(deletedItem, oldNeutron, newNeutron, true);
+    }
+
+    public void onDeleted(Port port, Neutron oldNeutron, Neutron newNeutron, boolean removeBaseEpMapping) {
         LOG.trace("deleted port - {}", port);
         if (PortUtils.isRouterInterfacePort(port)) {
             LOG.trace("Port is router interface port: {}", port.getUuid().getValue());
@@ -521,7 +567,7 @@ public class NeutronPortAware implements NeutronAware<Port> {
             FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get();
             L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue());
             // change L3Context for all EPs with same subnet as router port
-            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), oldNeutron);
+            changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), newNeutron);
             // set L3Context as parent for bridge domain which is parent of subnet
             TenantId tenantId = new TenantId(port.getTenantId().getValue());
             Optional<Subnet> potentialRouterPortSubnet = SubnetUtils.findSubnet(portIpWithSubnet.getSubnetId(),
@@ -543,22 +589,20 @@ public class NeutronPortAware implements NeutronAware<Port> {
             NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null);
             rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()),
                     subnet);
-            UniqueId portId = new UniqueId(port.getUuid().getValue());
-            PortByBaseEndpointKey portByBaseEndpointKey = new PortByBaseEndpointKey(port.getMacAddress().getValue(),
-                    MacAddressType.class, new ContextId(port.getNetworkId().getValue()), MappingUtils.L2_BRDIGE_DOMAIN);
-            removeBaseEndpointMappings(portByBaseEndpointKey, portId, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isDhcpPort(port)) {
             LOG.trace("Port is DHCP port: {}", port.getUuid().getValue());
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
-            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isNormalPort(port)) {
             LOG.trace("Port is normal port: {}", port.getUuid().getValue());
             ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
             unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);
-            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx);
+            unregisterEndpointAndRemoveMapping(createUnregisterBaseEndpointInput(port, oldNeutron), port, rwTx, removeBaseEpMapping);
             DataStoreHelper.submitToDs(rwTx);
         } else if (PortUtils.isRouterGatewayPort(port)) {
             // do nothing because actual trigger is detaching of port from router