/* * Copyright (c) 2016 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.ios_xe_provider.impl.util; import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN; import com.google.common.base.Preconditions; import com.google.common.collect.Iterables; import com.google.common.util.concurrent.Futures; import com.google.common.util.concurrent.ListenableFuture; import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.Set; import java.util.concurrent.TimeUnit; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.opendaylight.controller.md.sal.binding.api.DataBroker; import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase; import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.writer.PolicyWriterUtil; import org.opendaylight.groupbasedpolicy.sxp.ep.provider.api.EPToSgtMapper; import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath; import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType; import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroup; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroupBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Destination; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.DestinationBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Source; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.SourceBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicyBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.TypeBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain.Direction; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.MatchBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionList; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListKey; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.ForwardCaseBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.ForwardBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePath; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathBuilder; import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathKey; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey; 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.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.common.rev140421.ActionDefinitionId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName; 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.forwarding.l2_l3.rev160427.IpPrefixType; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.EndpointPolicyParticipation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration; 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.RendererEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.classifiers.Classifier; import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.rpc.fields.Binding; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.rpc.fields.BindingBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.ip.sgt.distribution.rev160715.rpc.fields.binding.PeerNodeBuilder; import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt; import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.NodeId; import org.opendaylight.yangtools.yang.binding.InstanceIdentifier; import org.slf4j.Logger; import org.slf4j.LoggerFactory; public class PolicyManagerUtil { private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class); private PolicyManagerUtil() { throw new IllegalAccessError("instance of util class not supported"); } /** * Main method for policy creation which looks for all actions specified in rules between two endpoints. Whichever * action has been found, it is resolved (only chain action is supported for now). * * @param sourceSgt - security group tag of source endpoint * @param destinationSgt - security group tag of destination endpoint * @param context - stores info about location of classifier/policy-map and status * @param data - new data, used to found appropriate rule group * @param peerEndpoint - contains info about rule groups between endpoint pairs * @param dataBroker - data provider for odl controller */ public static void syncEndpointPairCreatePolicy(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context, final Configuration data, final PeerEndpoint peerEndpoint, final DataBroker dataBroker) { // Create appropriate policy map if (! PolicyManagerUtil.constructEmptyPolicyMapWithInterface(context)) { final String policyMapName = context.getPolicyMapLocation().getPolicyMapName(); final String interfaceName = context.getPolicyMapLocation().getInterfaceName(); final String info = String.format("Unable to create policy-map %s on interface %s", policyMapName, interfaceName); context.appendUnconfiguredRendererEP(StatusUtil.assembleFullyNotConfigurableRendererEP(context, info)); LOG.warn(info); return; } // Find actions from acquired data final Map<ActionCase, ActionInDirection> actionMap = PolicyManagerUtil.getActionInDirection(data, peerEndpoint); if (actionMap.isEmpty()) { LOG.debug("No usable action found for EP-sgt[{}] | peerEP-sgt[{}]", sourceSgt, destinationSgt); return; } // Chain action if (actionMap.containsKey(ActionCase.CHAIN)) { ServiceChainingUtil.newChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context, dataBroker); } } /** * Method for policy removal which looks for all actions specified in rules between two endpoints. Whichever * action has been found, it is resolved (only chain action is supported). * * @param sourceSgt - security group tag of source endpoint * @param destinationSgt - security group tag of destination endpoint * @param context - stores info about location of classifier/policy-map and status * @param data - data used to identify all elements marked to remove * @param peerEndpoint - contains info about rule groups between endpoint pairs */ public static void syncEndpointPairRemovePolicy(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context, final Configuration data, final PeerEndpoint peerEndpoint) { // Find actions from acquired data final Map<ActionCase, ActionInDirection> actionMap = PolicyManagerUtil.getActionInDirection(data, peerEndpoint); if (actionMap.isEmpty()) { LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]", sourceSgt, destinationSgt); return; } // Chain action if (actionMap.containsKey(ActionCase.CHAIN)) { ServiceChainingUtil.resolveRemovedChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context); } // Remove policy-map if empty if (! deleteEmptyPolicyMapWithInterface(context.getPolicyMapLocation())) { final PolicyManagerImpl.PolicyMapLocation location = context.getPolicyMapLocation(); final String info = String.format("Unable to remove policy-map %s and interface %s", location.getPolicyMapName(), location.getInterfaceName()); LOG.warn(info); } } /** * According to info from {@link RuleGroupWithRendererEndpointParticipation} (composite key) finds appropriate subject * * @param data - contains all rule groups * @param ruleGroupWithParticipation - contains info about how to find right rule group * @return rule group if found, null otherwise */ @Nullable private static RuleGroup findRuleGroup(final Configuration data, final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) { final TenantId tenantId = ruleGroupWithParticipation.getTenantId(); final ContractId contractId = ruleGroupWithParticipation.getContractId(); final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName(); for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) { if (! ruleGroup.getTenantId().equals(tenantId)) { continue; } if (! ruleGroup.getContractId().equals(contractId)) { continue; } if (ruleGroup.getSubjectName().equals(subjectName)) { return ruleGroup; } } return null; } @Nullable public static Sgt findSgtTag(final EPToSgtMapper sxpEpProvider, final AddressEndpointKey endpointKey, final List<AddressEndpointWithLocation> endpointsWithLocation, final long timeout, final TimeUnit unit) { if (endpointKey == null || endpointsWithLocation == null) { return null; } final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey, endpointsWithLocation); final ListenableFuture<Collection<Sgt>> sgtForEPFu = sxpEpProvider.findSgtForEP(endpointWithLocation); Sgt sgt = null; try { sgt = Iterables.getFirst(sgtForEPFu.get(timeout, unit), null); LOG.trace("For ep[{}] found sgt: {}", endpointKey, sgt); } catch (Exception e) { LOG.debug("failed to obtain sgt for given endpoint: ", e.getMessage()); } return sgt; } /** * Creates empty policy-map if does not exist and bounds it to interface if it is not. If policy-map exists, method * checks whether it is connected to correct interface and creates it if necessary. If policy-map does not exist, * it is created with particular interface * * @param context - all data required to create/localize policy-map * @return true if policy-map and interface is present/written on the device, false otherwise */ private static boolean constructEmptyPolicyMapWithInterface(final PolicyConfigurationContext context) { final PolicyManagerImpl.PolicyMapLocation policyMapLocation = context.getPolicyMapLocation(); final String policyMapName = policyMapLocation.getPolicyMapName(); final DataBroker mountpoint = policyMapLocation.getMountpoint(); final String interfaceName = policyMapLocation.getInterfaceName(); final NodeId nodeId = policyMapLocation.getNodeId(); final InstanceIdentifier<PolicyMap> policyMapIid = PolicyWriterUtil.policyMapInstanceIdentifier(policyMapName); final Optional<PolicyMap> optionalPolicyMap = Optional.ofNullable(PolicyWriterUtil.netconfRead(mountpoint, policyMapIid)); if (optionalPolicyMap.isPresent()) { LOG.trace("Policy map with name {} on interface {} already exists", policyMapName, interfaceName); final InstanceIdentifier<ServicePolicy> servicePolicyIid = PolicyWriterUtil.interfaceInstanceIdentifier(interfaceName); final Optional<ServicePolicy> optionalServicePolicy = Optional.ofNullable(PolicyWriterUtil.netconfRead(mountpoint, servicePolicyIid)); if (optionalServicePolicy.isPresent()) { LOG.trace("Policy map {} is bound to correct interface {} ", policyMapName, interfaceName); return true; } else { boolean iResult = PolicyWriterUtil.writeInterface(context.getPolicyMapLocation()); context.setFutureResult(Futures.immediateCheckedFuture(iResult)); return iResult; } } else { final PolicyMap emptyMap = createEmptyPolicyMap(policyMapName); boolean pmResult = PolicyWriterUtil.writePolicyMap(emptyMap, context.getPolicyMapLocation()); context.setFutureResult(Futures.immediateCheckedFuture(pmResult)); if (pmResult) { LOG.info("Created policy-map {} on node {}", policyMapName, nodeId.getValue()); LOG.trace("Adding policy-map {} to interface {}", policyMapName, interfaceName); boolean iResult = PolicyWriterUtil.writeInterface(context.getPolicyMapLocation()); context.setFutureResult(Futures.immediateCheckedFuture(iResult)); return iResult; } return false; } } /** * Removes empty policy-map and its interface * * @param policyMapLocation - location of policy-map * @return true if policy-map is present and not empty or if it is successfully removed also with interface, false * otherwise */ private static boolean deleteEmptyPolicyMapWithInterface(PolicyManagerImpl.PolicyMapLocation policyMapLocation) { final String policyMapName = policyMapLocation.getPolicyMapName(); final DataBroker mountpoint = policyMapLocation.getMountpoint(); final InstanceIdentifier<PolicyMap> policyMapIid = PolicyWriterUtil.policyMapInstanceIdentifier(policyMapName); // Read policy map final Optional<PolicyMap> optionalPolicyMap = Optional.ofNullable(PolicyWriterUtil.netconfRead(mountpoint, policyMapIid)); if (optionalPolicyMap.isPresent()) { final PolicyMap policyMap = optionalPolicyMap.get(); if (policyMap.getXmlClass() == null || policyMap.getXmlClass().isEmpty()) { // No entries, remove if (PolicyWriterUtil.removePolicyMap(policyMapLocation)) { // Remove interface binding if exists LOG.info("Policy-map {} removed", policyMapName); return PolicyWriterUtil.removeInterface(policyMapLocation); } return false; } LOG.debug("Policy-map {} still contains entries, cannot be removed", policyMapLocation.getPolicyMapName()); return true; } return true; } public static ServicePolicy createServicePolicy(final String chainName, final Direction direction) { // Service Chain final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder(); serviceChainBuilder.setName(chainName) // Same as the policy map name .setDirection(direction); // Service policy final TypeBuilder typeBuilder = new TypeBuilder(); typeBuilder.setServiceChain(serviceChainBuilder.build()); // Service Policy ServicePolicyBuilder servicePolicyBuilder = new ServicePolicyBuilder(); servicePolicyBuilder.setType(typeBuilder.build()); return servicePolicyBuilder.build(); } private static PolicyMap createEmptyPolicyMap(String policyMapName) { // TODO maybe could be better to create also class-default entry with pass-through value than not to create any default entry at all // Construct policy map final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder(); policyMapBuilder.setName(policyMapName) .setKey(new PolicyMapKey(policyMapName)) .setType(PolicyMap.Type.ServiceChain); return policyMapBuilder.build(); } static Class createPolicyMapEntry(final String policyClassName, final RenderedServicePath renderedPath, final ActionCase actionCase) { // Forward Case final ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder(); if (actionCase.equals(CHAIN) && renderedPath != null) { // Chain Action final ForwardBuilder forwardBuilder = new ForwardBuilder(); final List<ServicePath> servicePaths = new ArrayList<>(); final ServicePathBuilder servicePathBuilder = new ServicePathBuilder(); servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId())) .setServicePathId(renderedPath.getPathId()) .setServiceIndex(renderedPath.getStartingIndex()); servicePaths.add(servicePathBuilder.build()); forwardBuilder.setServicePath(servicePaths); forwardCaseBuilder.setForward(forwardBuilder.build()); } // Create Action List final List<ActionList> actionList = new ArrayList<>(); final ActionListBuilder actionListBuilder = new ActionListBuilder(); actionListBuilder.setKey(new ActionListKey(PolicyActionType.Forward)) .setActionType(PolicyActionType.Forward) .setActionParam(forwardCaseBuilder.build()); actionList.add(actionListBuilder.build()); // Build class entry final ClassBuilder policyClassBuilder = new ClassBuilder(); policyClassBuilder.setName(new ClassNameType(policyClassName)) .setKey(new ClassKey(new ClassNameType(policyClassName))) .setActionList(actionList); return policyClassBuilder.build(); } static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) { final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder(); final Source source = new SourceBuilder().setTag(sourceTag).build(); final Destination destination = new DestinationBuilder().setTag(destinationTag).build(); sgBuilder.setDestination(destination) .setSource(source); final SecurityGroup securityGroup = sgBuilder.build(); final MatchBuilder matchBuilder = new MatchBuilder(); matchBuilder.setSecurityGroup(securityGroup); return matchBuilder.build(); } @Nonnull static ClassMap createClassMap(final String classMapName, final Match match) { final ClassMapBuilder cmBuilder = new ClassMapBuilder(); cmBuilder.setName(classMapName) .setKey(new ClassMapKey(classMapName)) .setPrematch(ClassMap.Prematch.MatchAll) .setMatch(match); return cmBuilder.build(); } /** * Constructs {@link ActionInDirection} object with {@link ActionCase} as a key. ActionInDirection object contains * info about action, participation and rule direction. * * @param data - used for finding rule's rule group * @param peer - contains {@link RuleGroupWithRendererEndpointParticipation} * @return map with actionCase/ActionInDirection entries, empty map if no rule is found */ @Nonnull private static Map<ActionCase, ActionInDirection> getActionInDirection(final Configuration data, final PeerEndpoint peer) { final Set<ResolvedRule> rulesInDirection = new HashSet<>(); EndpointPolicyParticipation participation = null; HasDirection.Direction direction = null; // Find all rules in desired direction for (RuleGroupWithRendererEndpointParticipation ruleGroupKey : peer.getRuleGroupWithRendererEndpointParticipation()) { participation = ruleGroupKey.getRendererEndpointParticipation(); final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey); if (ruleGroup == null || ruleGroup.getResolvedRule() == null) { continue; } for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) { if (resolvedRule == null) { continue; } if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) { continue; } // TODO only first Classifier used final Classifier classifier = resolvedRule.getClassifier().get(0); direction = classifier.getDirection(); rulesInDirection.add(resolvedRule); } } if (rulesInDirection.isEmpty()) { return Collections.emptyMap(); } // TODO use only first rule with ActionDefinitionID for now final Map<ActionCase, ActionInDirection> result = new HashMap<>(); for (ResolvedRule resolvedRule : rulesInDirection) { // TODO only first action used for now final Action action = resolvedRule.getAction().get(0); final RuleName name = resolvedRule.getName(); if (action.getActionDefinitionId() != null) { final ActionDefinitionId actionDefinitionId = action.getActionDefinitionId(); // Currently only chain action is supported if (actionDefinitionId.equals(ChainActionDefinition.ID)) { ActionInDirection actionInDirection = new ActionInDirection(name, action, participation, direction); result.put(ActionCase.CHAIN, actionInDirection); return result; } } } return Collections.emptyMap(); } public static InstanceIdentifier getMountpointIidFromAbsoluteLocation(final RendererEndpoint endpoint, final List<AddressEndpointWithLocation> endpointsWithLocation) { if (endpointsWithLocation.isEmpty()) { return null; } AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint, endpointsWithLocation); final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation(); final LocationType locationType = absoluteLocation.getLocationType(); ExternalLocationCase location = (ExternalLocationCase) locationType; if (location == null) { LOG.warn("Endpoint {} does not contain info about external location", endpointWithLocation.getKey().toString()); return null; } return location.getExternalNodeMountPoint(); } public static String getInterfaceNameFromAbsoluteLocation(final RendererEndpoint endpoint, final List<AddressEndpointWithLocation> endpointsWithLocation) { if (endpoint == null || endpointsWithLocation == null) { return null; } final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint, endpointsWithLocation); final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation(); final LocationType locationType = absoluteLocation.getLocationType(); final ExternalLocationCase location = (ExternalLocationCase) locationType; if (location == null) { LOG.warn("Endpoint {} does not contain info about external location", endpointWithLocation.getKey().toString()); return null; } return location.getExternalNodeConnector(); } static TenantId getTenantId(final PeerEndpoint peer) { for (RuleGroupWithRendererEndpointParticipation ruleGroup : peer.getRuleGroupWithRendererEndpointParticipation()) { if (ruleGroup.getTenantId() != null) { return ruleGroup.getTenantId(); } } return null; } static String generateClassMapName(final int sourceTag, final int destinationTag) { return "srcTag" + sourceTag + "_dstTag" + destinationTag; } public static Optional<Binding> createIpSgtBindingItem(final Sgt sgt, final AddressEndpointWithLocation addressEndpointWithLocation) { final Optional<Binding> result; final LocationType locationType = addressEndpointWithLocation.getAbsoluteLocation().getLocationType(); if (IpPrefixType.class == addressEndpointWithLocation.getAddressType() && locationType instanceof ExternalLocationCase && sgt != null) { final Binding binding = new BindingBuilder() .setSgt(sgt) .setIpPrefix(new IpPrefix(addressEndpointWithLocation.getAddress().toCharArray())) .setPeerNode(Collections.singletonList(new PeerNodeBuilder() .setNodeIid(((ExternalLocationCase) locationType).getExternalNodeMountPoint()) .build())) .build(); result = Optional.ofNullable(binding); } else { result = Optional.empty(); } return result; } /** * Action in Direction - wrapper class */ static class ActionInDirection { private final RuleName ruleName; private final Action action; private final EndpointPolicyParticipation participation; private final HasDirection.Direction direction; ActionInDirection(final RuleName ruleName, final Action action, final EndpointPolicyParticipation participation, final HasDirection.Direction direction) { this.ruleName = Preconditions.checkNotNull(ruleName); this.action = Preconditions.checkNotNull(action); this.participation = Preconditions.checkNotNull(participation); this.direction = Preconditions.checkNotNull(direction); } RuleName getRuleName() { return ruleName; } Action getAction() { return action; } EndpointPolicyParticipation getParticipation() { return participation; } HasDirection.Direction getDirection() { return direction; } } }