520784b41e74a481cb599358480bb45ccb9baeea
[groupbasedpolicy.git] / renderers / ios-xe / src / main / java / org / opendaylight / groupbasedpolicy / renderer / ios_xe_provider / impl / util / PolicyManagerUtil.java
1 /*
2  * Copyright (c) 2016 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8
9 package org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.util;
10
11 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.ActionCase.CHAIN;
12 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Create;
13 import static org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl.DsAction.Delete;
14
15 import java.util.ArrayList;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.List;
19 import java.util.Map;
20 import java.util.Set;
21 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
22 import org.opendaylight.groupbasedpolicy.api.sf.ChainActionDefinition;
23 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyConfigurationContext;
24 import org.opendaylight.groupbasedpolicy.renderer.ios_xe_provider.impl.manager.PolicyManagerImpl;
25 import org.opendaylight.yang.gen.v1.urn.cisco.params.xml.ns.yang.sfc.rsp.rev140701.rendered.service.paths.RenderedServicePath;
26 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.ClassNameType;
27 import org.opendaylight.yang.gen.v1.urn.ios.rev160308.PolicyActionType;
28 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroup;
29 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.SecurityGroupBuilder;
30 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Destination;
31 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.DestinationBuilder;
32 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.Source;
33 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._class.map.match.grouping.security.group.SourceBuilder;
34 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicy;
35 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.ServicePolicyBuilder;
36 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.TypeBuilder;
37 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChain;
38 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._interface.common.grouping.service.policy.type.ServiceChainBuilder;
39 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMap;
40 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapBuilder;
41 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.ClassMapKey;
42 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMap;
43 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapBuilder;
44 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.PolicyMapKey;
45 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.Match;
46 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native._class.map.MatchBuilder;
47 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.Class;
48 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassBuilder;
49 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map.ClassKey;
50 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionList;
51 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListBuilder;
52 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.ActionListKey;
53 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.ForwardCaseBuilder;
54 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.ForwardBuilder;
55 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePath;
56 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathBuilder;
57 import org.opendaylight.yang.gen.v1.urn.ios.rev160308._native.policy.map._class.action.list.action.param.forward._case.forward.ServicePathKey;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.AddressEndpointKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.AbsoluteLocation;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.LocationType;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.base_endpoint.rev160427.has.absolute.location.absolute.location.location.type.ExternalLocationCase;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ActionDefinitionId;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.has.rule.group.with.renderer.endpoint.participation.RuleGroupWithRendererEndpointParticipation;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.Configuration;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.endpoints.AddressEndpointWithLocation;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.RendererEndpoint;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.renderer.endpoints.renderer.endpoint.PeerEndpoint;
71 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.renderer.rev151103.renderers.renderer.renderer.policy.configuration.rule.groups.RuleGroup;
72 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.actions.Action;
73 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.resolved.policy.rev150828.has.resolved.rules.ResolvedRule;
74 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.controller.config.groupbasedpolicy.sxp.mapper.model.rev160302.AddressEndpointWithLocationAug;
75 import org.opendaylight.yang.gen.v1.urn.opendaylight.sxp.database.rev160308.Sgt;
76 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
77 import org.slf4j.Logger;
78 import org.slf4j.LoggerFactory;
79
80 public class PolicyManagerUtil {
81
82     private static final Logger LOG = LoggerFactory.getLogger(PolicyManagerUtil.class);
83     private static final String DEFAULT = "class-default";
84
85     public static void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context,
86                                           final Configuration dataAfter, final PeerEndpoint peerEndpoint,
87                                           final DataBroker dataBroker, final PolicyManagerImpl.DsAction action) {
88         // Action
89         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint);
90         if (actionMap == null || actionMap.isEmpty()) {
91             LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]",
92                     sourceSgt, destinationSgt);
93             return;
94         }
95
96         // TODO allow action not supported
97
98         // Resolve chain action - create
99         if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Create)) {
100             ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context,
101                     dataBroker);
102         }
103         if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Delete)) {
104             ServiceChainingUtil.removeChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
105                     context.getPolicyWriter());
106         }
107     }
108
109     public static Sgt findSgtTag(final AddressEndpointKey endpointKey,
110                                  final List<AddressEndpointWithLocation> endpointsWithLocation) {
111         if (endpointKey == null || endpointsWithLocation == null) {
112             return null;
113         }
114         final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey,
115                 endpointsWithLocation);
116         final AddressEndpointWithLocationAug augmentation = endpointWithLocation.getAugmentation(AddressEndpointWithLocationAug.class);
117         if (augmentation == null) {
118             return null;
119         }
120
121         return augmentation.getSgt();
122     }
123
124     static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
125         final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
126         final Source source = new SourceBuilder().setTag(sourceTag).build();
127         final Destination destination = new DestinationBuilder().setTag(destinationTag).build();
128         sgBuilder.setDestination(destination)
129                 .setSource(source);
130         final SecurityGroup securityGroup = sgBuilder.build();
131         final MatchBuilder matchBuilder = new MatchBuilder();
132         matchBuilder.setSecurityGroup(securityGroup);
133         return matchBuilder.build();
134     }
135
136     static ClassMap createClassMap(final String classMapName, final Match match) {
137         final ClassMapBuilder cmBuilder = new ClassMapBuilder();
138         cmBuilder.setName(classMapName)
139                 .setKey(new ClassMapKey(classMapName))
140                 .setPrematch(ClassMap.Prematch.MatchAll)
141                 .setMatch(match);
142         return cmBuilder.build();
143     }
144
145     static TenantId getTenantId(final PeerEndpoint peer) {
146         for (RuleGroupWithRendererEndpointParticipation ruleGroup :
147                 peer.getRuleGroupWithRendererEndpointParticipation()) {
148             if (ruleGroup.getTenantId() != null) {
149                 return ruleGroup.getTenantId();
150             }
151         }
152         return null;
153     }
154
155     static String generateClassMapName(final int sourceTag, final int destinationTag) {
156         return "srcTag" + sourceTag + "_dstTag" + destinationTag;
157     }
158
159     static Class createPolicyEntry(final String policyClassName, final RenderedServicePath renderedPath,
160                                    final PolicyManagerImpl.ActionCase actionCase) {
161         // Forward Case
162         final ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder();
163         if (actionCase.equals(CHAIN) && renderedPath != null) {
164             // Chain Action
165             final ForwardBuilder forwardBuilder = new ForwardBuilder();
166             final List<ServicePath> servicePaths = new ArrayList<>();
167             final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
168             servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
169                     .setServicePathId(renderedPath.getPathId())
170                     .setServiceIndex(renderedPath.getStartingIndex());
171             servicePaths.add(servicePathBuilder.build());
172             forwardBuilder.setServicePath(servicePaths);
173             forwardCaseBuilder.setForward(forwardBuilder.build());
174         }
175         // Create Action List
176         final List<ActionList> actionList = new ArrayList<>();
177         final ActionListBuilder actionListBuilder = new ActionListBuilder();
178         actionListBuilder.setKey(new ActionListKey(PolicyActionType.Forward))
179                 .setActionType(PolicyActionType.Forward)
180                 .setActionParam(forwardCaseBuilder.build());
181         actionList.add(actionListBuilder.build());
182         // Build class entry
183         final ClassBuilder policyClassBuilder = new ClassBuilder();
184         policyClassBuilder.setName(new ClassNameType(policyClassName))
185                 .setKey(new ClassKey(new ClassNameType(policyClassName)))
186                 .setActionList(actionList);
187         return policyClassBuilder.build();
188     }
189
190     public static PolicyMap createPolicyMap(final String policyMapName, final List<Class> policyMapEntries) {
191         // Create default class entry
192         final ClassBuilder defaultBuilder = new ClassBuilder();
193         defaultBuilder.setName(new ClassNameType(DEFAULT))
194                 .setKey(new ClassKey(new ClassNameType(DEFAULT)));
195         // TODO add pass-through value
196         policyMapEntries.add(defaultBuilder.build());
197         // Construct policy map
198         final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder();
199         policyMapBuilder.setName(policyMapName)
200                 .setKey(new PolicyMapKey(policyMapName))
201                 .setType(PolicyMap.Type.ServiceChain)
202                 .setXmlClass(policyMapEntries);
203         return policyMapBuilder.build();
204     }
205
206     public static ServicePolicy createServicePolicy(final String chainName, final ServiceChain.Direction direction) {
207         // Service Chain
208         final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
209         serviceChainBuilder.setName(chainName) // Same as the policy map name
210                 .setDirection(direction);
211         // Service policy
212         final TypeBuilder typeBuilder = new TypeBuilder();
213         typeBuilder.setServiceChain(serviceChainBuilder.build());
214         // Service Policy
215         ServicePolicyBuilder servicePolicyBuilder = new ServicePolicyBuilder();
216         servicePolicyBuilder.setType(typeBuilder.build());
217
218         return servicePolicyBuilder.build();
219     }
220
221     public static InstanceIdentifier getAbsoluteLocationMountpoint(final RendererEndpoint endpoint,
222                                                                    final List<AddressEndpointWithLocation> endpointsWithLocation) {
223         if (endpointsWithLocation.isEmpty()) {
224             return null;
225         }
226         AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
227                 endpointsWithLocation);
228         final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
229         final LocationType locationType = absoluteLocation.getLocationType();
230         ExternalLocationCase location = (ExternalLocationCase) locationType;
231         if (location == null) {
232             LOG.warn("Endpoint {} does not contain info about external location",
233                     endpointWithLocation.getKey().toString());
234             return null;
235         }
236         return location.getExternalNodeMountPoint();
237     }
238
239     public static String getInterfaceNameForPolicyMap(final RendererEndpoint endpoint,
240                                                       final List<AddressEndpointWithLocation> endpointsWithLocation) {
241         if (endpoint == null || endpointsWithLocation == null) {
242             return null;
243         }
244         final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
245                 endpointsWithLocation);
246         final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
247         final LocationType locationType = absoluteLocation.getLocationType();
248         final ExternalLocationCase location = (ExternalLocationCase) locationType;
249         if (location == null) {
250             LOG.warn("Endpoint {} does not contain info about external location",
251                     endpointWithLocation.getKey().toString());
252             return null;
253         }
254         return location.getExternalNodeConnector();
255     }
256
257
258     private static Map<PolicyManagerImpl.ActionCase, Action> getActionInDirection(final Configuration data, final PeerEndpoint peer) {
259         final Set<ResolvedRule> rulesInDirection = new HashSet<>();
260         // Find all rules in desired direction
261         for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
262                 peer.getRuleGroupWithRendererEndpointParticipation()) {
263             final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
264             if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
265                 continue;
266             }
267
268             for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
269                 if (resolvedRule == null) {
270                     continue;
271                 }
272                 if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
273                     continue;
274                 }
275                 rulesInDirection.add(resolvedRule);
276             }
277         }
278         if (rulesInDirection.isEmpty()) {
279             return null;
280         }
281         // TODO use only first rule with ActionDefinitionID for now
282         final Map<PolicyManagerImpl.ActionCase, Action> result = new HashMap<>();
283         for (ResolvedRule resolvedRule : rulesInDirection) {
284             // TODO only first action used for now
285             final Action action = resolvedRule.getAction().get(0);
286             if (action.getActionDefinitionId() != null) {
287                 final ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
288                 // Currently only chain action is supported
289                 if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
290                     result.put(PolicyManagerImpl.ActionCase.CHAIN, action);
291                     return result;
292                 }
293             }
294         }
295         return null;
296     }
297
298     private static RuleGroup findRuleGroup(final Configuration data,
299                                            final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
300         final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
301         final ContractId contractId = ruleGroupWithParticipation.getContractId();
302         final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
303         for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
304             if (!ruleGroup.getTenantId().equals(tenantId)) {
305                 continue;
306             }
307             if (!ruleGroup.getContractId().equals(contractId)) {
308                 continue;
309             }
310             if (ruleGroup.getSubjectName().equals(subjectName)) {
311                 return ruleGroup;
312             }
313         }
314         return null;
315     }
316 }