From 5d08027112b2880944d86b6ff4dc36bc09c9b73d Mon Sep 17 00:00:00 2001 From: Tomas Cechvala Date: Mon, 10 Apr 2017 17:39:51 +0200 Subject: [PATCH] Bug 8228 - metadata service fix made cleaner This patch sticks more to the architecture. In OPNFV scenarios, Openstack metadata service may be reached via DHCP port which acts as a GW to metadata server. VMs have a route configured to metadata server via DHCP port. Metadata IP and port are specified in blueprint cfg file and processed by neutron-mapper bundle. An ip-prefix endpoint is registered by neutron-mapper, it points to the same mac- address endpoint as DHCP ip-prefix endpoint, i.e. DHCP ip-prefix EP & Metadata ip-prefix EP point to the same mac address endpoint. This configuration is supported by VPP renderer's implementation of location resolver. In this case both DHCP and Metadata have the same absolute location. When ACL manager recongnizes this fact, it will build ACL for both endpoints behind the same interface. Remote IP prefix is revisioned here too. Remote IP prefix is mapped to GBP as external ip-prefix endpoint. Location resolver then looks for external interfaces and on nodes and create a relative location for this endpoint. Change-Id: Id72d5646fbd7af1a8094749e58ba714bb3d84959 Signed-off-by: Tomas Cechvala --- .../location/resolver/LocationResolver.java | 4 +- .../renderer/EndpointLocationInfo.java | 3 +- .../renderer/util/AddressEndpointUtils.java | 31 ++ .../util/DataTreeChangeHandler.java | 7 + .../groupbasedpolicy/util/EndpointUtils.java | 47 +++ .../groupbasedpolicy/util/IidFactory.java | 69 +--- .../impl/NeutronMapperInstance.java | 16 +- .../neutron/mapper/NeutronMapper.java | 8 +- .../infrastructure/MetadataService.java | 169 ++++++++ .../mapper/infrastructure/NetworkClient.java | 10 +- .../mapper/infrastructure/NetworkService.java | 375 ++++-------------- .../mapper/infrastructure/ServiceUtil.java | 166 ++++++++ .../mapper/mapping/NeutronNetworkAware.java | 22 +- .../mapper/mapping/NeutronPortAware.java | 40 +- .../rule/NeutronSecurityRuleAware.java | 59 ++- .../opendaylight/blueprint/neutron-mapper.xml | 2 +- neutron-mapper/src/main/resources/startup.cfg | 2 +- .../infrastructure/NetworkServiceTest.java | 13 +- .../NeutronNetworkAwareDataStoreTest.java | 4 +- .../NeutronPortAwareDataStoreTest.java | 6 +- .../NeutronRouterAwareDataStoreTest.java | 2 +- ...eutronSecurityGroupAwareDataStoreTest.java | 21 +- ...NeutronSecurityRuleAwareDataStoreTest.java | 23 +- .../rule/NeutronSecurityRuleAwareTest.java | 11 +- .../test/NeutronMapperDataBrokerTest.java | 23 +- .../vpp/mapper/processors/PortHandler.java | 3 +- .../config/vpp_provider/impl/VppRenderer.java | 2 +- .../renderer/vpp/iface/AclManager.java | 77 ---- .../renderer/vpp/iface/InterfaceManager.java | 2 +- .../iface/VppEndpointLocationProvider.java | 310 +++++++++++++-- .../renderer/vpp/manager/VppNodeManager.java | 28 ++ .../vpp/policy/ForwardingManager.java | 5 +- .../vpp/policy/VppRendererPolicyManager.java | 5 +- .../vpp/policy/acl/AccessListUtil.java | 64 +-- .../renderer/vpp/policy/acl/AclManager.java | 179 +++++++++ .../vpp/policy/acl/DestinationMapper.java | 39 +- .../renderer/vpp/policy/acl/SourceMapper.java | 38 +- .../renderer/vpp/util/VppIidFactory.java | 8 +- .../vpp/iface/InterfaceManagerTest.java | 25 +- .../VppEndpointLocationProviderTest.java | 56 ++- .../policy/BridgeDomainManagerImplTest.java | 2 +- .../vpp/policy/ForwardingManagerTest.java | 2 +- .../policy/VppRendererPolicyManagerTest.java | 14 +- .../vpp/policy/acl/AccessListUtilTest.java | 15 +- 44 files changed, 1309 insertions(+), 698 deletions(-) create mode 100644 neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java create mode 100644 neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java delete mode 100644 renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java create mode 100644 renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java index 02f5419e5..623a917d8 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/location/resolver/LocationResolver.java @@ -105,7 +105,9 @@ public class LocationResolver implements ClusteredDataTreeChangeListener iid = IidFactory.absoluteLocationIid(epKey); diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java index dabf7e90d..3bae3ff8d 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/EndpointLocationInfo.java @@ -125,8 +125,7 @@ public class EndpointLocationInfo { if (relLocations == null) { return false; } - List locs = relLocations.getInternalLocation(); - if (locs == null) { + if (relLocations.getInternalLocation() == null && relLocations.getExternalLocation() == null) { return false; } return true; diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/util/AddressEndpointUtils.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/util/AddressEndpointUtils.java index f8688cf0f..623ff8ab5 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/util/AddressEndpointUtils.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/renderer/util/AddressEndpointUtils.java @@ -8,7 +8,13 @@ package org.opendaylight.groupbasedpolicy.renderer.util; +import java.util.Optional; + 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.absolute.location.absolute.location.LocationType; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerExternalEndpointKey; @@ -40,8 +46,33 @@ public class AddressEndpointUtils { peerEpKey.getContextType()); } + public static AddressEndpointKey fromAddressEndpointWithLocationKey(AddressEndpointWithLocationKey key) { + return new AddressEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType()); + } + public static AddressEndpointKey fromPeerExtEpKey(PeerExternalEndpointKey peerExtEpKey) { return new AddressEndpointKey(peerExtEpKey.getAddress(), peerExtEpKey.getAddressType(), peerExtEpKey.getContextId(), peerExtEpKey.getContextType()); } + + /** + * Compares absolute external locations of address end-points in the arguments. + */ + public static boolean sameExternalLocationCase(AddressEndpointWithLocation ae0, AddressEndpointWithLocation ae1) { + if (ae0.getAbsoluteLocation() == null || ae1.getAbsoluteLocation() == null) { + return false; + } + Optional loc0Type = Optional.ofNullable(ae0.getAbsoluteLocation().getLocationType()); + Optional loc1Type = Optional.ofNullable(ae1.getAbsoluteLocation().getLocationType()); + if (!(loc0Type.isPresent() && loc0Type.get() instanceof ExternalLocationCase) + || !(loc1Type.isPresent() && loc1Type.get() instanceof ExternalLocationCase)) { + return false; + } + ExternalLocationCase loc0 = (ExternalLocationCase) loc0Type.get(); + ExternalLocationCase loc1 = (ExternalLocationCase) loc1Type.get(); + return (loc0.getExternalNodeMountPoint() == null || loc1.getExternalNodeMountPoint() == null + || loc0.getExternalNodeConnector() == null || loc1.getExternalNodeConnector() == null) ? false : loc0 + .getExternalNodeMountPoint().toString().equals(loc1.getExternalNodeMountPoint().toString()) + && loc0.getExternalNodeConnector().equals(loc1.getExternalNodeConnector()); + } } diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/DataTreeChangeHandler.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/DataTreeChangeHandler.java index 9321163a4..f19797fb3 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/DataTreeChangeHandler.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/DataTreeChangeHandler.java @@ -108,6 +108,13 @@ public abstract class DataTreeChangeHandler implements Clu @Override public void close() { + closeRegisteredListener(); + } + + /** + * For child classes which override close() method. + */ + protected void closeRegisteredListener() { registeredListener.close(); } diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/EndpointUtils.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/EndpointUtils.java index dcc056a7d..909f69599 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/EndpointUtils.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/EndpointUtils.java @@ -8,19 +8,34 @@ package org.opendaylight.groupbasedpolicy.util; +import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.concurrent.ExecutionException; import javax.annotation.Nonnull; import javax.annotation.Nullable; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +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.absolute.location.absolute.location.location.type.ExternalLocationCase; 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.parent.child.endpoints.ParentEndpointChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentContainmentEndpointCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.ParentEndpointCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.containment.endpoint._case.ParentContainmentEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; + +import com.google.common.base.Function; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; public class EndpointUtils { @@ -57,4 +72,36 @@ public class EndpointUtils { } return Collections.emptyList(); } + + public static boolean isExternalEndpoint(@Nonnull DataBroker dataBroker, @Nonnull AddressEndpoint addrEp) { + ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction(); + List> results = new ArrayList<>(); + for (EndpointGroupId epgId : addrEp.getEndpointGroup()) { + results.add(Futures.transform( + rTx.read(LogicalDatastoreType.CONFIGURATION, + IidFactory.externalImplicitGroupIid(addrEp.getTenant(), epgId)), + new Function, Boolean>() { + + @Override + public Boolean apply(Optional input) { + return input.isPresent(); + } + })); + } + rTx.close(); + try { + List list = Futures.allAsList(results).get(); + return list.stream().anyMatch(Boolean::booleanValue); + } catch (InterruptedException | ExecutionException e) { + return false; + } + } + + public static Optional getExternalLocationFrom(AddressEndpointWithLocation input) { + if (input.getAbsoluteLocation() != null && input.getAbsoluteLocation().getLocationType() != null + && input.getAbsoluteLocation().getLocationType() instanceof ExternalLocationCase) { + return Optional.of((ExternalLocationCase) input.getAbsoluteLocation().getLocationType()); + } + return Optional.absent(); + } } diff --git a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java index 5c7cf1dee..6c90580c9 100644 --- a/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java +++ b/groupbasedpolicy/src/main/java/org/opendaylight/groupbasedpolicy/util/IidFactory.java @@ -115,6 +115,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecord; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.statistics.store.rev151215.statistics.store.StatisticRecordKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier.InstanceIdentifierBuilder; public class IidFactory { @@ -129,96 +130,69 @@ public class IidFactory { return InstanceIdentifier.builder(Tenants.class).child(Tenant.class, new TenantKey(id)).build(); } - public static InstanceIdentifier endpointGroupIid(TenantId tenantId, EndpointGroupId epgId) { + public static InstanceIdentifierBuilder policyIid(TenantId tenantId) { return InstanceIdentifier.builder(Tenants.class) .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(EndpointGroup.class, new EndpointGroupKey(epgId)) - .build(); + .child(Policy.class); + } + + public static InstanceIdentifier endpointGroupIid(TenantId tenantId, EndpointGroupId epgId) { + return policyIid(tenantId).child(EndpointGroup.class, new EndpointGroupKey(epgId)).build(); } public static InstanceIdentifier contractIid(TenantId tenantId, ContractId contractId) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(Contract.class, new ContractKey(contractId)) - .build(); + return policyIid(tenantId).child(Contract.class, new ContractKey(contractId)).build(); } public static InstanceIdentifier contractWildcardIid(TenantId tenantId) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(Contract.class) - .build(); + return policyIid(tenantId).child(Contract.class).build(); } public static InstanceIdentifier subjectIid(TenantId tenantId, ContractId contractId, SubjectName subjectName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(Contract.class, new ContractKey(contractId)) + return policyIid(tenantId).child(Contract.class, new ContractKey(contractId)) .child(Subject.class, new SubjectKey(subjectName)) .build(); } public static InstanceIdentifier providerNamedSelectorIid(TenantId tenantId, EndpointGroupId epgId, SelectorName providerSelectorName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(EndpointGroup.class, new EndpointGroupKey(epgId)) + return policyIid(tenantId).child(EndpointGroup.class, new EndpointGroupKey(epgId)) .child(ProviderNamedSelector.class, new ProviderNamedSelectorKey(providerSelectorName)) .build(); } public static InstanceIdentifier consumerNamedSelectorIid(TenantId tenantId, EndpointGroupId epgId, SelectorName consumerSelectorName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(EndpointGroup.class, new EndpointGroupKey(epgId)) + return policyIid(tenantId).child(EndpointGroup.class, new EndpointGroupKey(epgId)) .child(ConsumerNamedSelector.class, new ConsumerNamedSelectorKey(consumerSelectorName)) .build(); } public static InstanceIdentifier clauseIid(TenantId tenantId, ContractId contractId, ClauseName clauseName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(Contract.class, new ContractKey(contractId)) + return policyIid(tenantId).child(Contract.class, new ContractKey(contractId)) .child(Clause.class, new ClauseKey(clauseName)) .build(); } public static InstanceIdentifier ruleIid(TenantId tenantId, ContractId contractId, SubjectName subjectName, RuleName ruleName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(Contract.class, new ContractKey(contractId)) + return policyIid(tenantId).child(Contract.class, new ContractKey(contractId)) .child(Subject.class, new SubjectKey(subjectName)) .child(Rule.class, new RuleKey(ruleName)) .build(); } public static InstanceIdentifier actionInstanceIid(TenantId tenantId, ActionName actionName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(SubjectFeatureInstances.class) + return policyIid(tenantId).child(SubjectFeatureInstances.class) .child(ActionInstance.class, new ActionInstanceKey(actionName)) .build(); } public static InstanceIdentifier classifierInstanceIid(TenantId tenantId, ClassifierName classifierName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(SubjectFeatureInstances.class) + return policyIid(tenantId).child(SubjectFeatureInstances.class) .child(ClassifierInstance.class, new ClassifierInstanceKey(classifierName)) .build(); } @@ -238,10 +212,7 @@ public class IidFactory { public static InstanceIdentifier classifierRefIid(TenantId tenantId, ContractId contractId, SubjectName subjectName, RuleName ruleName, ClassifierName classifierRefName) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(Contract.class, new ContractKey(contractId)) + return policyIid(tenantId).child(Contract.class, new ContractKey(contractId)) .child(Subject.class, new SubjectKey(subjectName)) .child(Rule.class, new RuleKey(ruleName)) .child(ClassifierRef.class, new ClassifierRefKey(classifierRefName)) @@ -384,11 +355,7 @@ public class IidFactory { public static InstanceIdentifier externalImplicitGroupIid(TenantId tenantId, EndpointGroupId epgId) { - return InstanceIdentifier.builder(Tenants.class) - .child(Tenant.class, new TenantKey(tenantId)) - .child(Policy.class) - .child(ExternalImplicitGroup.class, new ExternalImplicitGroupKey(epgId)) - .build(); + return policyIid(tenantId).child(ExternalImplicitGroup.class, new ExternalImplicitGroupKey(epgId)).build(); } public static InstanceIdentifier containmentEndpointIid(ContainmentEndpointKey key) { diff --git a/neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java b/neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java index e7a6d2cd8..b761246ed 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java +++ b/neutron-mapper/src/main/java/org/opendaylight/controller/config/yang/config/neutron_mapper/impl/NeutronMapperInstance.java @@ -8,7 +8,9 @@ package org.opendaylight.controller.config.yang.config.neutron_mapper.impl; -import java.util.regex.Pattern; +import java.net.Inet4Address; +import java.net.Inet6Address; +import java.net.InetAddress; import com.google.common.base.Preconditions; import com.google.common.util.concurrent.Futures; @@ -23,6 +25,7 @@ import org.opendaylight.mdsal.singleton.common.api.ClusterSingletonServiceRegist import org.opendaylight.mdsal.singleton.common.api.ServiceGroupIdentifier; 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.inet.types.rev130715.Ipv4Prefix; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.BaseEndpointService; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.EndpointService; import org.slf4j.Logger; @@ -51,11 +54,15 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose this.rpcBroker = Preconditions.checkNotNull(rpcBroker); this.clusterSingletonService = Preconditions.checkNotNull(clusterSingletonService); try { - this.metadataIpPrefix = new IpPrefix(new Ipv4Prefix(Preconditions.checkNotNull(metadataIp))); + InetAddress inetAddr = InetAddress.getByName(metadataIp); + if (inetAddr instanceof Inet4Address) { + this.metadataIpPrefix = new IpPrefix(new Ipv4Prefix(Preconditions.checkNotNull(metadataIp) + "/32")); + } else if (inetAddr instanceof Inet6Address) { + this.metadataIpPrefix = new IpPrefix(new Ipv6Prefix(Preconditions.checkNotNull(metadataIp) + "/128")); + } this.metadataPort = Integer.parseInt(Preconditions.checkNotNull(metadataPort)); - LOG.trace("Resolved Metadata IP prefix: {}", metadataIpPrefix); + LOG.info("Resolved Metadata CIDR: {} and port {}.", metadataIpPrefix, metadataPort); } catch (Exception ex) { - if (ex instanceof NumberFormatException) { LOG.warn("Metadata port cannot be resolved. Provided value: {}. Continue without support for metadata.", metadataPort); @@ -65,7 +72,6 @@ public class NeutronMapperInstance implements ClusterSingletonService, AutoClose } this.metadataIpPrefix = null; } - } public void instantiate() { diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java index 1b6239717..da456032c 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/NeutronMapper.java @@ -106,13 +106,13 @@ public class NeutronMapper implements ClusteredDataTreeChangeListener, private Neutron neutronAfter; public NeutronMapper(DataBroker dataProvider, EndpointService epService, BaseEndpointService baseEpService, - @Nullable IpPrefix metadataIpPrefix, long metadataPort) { + @Nullable IpPrefix metadataIpPrefix, long metadataTcpPort) { EndpointRegistrator epRegistrator = new EndpointRegistrator(epService, baseEpService); - networkAware = new NeutronNetworkAware(dataProvider, metadataIpPrefix, metadataPort); - securityRuleAware = new NeutronSecurityRuleAware(dataProvider); + networkAware = new NeutronNetworkAware(dataProvider, metadataTcpPort); + securityRuleAware = new NeutronSecurityRuleAware(dataProvider, epRegistrator); securityGroupAware = new NeutronSecurityGroupAware(dataProvider, securityRuleAware); subnetAware = new NeutronSubnetAware(dataProvider, epRegistrator); - portAware = new NeutronPortAware(dataProvider, epRegistrator); + portAware = new NeutronPortAware(dataProvider, epRegistrator, metadataIpPrefix); routerAware = new NeutronRouterAware(dataProvider, epRegistrator); floatingIpAware = new NeutronFloatingIpAware(dataProvider); registerDataTreeChangeListener = diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java new file mode 100644 index 000000000..5fe122044 --- /dev/null +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/MetadataService.java @@ -0,0 +1,169 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure; + +import java.util.Collections; +import java.util.HashSet; +import java.util.Set; + +import javax.annotation.Nullable; + +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; +import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition; +import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition; +import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition; +import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; +import org.opendaylight.groupbasedpolicy.util.IidFactory; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraints; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance; + +import com.google.common.collect.ImmutableList; + +public class MetadataService extends ServiceUtil { + + private static final ClassifierName METADATA_SERVER_TO_CLIENT_NAME = + new ClassifierName("METADATA_FROM_SERVER_TO_CLIENT"); + private static final ClassifierName METADATA_CLIENT_TO_SERVER_NAME = + new ClassifierName("METADATA_FROM_CLIENT_TO_SERVER"); + private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA"); + private static final Description METADATA_CONTRACT_DESC = + new Description("Allow METADATA management communication between server and client."); + + /** + * Id of {@link #METADATA_CONTRACT} + */ + public static final ContractId METADATA_CONTRACT_ID = new ContractId("be0675b7-b0d6-46cc-acf1-247ed31cf572"); + /** + * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH + * communication + * between Client and Server. + */ + public static final Contract METADATA_CONTRACT; + /** + * {@link ConsumerNamedSelector} pointing to {@link #METADATA_CONTRACT} + */ + public static final ConsumerNamedSelector METADATA_CONTRACT_CONSUMER_SELECTOR; + + // ########### NETWORK-SERVICE ENDPOINT-GROUP + private static final Name METADATA_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE"); + private static final Description METADATA_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers."); + /** + * ID of {@link #EPG} + */ + public static final EndpointGroupId EPG_ID = new EndpointGroupId("ffff1111-dfe5-11e4-8a00-1681e6b88ec1"); + /** + * Network-service endpoint-group providing {@link #METADATA_CONTRACT} + */ + public static final EndpointGroup EPG; + + static { + METADATA_CONTRACT = createContractMetadata(); + METADATA_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(METADATA_CONTRACT); + EPG = createNetworkServiceEpg(); + } + + private static EndpointGroup createNetworkServiceEpg() { + ProviderNamedSelector metadataProviderSelector = createProviderSelector(METADATA_CONTRACT); + return createEpgBuilder(EPG_ID, METADATA_SERVICE_EPG_NAME, METADATA_SERVICE_EPG_DESC) + .setProviderNamedSelector(ImmutableList.of(metadataProviderSelector)) + .build(); + } + + private static Contract createContractMetadata() { + Rule serverClientMetadataIpv4Rule = createRuleAllow(METADATA_SERVER_TO_CLIENT_NAME, Direction.Out); + Rule clientServerMetadataIpv4Rule = createRuleAllow(METADATA_CLIENT_TO_SERVER_NAME, Direction.In); + Subject subject = new SubjectBuilder().setName(METADATA_SUBJECT_NAME) + .setOrder(0) + .setRule(ImmutableList.of(serverClientMetadataIpv4Rule, clientServerMetadataIpv4Rule)) + .build(); + return createContract(METADATA_CONTRACT_ID, ImmutableList.of(subject), METADATA_CONTRACT_DESC); + } + + /** + * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers} + * and {@link ProviderMatchers}. This clause points to subject in {@link #METADATA_CONTRACT}. + * + * @param tenantId location of {@link #METADATA_CONTRACT} + * @param ipPrefix used in {@link L3EndpointIdentificationConstraints} + * @param wTx transaction where entities are written + */ + public static void writeMetadataClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix, + WriteTransaction wTx) { + Clause clause = createClauseWithConsProvEic(ipPrefix, METADATA_SUBJECT_NAME); + wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, METADATA_CONTRACT_ID, clause.getName()), + clause, true); + } + + /** + * Puts network service entities (classifier-instances, {@link #METADATA_CONTRACT}, + * and {@link #EPG}) to {@link LogicalDatastoreType#CONFIGURATION} + * + * @param tenantId location of network-service entities + * @param wTx transaction where network-service entities are written + */ + public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx, long metadataPort) { + Set classifierInstances = getAllClassifierInstances(metadataPort); + for (ClassifierInstance ci : classifierInstances) { + wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci, + true); + } + for (ActionInstance ai : Collections.singleton(MappingUtils.ACTION_ALLOW)) { + wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.actionInstanceIid(tenantId, ai.getName()), ai, true); + } + wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, METADATA_CONTRACT_ID), METADATA_CONTRACT, + true); + wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true); + } + + /** + * @return All classifier-instances used in {@link #METADATA_CONTRACT} + */ + public static Set getAllClassifierInstances(long metadataPort) { + HashSet cis = new HashSet<>(); + // METADATA + cis.add(createMetadataIpv4ClientServer(metadataPort)); + cis.add(createMetadataIpv4ServerClient(metadataPort)); + return cis; + } + + private static ClassifierInstance createMetadataIpv4ClientServer(long dstPort) { + return createClassifInstance(METADATA_CLIENT_TO_SERVER_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, null, dstPort)); + } + + private static ClassifierInstance createMetadataIpv4ServerClient(long srcPort) { + return createClassifInstance(METADATA_SERVER_TO_CLIENT_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, srcPort, null)); + } +} diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java index 0ac5cf05e..75a7907a0 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkClient.java @@ -16,13 +16,11 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev 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.policy.rev140421.tenants.tenant.policy.EndpointGroup; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector; import com.google.common.base.Preconditions; -public class NetworkClient { +public class NetworkClient extends ServiceUtil { private static final Name NETWORK_CLIENT_EPG_NAME = new Name("NETWORK_CLIENT"); private static final Description NETWORK_CLIENT_EPG_DESC = new Description("Represents DHCP and DNS clients."); @@ -40,11 +38,7 @@ public class NetworkClient { } private static EndpointGroup createNetworkClientEpg() { - return new EndpointGroupBuilder().setId(EPG_ID) - .setName(NETWORK_CLIENT_EPG_NAME) - .setIntraGroupPolicy(IntraGroupPolicy.RequireContract) - .setDescription(NETWORK_CLIENT_EPG_DESC) - .build(); + return createEpgBuilder(EPG_ID, NETWORK_CLIENT_EPG_NAME, NETWORK_CLIENT_EPG_DESC).build(); } /** diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java index 5ce0b774c..5dad3f059 100755 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkService.java @@ -8,10 +8,8 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure; -import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; -import java.util.List; import java.util.Set; import javax.annotation.Nullable; @@ -22,56 +20,33 @@ import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition; import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition; import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; -import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils; import org.opendaylight.groupbasedpolicy.util.IidFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraints; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder; import com.google.common.collect.ImmutableList; -public class NetworkService { +public class NetworkService extends ServiceUtil { /** * Unit tests {@link NetworkServiceTest} @@ -175,30 +150,6 @@ public class NetworkService { */ public static final ConsumerNamedSelector MGMT_CONTRACT_CONSUMER_SELECTOR; - // ########### METADATA management - private static final ClassifierName METADATA_SERVER_TO_CLIENT_NAME = - new ClassifierName("METADATA_FROM_SERVER_TO_CLIENT"); - private static final ClassifierName METADATA_CLIENT_TO_SERVER_NAME = - new ClassifierName("METADATA_FROM_CLIENT_TO_SERVER"); - private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA"); - private static final Description METADATA_CONTRACT_DESC = - new Description("Allow METADATA management communication between server and client."); - - /** - * Id of {@link #METADATA_CONTRACT} - */ - public static final ContractId METADATA_CONTRACT_ID = new ContractId("be0675b7-b0d6-46cc-acf1-247ed31cf572"); - /** - * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH - * communication - * between Client and Server. - */ - public static final Contract METADATA_CONTRACT; - /** - * {@link ConsumerNamedSelector} pointing to {@link #METADATA_CONTRACT} - */ - public static final ConsumerNamedSelector METADATA_CONTRACT_CONSUMER_SELECTOR; - // ########### NETWORK-SERVICE ENDPOINT-GROUP private static final Name NETWORK_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE"); private static final Description NETWORK_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers."); @@ -218,8 +169,6 @@ public class NetworkService { DNS_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DNS_CONTRACT); MGMT_CONTRACT = createContractMgmt(); MGMT_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(MGMT_CONTRACT); - METADATA_CONTRACT = createContractMetadata(); - METADATA_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(METADATA_CONTRACT); EPG = createNetworkServiceEpg(); } @@ -227,27 +176,8 @@ public class NetworkService { ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT); ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT); ProviderNamedSelector mgmtProviderSelector = createProviderSelector(MGMT_CONTRACT); - ProviderNamedSelector metadataProviderSelector = createProviderSelector(METADATA_CONTRACT); - return new EndpointGroupBuilder().setId(EPG_ID) - .setName(NETWORK_SERVICE_EPG_NAME) - .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector, - metadataProviderSelector)) - .setIntraGroupPolicy(IntraGroupPolicy.RequireContract) - .setDescription(NETWORK_SERVICE_EPG_DESC) - .build(); - } - - private static ProviderNamedSelector createProviderSelector(Contract contract) { - SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue()); - return new ProviderNamedSelectorBuilder().setName(selectorName) - .setContract(ImmutableList.of(contract.getId())) - .build(); - } - - private static ConsumerNamedSelector createConsumerSelector(Contract contract) { - SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue()); - return new ConsumerNamedSelectorBuilder().setName(selectorName) - .setContract(ImmutableList.of(contract.getId())) + return createEpgBuilder(EPG_ID, NETWORK_SERVICE_EPG_NAME, NETWORK_SERVICE_EPG_DESC) + .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector)) .build(); } @@ -261,10 +191,7 @@ public class NetworkService { .setRule(ImmutableList.of(clientServerIpv4Rule, serverClientIpv4Rule, clientServerIpv6Rule, serverClientIpv6Rule)) .build(); - return new ContractBuilder().setId(DHCP_CONTRACT_ID) - .setSubject(ImmutableList.of(subject)) - .setDescription(DHCP_CONTRACT_DESC) - .build(); + return createContract(DHCP_CONTRACT_ID, ImmutableList.of(subject), DHCP_CONTRACT_DESC); } private static Contract createContractDns() { @@ -282,10 +209,7 @@ public class NetworkService { serverClientUdpIpv6Rule, clientServerTcpIpv4Rule, serverClientTcpIpv4Rule, clientServerTcpIpv6Rule, serverClientTcpIpv6Rule)) .build(); - return new ContractBuilder().setId(DNS_CONTRACT_ID) - .setSubject(ImmutableList.of(subject)) - .setDescription(DNS_CONTRACT_DESC) - .build(); + return createContract(DNS_CONTRACT_ID, ImmutableList.of(subject), DNS_CONTRACT_DESC); } private static Contract createContractMgmt() { @@ -304,43 +228,7 @@ public class NetworkService { clientServerSshIpv6Rule, clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule, serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule)) .build(); - return new ContractBuilder().setId(MGMT_CONTRACT_ID) - .setSubject(ImmutableList.of(subject)) - .setDescription(MGMT_CONTRACT_DESC) - .build(); - } - - private static Contract createContractMetadata() { - Rule serverClientMetadataIpv4Rule = createRuleAllow(METADATA_SERVER_TO_CLIENT_NAME, Direction.Out); - Rule clientServerMetadataIpv4Rule = createRuleAllow(METADATA_CLIENT_TO_SERVER_NAME, Direction.In); - Rule serverClientIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.Out); - Rule serverClientIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.Out); - Rule clientServerIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.In); - Rule clientServerIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.In); - - Subject subject = new SubjectBuilder().setName(METADATA_SUBJECT_NAME) - .setOrder(0) - .setRule(ImmutableList.of(serverClientMetadataIpv4Rule, clientServerMetadataIpv4Rule, - clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule, - serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule)) - .build(); - return new ContractBuilder().setId(METADATA_CONTRACT_ID) - .setSubject(ImmutableList.of(subject)) - .setDescription(METADATA_CONTRACT_DESC) - .build(); - } - - private static Rule createRuleAllow(ClassifierName classifierName, Direction direction) { - ClassifierName name = - new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue()); - ClassifierRef classifierRef = new ClassifierRefBuilder().setName(name) - .setInstanceName(classifierName) - .setDirection(direction) - .build(); - return new RuleBuilder().setName(new RuleName(name)) - .setActionRef(ImmutableList.of(MappingUtils.ACTION_REF_ALLOW)) - .setClassifierRef(ImmutableList.of(classifierRef)) - .build(); + return createContract(MGMT_CONTRACT_ID, ImmutableList.of(subject), MGMT_CONTRACT_DESC); } /** @@ -388,54 +276,6 @@ public class NetworkService { clause, true); } - /** - * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers} - * and {@link ProviderMatchers}. This clause points to subject in {@link #METADATA_CONTRACT}. - * - * @param tenantId location of {@link #METADATA_CONTRACT} - * @param ipPrefix used in {@link L3EndpointIdentificationConstraints} - * @param wTx transaction where entities are written - */ - public static void writeMetadataClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix, - WriteTransaction wTx) { - Clause clause = createClauseWithConsProvEic(ipPrefix, METADATA_SUBJECT_NAME); - wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, METADATA_CONTRACT_ID, clause.getName()), - clause, true); - } - - private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) { - ConsumerMatchers consumerMatchers = null; - ProviderMatchers providerMatchers = null; - StringBuilder clauseName = new StringBuilder(); - clauseName.append(subjectName.getValue()); - if (ipPrefix != null) { - clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix)); - consumerMatchers = - new ConsumerMatchersBuilder() - .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder() - .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder() - .setPrefixConstraint( - ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build())) - .build()) - .build()) - .build(); - providerMatchers = - new ProviderMatchersBuilder() - .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder() - .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder() - .setPrefixConstraint( - ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build())) - .build()) - .build()) - .build(); - } - return new ClauseBuilder().setName(new ClauseName(clauseName.toString())) - .setSubjectRefs(ImmutableList.of(subjectName)) - .setConsumerMatchers(consumerMatchers) - .setProviderMatchers(providerMatchers) - .build(); - } - /** * Puts network service entities (classifier-instances, {@link #DHCP_CONTRACT}, * {@link #DNS_CONTRACT}, {@link #MGMT_CONTRACT} and {@link #EPG}) to @@ -444,8 +284,8 @@ public class NetworkService { * @param tenantId location of network-service entities * @param wTx transaction where network-service entities are written */ - public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx, long metadataPort) { - Set classifierInstances = getAllClassifierInstances(metadataPort); + public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx) { + Set classifierInstances = getAllClassifierInstances(); for (ClassifierInstance ci : classifierInstances) { wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci, true); @@ -459,8 +299,6 @@ public class NetworkService { true); wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, MGMT_CONTRACT_ID), MGMT_CONTRACT, true); - wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, METADATA_CONTRACT_ID), METADATA_CONTRACT, - true); wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true); } @@ -468,7 +306,7 @@ public class NetworkService { * @return All classifier-instances used in {@link #DHCP_CONTRACT}, {@link #DNS_CONTRACT} and * {@link #MGMT_CONTRACT} */ - public static Set getAllClassifierInstances(long metadataPort) { + public static Set getAllClassifierInstances() { HashSet cis = new HashSet<>(); cis.add(createDhcpIpv4ClientServer()); cis.add(createDhcpIpv4ServerClient()); @@ -489,198 +327,127 @@ public class NetworkService { cis.add(createSshTcpIpv6ClientServer()); cis.add(createIcmpIpv4()); cis.add(createIcmpIpv6()); - // METADATA - cis.add(createMetadataIpv4ClientServer(metadataPort)); - cis.add(createMetadataIpv4ServerClient(metadataPort)); - return cis; } // ###################### DHCP private static ClassifierInstance createDhcpIpv4ClientServer() { - return new ClassifierInstanceBuilder().setName(DHCP_IPV4_CLIENT_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, - DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT)) - .build(); + return createClassifInstance(DHCP_IPV4_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, + DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT)); } private static ClassifierInstance createDhcpIpv4ServerClient() { - return new ClassifierInstanceBuilder().setName(DHCP_IPV4_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, - DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT)) - .build(); + return createClassifInstance(DHCP_IPV4_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, + DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT)); } private static ClassifierInstance createDhcpIpv6ClientServer() { - return new ClassifierInstanceBuilder().setName(DHCP_IPV6_CLIENT_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, - DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT)) - .build(); + return createClassifInstance(DHCP_IPV6_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, + DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT)); } private static ClassifierInstance createDhcpIpv6ServerClient() { - return new ClassifierInstanceBuilder().setName(DHCP_IPV6_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, - DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT)) - .build(); + return createClassifInstance(DHCP_IPV6_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, + DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT)); } // ###################### DNS UDP private static ClassifierInstance createDnsUdpIpv4ClientServer() { - return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_CLIENT_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT)) - .build(); + return createClassifInstance(DNS_UDP_IPV4_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, + DNS_SERVER_PORT)); } private static ClassifierInstance createDnsUdpIpv4ServerClient() { - return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null)) - .build(); + return createClassifInstance(DNS_UDP_IPV4_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, + DNS_SERVER_PORT, null)); } private static ClassifierInstance createDnsUdpIpv6ClientServer() { - return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_CLIENT_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT)) - .build(); + return createClassifInstance(DNS_UDP_IPV6_CLIENT_SERVER_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, + DNS_SERVER_PORT)); } private static ClassifierInstance createDnsUdpIpv6ServerClient() { - return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null)) - .build(); + return createClassifInstance(DNS_UDP_IPV6_SERVER_CLIENT_NAME, L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, + DNS_SERVER_PORT, null)); } // ###################### DNS TCP private static ClassifierInstance createDnsTcpIpv4ClientServer() { - return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_CLIENT_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT)) - .build(); + return createClassifInstance(DNS_TCP_IPV4_CLIENT_SERVER_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT)); } private static ClassifierInstance createDnsTcpIpv4ServerClient() { - return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null)) - .build(); + return createClassifInstance(DNS_TCP_IPV4_SERVER_CLIENT_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null)); } private static ClassifierInstance createDnsTcpIpv6ClientServer() { - return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_CLIENT_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT)) - .build(); + return createClassifInstance(DNS_TCP_IPV6_CLIENT_SERVER_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT)); } private static ClassifierInstance createDnsTcpIpv6ServerClient() { - return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null)) - .build(); + return createClassifInstance(DNS_TCP_IPV6_SERVER_CLIENT_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null)); } // ###################### SSH TCP private static ClassifierInstance createSshTcpIpv4ClientServer() { - return new ClassifierInstanceBuilder().setName(SSH_IPV4_CLIENT_TO_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null)) - .build(); + return createClassifInstance(SSH_IPV4_CLIENT_TO_SERVER_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null)); } private static ClassifierInstance createSshTcpIpv4ServerClient() { - return new ClassifierInstanceBuilder().setName(SSH_IPV4_SERVER_TO_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT)) - .build(); + return createClassifInstance(SSH_IPV4_SERVER_TO_CLIENT_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv4_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT)); } private static ClassifierInstance createSshTcpIpv6ClientServer() { - return new ClassifierInstanceBuilder().setName(SSH_IPV6_CLIENT_TO_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null)) - .build(); + return createClassifInstance(SSH_IPV6_CLIENT_TO_SERVER_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null)); } private static ClassifierInstance createSshTcpIpv6ServerClient() { - return new ClassifierInstanceBuilder().setName(SSH_IPV6_SERVER_TO_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT)) - .build(); + return createClassifInstance(SSH_IPV6_SERVER_TO_CLIENT_NAME, + L4ClassifierDefinition.DEFINITION.getId(), + createParams(EtherTypeClassifierDefinition.IPv6_VALUE, + IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT)); } // ###################### ICMP private static ClassifierInstance createIcmpIpv4() { - return new ClassifierInstanceBuilder().setName(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId()) - .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null)) - .build(); + return createClassifInstance(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, + IpProtoClassifierDefinition.DEFINITION.getId(), createParams( + EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null)); } private static ClassifierInstance createIcmpIpv6() { - return new ClassifierInstanceBuilder().setName(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME) - .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId()) - .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null)) - .build(); - } - - // ###################### METADATA - private static ClassifierInstance createMetadataIpv4ClientServer(long dstPort) { - return new ClassifierInstanceBuilder().setName(METADATA_CLIENT_TO_SERVER_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, - dstPort)) - .build(); - } - - private static ClassifierInstance createMetadataIpv4ServerClient(long srcPort) { - return new ClassifierInstanceBuilder().setName(METADATA_SERVER_TO_CLIENT_NAME) - .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId()) - .setParameterValue( - createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, - srcPort, null)) - .build(); - } - - private static List createParams(long etherType, long proto, @Nullable Long srcPort, - @Nullable Long dstPort) { - List params = new ArrayList<>(); - if (srcPort != null) { - params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM)) - .setIntValue(srcPort) - .build()); - } - if (dstPort != null) { - params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM)) - .setIntValue(dstPort) - .build()); - } - params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM)) - .setIntValue(proto) - .build()); - params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM)) - .setIntValue(etherType) - .build()); - return params; + return createClassifInstance((ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME), + IpProtoClassifierDefinition.DEFINITION.getId(), createParams( + EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null)); } } diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java new file mode 100644 index 000000000..db66f120f --- /dev/null +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/ServiceUtil.java @@ -0,0 +1,166 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure; + +import java.util.ArrayList; +import java.util.List; + +import javax.annotation.Nullable; + +import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition; +import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition; +import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition; +import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; +import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierDefinitionId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder; + +import com.google.common.collect.ImmutableList; + +public class ServiceUtil { + + protected static Contract createContract(ContractId cid, List subjects, Description description) { + return new ContractBuilder().setId(cid).setSubject(subjects).setDescription(description).build(); + } + + protected static ClassifierInstance createClassifInstance(ClassifierName name, ClassifierDefinitionId id, + List pv) { + return new ClassifierInstanceBuilder().setName(name) + .setClassifierDefinitionId(id) + .setParameterValue(pv) + .build(); + } + + protected static EndpointGroupBuilder createEpgBuilder(EndpointGroupId epgId, Name name, Description description) { + return new EndpointGroupBuilder().setId(epgId) + .setName(name) + .setIntraGroupPolicy(IntraGroupPolicy.RequireContract) + .setDescription(description); + } + + protected static List createParams(long etherType, long proto, @Nullable Long srcPort, + @Nullable Long dstPort) { + List params = new ArrayList<>(); + if (srcPort != null) { + params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM)) + .setIntValue(srcPort) + .build()); + } + if (dstPort != null) { + params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM)) + .setIntValue(dstPort) + .build()); + } + params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM)) + .setIntValue(proto) + .build()); + params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM)) + .setIntValue(etherType) + .build()); + return params; + } + + protected static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) { + ConsumerMatchers consumerMatchers = null; + ProviderMatchers providerMatchers = null; + StringBuilder clauseName = new StringBuilder(); + clauseName.append(subjectName.getValue()); + if (ipPrefix != null) { + clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix)); + consumerMatchers = + new ConsumerMatchersBuilder() + .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder() + .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder() + .setPrefixConstraint( + ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build())) + .build()) + .build()) + .build(); + providerMatchers = + new ProviderMatchersBuilder() + .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder() + .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder() + .setPrefixConstraint( + ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build())) + .build()) + .build()) + .build(); + } + return new ClauseBuilder().setName(new ClauseName(clauseName.toString())) + .setSubjectRefs(ImmutableList.of(subjectName)) + .setConsumerMatchers(consumerMatchers) + .setProviderMatchers(providerMatchers) + .build(); + } + + protected static Rule createRuleAllow(ClassifierName classifierName, Direction direction) { + ClassifierName name = + new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue()); + ClassifierRef classifierRef = new ClassifierRefBuilder().setName(name) + .setInstanceName(classifierName) + .setDirection(direction) + .build(); + return new RuleBuilder().setName(new RuleName(name)) + .setActionRef(ImmutableList.of(MappingUtils.ACTION_REF_ALLOW)) + .setClassifierRef(ImmutableList.of(classifierRef)) + .build(); + } + + protected static ProviderNamedSelector createProviderSelector(Contract contract) { + SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue()); + return new ProviderNamedSelectorBuilder().setName(selectorName) + .setContract(ImmutableList.of(contract.getId())) + .build(); + } + + protected static ConsumerNamedSelector createConsumerSelector(Contract contract) { + SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue()); + return new ConsumerNamedSelectorBuilder().setName(selectorName) + .setContract(ImmutableList.of(contract.getId())) + .build(); + } +} diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java index c7d7ca2b0..00342dcb2 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAware.java @@ -12,21 +12,19 @@ import static com.google.common.base.Preconditions.checkNotNull; import java.util.HashSet; import java.util.Set; -import javax.annotation.Nullable; - 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.domain_extension.l2_l3.util.L2L3IidFactory; import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory; +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; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils; 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.IpPrefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId; @@ -60,13 +58,11 @@ public class NeutronNetworkAware implements NeutronAware { InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build(); private final DataBroker dataProvider; private final Set tenantsWithRouterAndNetworkServiceEntities = new HashSet<>(); - private final IpPrefix metadataIpPrefix; - private final long metadataPort; + private final long metadataTcpPort; - public NeutronNetworkAware(DataBroker dataProvider, @Nullable IpPrefix metadataIpPrefix, long metadataPort) { + public NeutronNetworkAware(DataBroker dataProvider, long metadataPort) { this.dataProvider = checkNotNull(dataProvider); - this.metadataIpPrefix = metadataIpPrefix; - this.metadataPort = metadataPort; + this.metadataTcpPort = metadataPort; } @Override @@ -108,7 +104,7 @@ public class NeutronNetworkAware implements NeutronAware { if (!tenantsWithRouterAndNetworkServiceEntities.contains(tenantId)) { tenantsWithRouterAndNetworkServiceEntities.add(tenantId); - NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataPort); + NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx); NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx); NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx); NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx); @@ -116,9 +112,11 @@ public class NeutronNetworkAware implements NeutronAware { 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); - if (metadataIpPrefix != null) { - NetworkService.writeMetadataClauseWithConsProvEic(tenantId, metadataIpPrefix, rwTx); - NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.METADATA_CONTRACT_CONSUMER_SELECTOR, + MetadataService.writeMetadataClauseWithConsProvEic(tenantId, null, rwTx); + if (metadataTcpPort != 0) { + MetadataService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataTcpPort); + MetadataService.writeMetadataClauseWithConsProvEic(tenantId, null, rwTx); + NetworkClient.writeConsumerNamedSelector(tenantId, MetadataService.METADATA_CONTRACT_CONSUMER_SELECTOR, rwTx); } } 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 c6bb87ddc..f9550d7bc 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,8 +10,10 @@ 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.stream.Collectors; import javax.annotation.Nullable; @@ -22,6 +24,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; @@ -29,6 +32,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; @@ -76,8 +81,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; @@ -86,6 +94,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 { @@ -94,10 +103,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) { @@ -193,21 +205,26 @@ 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 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); + + AddressEndpointRegBuilder metadataEp = createBasicL3AddrEpInputBuilder(cloneMetadataPortFromDhcpPort(port, metadataIpPrefix), networkContainment, + Lists.newArrayList(MetadataService.EPG_ID), neutron); + setParentChildRelationshipForEndpoints(metadataEp, l2BaseEp); + registerBaseEndpointAndStoreMapping( + ImmutableList.of(metadataEp.build()), port, rwTx, true); + registerEndpointAndStoreMapping(epInBuilder.build(), port, rwTx); DataStoreHelper.submitToDs(rwTx); } else if (PortUtils.isNormalPort(port)) { @@ -252,6 +269,15 @@ 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 setParentChildRelationshipForEndpoints(AddressEndpointRegBuilder parentEp, AddressEndpointRegBuilder childEp) { childEp.setParentEndpointChoice(new ParentEndpointCaseBuilder().setParentEndpoint( @@ -456,7 +482,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()); @@ -497,7 +523,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) { diff --git a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java index 86e21b876..62006ec90 100644 --- a/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java +++ b/neutron-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAware.java @@ -14,7 +14,6 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; -import java.util.stream.Collector; import java.util.stream.Collectors; import javax.annotation.Nonnull; @@ -26,27 +25,36 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition; import org.opendaylight.groupbasedpolicy.dto.EpgKeyDto; +import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator; import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronAware; import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.NeutronSecurityGroupAware; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; +import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SecurityGroupUtils; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.SecurityRuleUtils; 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.yang.types.rev130715.Uuid; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInputBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.register.endpoint.input.AddressEndpointRegBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.IpPrefixType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector; @@ -54,6 +62,7 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstanceBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance; +import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupKey; @@ -85,21 +94,23 @@ public class NeutronSecurityRuleAware implements NeutronAware { private final Map pendingDeletedGroups; final static String PROVIDED_BY = "provided_by-"; final static String POSSIBLE_CONSUMER = "possible_consumer-"; + private final EndpointRegistrator epRegistrator; - public NeutronSecurityRuleAware(DataBroker dataProvider) { + public NeutronSecurityRuleAware(DataBroker dataProvider, EndpointRegistrator epRegistrator) { this(dataProvider, HashMultiset.>create(), - HashMultiset.>create()); + HashMultiset.>create(), epRegistrator); } @VisibleForTesting NeutronSecurityRuleAware(DataBroker dataProvider, Multiset> classifierInstanceNames, - Multiset> createdActionInstances) { + Multiset> createdActionInstances, EndpointRegistrator epRegistrator) { this.dataProvider = checkNotNull(dataProvider); this.createdClassifierInstances = checkNotNull(classifierInstanceNames); this.createdActionInstances = checkNotNull(createdActionInstances); this.pendingCreatedRules = new HashMap<>(); this.pendingDeletedGroups = new HashMap<>(); + this.epRegistrator = Preconditions.checkNotNull(epRegistrator); } @Override @@ -155,7 +166,7 @@ public class NeutronSecurityRuleAware implements NeutronAware { EndpointGroupId providerEpgId = new EndpointGroupId(providerSecGroupId.getValue()); Description contractDescription = createContractDescription(secRule, neutron); - SingleRuleContract singleRuleContract = createSingleRuleContract(secRule, contractDescription, action); + SingleRuleContract singleRuleContract = createSingleRuleContract(secRule, contractDescription, action, neutron); Contract contract = singleRuleContract.getContract(); rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, contract.getId()), contract, true); SelectorName providerSelector = getSelectorNameWithConsumer(secRule, neutron); @@ -196,8 +207,44 @@ public class NeutronSecurityRuleAware implements NeutronAware { } @VisibleForTesting - static SingleRuleContract createSingleRuleContract(SecurityRule secRule, Description contractDescription, ActionChoice action) { + SingleRuleContract createSingleRuleContract(SecurityRule secRule, Description contractDescription, + ActionChoice action, Neutron neutron) { if (secRule.getRemoteIpPrefix() != null) { + if (neutron.getNetworks() != null && neutron.getNetworks().getNetwork() != null) { + java.util.Optional publicNet = neutron.getNetworks() + .getNetwork() + .stream() + .filter(net -> NetworkUtils.isRouterExternal(net)) + .findAny(); + if (publicNet.isPresent()) { + WriteTransaction wTx = dataProvider.newWriteOnlyTransaction(); + wTx.merge(LogicalDatastoreType.CONFIGURATION, + IidFactory.externalImplicitGroupIid(new TenantId(secRule.getTenantId().getValue()), + MappingUtils.EPG_EXTERNAL_ID), + new ExternalImplicitGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build(), true); + wTx.merge(LogicalDatastoreType.CONFIGURATION, + IidFactory.endpointGroupIid(new TenantId(secRule.getTenantId().getValue()), + MappingUtils.EPG_EXTERNAL_ID), + new EndpointGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build(), true); + DataStoreHelper.submitToDs(wTx); + AddressEndpointRegBuilder addrEpbuilder = new AddressEndpointRegBuilder() + .setAddress(String.valueOf(secRule.getRemoteIpPrefix().getValue())) + .setAddressType(IpPrefixType.class) + .setContextType(MappingUtils.L3_CONTEXT) + .setContextId(new ContextId(publicNet.get().getUuid().getValue())) + .setTenant(new TenantId(secRule.getTenantId().getValue())) + .setTimestamp(System.currentTimeMillis()) + .setEndpointGroup(ImmutableList.of(MappingUtils.EPG_EXTERNAL_ID)); + RegisterEndpointInput regEp = new RegisterEndpointInputBuilder() + .setAddressEndpointReg(ImmutableList.of(addrEpbuilder.build())).build(); + boolean registered = epRegistrator.registerEndpoint(regEp); + if (registered) { + LOG.info("Registering endpoint representing remote-ip-prefix {}", addrEpbuilder.getKey()); + } else { + LOG.error("Failed to register endpoint {}", addrEpbuilder.getKey()); + } + } + } return new SingleRuleContract(secRule, 0, contractDescription, action); } return new SingleRuleContract(secRule, 400, contractDescription, action); diff --git a/neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml b/neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml index ed69af45f..b9bc8a365 100644 --- a/neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml +++ b/neutron-mapper/src/main/resources/org/opendaylight/blueprint/neutron-mapper.xml @@ -10,7 +10,7 @@ - + diff --git a/neutron-mapper/src/main/resources/startup.cfg b/neutron-mapper/src/main/resources/startup.cfg index 4fa71dd15..6ba246d09 100644 --- a/neutron-mapper/src/main/resources/startup.cfg +++ b/neutron-mapper/src/main/resources/startup.cfg @@ -6,7 +6,7 @@ # To explicitly specify which IP prefix should be used for metadata # service in openstack, uncomment and modify following line. # Specifying one IP for metadata service is currently supported. -#metadata-ip = 169.254.169.254/32 +#metadata-ip = 169.254.169.254 # To explicitly specify which port should be used for metadata # service in openstack, uncomment and modify following line. diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkServiceTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkServiceTest.java index 121476820..2d5c2fcb5 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkServiceTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/infrastructure/NetworkServiceTest.java @@ -178,7 +178,7 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest { // ipv4 DataBroker dataBroker = getDataBroker(); ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); - NetworkService.writeMetadataClauseWithConsProvEic(new TenantId(tenantId), metadataIpv4Prefix, rwTx); + MetadataService.writeMetadataClauseWithConsProvEic(new TenantId(tenantId), metadataIpv4Prefix, rwTx); rwTx.submit().get(); // expected clause name @@ -186,7 +186,7 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest { + metadataIpv4Prefix.getIpv4Prefix().getValue(); clauseNameIpV4 = clauseNameIpV4.replace('/', '_'); - PolicyAssert.assertClauseExists(dataBroker, tenantId, NetworkService.METADATA_CONTRACT_ID.getValue(), + PolicyAssert.assertClauseExists(dataBroker, tenantId, MetadataService.METADATA_CONTRACT_ID.getValue(), clauseNameIpV4); } @@ -195,7 +195,7 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest { // write everything DataBroker dataBroker = getDataBroker(); ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); - NetworkService.writeNetworkServiceEntitiesToTenant(new TenantId(tenantId), rwTx, METADATA_IPV4_SERVER_PORT); + NetworkService.writeNetworkServiceEntitiesToTenant(new TenantId(tenantId), rwTx); rwTx.submit().get(); // read classifier instances @@ -217,14 +217,11 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest { PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, SSH_IPV6_CLIENT_TO_SERVER_NAME); PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME); PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME); - PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, METADATA_CLIENT_TO_SERVER_NAME); - PolicyAssert.assertClassifierInstanceExists(dataBroker, tenantId, METADATA_SERVER_TO_CLIENT_NAME); // read contracts PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.DHCP_CONTRACT_ID.getValue()); PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.DNS_CONTRACT_ID.getValue()); PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.MGMT_CONTRACT_ID.getValue()); - PolicyAssert.assertContractExists(dataBroker, tenantId, NetworkService.METADATA_CONTRACT_ID.getValue()); // read group id PolicyAssert.assertEndpointGroupExists(dataBroker, tenantId, NetworkService.EPG_ID.getValue()); @@ -233,10 +230,10 @@ public class NetworkServiceTest extends NeutronMapperDataBrokerTest { @Test public void testGetAllClassifierInstances() { Set classifierInstances = - NetworkService.getAllClassifierInstances(METADATA_IPV4_SERVER_PORT); + NetworkService.getAllClassifierInstances(); assertNotNull(classifierInstances); assertFalse(classifierInstances.isEmpty()); - assertEquals(20, classifierInstances.size()); + assertEquals(18, classifierInstances.size()); } } diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAwareDataStoreTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAwareDataStoreTest.java index 3cc85f2ba..e18818bd4 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAwareDataStoreTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronNetworkAwareDataStoreTest.java @@ -85,7 +85,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes .addAugmentation(NetworkProviderExtension.class, providerExtension) .build(); - networkAware = new NeutronNetworkAware(dataBroker, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT); + networkAware = new NeutronNetworkAware(dataBroker, METADATA_IPV4_SERVER_PORT); } @Rule @@ -94,7 +94,7 @@ public class NeutronNetworkAwareDataStoreTest extends NeutronMapperDataBrokerTes @Test public void testConstructor_invalidArgument() throws NullPointerException { thrown.expect(NullPointerException.class); - new NeutronNetworkAware(null, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT); + new NeutronNetworkAware(null, METADATA_IPV4_SERVER_PORT); } @Test diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAwareDataStoreTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAwareDataStoreTest.java index 8d375b4b1..0f7d06087 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAwareDataStoreTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronPortAwareDataStoreTest.java @@ -25,7 +25,9 @@ import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBr import org.opendaylight.groupbasedpolicy.neutron.mapper.util.PortUtils; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils; 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.inet.types.rev130715.Ipv4Address; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; 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; @@ -71,7 +73,7 @@ public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest { any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput.class))) .thenReturn(true); - portAware = new NeutronPortAware(dataBroker, epRegistrator); + portAware = new NeutronPortAware(dataBroker, epRegistrator, new IpPrefix(new Ipv4Prefix("192.168.192.168/32"))); } @Rule @@ -80,7 +82,7 @@ public class NeutronPortAwareDataStoreTest extends NeutronMapperDataBrokerTest { @Test public void testConstructor_invalidArgument() throws NullPointerException { thrown.expect(NullPointerException.class); - new NeutronPortAware(null, null); + new NeutronPortAware(null, null, null); } @Test diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAwareDataStoreTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAwareDataStoreTest.java index b6e42d545..813d8df7d 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAwareDataStoreTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronRouterAwareDataStoreTest.java @@ -112,7 +112,7 @@ public class NeutronRouterAwareDataStoreTest extends NeutronMapperDataBrokerTest .thenReturn(futureRpcResult); epRegistrator = new EndpointRegistrator(epService, baseEpService); - networkAware = new NeutronNetworkAware(dataBroker, METADATA_IP_PREFIX, METADATA_IPV4_SERVER_PORT); + networkAware = new NeutronNetworkAware(dataBroker, METADATA_IPV4_SERVER_PORT); network = new NetworkBuilder().setTenantId(tenantUuid).setUuid(networkUuid).setName("networkName").build(); routerAware = new NeutronRouterAware(dataBroker, epRegistrator); diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityGroupAwareDataStoreTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityGroupAwareDataStoreTest.java index bb2f9695c..c4bfd09b6 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityGroupAwareDataStoreTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/NeutronSecurityGroupAwareDataStoreTest.java @@ -8,6 +8,10 @@ package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import org.apache.commons.lang3.StringUtils; import org.junit.Before; import org.junit.Rule; @@ -15,11 +19,14 @@ import org.junit.Test; import org.junit.rules.ExpectedException; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest; +import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator; import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule.NeutronSecurityRuleAware; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.PolicyAssert; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; 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; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.groups.attributes.security.groups.SecurityGroupBuilder; @@ -34,14 +41,26 @@ public class NeutronSecurityGroupAwareDataStoreTest extends NeutronMapperDataBro private NeutronSecurityGroupAware groupAware; private SecurityGroup secGroup1; private SecurityGroup secGroup2; + private EndpointRegistrator epRegistrator; @Before public void init() { dataBroker = getDataBroker(); - groupAware = new NeutronSecurityGroupAware(dataBroker, new NeutronSecurityRuleAware(dataBroker)); secGroup1 = NeutronEntityFactory.securityGroup(secGroupId1, tenantId); secGroup2 = NeutronEntityFactory.securityGroup(secGroupId2, tenantId); + + + epRegistrator = mock(EndpointRegistrator.class); + when(epRegistrator.registerEndpoint(any(RegisterEndpointInput.class))).thenReturn(true); + when(epRegistrator.registerEndpoint( + any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput.class))) + .thenReturn(true); + when(epRegistrator.unregisterEndpoint(any(UnregisterEndpointInput.class))).thenReturn(true); + when(epRegistrator.unregisterEndpoint( + any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput.class))) + .thenReturn(true); + groupAware = new NeutronSecurityGroupAware(dataBroker, new NeutronSecurityRuleAware(dataBroker, epRegistrator)); } @Test diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java index a5ee96a3b..5e7320797 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareDataStoreTest.java @@ -13,13 +13,15 @@ import static org.junit.Assert.fail; import java.util.ArrayList; import java.util.List; +import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; +import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.ConfigDataStoreReader; -import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory; +import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.PolicyAssert; import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils; import org.opendaylight.groupbasedpolicy.util.IidFactory; @@ -56,6 +58,13 @@ import com.google.common.collect.ImmutableSet; public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrokerTest { + private EndpointRegistrator epRegistrator; + + @Before + public void init() { + epRegistrator = getEpRegistrator(); + } + @Test public final void testAddNeutronSecurityRule_rulesWithRemoteIpPrefix() throws Exception { String tenant = "ad4c6c25-2424-4ad3-97ee-f9691ce03645"; @@ -98,7 +107,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok ImmutableList.of(goldInIpv4, goldOutIpv4, serverIn80Tcp10_1_1_0, serverInIp20_1_1_0, serverOutIpv4)) .build()) .build(); - NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker); + NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator); ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); ruleAware.addNeutronSecurityRule(goldInIpv4, neutron, rwTx); ruleAware.addNeutronSecurityRule(goldOutIpv4, neutron, rwTx); @@ -158,7 +167,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok @Test public final void testAddAndDeleteNeutronSecurityRule() throws Exception { DataBroker dataBroker = getDataBroker(); - NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker); + NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator); final String tenantId = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa"; final String secGroupId1 = "bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb"; @@ -282,7 +291,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok .setSecurityRules(new SecurityRulesBuilder() .setSecurityRule(ImmutableList.of(goldInIpv4, goldOutIpv4, serverOutIpv4, serverInIpv4)).build()) .build(); - NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker); + NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator); ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); ruleAware.addNeutronSecurityRule(goldInIpv4, neutron, rwTx); ruleAware.addNeutronSecurityRule(goldOutIpv4, neutron, rwTx); @@ -363,7 +372,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok .setSecurityRules(new SecurityRulesBuilder() .setSecurityRule(ImmutableList.of(goldInIpv4, goldOutIpv4, serverOutIpv4, serverIn80TcpIpv4)).build()) .build(); - NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker); + NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator); ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); ruleAware.addNeutronSecurityRule(goldInIpv4, neutron, rwTx); ruleAware.addNeutronSecurityRule(goldOutIpv4, neutron, rwTx); @@ -431,7 +440,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok secGroups.add(NeutronEntityFactory.securityGroup(defaultSecGrp, tenant)); Neutron neutron = new NeutronBuilder() .setSecurityGroups(new SecurityGroupsBuilder().setSecurityGroup(secGroups).build()).build(); - NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker); + NeutronSecurityRuleAware ruleAware = new NeutronSecurityRuleAware(dataBroker, epRegistrator); ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); ruleAware.addNeutronSecurityRule(defaultInIpv4Default, neutron, rwTx); ruleAware.addNeutronSecurityRule(defaultInIpv6Default, neutron, rwTx); @@ -463,7 +472,7 @@ public class NeutronSecurityRuleAwareDataStoreTest extends NeutronMapperDataBrok @Test public void testConstructor_invalidArgument() throws Exception { try { - new NeutronSecurityRuleAware(null); + new NeutronSecurityRuleAware(null, null); fail(NullPointerException.class.getName() + " expected"); } catch (NullPointerException ex) { // do nothing diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java index b3366fc0b..0f0951ee0 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/mapping/rule/NeutronSecurityRuleAwareTest.java @@ -16,8 +16,10 @@ import static org.junit.Assert.assertTrue; import java.util.ArrayList; import java.util.List; +import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.ConfigDataStoreReader; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronMapperDataBrokerTest; import org.opendaylight.groupbasedpolicy.neutron.mapper.test.NeutronEntityFactory; @@ -44,6 +46,13 @@ public class NeutronSecurityRuleAwareTest extends NeutronMapperDataBrokerTest { private static final String RULE_TENANT_ID = "00000000-0000-0000-0000-000000000002"; private static final String RULE_GROUP_ID = "00000000-0000-0000-0000-000000000003"; + private EndpointRegistrator epRegistrator; + + @Before + public void init() { + epRegistrator = getEpRegistrator(); + } + @Test public final void testIsDirectionOpposite_InIn() { assertFalse(NeutronSecurityRuleAware.isDirectionOpposite(Direction.In, Direction.In)); @@ -67,7 +76,7 @@ public class NeutronSecurityRuleAwareTest extends NeutronMapperDataBrokerTest { @Test public void testNeutronSecurityRuleCreatedAndDeleted() throws Exception { DataBroker dataProvider = getDataBroker(); - NeutronSecurityRuleAware neutronSecurityRuleAware = new NeutronSecurityRuleAware(dataProvider); + NeutronSecurityRuleAware neutronSecurityRuleAware = new NeutronSecurityRuleAware(dataProvider, epRegistrator); //create security rule and put to DS SecurityRule neutronRule = buildNeutronSecurityRule(); diff --git a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/NeutronMapperDataBrokerTest.java b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/NeutronMapperDataBrokerTest.java index 01269fe51..ef416e4f5 100644 --- a/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/NeutronMapperDataBrokerTest.java +++ b/neutron-mapper/src/test/java/org/opendaylight/groupbasedpolicy/neutron/mapper/test/NeutronMapperDataBrokerTest.java @@ -7,16 +7,24 @@ */ package org.opendaylight.groupbasedpolicy.neutron.mapper.test; +import static org.mockito.Matchers.any; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + import java.util.Collection; -import com.google.common.collect.ImmutableList; import org.opendaylight.controller.md.sal.binding.test.AbstractDataBrokerTest; +import org.opendaylight.groupbasedpolicy.neutron.mapper.EndpointRegistrator; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.RegisterEndpointInput; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.UnregisterEndpointInput; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentForwarding; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.Forwarding; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.Mappings; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.Tenants; import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron; +import com.google.common.collect.ImmutableList; + /** * Loads only modules of GBP and it's dependencies for data broker. *
@@ -30,4 +38,17 @@ public class NeutronMapperDataBrokerTest extends CustomDataBrokerTest { Mappings.class); } + protected EndpointRegistrator getEpRegistrator() { + EndpointRegistrator epRegistrator = mock(EndpointRegistrator.class); + when(epRegistrator.registerEndpoint(any(RegisterEndpointInput.class))).thenReturn(true); + when(epRegistrator.registerEndpoint( + any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.RegisterEndpointInput.class))) + .thenReturn(true); + when(epRegistrator.unregisterEndpoint(any(UnregisterEndpointInput.class))).thenReturn(true); + when(epRegistrator.unregisterEndpoint( + any(org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint.rev140421.UnregisterEndpointInput.class))) + .thenReturn(true); + return epRegistrator; + } + } diff --git a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java index 3ca0883ea..d22ff19d0 100644 --- a/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java +++ b/neutron-vpp-mapper/src/main/java/org/opendaylight/groupbasedpolicy/neutron/vpp/mapper/processors/PortHandler.java @@ -11,6 +11,7 @@ package org.opendaylight.groupbasedpolicy.neutron.vpp.mapper.processors; import java.util.Collections; import java.util.List; +import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; @@ -65,8 +66,6 @@ import org.slf4j.LoggerFactory; import com.google.common.annotations.VisibleForTesting; import com.google.common.base.Optional; import com.google.common.base.Strings; - -import javax.annotation.Nonnull; public class PortHandler implements TransactionChainListener { private static final Logger LOG = LoggerFactory.getLogger(PortHandler.class); diff --git a/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java b/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java index 9dc7a8537..3bac3905a 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java +++ b/renderers/vpp/src/main/java/org/opendaylight/controller/config/yang/config/vpp_provider/impl/VppRenderer.java @@ -22,7 +22,6 @@ import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFaile import org.opendaylight.controller.sal.binding.api.BindingAwareBroker; import org.opendaylight.controller.sal.binding.api.BindingAwareProvider; import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager; -import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.RendererPolicyListener; import org.opendaylight.groupbasedpolicy.renderer.vpp.listener.VppEndpointListener; @@ -32,6 +31,7 @@ import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.BridgeDomainManagerImpl; import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.ForwardingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.VppRendererPolicyManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.AllowAction; import org.opendaylight.groupbasedpolicy.renderer.vpp.sf.Classifier; diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java deleted file mode 100644 index 502abd7c3..000000000 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/AclManager.java +++ /dev/null @@ -1,77 +0,0 @@ -/* - * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. - * - * This program and the accompanying materials are made available under the - * terms of the Eclipse Public License v1.0 which accompanies this distribution, - * and is available at http://www.eclipse.org/legal/epl-v10.html - */ - -package org.opendaylight.groupbasedpolicy.renderer.vpp.iface; - -import java.util.stream.Collectors; - -import javax.annotation.Nonnull; - -import org.opendaylight.controller.md.sal.binding.api.DataBroker; -import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils; -import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext; -import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil; -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; -import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider; -import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey; -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.Preconditions; -import com.google.common.collect.ImmutableSet; - -public class AclManager { - - private static final Logger LOG = LoggerFactory.getLogger(AclManager.class); - private final MountedDataBrokerProvider mountDataProvider; - - public AclManager(@Nonnull MountedDataBrokerProvider mountDataProvider) { - this.mountDataProvider = Preconditions.checkNotNull(mountDataProvider); - } - - public void updateAclsForPeers(PolicyContext policyCtx, RendererEndpointKey rEpKey) { - ImmutableSet peers = policyCtx.getPolicyTable().row(rEpKey).keySet(); - for (RendererEndpointKey peerRendEp : peers.stream() - .map(AddressEndpointUtils::fromPeerEpKey) - .collect(Collectors.toList()) - .stream() - .map(AddressEndpointUtils::toRendererEpKey) - .collect(Collectors.toList())) { - updateAclsForRendEp(peerRendEp, policyCtx); - } - } - - public void updateAclsForRendEp(RendererEndpointKey rEpKey, PolicyContext policyCtx) { - LOG.info("Updating policy for endpoint {}", rEpKey); - AddressEndpointWithLocation peerAddrEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey)); - ExternalLocationCase epLoc; - try { - epLoc = InterfaceManager.resolveAndValidateLocation(peerAddrEp); - } catch (NullPointerException | IllegalArgumentException e) { - //TODO investigate, don't just move on. - LOG.warn("Peer {} has no location. Moving on...", peerAddrEp, e.getMessage()); - return; - } - InstanceIdentifier vppNodeIid = epLoc.getExternalNodeMountPoint(); - Optional> optInterfaceIid = - VppPathMapper.interfaceToInstanceIdentifier(epLoc.getExternalNodeConnector()); - if (!optInterfaceIid.isPresent()) { - LOG.warn("Cannot find interface for endpoint {}. ACLs for endpoint not updated {}. ", rEpKey); - return; - } - Optional optMountPoint = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid); - AccessListUtil.resolveAclsOnInterface(rEpKey, policyCtx).forEach(aclWrapper -> aclWrapper - .writeAcl(optMountPoint.get(), optInterfaceIid.get().firstKeyOf(Interface.class))); - } -} diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java index d2bfec90e..9b3471fcb 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManager.java @@ -589,7 +589,7 @@ public class InterfaceManager implements AutoCloseable { } } - static ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) { + public static ExternalLocationCase resolveAndValidateLocation(AddressEndpointWithLocation addrEpWithLoc) { LocationType locationType = addrEpWithLoc.getAbsoluteLocation().getLocationType(); if (!(locationType instanceof ExternalLocationCase)) { throw new IllegalArgumentException("Endpoint does not have external location " + addrEpWithLoc); diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProvider.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProvider.java index 93f770e8a..3a32c8978 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProvider.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProvider.java @@ -10,23 +10,41 @@ package org.opendaylight.groupbasedpolicy.renderer.vpp.iface; import static com.google.common.base.Preconditions.checkNotNull; +import java.util.HashMap; +import java.util.Map; +import java.util.concurrent.ExecutionException; +import java.util.stream.Collectors; + import javax.annotation.Nonnull; -import com.google.common.base.Function; -import com.google.common.util.concurrent.FutureCallback; -import com.google.common.util.concurrent.Futures; -import com.google.common.util.concurrent.ListenableFuture; + import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.controller.md.sal.binding.api.DataObjectModification; +import org.opendaylight.controller.md.sal.binding.api.DataTreeIdentifier; +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.renderer.vpp.manager.VppNodeManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.CloseOnFailTransactionChain; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; +import org.opendaylight.groupbasedpolicy.util.DataStoreHelper; +import org.opendaylight.groupbasedpolicy.util.DataTreeChangeHandler; +import org.opendaylight.groupbasedpolicy.util.EndpointUtils; import org.opendaylight.groupbasedpolicy.util.IidFactory; +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.Endpoints; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.AddressEndpoints; +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.has.absolute.location.AbsoluteLocation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocationBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocations; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.RelativeLocationsBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.relative.location.relative.locations.ExternalLocationBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpointKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.ProviderName; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProviderBuilder; @@ -35,20 +53,32 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_l import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.location.provider.ProviderAddressEndpointLocationKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -public class VppEndpointLocationProvider implements AutoCloseable { +import com.google.common.annotations.VisibleForTesting; +import com.google.common.base.Function; +import com.google.common.util.concurrent.FutureCallback; +import com.google.common.util.concurrent.Futures; +import com.google.common.util.concurrent.ListenableFuture; + +public class VppEndpointLocationProvider extends DataTreeChangeHandler { private static final Logger LOG = LoggerFactory.getLogger(VppEndpointLocationProvider.class); public static final ProviderName VPP_ENDPOINT_LOCATION_PROVIDER = new ProviderName("VPP endpoint location provider"); public static final long PROVIDER_PRIORITY = 10L; private final BindingTransactionChain txChain; + private final Map vppEndpoints = new HashMap<>(); + private final Map> cachedVppEndpoints = new HashMap<>(); public VppEndpointLocationProvider(DataBroker dataProvider) { + super(dataProvider); LocationProvider locationProvider = new LocationProviderBuilder().setProvider(VPP_ENDPOINT_LOCATION_PROVIDER) .setPriority(PROVIDER_PRIORITY) .build(); @@ -70,54 +100,171 @@ public class VppEndpointLocationProvider implements AutoCloseable { LOG.error("{} was NOT created", VPP_ENDPOINT_LOCATION_PROVIDER.getValue()); } }); + registerDataTreeChangeListener(new DataTreeIdentifier<>(LogicalDatastoreType.OPERATIONAL, + InstanceIdentifier.builder(Endpoints.class).child(AddressEndpoints.class).child(AddressEndpoint.class).build())); } - ListenableFuture createLocationForVppEndpoint(final VppEndpoint vppEndpoint) { - final ProviderAddressEndpointLocation providerAddressEndpointLocation = - createProviderAddressEndpointLocation(vppEndpoint); - final WriteTransaction wTx = txChain.newWriteOnlyTransaction(); - wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.providerAddressEndpointLocationIid( - VPP_ENDPOINT_LOCATION_PROVIDER, providerAddressEndpointLocation.getKey()), - providerAddressEndpointLocation); - LOG.debug("Creating location for {}", providerAddressEndpointLocation.getKey()); - return Futures.transform(wTx.submit(), (Function) input -> { - LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), - providerAddressEndpointLocation); - return null; - }); + @Override + protected void onWrite(DataObjectModification rootNode, + InstanceIdentifier rootIdentifier) { + LOG.debug("onWrite triggered by {}", rootNode.getDataAfter()); + try { + if (EndpointUtils.isExternalEndpoint(dataProvider, rootNode.getDataAfter())) { + writeLocation(createRelativeAddressEndpointLocation(rootNode.getDataAfter().getKey(), + VppNodeManager.resolvePublicInterfaces(dataProvider))).get(); + } else { + createAbsoluteAddressEndpointLocation(null, rootNode).get(); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to write location for endpoint {}. {}", rootNode.getDataAfter().getKey(), e.getMessage()); + } + } + + @Override + protected void onDelete(DataObjectModification rootNode, + InstanceIdentifier rootIdentifier) { + LOG.debug("onDelete triggered by {}", rootNode.getDataBefore()); + try { + if (EndpointUtils.isExternalEndpoint(dataProvider, rootNode.getDataBefore())) { + deleteLocation(createProviderAddressEndpointLocationKey(rootNode.getDataBefore().getKey())).get(); + } else { + createAbsoluteAddressEndpointLocation(null, rootNode).get(); + } + } catch (InterruptedException | ExecutionException e) { + LOG.error("Failed to delete location for endpoint {}. {}", rootNode.getDataBefore().getKey(), + e.getMessage()); + } + } + + @Override + protected void onSubtreeModified(DataObjectModification rootNode, + InstanceIdentifier rootIdentifier) { + LOG.debug("onSubtreeModified triggered by change: before={} after={}", rootNode.getDataBefore(), + rootNode.getDataAfter()); + if (rootNode.getDataBefore() != null) { + onDelete(rootNode, rootIdentifier); + } + if (rootNode.getDataAfter() != null) { + onWrite(rootNode, rootIdentifier); + } + } + + public ListenableFuture createLocationForVppEndpoint(VppEndpoint vppEndpoint) { + return createAbsoluteAddressEndpointLocation(vppEndpoint, null); + } + + public ListenableFuture deleteLocationForVppEndpoint(VppEndpoint vppEndpoint) { + // removing VPP EP from cache out of since block, it's not needed for the other thread. + vppEndpoints.remove(vppEndpoint.getKey()); + return deleteLocation(createProviderAddressEndpointLocationKey(vppEndpoint)); + } + + /** + * There are two inputs from which we need to resolve location - {@link AddressEndpoint} and {@link VppEndpoint} + * These data are delivered by different threads which meet here. + */ + @VisibleForTesting + synchronized ListenableFuture createAbsoluteAddressEndpointLocation(VppEndpoint vppEndpoint, + DataObjectModification rootNode) { + if (vppEndpoint != null) { + vppEndpoints.put(vppEndpoint.getKey(), vppEndpoint); + if (cachedVppEndpoints.get(vppEndpoint.getKey()) != null) { + return processAddrEp(cachedVppEndpoints.get(vppEndpoint.getKey())); + } + } else if (rootNode != null) { + return processAddrEp(rootNode); + } + return Futures.immediateFuture(null); + } + + private ListenableFuture processAddrEp(DataObjectModification rootNode) { + if (rootNode != null) { + AddressEndpointChange aec = new AddressEndpointChange(rootNode, dataProvider); + switch (rootNode.getModificationType()) { + case WRITE: + case SUBTREE_MODIFIED: { + VppEndpoint vpp = vppEndpoints.get(vppEndpointKeyFrom(rootNode.getDataAfter().getKey())); + if (vpp == null) { + VppEndpointKey key = vppEndpointKeyFrom(rootNode.getDataAfter().getKey()); + cachedVppEndpoints.put(key, rootNode); + return Futures.immediateFuture(null); + } + if (aec.hasMoreParents()) { + return aec.syncMultiparents(); + } + return aec.write(); + } + case DELETE: { + if (aec.hasMoreParents()) { + return aec.syncMultiparents(); + } else { + return aec.delete(); + } + } + } + } + return Futures.immediateFuture(null); } - public static ProviderAddressEndpointLocation createProviderAddressEndpointLocation(VppEndpoint vppEndpoint) { + private ProviderAddressEndpointLocation createAbsoluteLocationFromVppEndpoint(VppEndpoint vppEndpoint) { InstanceIdentifier vppNodeIid = VppIidFactory.getNetconfNodeIid(vppEndpoint.getVppNodeId()); String restIfacePath = VppPathMapper.interfaceToRestPath(vppEndpoint.getVppInterfaceName()); - AbsoluteLocation absoluteLocation = new AbsoluteLocationBuilder() - .setLocationType(new ExternalLocationCaseBuilder().setExternalNodeMountPoint(vppNodeIid) - .setExternalNodeConnector(restIfacePath) - .build()) - .build(); + AbsoluteLocation absoluteLocation = + new AbsoluteLocationBuilder().setLocationType(new ExternalLocationCaseBuilder() + .setExternalNodeMountPoint(vppNodeIid).setExternalNodeConnector(restIfacePath).build()).build(); return new ProviderAddressEndpointLocationBuilder() .setKey(createProviderAddressEndpointLocationKey(vppEndpoint)) .setAbsoluteLocation(absoluteLocation) .build(); } - ListenableFuture deleteLocationForVppEndpoint(final VppEndpoint vppEndpoint) { - final ProviderAddressEndpointLocationKey provAddrEpLocKey = - createProviderAddressEndpointLocationKey(vppEndpoint); - final WriteTransaction wTx = txChain.newWriteOnlyTransaction(); - wTx.delete(LogicalDatastoreType.CONFIGURATION, - IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, provAddrEpLocKey)); - LOG.debug("Deleting location for {}", provAddrEpLocKey); - return Futures.transform(wTx.submit(), (Function) input -> { - LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), provAddrEpLocKey); - return null; + public ProviderAddressEndpointLocation createRelativeAddressEndpointLocation(@Nonnull AddressEndpointKey addrEp, + @Nonnull Map publicIntfNamesByNodes) { + RelativeLocations relLocations = + new RelativeLocationsBuilder() + .setExternalLocation(publicIntfNamesByNodes.keySet() + .stream() + .filter(nodeId -> publicIntfNamesByNodes.get(nodeId) != null) + .map(nodeId -> new ExternalLocationBuilder() + .setExternalNodeMountPoint(VppIidFactory.getNetconfNodeIid(nodeId)) + .setExternalNodeConnector( + VppPathMapper.interfaceToRestPath(publicIntfNamesByNodes.get(nodeId))) + .build()) + .collect(Collectors.toList())) + .build(); + return new ProviderAddressEndpointLocationBuilder().setKey(createProviderAddressEndpointLocationKey(addrEp)) + .setRelativeLocations(relLocations) + .build(); + } + + public ListenableFuture writeLocation(ProviderAddressEndpointLocation location) { + WriteTransaction wTx = txChain.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.CONFIGURATION, + IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, location.getKey()), + location, true); + return Futures.transform(wTx.submit(), new Function() { + + @Override + public Void apply(Void input) { + LOG.debug("{} provided location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), location); + return null; + } }); } - private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey( - VppEndpoint vppEndpoint) { - return new ProviderAddressEndpointLocationKey(vppEndpoint.getAddress(), vppEndpoint.getAddressType(), - vppEndpoint.getContextId(), vppEndpoint.getContextType()); + public ListenableFuture deleteLocation(ProviderAddressEndpointLocationKey key) { + ReadWriteTransaction rwTx = txChain.newReadWriteTransaction(); + LOG.debug("Deleting location for {}", key); + DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, + IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, key), rwTx); + return Futures.transform(rwTx.submit(), new Function() { + + @Override + public Void apply(Void input) { + LOG.debug("{} removed location: {}", VPP_ENDPOINT_LOCATION_PROVIDER.getValue(), key); + return null; + } + }); } public ListenableFuture replaceLocationForEndpoint(@Nonnull ExternalLocationCase location, @Nonnull AddressEndpointWithLocationKey addrEpWithLocKey) { @@ -144,10 +291,95 @@ public class VppEndpointLocationProvider implements AutoCloseable { }); } + static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(VppEndpoint vpp) { + return new ProviderAddressEndpointLocationKey(vpp.getAddress(), vpp.getAddressType(), vpp.getContextId(), + vpp.getContextType()); + } + + static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(AddressEndpointKey key) { + return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(), + key.getContextType()); + } + + private static ProviderAddressEndpointLocationKey createProviderAddressEndpointLocationKey(ParentEndpointKey key) { + return new ProviderAddressEndpointLocationKey(key.getAddress(), key.getAddressType(), key.getContextId(), + key.getContextType()); + } + + private VppEndpointKey vppEndpointKeyFrom(AddressEndpointKey key) { + return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType()); + } + + private VppEndpointKey vppEndpointKeyFrom(ParentEndpointKey key) { + return new VppEndpointKey(key.getAddress(), key.getAddressType(), key.getContextId(), key.getContextType()); + } + @Override - public void close() throws Exception { + public void close() { + super.closeRegisteredListener(); WriteTransaction wTx = txChain.newWriteOnlyTransaction(); wTx.delete(LogicalDatastoreType.CONFIGURATION, IidFactory.locationProviderIid(VPP_ENDPOINT_LOCATION_PROVIDER)); wTx.submit(); } + + private class AddressEndpointChange { + + private final AddressEndpoint before; + private final AddressEndpoint after; + private final DataBroker dataBroker; + + public AddressEndpointChange(DataObjectModification addrEp, @Nonnull DataBroker dataBroker) { + this.before = addrEp.getDataBefore(); + this.after = addrEp.getDataAfter(); + this.dataBroker = dataBroker; + } + + boolean hasMoreParents() { + return (before != null && EndpointUtils.getParentEndpoints(before.getParentEndpointChoice()).size() > 1) + || (after != null && EndpointUtils.getParentEndpoints(after.getParentEndpointChoice()).size() > 1); + } + + ListenableFuture syncMultiparents() { + ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); + if (before != null) { + for (ParentEndpoint pe : EndpointUtils.getParentEndpoints(before.getParentEndpointChoice())) { + InstanceIdentifier iid = + IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, + createProviderAddressEndpointLocationKey(pe.getKey())); + DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, iid, rwTx); + } + } + if (after != null) { + for (ParentEndpoint pe : EndpointUtils.getParentEndpoints(after.getParentEndpointChoice())) { + VppEndpoint vppEndpoint = vppEndpoints.get(vppEndpointKeyFrom(after.getKey())); + InstanceIdentifier iid = + IidFactory.providerAddressEndpointLocationIid(VPP_ENDPOINT_LOCATION_PROVIDER, + createProviderAddressEndpointLocationKey(pe.getKey())); + ProviderAddressEndpointLocation location = createAbsoluteLocationFromVppEndpoint( + new VppEndpointBuilder(vppEndpoint).setKey(vppEndpointKeyFrom(pe.getKey())).build()); + rwTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true); + } + } + return rwTx.submit(); + } + + ListenableFuture write() { + VppEndpoint vpp = vppEndpoints.get(vppEndpointKeyFrom(after.getKey())); + WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + ProviderAddressEndpointLocation location = + createAbsoluteLocationFromVppEndpoint(vpp); + InstanceIdentifier iid = IidFactory.providerAddressEndpointLocationIid( + VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(vpp)); + wTx.put(LogicalDatastoreType.CONFIGURATION, iid, location, true); + return wTx.submit(); + } + + ListenableFuture delete() { + ReadWriteTransaction rwTx = dataBroker.newReadWriteTransaction(); + InstanceIdentifier iid = IidFactory.providerAddressEndpointLocationIid( + VPP_ENDPOINT_LOCATION_PROVIDER, createProviderAddressEndpointLocationKey(before.getKey())); + DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION, iid, rwTx); + return rwTx.submit(); + } + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java index 6988567f3..501256c9c 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/manager/VppNodeManager.java @@ -54,6 +54,7 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Address; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.ip.rev140616.Interface1; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.RendererNodes; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNode; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.nodes.RendererNodeKey; @@ -441,4 +442,31 @@ public class VppNodeManager { } return Lists.newArrayList(); } + + public static Map resolvePublicInterfaces(DataBroker dataProvider) { + Map nodes = new HashMap<>(); + ReadOnlyTransaction rTx = dataProvider.newReadOnlyTransaction(); + Optional rendNodes = + DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, VppIidFactory.getRendererNodesIid(), rTx); + rTx.close(); + if (!rendNodes.isPresent()) { + return nodes; + } + rendNodes.get() + .getRendererNode() + .stream() + .filter(rn -> rn.getAugmentation(VppInterfaceAugmentation.class) != null) + .filter(rn -> rn.getAugmentation(VppInterfaceAugmentation.class).getPhysicalInterface() != null) + .forEach(rn -> { + java.util.Optional pubInt = rn.getAugmentation(VppInterfaceAugmentation.class) + .getPhysicalInterface() + .stream() + .filter(phInt -> phInt.isExternal()) + .findFirst(); + if (pubInt.isPresent()) { + nodes.put(rn.getNodePath().firstKeyOf(Node.class).getNodeId(), pubInt.get().getInterfaceName()); + } + }); + return nodes; + } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java index 91396d85f..be7f5d09c 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManager.java @@ -25,11 +25,10 @@ import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.commands.RoutingCommand; -import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatUtil; -import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.General; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; @@ -211,7 +210,7 @@ public final class ForwardingManager { } String l2FloodDomain = optL2FloodDomain.get(); try { - ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, AccessListUtil.resolveAclsOnInterface( + ifaceManager.addBridgeDomainToInterface(l2FloodDomain, rEp, aclManager.resolveAclsOnInterface( rEpKey, policyCtx), isBviForEndpoint(rEp)).get(); aclManager.updateAclsForPeers(policyCtx, rEpKey); LOG.debug("Interface added to bridge-domain {} for endpoint {}", l2FloodDomain, rEp); diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManager.java index 3b7ae6046..59d80322d 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManager.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManager.java @@ -24,7 +24,7 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.NodeOperEvent; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEvent; -import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; import org.opendaylight.groupbasedpolicy.util.IidFactory; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.endpoints.address.endpoints.AddressEndpointKey; @@ -120,6 +120,7 @@ public class VppRendererPolicyManager { LOG.trace("VPP renderer policy updated"); PolicyContext policyCtxBefore = new PolicyContext(rPolicyBefore); PolicyContext policyCtxAfter = new PolicyContext(rPolicyAfter); + aclManager.cacheMultiInterfaces(policyCtxAfter); MapDifference> vppNodesByL2FlDiff = createDiffForVppNodesByL2Fd(policyCtxBefore, policyCtxAfter); SetMultimap removedVppNodesByL2Fd = HashMultimap.create(); @@ -264,6 +265,7 @@ public class VppRendererPolicyManager { private void rendererPolicyCreated(RendererPolicy rPolicy) { LOG.trace("VPP renderer policy version {} created", rPolicy.getVersion()); PolicyContext policyCtx = new PolicyContext(rPolicy); + aclManager.cacheMultiInterfaces(policyCtx); ImmutableSet rEpKeys = policyCtx.getPolicyTable().rowKeySet(); SetMultimap vppNodesByL2Fd = resolveVppNodesByL2Fd(rEpKeys, policyCtx); @@ -276,6 +278,7 @@ public class VppRendererPolicyManager { private void rendererPolicyDeleted(RendererPolicy rendererPolicy) { LOG.trace("VPP renderer policy version {} deleted", rendererPolicy.getVersion()); PolicyContext policyCtx = new PolicyContext(rendererPolicy); + aclManager.cacheMultiInterfaces(policyCtx); ImmutableSet rEpKeys = policyCtx.getPolicyTable().rowKeySet(); rEpKeys.forEach(rEpKey -> fwManager.removeForwardingForEndpoint(rEpKey, policyCtx)); diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtil.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtil.java index 6e15411df..9f7715da1 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtil.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtil.java @@ -33,7 +33,6 @@ import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types. import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv4Prefix; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.Ipv6Prefix; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.parent.child.endpoints.parent.endpoint.choice.parent.endpoint._case.ParentEndpoint; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2BridgeDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.SubnetAugmentRenderer; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.has.subnet.Subnet; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction; @@ -74,55 +73,26 @@ public class AccessListUtil { // hiding default public constructor private AccessListUtil() {} - public static List resolveAclsOnInterface(RendererEndpointKey rEpKey, PolicyContext ctx) { - List aclWrappers = new ArrayList<>(); - for (ACE_DIRECTION dir : new ACE_DIRECTION[] {ACE_DIRECTION.INGRESS, ACE_DIRECTION.EGRESS}) { - aclWrappers.add(buildAccessListWrappers(dir, ctx, rEpKey)); - } - return aclWrappers; - } - - /** - * @param policyDirection direction for which policy should be resolved. EP -> VPP = OUTBOUND, EP <- VPP = INBOUND - * @param ctx with cached data - * @param rEpKey key of EP for which to create ACLs. - * @return synchronization futures, so that INGRESS and EGRESS ACLS can be resolved in parallel. - */ - private static AccessListWrapper buildAccessListWrappers(ACE_DIRECTION policyDirection, PolicyContext ctx, - RendererEndpointKey rEpKey) { - LOG.trace("Resolving policy for VPP renderer endpoint {} in a separate thread in {} direction.", rEpKey, - policyDirection); - AccessListWrapper aclWrapper = AccessListUtil.ACE_DIRECTION.INGRESS - .equals(policyDirection) ? new IngressAccessListWrapper() : new EgressAccessListWrapper(); + static void configureLocalRules(PolicyContext ctx, RendererEndpointKey rEpKey, ACE_DIRECTION policyDirection, + AccessListWrapper aclWrapper) { ctx.getPolicyTable() .row(rEpKey) .keySet() .stream() .filter(peerEpKey -> peerHasLocation(ctx, peerEpKey)) .forEach(peerEpKey -> { - ctx.getPolicyTable().get(rEpKey, peerEpKey).forEach(resolvedRules -> { - List rules = new ArrayList<>(); - LOG.debug("Resolving policy for {} and peer endpoint {}", rEpKey, peerEpKey); - Direction classifDir = - calculateClassifDirection(resolvedRules.getRendererEndpointParticipation(), policyDirection); - rules.addAll(resolveAclRulesFromPolicy(resolvedRules, classifDir, - rEpKey.getAddress() + UNDERSCORE + peerEpKey.getAddress())); - updateAddressesInRules(rules, rEpKey, peerEpKey, ctx, policyDirection, true); - aclWrapper.writeRules(rules); + ctx.getPolicyTable().get(rEpKey, peerEpKey).forEach(resolvedRules -> { + List rules = new ArrayList<>(); + LOG.debug("Resolving policy for {} and peer endpoint {}", rEpKey, peerEpKey); + Direction classifDir = calculateClassifDirection(resolvedRules.getRendererEndpointParticipation(), + policyDirection); + rules.addAll(resolveAclRulesFromPolicy(resolvedRules, classifDir, + rEpKey.getAddress() + UNDERSCORE + peerEpKey.getAddress())); + updateAddressesInRules(rules, rEpKey, peerEpKey, ctx, policyDirection, true); + aclWrapper.writeRules(rules); + + }); }); - }); - // resolve peers with no location - aclWrapper.writeRules(denyDomainSubnets(ctx, policyDirection)); - // TODO currently any traffic heading to/from outside of managed domain is - // permitted for demonstration purposes - if (rEpKey.getContextType().isAssignableFrom(L2BridgeDomain.class) && findAddrEp(ctx, rEpKey) != null) { - Optional allowExtAccess = - allowExternalNetworksForEp(findAddrEp(ctx, rEpKey), policyDirection); - if (allowExtAccess.isPresent()) { - aclWrapper.writeRule(allowExtAccess.get()); - } - } - return aclWrapper; } /** @@ -174,7 +144,7 @@ public class AccessListUtil { AddressEndpointUtils.fromPeerEpKey(peerEpKey)) != null; } - private static AddressEndpointWithLocation findAddrEp(PolicyContext ctx, RendererEndpointKey rEpKey) { + static AddressEndpointWithLocation findAddrEp(PolicyContext ctx, RendererEndpointKey rEpKey) { return ctx.getAddrEpByKey().get( AddressEndpointUtils.fromRendererEpKey(rEpKey)); } @@ -270,7 +240,7 @@ public class AccessListUtil { * purposes * TODO initial workaround for external networking */ - private static Optional allowExternalNetworksForEp(@Nonnull AddressEndpointWithLocation addrEp, + static Optional allowExternalNetworksForEp(@Nonnull AddressEndpointWithLocation addrEp, AccessListUtil.ACE_DIRECTION dir) { List parentEndpoints = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()); if (parentEndpoints.isEmpty()) { @@ -312,7 +282,7 @@ public class AccessListUtil { return (address.contains("/") && address.split("/").length > 0) ? address.split("/")[0] : address; } - private static List denyDomainSubnets(@Nonnull PolicyContext ctx, @Nonnull ACE_DIRECTION policyDirection) { + static List denyDomainSubnets(@Nonnull PolicyContext ctx, @Nonnull ACE_DIRECTION policyDirection) { List aclRuleBuilders = new ArrayList<>(); for (RendererForwardingByTenant rf : ctx.getPolicy() .getConfiguration() @@ -329,7 +299,7 @@ public class AccessListUtil { if (policyDirection.equals(ACE_DIRECTION.INGRESS) && subnetAug.getSubnet().isIsTenant()) { aclRuleBuilders.add(denyIngressTrafficForPrefix(subnetAug.getSubnet())); } - else if(subnetAug.getSubnet().isIsTenant()) { + else if (subnetAug.getSubnet().isIsTenant()) { aclRuleBuilders.add(denyEgressTrafficForPrefix(subnetAug.getSubnet())); } }); diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java new file mode 100644 index 000000000..aba8d1200 --- /dev/null +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AclManager.java @@ -0,0 +1,179 @@ +/* + * Copyright (c) 2017 Cisco Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ + +package org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +import javax.annotation.Nonnull; +import javax.annotation.Nullable; + +import org.opendaylight.controller.md.sal.binding.api.DataBroker; +import org.opendaylight.groupbasedpolicy.renderer.util.AddressEndpointUtils; +import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppPathMapper; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListUtil.ACE_DIRECTION; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider; +import org.opendaylight.groupbasedpolicy.util.EndpointUtils; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; +import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +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.absolute.location.absolute.location.location.type.ExternalLocationCase; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.l2_l3.rev160427.L2BridgeDomain; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpointKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpointKey; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; +import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +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.Preconditions; +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableSet; +import com.google.common.collect.ImmutableTable; +import com.google.common.collect.ImmutableTable.Builder; +import com.google.common.collect.Sets; + +public class AclManager { + + private static final Logger LOG = LoggerFactory.getLogger(AclManager.class); + private final MountedDataBrokerProvider mountDataProvider; + + private static ImmutableTable> multipleEndpointsOnInterface; + + public AclManager(@Nonnull MountedDataBrokerProvider mountDataProvider) { + this.mountDataProvider = Preconditions.checkNotNull(mountDataProvider); + } + + public List resolveAclsOnInterface(RendererEndpointKey rEpKey, PolicyContext ctx) { + List aclWrappers = new ArrayList<>(); + for (ACE_DIRECTION dir : new ACE_DIRECTION[] {ACE_DIRECTION.INGRESS, ACE_DIRECTION.EGRESS}) { + aclWrappers.add(buildAccessListWrappers(dir, ctx, rEpKey)); + } + return aclWrappers; + } + + /** + * @param policyDirection direction for which policy should be resolved. EP -> VPP = OUTBOUND, EP <- VPP = INBOUND + * @param ctx with cached data + * @param rEpKey key of EP for which to create ACLs. + * @return synchronization futures, so that INGRESS and EGRESS ACLS can be resolved in parallel. + */ + private static AccessListWrapper buildAccessListWrappers(ACE_DIRECTION policyDirection, PolicyContext ctx, + RendererEndpointKey rEpKey) { + LOG.trace("Resolving policy for VPP renderer endpoint {} in a separate thread in {} direction.", rEpKey, + policyDirection); + AccessListWrapper aclWrapper = AccessListUtil.ACE_DIRECTION.INGRESS + .equals(policyDirection) ? new IngressAccessListWrapper() : new EgressAccessListWrapper(); + AccessListUtil.configureLocalRules(ctx, rEpKey, policyDirection, aclWrapper); + // we support multiple IP end-points on a same interface + for (AddressEndpointKey aek : otherEndpointsOnTheSameInterface(ctx, + AddressEndpointUtils.fromRendererEpKey(rEpKey))) { + AccessListUtil.configureLocalRules(ctx, AddressEndpointUtils.toRendererEpKey(aek), policyDirection, aclWrapper); + } + // resolve peers with no location + aclWrapper.writeRules(AccessListUtil.denyDomainSubnets(ctx, policyDirection)); + // TODO currently any traffic heading to/from outside of managed domain is + // permitted for demonstration purposes + if (rEpKey.getContextType().isAssignableFrom(L2BridgeDomain.class) && AccessListUtil.findAddrEp(ctx, rEpKey) != null) { + Optional allowExtAccess = + AccessListUtil.allowExternalNetworksForEp(AccessListUtil.findAddrEp(ctx, rEpKey), policyDirection); + if (allowExtAccess.isPresent()) { + aclWrapper.writeRule(allowExtAccess.get()); + } + } + return aclWrapper; + } + + public void updateAclsForPeers(PolicyContext policyCtx, RendererEndpointKey rEpKey) { + ImmutableSet peers = policyCtx.getPolicyTable().row(rEpKey).keySet(); + for (RendererEndpointKey peerRendEp : peers.stream() + .map(AddressEndpointUtils::fromPeerEpKey) + .collect(Collectors.toList()) + .stream() + .map(AddressEndpointUtils::toRendererEpKey) + .collect(Collectors.toList())) { + updateAclsForRendEp(peerRendEp, policyCtx); + } + } + + public void updateAclsForRendEp(RendererEndpointKey rEpKey, PolicyContext policyCtx) { + LOG.info("Updating policy for endpoint {}", rEpKey); + AddressEndpointWithLocation peerAddrEp = policyCtx.getAddrEpByKey().get(KeyFactory.addressEndpointKey(rEpKey)); + ExternalLocationCase epLoc; + try { + epLoc = InterfaceManager.resolveAndValidateLocation(peerAddrEp); + } catch (NullPointerException | IllegalArgumentException e) { + //TODO investigate, don't just move on. + LOG.warn("Peer {} has no location. Moving on...", peerAddrEp, e.getMessage()); + return; + } + InstanceIdentifier vppNodeIid = epLoc.getExternalNodeMountPoint(); + Optional> optInterfaceIid = + VppPathMapper.interfaceToInstanceIdentifier(epLoc.getExternalNodeConnector()); + if (!optInterfaceIid.isPresent()) { + LOG.warn("Cannot find interface for endpoint {}. ACLs for endpoint not updated {}. ", rEpKey); + return; + } + Optional optMountPoint = mountDataProvider.getDataBrokerForMountPoint(vppNodeIid); + resolveAclsOnInterface(rEpKey, policyCtx).forEach(aclWrapper -> aclWrapper + .writeAcl(optMountPoint.get(), optInterfaceIid.get().firstKeyOf(Interface.class))); + } + + /** + * Cache end-points accessible via a single interface for further processing. + */ + public void cacheMultiInterfaces(@Nonnull PolicyContext ctx) { + Builder> resultBuilder = new Builder<>(); + resolveEndpointsOnMultipleInterface(ImmutableList.copyOf(ctx.getAddrEpByKey().values()), resultBuilder); + multipleEndpointsOnInterface = resultBuilder.build(); + } + + private void resolveEndpointsOnMultipleInterface(@Nullable ImmutableList eps, + @Nonnull Builder> builder) { + if (eps == null || eps.isEmpty()) { + return; + } + eps.get(0); + ImmutableSet copyOf = ImmutableSet.copyOf(eps.stream() + .filter(addrEp -> AddressEndpointUtils.sameExternalLocationCase(eps.get(0), addrEp)) + .map(addrEp -> AddressEndpointUtils.fromAddressEndpointWithLocationKey(addrEp.getKey())) + .collect(Collectors.toSet())); + Optional extLoc = EndpointUtils.getExternalLocationFrom(eps.get(0)); + builder.put(extLoc.get().getExternalNodeMountPoint().firstKeyOf(Node.class).getNodeId(), + new InterfaceKey(extLoc.get().getExternalNodeConnector()), copyOf); + ImmutableList lisst = ImmutableList.copyOf(eps.stream() + .filter(addrEp -> !AddressEndpointUtils.sameExternalLocationCase(eps.get(0), addrEp)) + .collect(Collectors.toList())); + if (!lisst.isEmpty()) { + resolveEndpointsOnMultipleInterface(lisst, builder); + } + } + + public @Nonnull static ImmutableSet otherEndpointsOnTheSameInterface(@Nonnull PolicyContext ctx, + @Nonnull AddressEndpointKey key) { + if (multipleEndpointsOnInterface != null) { + for (InterfaceKey ifaceKey : multipleEndpointsOnInterface.columnKeySet()) { + for (NodeId nodeId : multipleEndpointsOnInterface.column(ifaceKey).keySet()) { + ImmutableSet addrEps = multipleEndpointsOnInterface.get(nodeId, ifaceKey); + if (addrEps != null && addrEps.contains(key) && addrEps.size() > 1) { + return multipleEndpointsOnInterface.get(nodeId, ifaceKey); + } + } + } + } + return ImmutableSet.copyOf(Sets.newHashSet()); + } +} diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/DestinationMapper.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/DestinationMapper.java index 1eca68663..73c2bbdfd 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/DestinationMapper.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/DestinationMapper.java @@ -23,8 +23,6 @@ import org.slf4j.LoggerFactory; class DestinationMapper extends AddressMapper { private static final Logger LOG = LoggerFactory.getLogger(DestinationMapper.class); - private static final String METADATA_IP_PREFIX = "169.254.169.254/32"; - private static final String IN__METADATA = "In__METADATA"; DestinationMapper(ACE_DIRECTION direction) { super(direction); @@ -39,31 +37,22 @@ class DestinationMapper extends AddressMapper { @Override void updateRule(AddressEndpointWithLocation addrEp, GbpAceBuilder aclRuleBuilder) { - if (!EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).isEmpty()) { - // TODO more parents, when supported + String address; + if (addrEp.getContextType().isAssignableFrom(L3Context.class)) { + address = addrEp.getAddress(); + } else { ParentEndpoint parentEp = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).get(0); - if (parentEp != null && parentEp.getContextType().isAssignableFrom(L3Context.class)) { - // TODO this is a fix for metadata agent in DHCP namespace, when we will fully support multiple IPs - // per interface we shall rework this - if (aclRuleBuilder.getName().contains(IN__METADATA)) { - LOG.trace("Setting dst IP address {} in rule {}", METADATA_IP_PREFIX, aclRuleBuilder); - try { - AccessListUtil.setDestinationL3Address(aclRuleBuilder, METADATA_IP_PREFIX); - } catch (UnknownHostException e) { - LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", METADATA_IP_PREFIX, - aclRuleBuilder, e); - } - } else { - LOG.trace("Setting dst IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder); - try { - AccessListUtil.setDestinationL3Address(aclRuleBuilder, parentEp.getAddress()); - } catch (UnknownHostException e) { - LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(), - aclRuleBuilder, e); - } - } - + if (parentEp == null || !parentEp.getContextType().isAssignableFrom(L3Context.class)) { + LOG.warn("Cannot resolve IP address for endpoint {}", addrEp); + return; } + address = parentEp.getAddress(); + } + LOG.trace("Setting dst IP address {} in rule {}", address, aclRuleBuilder); + try { + AccessListUtil.setDestinationL3Address(aclRuleBuilder, address); + } catch (UnknownHostException e) { + LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", address, aclRuleBuilder, e); } } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/SourceMapper.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/SourceMapper.java index 28b03d8f9..a163f09a3 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/SourceMapper.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/SourceMapper.java @@ -23,8 +23,6 @@ import org.slf4j.LoggerFactory; class SourceMapper extends AddressMapper { private static final Logger LOG = LoggerFactory.getLogger(SourceMapper.class); - private static final String METADATA_IP_PREFIX = "169.254.169.254/32"; - private static final String OUT__METADATA = "Out__METADATA"; SourceMapper(ACE_DIRECTION direction) { super(direction); @@ -39,30 +37,22 @@ class SourceMapper extends AddressMapper { @Override void updateRule(AddressEndpointWithLocation addrEp, GbpAceBuilder aclRuleBuilder) { - if (!EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).isEmpty()) { - // TODO more parents + String address; + if (addrEp.getContextType().isAssignableFrom(L3Context.class)) { + address = addrEp.getAddress(); + } else { ParentEndpoint parentEp = EndpointUtils.getParentEndpoints(addrEp.getParentEndpointChoice()).get(0); - if (parentEp != null && parentEp.getContextType().isAssignableFrom(L3Context.class)) { - // TODO this is a fix for metadata agent in DHCP namespace, when we will fully support multiple IPs - // per interface we shall rework this - if (aclRuleBuilder.getName().contains(OUT__METADATA)) { - LOG.trace("Setting src IP address {} in rule {}", METADATA_IP_PREFIX, aclRuleBuilder); - try { - AccessListUtil.setSourceL3Address(aclRuleBuilder, METADATA_IP_PREFIX); - } catch (UnknownHostException e) { - LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", METADATA_IP_PREFIX, - aclRuleBuilder, e); - } - } else { - LOG.trace("Setting src IP address {} in rule {}", parentEp.getAddress(), aclRuleBuilder); - try { - AccessListUtil.setSourceL3Address(aclRuleBuilder, parentEp.getAddress()); - } catch (UnknownHostException e) { - LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", parentEp.getAddress(), - aclRuleBuilder, e); - } - } + if (parentEp == null || !parentEp.getContextType().isAssignableFrom(L3Context.class)) { + LOG.warn("Cannot resolve IP address for endpoint {}", addrEp); + return; } + address = parentEp.getAddress(); + } + LOG.trace("Setting src IP address {} in rule {}", address, aclRuleBuilder); + try { + AccessListUtil.setSourceL3Address(aclRuleBuilder, address); + } catch (UnknownHostException e) { + LOG.error("Failed to parse address {}. Cannot apply ACL entry {}. {}", address, aclRuleBuilder, e); } } } diff --git a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java index 150bc3128..952ba2d7b 100644 --- a/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java +++ b/renderers/vpp/src/main/java/org/opendaylight/groupbasedpolicy/renderer/vpp/util/VppIidFactory.java @@ -35,9 +35,9 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.r import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang._interface.acl.rev161214.VppAclInterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.BridgeDomainsState; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation; -import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.bridge.domains.state.BridgeDomain; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.bridge.domains.state.BridgeDomainKey; +import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.interfaces._interface.L2; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.vpp.acl.rev161214.VppAcl; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NetworkTopology; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; @@ -75,11 +75,7 @@ public class VppIidFactory { } public static InstanceIdentifier getRendererNodeIid(RendererNode rendererNode) { - return InstanceIdentifier.builder(Renderers.class) - .child(Renderer.class, new RendererKey(VppRenderer.NAME)) - .child(RendererNodes.class) - .child(RendererNode.class, new RendererNodeKey(rendererNode.getNodePath())) - .build(); + return getRendererNodesIid().child(RendererNode.class, new RendererNodeKey(rendererNode.getNodePath())); } public static InstanceIdentifier getNodeIid(TopologyKey topologyKey, NodeKey nodeKey) { diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManagerTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManagerTest.java index 0ee2f999a..12ac16add 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManagerTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/InterfaceManagerTest.java @@ -18,6 +18,7 @@ import org.junit.Test; import org.mockito.Mockito; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction; +import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider; @@ -26,6 +27,9 @@ import org.opendaylight.groupbasedpolicy.util.IidFactory; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey; +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.AddressEndpointBuilder; +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.common.rev140421.ContextId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.LocationProviders; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.endpoint_location_provider.rev160419.location.providers.LocationProvider; @@ -42,13 +46,12 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.VppInterfaceAugmentation; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.v3po.rev170315.BridgeDomains; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.TopologyId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.TopologyKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.NodeKey; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import com.google.common.base.Optional; +import com.google.common.collect.ImmutableList; public class InterfaceManagerTest extends CustomDataBrokerTest { @@ -59,7 +62,6 @@ public class InterfaceManagerTest extends CustomDataBrokerTest { new VppEndpointKey(ADDRESS, AddressType.class, CONTEXT_ID, ContextType.class); private final static InstanceIdentifier BASIC_VPP_EP_IID = InstanceIdentifier.builder(Config.class).child(VppEndpoint.class, BASIC_VPP_EP_KEY).build(); - private final static TopologyKey TOPO_KEY = new TopologyKey(new TopologyId("topo1")); private final static NodeKey NODE_KEY = new NodeKey(new NodeId("node1")); private final static String SOCKET = "socket1"; @@ -87,6 +89,15 @@ public class InterfaceManagerTest extends CustomDataBrokerTest { @Test public void testVppEndpointChanged_created() throws Exception { + VppEndpointLocationProvider vppEpLocProvider = new VppEndpointLocationProvider(dataBroker); + AddressEndpoint addrEp = new AddressEndpointBuilder() + .setKey(new AddressEndpointKey(vhostVppEpBuilder().getAddress(), vhostVppEpBuilder().getAddressType(), + vhostVppEpBuilder().getContextId(), vhostVppEpBuilder().getContextType())) + .setEndpointGroup(ImmutableList.of()) + .build(); + WriteTransaction wTx = dataBroker.newWriteOnlyTransaction(); + wTx.put(LogicalDatastoreType.OPERATIONAL, IidFactory.addressEndpointIid(addrEp.getKey()), addrEp, true); + wTx.submit().get(); VppEndpoint vhostEp = vhostVppEpBuilder().build(); VppEndpointConfEvent event = new VppEndpointConfEvent(BASIC_VPP_EP_IID, null, vhostEp); @@ -116,8 +127,7 @@ public class InterfaceManagerTest extends CustomDataBrokerTest { List epLocs = optLocationProvider.get().getProviderAddressEndpointLocation(); Assert.assertNotNull(epLocs); Assert.assertEquals(1, epLocs.size()); - ProviderAddressEndpointLocation epLoc = VppEndpointLocationProvider.createProviderAddressEndpointLocation(vhostEp); - Assert.assertEquals(epLoc, epLocs.get(0)); + vppEpLocProvider.close(); } @Test @@ -137,11 +147,10 @@ public class InterfaceManagerTest extends CustomDataBrokerTest { Assert.assertFalse(potentialIface.isPresent()); // assert state on ODL data store ReadOnlyTransaction rTx = dataBroker.newReadOnlyTransaction(); - ProviderAddressEndpointLocation providerAddressEndpointLocation = - VppEndpointLocationProvider.createProviderAddressEndpointLocation(vhostEp); + VppEndpointLocationProvider.createProviderAddressEndpointLocationKey(vhostEp); InstanceIdentifier providerAddressEndpointLocationIid = IidFactory .providerAddressEndpointLocationIid(VppEndpointLocationProvider.VPP_ENDPOINT_LOCATION_PROVIDER, - providerAddressEndpointLocation.getKey()); + VppEndpointLocationProvider.createProviderAddressEndpointLocationKey(vhostEp)); Optional optProvEpLoc = rTx.read(LogicalDatastoreType.CONFIGURATION, providerAddressEndpointLocationIid).get(); Assert.assertFalse(optProvEpLoc.isPresent()); diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProviderTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProviderTest.java index e9026fa50..6a766cba5 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProviderTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/iface/VppEndpointLocationProviderTest.java @@ -15,17 +15,16 @@ import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; -import com.google.common.util.concurrent.CheckedFuture; -import com.google.common.util.concurrent.ListenableFuture; import org.junit.Assert; import org.junit.Before; import org.junit.Test; import org.opendaylight.controller.md.sal.binding.api.BindingTransactionChain; 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.controller.md.sal.common.api.data.ReadFailedException; import org.opendaylight.controller.md.sal.common.api.data.TransactionCommitFailedException; -import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCaseBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId; @@ -36,10 +35,15 @@ import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocationKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointBuilder; +import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.vpp_renderer.rev160425.config.VppEndpointKey; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; -import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node; +import org.opendaylight.yangtools.yang.binding.DataObject; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; +import com.google.common.base.Optional; +import com.google.common.util.concurrent.CheckedFuture; +import com.google.common.util.concurrent.ListenableFuture; + @SuppressWarnings("unchecked") public class VppEndpointLocationProviderTest { @@ -49,19 +53,29 @@ public class VppEndpointLocationProviderTest { private final DataBroker dataProvider = mock(DataBroker.class); private final BindingTransactionChain transactionChain = mock(BindingTransactionChain.class); private final WriteTransaction wTx = mock(WriteTransaction.class); + private final ReadWriteTransaction rwTx = mock(ReadWriteTransaction.class); private final CheckedFuture future = mock(CheckedFuture.class); + private final CheckedFuture,ReadFailedException> readFuture = mock(CheckedFuture.class); + private final Optional vppEpOpt = mock(Optional.class); + private final VppEndpointKey VPP_EP_KEY = + new VppEndpointKey("192.168.192.168/32", IpPrefixType.class, new ContextId("TEST_CTX"), L3Context.class); @Before - public void init() { + public void init() throws ReadFailedException { when(dataProvider.createTransactionChain(any())).thenReturn(transactionChain); when(transactionChain.newWriteOnlyTransaction()).thenReturn(wTx); + when(transactionChain.newReadWriteTransaction()).thenReturn(rwTx); + when(dataProvider.newReadWriteTransaction()).thenReturn(rwTx); + when(rwTx.read(any(LogicalDatastoreType.class), any(InstanceIdentifier.class))).thenReturn(readFuture); + when(readFuture.checkedGet()).thenReturn(vppEpOpt); + when(vppEpOpt.isPresent()).thenReturn(true); when(wTx.submit()).thenReturn(future); + when(rwTx.submit()).thenReturn(future); } @Test public void constructorTest() { new VppEndpointLocationProvider(dataProvider); - verify(dataProvider, times(1)).createTransactionChain(any()); verify(transactionChain, times(1)).newWriteOnlyTransaction(); verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION), @@ -73,44 +87,29 @@ public class VppEndpointLocationProviderTest { public void createLocationForVppEndpointTest() { final VppEndpointLocationProvider locationProvider = new VppEndpointLocationProvider(dataProvider); final ListenableFuture result = locationProvider.createLocationForVppEndpoint(vppEndpointBuilder()); - Assert.assertNotNull(result); verify(dataProvider, times(1)).createTransactionChain(any()); - verify(transactionChain, times(2)).newWriteOnlyTransaction(); + verify(transactionChain, times(1)).newWriteOnlyTransaction(); verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class), any(LocationProvider.class), eq(true)); verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class), any(ProviderAddressEndpointLocation.class), eq(true)); - verify(wTx, times(2)).submit(); - } - - @Test - public void createProviderAddressEndpointLocationTest() { - final ProviderAddressEndpointLocation result = - VppEndpointLocationProvider.createProviderAddressEndpointLocation(vppEndpointBuilder()); - Assert.assertNotNull(result); - final AbsoluteLocation location = result.getAbsoluteLocation(); - Assert.assertNotNull(location); - Assert.assertEquals(location.getLocationType().getImplementedInterface(), ExternalLocationCase.class); - final ExternalLocationCase locationType = (ExternalLocationCase) location.getLocationType(); - Assert.assertEquals(locationType.getExternalNodeMountPoint().firstKeyOf(Node.class).getNodeId(), nodeId); - Assert.assertTrue(locationType.getExternalNodeConnector().contains(INTERFACE_NAME)); - + verify(wTx, times(1)).submit(); } @Test public void deleteLocationForVppEndpointTest() { final VppEndpointLocationProvider locationProvider = new VppEndpointLocationProvider(dataProvider); final ListenableFuture result = locationProvider.deleteLocationForVppEndpoint(vppEndpointBuilder()); - Assert.assertNotNull(result); verify(dataProvider, times(1)).createTransactionChain(any()); - verify(transactionChain, times(2)).newWriteOnlyTransaction(); + verify(transactionChain, times(1)).newWriteOnlyTransaction(); verify(wTx, times(1)).put(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class), any(LocationProvider.class), eq(true)); - verify(wTx, times(1)).delete(eq(LogicalDatastoreType.CONFIGURATION), + verify(rwTx, times(1)).delete(eq(LogicalDatastoreType.CONFIGURATION), any(InstanceIdentifier.class)); - verify(wTx, times(2)).submit(); + verify(wTx, times(1)).submit(); + verify(rwTx, times(1)).submit(); } @Test @@ -131,8 +130,7 @@ public class VppEndpointLocationProviderTest { private VppEndpoint vppEndpointBuilder() { final VppEndpointBuilder vppEndpointBuilder = new VppEndpointBuilder(); - vppEndpointBuilder.setVppNodeId(nodeId) - .setVppInterfaceName(INTERFACE_NAME); + vppEndpointBuilder.setKey(VPP_EP_KEY).setVppNodeId(nodeId).setVppInterfaceName(INTERFACE_NAME); return vppEndpointBuilder.build(); } diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImplTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImplTest.java index da8f75781..66fc78951 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImplTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/BridgeDomainManagerImplTest.java @@ -22,9 +22,9 @@ import org.mockito.Mockito; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; -import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.VppIidFactory; import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest; diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManagerTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManagerTest.java index 09e5d719e..40caf4490 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManagerTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/ForwardingManagerTest.java @@ -22,10 +22,10 @@ import org.opendaylight.controller.md.sal.binding.api.WriteTransaction; import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.vpp.DtoFactory; import org.opendaylight.groupbasedpolicy.renderer.vpp.api.BridgeDomainManager; -import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AccessListWrapper; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; import org.opendaylight.groupbasedpolicy.test.CustomDataBrokerTest; diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java index fb609691e..112c8aadb 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/VppRendererPolicyManagerTest.java @@ -26,10 +26,10 @@ import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType; import org.opendaylight.groupbasedpolicy.renderer.vpp.DtoFactory; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.RendererPolicyConfEvent; import org.opendaylight.groupbasedpolicy.renderer.vpp.event.VppEndpointConfEvent; -import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.InterfaceManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.iface.VppEndpointLocationProvider; import org.opendaylight.groupbasedpolicy.renderer.vpp.nat.NatManager; +import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.acl.AclManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.routing.RoutingManager; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.KeyFactory; import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider; @@ -115,12 +115,12 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest { @Test public void testRendererPolicyChanged_created_oneEpPerEpg() throws Exception { - String clientIp = "1.1.1.1"; + String clientIp = "1.1.1.1/32"; String clientIfaceName = "client1"; AbsoluteLocation clientLocation = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, clientIfaceName); AddressEndpointWithLocation clientEp = DtoFactory.createEndpoint(clientIp, DtoFactory.L2FD_CTX.getValue(), clientLocation); - String webIp = "2.2.2.2"; + String webIp = "2.2.2.2/32"; String webIfaceName = "web1"; AbsoluteLocation webLocation = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, webIfaceName); AddressEndpointWithLocation webEp = @@ -164,22 +164,22 @@ public class VppRendererPolicyManagerTest extends CustomDataBrokerTest { AbsoluteLocation client1LocationNodeNull = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, client1IfaceName); AddressEndpointWithLocation client1Ep = - DtoFactory.createEndpoint("10.0.0.1", DtoFactory.L2FD_CTX.getValue(), client1LocationNodeNull); + DtoFactory.createEndpoint("10.0.0.1/32", DtoFactory.L2FD_CTX.getValue(), client1LocationNodeNull); String web1IfaceName = "web1"; AbsoluteLocation web1LocationNodeNull = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID, null, web1IfaceName); AddressEndpointWithLocation web1Ep = - DtoFactory.createEndpoint("20.0.0.1", DtoFactory.L2FD_CTX.getValue(), web1LocationNodeNull); + DtoFactory.createEndpoint("20.0.0.1/32", DtoFactory.L2FD_CTX.getValue(), web1LocationNodeNull); String client2IfaceName = "client2"; AbsoluteLocation client2LocationNodeNull = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_1_IID, null, client2IfaceName); AddressEndpointWithLocation client2Ep = - DtoFactory.createEndpoint("10.0.0.2", DtoFactory.L2FD_CTX.getValue(), client2LocationNodeNull); + DtoFactory.createEndpoint("10.0.0.2/32", DtoFactory.L2FD_CTX.getValue(), client2LocationNodeNull); String web2IfaceName = "web2"; AbsoluteLocation web2LocationNodeNull = DtoFactory.absoluteLocation(DtoFactory.VPP_NODE_2_IID, null, web2IfaceName); AddressEndpointWithLocation web2Ep = - DtoFactory.createEndpoint("20.0.0.2", DtoFactory.L2FD_CTX.getValue(), web2LocationNodeNull); + DtoFactory.createEndpoint("20.0.0.2/32", DtoFactory.L2FD_CTX.getValue(), web2LocationNodeNull); storeVppEndpoint(client1Ep.getKey(), client1IfaceName, createVppEndpointIid(client1Ep.getKey())); storeVppEndpoint(web1Ep.getKey(), web1IfaceName, createVppEndpointIid(web1Ep.getKey())); diff --git a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtilTest.java b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtilTest.java index 5828b9b93..122290353 100644 --- a/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtilTest.java +++ b/renderers/vpp/src/test/java/org/opendaylight/groupbasedpolicy/renderer/vpp/policy/acl/AccessListUtilTest.java @@ -14,22 +14,35 @@ import java.util.stream.Collectors; import org.junit.Assert; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.groupbasedpolicy.renderer.vpp.policy.PolicyContext; +import org.opendaylight.groupbasedpolicy.renderer.vpp.util.MountedDataBrokerProvider; +import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; + +import com.google.common.base.Optional; public class AccessListUtilTest extends TestResources { private PolicyContext ctx; + private MountedDataBrokerProvider mountedDataProviderMock; + private DataBroker mountPointDataBroker; @Before public void init() { ctx = super.createPolicyContext(); + mountedDataProviderMock = Mockito.mock(MountedDataBrokerProvider.class); + mountPointDataBroker = Mockito.mock(DataBroker.class); + Mockito.when(mountedDataProviderMock.getDataBrokerForMountPoint(Mockito.any(InstanceIdentifier.class))) + .thenReturn(Optional.of(mountPointDataBroker)); } @Test public void resolveAclsOnInterfaceTest() { // TODO add more checking + AclManager aclManager = new AclManager(mountedDataProviderMock); List acls = - AccessListUtil.resolveAclsOnInterface(rendererEndpoint(l2AddrEp2).build().getKey(), ctx); + aclManager.resolveAclsOnInterface(rendererEndpoint(l2AddrEp2).build().getKey(), ctx); Assert.assertEquals(2, acls.size()); Assert.assertEquals(2, acls.stream().map(AccessListWrapper::getDirection).collect(Collectors.toSet()).size()); acls.stream().forEach(ace -> { -- 2.36.6