Bug 5213 - Missing segmentation-id for physical networks
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronNetworkAware.java
index edcd33e92f4104550b71d18dd1de8186eaf2c107..514dbef866055258874de9344f2b9ad929a3ad86 100644 (file)
@@ -9,48 +9,66 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
 
 import static com.google.common.base.Preconditions.checkNotNull;
 
+import java.util.HashSet;
+import java.util.Set;
 import java.util.UUID;
 
 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;
 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
+import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
+import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
 import org.opendaylight.groupbasedpolicy.util.IidFactory;
 import org.opendaylight.neutron.spi.INeutronNetworkAware;
 import org.opendaylight.neutron.spi.NeutronNetwork;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
+import org.opendaylight.neutron.spi.NeutronSecurityGroup;
+import org.opendaylight.neutron.spi.NeutronSecurityRule;
+import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroup.IntraGroupPolicy;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.EndpointGroupBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2BridgeDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomain;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L2FloodDomainBuilder;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3Context;
-import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.L3ContextBuilder;
+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.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
+import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder;
 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import com.google.common.base.Optional;
+import com.google.common.base.Strings;
+import com.google.common.collect.ImmutableList;
 
 public class NeutronNetworkAware implements INeutronNetworkAware {
 
     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
     private final DataBroker dataProvider;
+    private final Set<TenantId> tenantsWithRouterAndNetworkSeviceEntities = new HashSet<>();
+    private final NeutronSecurityGroupAware secGrpAware;
+    private final NeutronNetworkDao networkDao;
 
-    public NeutronNetworkAware(DataBroker dataProvider) {
+    public NeutronNetworkAware(DataBroker dataProvider, NeutronSecurityGroupAware secGrpAware, NeutronNetworkDao networkDao) {
         this.dataProvider = checkNotNull(dataProvider);
+        this.secGrpAware = checkNotNull(secGrpAware);
+        this.networkDao = checkNotNull(networkDao);
     }
 
     /**
@@ -72,86 +90,104 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
-        addEpgDhcpIfMissing(tenantId, rwTx);
-        addEpgRouterIfMissing(tenantId, rwTx);
-        // Note that Router External doesn't mean the router exists yet, it simply means it will connect to one.
-        if(network.getRouterExternal()) {
-            addEpgExternalIfMissing(tenantId, rwTx);
-        }
-        Description domainDescription = new Description(MappingUtils.NEUTRON_NETWORK__ + network.getID());
         Name name = null;
         if (network.getNetworkName() != null) {
-            name = new Name(network.getNetworkName());
+            try {
+                name = new Name(network.getNetworkName());
+            } catch (Exception e) {
+                name = null;
+                LOG.info("Name of Neutron Network '{}' is ignored.", network.getNetworkName());
+                LOG.debug("Name exception", e);
+            }
         }
+
         L3ContextId l3ContextId = new L3ContextId(UUID.randomUUID().toString());
-        L3Context l3Context = new L3ContextBuilder().setId(l3ContextId)
-            .setDescription(domainDescription)
-            .setName(name)
-            .build();
+        L3Context l3Context = new L3ContextBuilder().setId(l3ContextId).setName(name).build();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
 
         L2BridgeDomainId l2BdId = new L2BridgeDomainId(UUID.randomUUID().toString());
-        L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId)
-            .setParent(l3ContextId)
-            .setDescription(domainDescription)
-            .setName(name)
-            .build();
+        L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3ContextId).setName(name).build();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
 
-        L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId)
-            .setParent(l2BdId)
-            .setDescription(domainDescription)
-            .setName(name)
-            .build();
+        L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId).setParent(l2BdId).setName(name).build();
         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
 
         NetworkMapping networkMapping = new NetworkMappingBuilder().setNetworkId(l2FdId)
             .setL2BridgeDomainId(l2BdId)
             .setL3ContextId(l3ContextId)
             .build();
-        rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping, true);
-
-        DataStoreHelper.submitToDs(rwTx);
-    }
+        rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping,
+                true);
 
-    private void addEpgExternalIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
-        Optional<EndpointGroup> potentialEpgExternal = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), rwTx);
-        if (!potentialEpgExternal.isPresent()) {
-            EndpointGroup epgExternal = new EndpointGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID)
-                .setDescription(new Description(MappingUtils.NEUTRON_EXTERNAL__ + "epg_external_networks"))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-                .build();
-            rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_EXTERNAL_ID), epgExternal);
+        if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
+            tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
+            NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
+            NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
+            NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
+            NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
+            NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
+            NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
+            NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
+            NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
         }
+        networkDao.addNetwork(network);
+        if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
+            addEigEpgExternalWithContracts(tenantId, rwTx);
+        }
+        if (!Strings.isNullOrEmpty(network.getProviderPhysicalNetwork())) {
+            String segmentationId = network.getProviderSegmentationID();
+            addProviderPhysicalNetworkMapping(tenantId, l2FdId, segmentationId, rwTx);
+        }
+        DataStoreHelper.submitToDs(rwTx);
     }
 
-    private void addEpgDhcpIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
-        InstanceIdentifier<EndpointGroup> epgDhcpIid = IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_DHCP_ID);
-        Optional<EndpointGroup> potentialDhcpEpg = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                epgDhcpIid, rwTx);
-        if (!potentialDhcpEpg.isPresent()) {
-            EndpointGroup epgDhcp = new EndpointGroupBuilder().setId(MappingUtils.EPG_DHCP_ID)
-                .setName(new Name("DHCP_group"))
-                .setDescription(new Description("Group where are all DHCP endpoints."))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-                .build();
-            rwTx.put(LogicalDatastoreType.CONFIGURATION, epgDhcpIid, epgDhcp);
+    private void addEigEpgExternalWithContracts(TenantId tenantId, ReadWriteTransaction rwTx) {
+        Uuid tenantUuid = new Uuid(tenantId.getValue());
+        NeutronSecurityRule inIpv4 = new NeutronSecurityRule();
+        inIpv4.setID("19b85ad2-bdfc-11e5-9912-ba0be0483c18");
+        inIpv4.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        inIpv4.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        inIpv4.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
+        inIpv4.setTenantID(tenantUuid);
+        NeutronSecurityRule outIpv4 = new NeutronSecurityRule();
+        outIpv4.setID("19b85eba-bdfc-11e5-9912-ba0be0483c18");
+        outIpv4.setSecurityRuleDirection(NeutronUtils.EGRESS);
+        outIpv4.setSecurityRuleEthertype(NeutronUtils.IPv4);
+        outIpv4.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
+        outIpv4.setTenantID(tenantUuid);
+        NeutronSecurityRule inIpv6 = new NeutronSecurityRule();
+        inIpv6.setID("19b86180-bdfc-11e5-9912-ba0be0483c18");
+        inIpv6.setSecurityRuleDirection(NeutronUtils.INGRESS);
+        inIpv6.setSecurityRuleEthertype(NeutronUtils.IPv6);
+        inIpv6.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
+        inIpv6.setTenantID(tenantUuid);
+        NeutronSecurityRule outIpv6 = new NeutronSecurityRule();
+        outIpv6.setID("19b86270-bdfc-11e5-9912-ba0be0483c18");
+        outIpv6.setSecurityRuleDirection(NeutronUtils.EGRESS);
+        outIpv6.setSecurityRuleEthertype(NeutronUtils.IPv6);
+        outIpv6.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
+        outIpv6.setTenantID(tenantUuid);
+        NeutronSecurityGroup externalSecGrp = new NeutronSecurityGroup();
+        externalSecGrp.setID(MappingUtils.EPG_EXTERNAL_ID.getValue());
+        externalSecGrp.setSecurityGroupName("EXTERNAL_group");
+        externalSecGrp.setTenantID(tenantUuid);
+        externalSecGrp.setSecurityRules(ImmutableList.of(inIpv4, outIpv4, inIpv6, outIpv6));
+        boolean isAddedNeutronSecurityGroup = secGrpAware.addNeutronSecurityGroup(externalSecGrp, rwTx);
+        if (!isAddedNeutronSecurityGroup) {
+            LOG.error("Problem with adding External Neutron Security Group representing External Implicit Group. {}", externalSecGrp);
+            return;
         }
+        ExternalImplicitGroup eig = new ExternalImplicitGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build();
+        rwTx.put(LogicalDatastoreType.CONFIGURATION,
+                IidFactory.externalImplicitGroupIid(tenantId, eig.getId()), eig, true);
     }
 
-    private void addEpgRouterIfMissing(TenantId tenantId, ReadWriteTransaction rwTx) {
-        Optional<EndpointGroup> potentialEpgRouter = DataStoreHelper.readFromDs(LogicalDatastoreType.CONFIGURATION,
-                IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), rwTx);
-        if (!potentialEpgRouter.isPresent()) {
-            EndpointGroup epgRouter = new EndpointGroupBuilder().setId(MappingUtils.EPG_ROUTER_ID)
-                .setDescription(new Description(MappingUtils.NEUTRON_ROUTER__ + "epg_routers"))
-                .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
-                .build();
-            rwTx.put(LogicalDatastoreType.CONFIGURATION,
-                    IidFactory.endpointGroupIid(tenantId, MappingUtils.EPG_ROUTER_ID), epgRouter);
-        }
+    private void addProviderPhysicalNetworkMapping(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId,
+            WriteTransaction wTx) {
+        ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder()
+            .setTenantId(tenantId).setL2FloodDomainId(l2FdId).setSegmentationId(segmentationId).build();
+        wTx.put(LogicalDatastoreType.OPERATIONAL,
+                NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, l2FdId), provNetAsL2Fd);
     }
 
     /**
@@ -193,8 +229,9 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
-        Optional<NetworkMapping> potentionalNetworkMapping = DataStoreHelper.readFromDs(
-                LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), rwTx);
+        InstanceIdentifier<NetworkMapping> networkMappingIid = NeutronMapperIidFactory.networkMappingIid(l2FdId);
+        Optional<NetworkMapping> potentionalNetworkMapping =
+                DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, networkMappingIid, rwTx);
         if (!potentionalNetworkMapping.isPresent()) {
             LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
             rwTx.cancel();
@@ -234,7 +271,8 @@ public class NeutronNetworkAware implements INeutronNetworkAware {
             return;
         }
 
+        rwTx.delete(LogicalDatastoreType.OPERATIONAL, networkMappingIid);
+
         DataStoreHelper.submitToDs(rwTx);
     }
-
 }