X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=neutron-mapper%2Fsrc%2Fmain%2Fjava%2Forg%2Fopendaylight%2Fgroupbasedpolicy%2Fneutron%2Fmapper%2Fmapping%2FNeutronPortAware.java;h=368699ddaf02db78419d56c475d8dc4fed89e591;hb=refs%2Fchanges%2F29%2F60029%2F3;hp=07a0129a81c9dcd1d3042f2fa58794e87cd08972;hpb=81de018f6fd0dd13818e636b7ea577eec3ed536d;p=groupbasedpolicy.git diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java index 07a0129a8..368699dda 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAware.java @@ -10,12 +10,14 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping; import static com.google.common.base.Preconditions.checkNotNull; import java.util.ArrayList; +import java.util.Collections; import java.util.List; import java.util.Set; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; 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; @@ -23,6 +25,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.domain_extension.l2_l3.util.L2L3IidFactory; import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory; import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator; +import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.MetadataService; import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient; import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; @@ -30,6 +33,8 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SubnetUtils; import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; import org.opendaylight.groupbasedpolicy.util.IidFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpAddress; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.MacAddress; 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.base_endpoint.rev160427.RegisterEndpointInput; @@ -38,6 +43,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpo import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInputBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.NetworkContainmentBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.common.endpoint.fields.network.containment.containment.NetworkDomainContainmentBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.child.endpoints.ChildEndpointBuilder; @@ -62,9 +68,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.r import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L2Builder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.unregister.endpoint.input.L3Builder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L3Context; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.MacAddressType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.IpPrefixType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.L3Context; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev170511.MacAddressType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.NetworkDomain; @@ -77,8 +83,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev 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.port.attributes.FixedIpsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIpsKey; 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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortBuilder; 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.Subnet; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; @@ -87,6 +96,7 @@ import org.slf4j.LoggerFactory; import com.google.common.base.Optional; import com.google.common.collect.ImmutableList; +import com.google.common.collect.Lists; public class NeutronPortAware implements NeutronAware { @@ -95,10 +105,13 @@ public class NeutronPortAware implements NeutronAware { InstanceIdentifier.builder(Neutron.class).child(Ports.class).child(Port.class).build(); private final DataBroker dataProvider; private final EndpointRegistrator epRegistrator; + private final IpPrefix metadataIpPrefix; - public NeutronPortAware(DataBroker dataProvider, EndpointRegistrator epRegistrator) { + public NeutronPortAware(DataBroker dataProvider, EndpointRegistrator epRegistrator, + @Nullable IpPrefix metadataIpPrefix) { this.dataProvider = checkNotNull(dataProvider); this.epRegistrator = checkNotNull(epRegistrator); + this.metadataIpPrefix = checkNotNull(metadataIpPrefix); } @Override public void onCreated(Port createdItem, Neutron neutron) { @@ -119,12 +132,10 @@ public class NeutronPortAware implements NeutronAware { 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())) { @@ -134,19 +145,16 @@ public class NeutronPortAware implements NeutronAware { LOG.warn("QRouter port does not have an IP address. {}", port); return; } - FixedIps ipWithSubnet = firstFixedIps.get(); NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue()); List 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 = @@ -156,7 +164,6 @@ public class NeutronPortAware implements NeutronAware { 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 @@ -175,8 +182,7 @@ public class NeutronPortAware implements NeutronAware { .build(); rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true); // set virtual router IP for subnet - NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet( - routerPortSubnet, portIpWithSubnet.getIpAddress()); + NetworkDomain subnetDomain = NeutronSubnetAware.createSubnet(routerPortSubnet, neutron, null); rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnetDomain.getNetworkDomainId()), subnetDomain); // does the same for tenant forwarding domains @@ -195,21 +201,18 @@ public class NeutronPortAware implements NeutronAware { NetworkDomainId networkContainment = new NetworkDomainId(ipWithSubnet.getSubnetId().getValue()); List epgsFromSecGroups = resolveEpgIdsFromSecGroups(port.getSecurityGroups()); epgsFromSecGroups.add(NetworkService.EPG_ID); - - // BUILD BASE ENDPOINT AddressEndpointRegBuilder l2BaseEp = createBasicMacAddrEpInputBuilder(port, networkContainment, - epgsFromSecGroups); + Collections.emptyList()); AddressEndpointRegBuilder l3BaseEp = createBasicL3AddrEpInputBuilder(port, networkContainment, epgsFromSecGroups, neutron); - setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp); - // BUILD ENDPOINT + setParentChildRelationshipForEndpoints(l3BaseEp, l2BaseEp); org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInputBuilder epInBuilder = createEndpointRegFromPort( port, ipWithSubnet, networkContainment, epgsFromSecGroups, neutron); - ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); registerBaseEndpointAndStoreMapping( - ImmutableList.of(l2BaseEp.build(), l3BaseEp.build()), port, rwTx, addBaseEpMapping); + ImmutableList.of(l3BaseEp.build(), l2BaseEp.build()), port, rwTx, addBaseEpMapping); + registerMetadataServiceForDhcpPort(port, neutron, l2BaseEp, rwTx, true); registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx); DataStoreHelper.submitToDs(rwTx); } else if (PortUtils.isNormalPort(port)) { @@ -254,6 +257,39 @@ public class NeutronPortAware implements NeutronAware { } } + private Port cloneMetadataPortFromDhcpPort(Port port, IpPrefix metadataPrefix) { + IpAddress metadataIp = MappingUtils.ipPrefixToIpAddress(metadataPrefix); + List metadataIps = port.getFixedIps().stream().map(fi -> { + FixedIpsKey key = new FixedIpsKey(metadataIp, fi.getKey().getSubnetId()); + return new FixedIpsBuilder(fi).setKey(key).setIpAddress(metadataIp).build(); + }).collect(Collectors.toList()); + return new PortBuilder(port).setFixedIps(metadataIps).build(); + } + + private void registerMetadataServiceForDhcpPort(Port port, Neutron neutron, AddressEndpointRegBuilder childEpToAdd, + ReadWriteTransaction rwTx, boolean registerMapping) { + Optional resolveNetworkContainment = PortUtils.resolveNetworkContainment(port); + if (!resolveNetworkContainment.isPresent()) { + LOG.warn("DHCP port does not have an IP address. {}", port); + return; + } + AddressEndpointRegBuilder metadataEp = + createBasicL3AddrEpInputBuilder(cloneMetadataPortFromDhcpPort(port, metadataIpPrefix), + resolveNetworkContainment.get(), Lists.newArrayList(MetadataService.EPG_ID), neutron); + AddressEndpointKey aek = new AddressEndpointKey(metadataEp.getAddress(), metadataEp.getAddressType(), + metadataEp.getContextId(), metadataEp.getContextType()); + Optional optMetadataEp = + DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(aek), rwTx); + if (!optMetadataEp.isPresent()) { + setParentChildRelationshipForEndpoints(metadataEp, childEpToAdd); + } else { + List childs = optMetadataEp.get().getChildEndpoint(); + childs.add(createChildEndpoint(childEpToAdd)); + metadataEp.setChildEndpoint(childs); + } + registerBaseEndpointAndStoreMapping(ImmutableList.of(metadataEp.build()), port, rwTx, registerMapping); + } + private void setParentChildRelationshipForEndpoints(AddressEndpointRegBuilder parentEp, AddressEndpointRegBuilder childEp) { childEp.setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint( @@ -292,6 +328,26 @@ public class NeutronPortAware implements NeutronAware { } private void changeL3ContextForEpsInSubnet(Uuid subnetUuid, Neutron neutron) { + if (neutron == null) { + LOG.debug("No new data are written, there is no L3 context in subnet {} to update", subnetUuid); + return; + } + java.util.Optional optSubnet = neutron.getSubnets() + .getSubnet() + .stream() + .filter(subnet -> subnet.getNetworkId() != null && subnet.getUuid().getValue().equals(subnetUuid.getValue())) + .findAny(); + if (!optSubnet.isPresent()) { + LOG.error("Failed to update metadata endpoint in subnet {}. Could not resolve Network ID", subnetUuid); + } else { + AddressEndpointUnreg metadataEpUnreg = + new AddressEndpointUnregBuilder().setAddress(String.valueOf(metadataIpPrefix.getValue())) + .setAddressType(IpPrefixType.class) + .setContextId(new ContextId(optSubnet.get().getNetworkId().getValue())) + .setContextType(MappingUtils.L3_CONTEXT) + .build(); + epRegistrator.unregisterEndpoint(metadataEpUnreg); + } Set portsInSameSubnet = PortUtils.findPortsBySubnet(subnetUuid, neutron.getPorts()); for (Port portInSameSubnet : portsInSameSubnet) { if (PortUtils.isNormalPort(portInSameSubnet) || PortUtils.isDhcpPort(portInSameSubnet) @@ -322,7 +378,15 @@ public class NeutronPortAware implements NeutronAware { RegisterEndpointInput regBaseEpInput = new RegisterEndpointInputBuilder() .setAddressEndpointReg(ImmutableList.of(l2BaseEp.build(), l3BaseEp.build())).build(); epRegistrator.registerEndpoint(regBaseEpInput); - + if(PortUtils.isDhcpPort(portInSameSubnet)) { + ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction(); + registerMetadataServiceForDhcpPort(portInSameSubnet, neutron, l2BaseEp, rwTx, false); + try { + rwTx.submit().get(); + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to update metadata endpoint for DHCP port {}. {}", portInSameSubnet, e); + } + } modifyL3ContextForEndpoints(portInSameSubnet, ipWithSubnet, l3BaseEp.getContextId()); } } @@ -454,7 +518,7 @@ public class NeutronPortAware implements NeutronAware { Port port, ReadWriteTransaction rwTx) { boolean isRegisteredEndpoint = epRegistrator.registerEndpoint(regEpInput); if (!isRegisteredEndpoint) { - LOG.error("Failed to register an endpoint: {}", regEpInput); + LOG.error("Failed to register endpoint: {}", regEpInput); return; } UniqueId portId = new UniqueId(port.getUuid().getValue()); @@ -495,7 +559,7 @@ public class NeutronPortAware implements NeutronAware { boolean isRegisteredBaseEndpoint = epRegistrator.registerEndpoint(regBaseEpInput); if (!isRegisteredBaseEndpoint) { - LOG.error("Failed to register an address endpoint: {}", addrEpRegs); + LOG.error("Failed to register address endpoint: {}", addrEpRegs); return; } for (AddressEndpointReg addrEpReg : addrEpRegs) { @@ -566,7 +630,7 @@ public class NeutronPortAware implements NeutronAware { } FixedIps portIpWithSubnet = potentialPortIpWithSubnet.get(); L3ContextId l3Context = new L3ContextId(port.getNetworkId().getValue()); - // change L3Context for all EPs with same subnet as router port + // change L3Context for all new EPs with same subnet as router port changeL3ContextForEpsInSubnet(portIpWithSubnet.getSubnetId(), newNeutron); // set L3Context as parent for bridge domain which is parent of subnet TenantId tenantId = new TenantId(port.getTenantId().getValue()); @@ -586,7 +650,7 @@ public class NeutronPortAware implements NeutronAware { .build(); rwTx.merge(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, fwdCtx.getContextId()), fwdCtx); - NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, null); + NetworkDomain subnet = NeutronSubnetAware.createSubnet(routerPortSubnet, newNeutron, null); rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.subnetIid(tenantId, subnet.getNetworkDomainId()), subnet); unregisterEndpointAndRemoveMapping(createUnregisterEndpointInput(port, oldNeutron), port, rwTx);