ios-xe renderer bugfix #2
[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
84     public static void syncPolicyEntities(final Sgt sourceSgt, final Sgt destinationSgt, final PolicyConfigurationContext context,
85                                           final Configuration dataAfter, final PeerEndpoint peerEndpoint,
86                                           final DataBroker dataBroker, final PolicyManagerImpl.DsAction action) {
87         // Action
88         final Map<PolicyManagerImpl.ActionCase, Action> actionMap = PolicyManagerUtil.getActionInDirection(dataAfter, peerEndpoint);
89         if (actionMap == null || actionMap.isEmpty()) {
90             LOG.debug("no usable action found for EP-sgt[{}] | peerEP-sgt[{}]",
91                     sourceSgt, destinationSgt);
92             return;
93         }
94
95         // TODO allow action not supported
96
97         // Resolve chain action - create
98         if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Create)) {
99             ServiceChainingUtil.resolveNewChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap, context,
100                     dataBroker);
101         }
102         if (actionMap.containsKey(PolicyManagerImpl.ActionCase.CHAIN) && action.equals(Delete)) {
103             ServiceChainingUtil.removeChainAction(peerEndpoint, sourceSgt, destinationSgt, actionMap,
104                     context.getPolicyWriter());
105         }
106     }
107
108     public static Sgt findSgtTag(final AddressEndpointKey endpointKey,
109                                  final List<AddressEndpointWithLocation> endpointsWithLocation) {
110         if (endpointKey == null || endpointsWithLocation == null) {
111             return null;
112         }
113         final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpointKey,
114                 endpointsWithLocation);
115         final AddressEndpointWithLocationAug augmentation = endpointWithLocation.getAugmentation(AddressEndpointWithLocationAug.class);
116         if (augmentation == null) {
117             return null;
118         }
119
120         return augmentation.getSgt();
121     }
122
123     static Match createSecurityGroupMatch(final int sourceTag, final int destinationTag) {
124         final SecurityGroupBuilder sgBuilder = new SecurityGroupBuilder();
125         final Source source = new SourceBuilder().setTag(sourceTag).build();
126         final Destination destination = new DestinationBuilder().setTag(destinationTag).build();
127         sgBuilder.setDestination(destination)
128                 .setSource(source);
129         final SecurityGroup securityGroup = sgBuilder.build();
130         final MatchBuilder matchBuilder = new MatchBuilder();
131         matchBuilder.setSecurityGroup(securityGroup);
132         return matchBuilder.build();
133     }
134
135     static ClassMap createClassMap(final String classMapName, final Match match) {
136         final ClassMapBuilder cmBuilder = new ClassMapBuilder();
137         cmBuilder.setName(classMapName)
138                 .setKey(new ClassMapKey(classMapName))
139                 .setPrematch(ClassMap.Prematch.MatchAll)
140                 .setMatch(match);
141         return cmBuilder.build();
142     }
143
144     static TenantId getTenantId(final PeerEndpoint peer) {
145         for (RuleGroupWithRendererEndpointParticipation ruleGroup :
146                 peer.getRuleGroupWithRendererEndpointParticipation()) {
147             if (ruleGroup.getTenantId() != null) {
148                 return ruleGroup.getTenantId();
149             }
150         }
151         return null;
152     }
153
154     static String generateClassMapName(final int sourceTag, final int destinationTag) {
155         return "srcTag" + sourceTag + "_dstTag" + destinationTag;
156     }
157
158     static Class createPolicyEntry(final String policyClassName, final RenderedServicePath renderedPath,
159                                    final PolicyManagerImpl.ActionCase actionCase) {
160         // Forward Case
161         final ForwardCaseBuilder forwardCaseBuilder = new ForwardCaseBuilder();
162         if (actionCase.equals(CHAIN) && renderedPath != null) {
163             // Chain Action
164             final ForwardBuilder forwardBuilder = new ForwardBuilder();
165             final List<ServicePath> servicePaths = new ArrayList<>();
166             final ServicePathBuilder servicePathBuilder = new ServicePathBuilder();
167             servicePathBuilder.setKey(new ServicePathKey(renderedPath.getPathId()))
168                     .setServicePathId(renderedPath.getPathId())
169                     .setServiceIndex(renderedPath.getStartingIndex());
170             servicePaths.add(servicePathBuilder.build());
171             forwardBuilder.setServicePath(servicePaths);
172             forwardCaseBuilder.setForward(forwardBuilder.build());
173         }
174         // Create Action List
175         final List<ActionList> actionList = new ArrayList<>();
176         final ActionListBuilder actionListBuilder = new ActionListBuilder();
177         actionListBuilder.setKey(new ActionListKey(PolicyActionType.Forward))
178                 .setActionType(PolicyActionType.Forward)
179                 .setActionParam(forwardCaseBuilder.build());
180         actionList.add(actionListBuilder.build());
181         // Build class entry
182         final ClassBuilder policyClassBuilder = new ClassBuilder();
183         policyClassBuilder.setName(new ClassNameType(policyClassName))
184                 .setKey(new ClassKey(new ClassNameType(policyClassName)))
185                 .setActionList(actionList);
186         return policyClassBuilder.build();
187     }
188
189     public static PolicyMap createPolicyMap(final String policyMapName, final Set<Class> policyMapEntries) {
190         // TODO maybe could be better to create also class-default entry with pass-through value than not to create any default entry at all
191         final List<Class> policyMapEntriesList = new ArrayList<>(policyMapEntries);
192
193         // Construct policy map
194         final PolicyMapBuilder policyMapBuilder = new PolicyMapBuilder();
195         policyMapBuilder.setName(policyMapName)
196                 .setKey(new PolicyMapKey(policyMapName))
197                 .setType(PolicyMap.Type.ServiceChain)
198                 .setXmlClass(policyMapEntriesList);
199         return policyMapBuilder.build();
200     }
201
202     public static ServicePolicy createServicePolicy(final String chainName, final ServiceChain.Direction direction) {
203         // Service Chain
204         final ServiceChainBuilder serviceChainBuilder = new ServiceChainBuilder();
205         serviceChainBuilder.setName(chainName) // Same as the policy map name
206                 .setDirection(direction);
207         // Service policy
208         final TypeBuilder typeBuilder = new TypeBuilder();
209         typeBuilder.setServiceChain(serviceChainBuilder.build());
210         // Service Policy
211         ServicePolicyBuilder servicePolicyBuilder = new ServicePolicyBuilder();
212         servicePolicyBuilder.setType(typeBuilder.build());
213
214         return servicePolicyBuilder.build();
215     }
216
217     public static InstanceIdentifier getAbsoluteLocationMountpoint(final RendererEndpoint endpoint,
218                                                                    final List<AddressEndpointWithLocation> endpointsWithLocation) {
219         if (endpointsWithLocation.isEmpty()) {
220             return null;
221         }
222         AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
223                 endpointsWithLocation);
224         final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
225         final LocationType locationType = absoluteLocation.getLocationType();
226         ExternalLocationCase location = (ExternalLocationCase) locationType;
227         if (location == null) {
228             LOG.warn("Endpoint {} does not contain info about external location",
229                     endpointWithLocation.getKey().toString());
230             return null;
231         }
232         return location.getExternalNodeMountPoint();
233     }
234
235     public static String getInterfaceNameForPolicyMap(final RendererEndpoint endpoint,
236                                                       final List<AddressEndpointWithLocation> endpointsWithLocation) {
237         if (endpoint == null || endpointsWithLocation == null) {
238             return null;
239         }
240         final AddressEndpointWithLocation endpointWithLocation = RendererPolicyUtil.lookupEndpoint(endpoint,
241                 endpointsWithLocation);
242         final AbsoluteLocation absoluteLocation = endpointWithLocation.getAbsoluteLocation();
243         final LocationType locationType = absoluteLocation.getLocationType();
244         final ExternalLocationCase location = (ExternalLocationCase) locationType;
245         if (location == null) {
246             LOG.warn("Endpoint {} does not contain info about external location",
247                     endpointWithLocation.getKey().toString());
248             return null;
249         }
250         return location.getExternalNodeConnector();
251     }
252
253
254     private static Map<PolicyManagerImpl.ActionCase, Action> getActionInDirection(final Configuration data, final PeerEndpoint peer) {
255         final Set<ResolvedRule> rulesInDirection = new HashSet<>();
256         // Find all rules in desired direction
257         for (RuleGroupWithRendererEndpointParticipation ruleGroupKey :
258                 peer.getRuleGroupWithRendererEndpointParticipation()) {
259             final RuleGroup ruleGroup = findRuleGroup(data, ruleGroupKey);
260             if (ruleGroup == null || ruleGroup.getResolvedRule() == null) {
261                 continue;
262             }
263
264             for (ResolvedRule resolvedRule : ruleGroup.getResolvedRule()) {
265                 if (resolvedRule == null) {
266                     continue;
267                 }
268                 if (resolvedRule.getClassifier() == null || resolvedRule.getAction() == null) {
269                     continue;
270                 }
271                 rulesInDirection.add(resolvedRule);
272             }
273         }
274         if (rulesInDirection.isEmpty()) {
275             return null;
276         }
277         // TODO use only first rule with ActionDefinitionID for now
278         final Map<PolicyManagerImpl.ActionCase, Action> result = new HashMap<>();
279         for (ResolvedRule resolvedRule : rulesInDirection) {
280             // TODO only first action used for now
281             final Action action = resolvedRule.getAction().get(0);
282             if (action.getActionDefinitionId() != null) {
283                 final ActionDefinitionId actionDefinitionId = action.getActionDefinitionId();
284                 // Currently only chain action is supported
285                 if (actionDefinitionId.equals(ChainActionDefinition.ID)) {
286                     result.put(PolicyManagerImpl.ActionCase.CHAIN, action);
287                     return result;
288                 }
289             }
290         }
291         return null;
292     }
293
294     private static RuleGroup findRuleGroup(final Configuration data,
295                                            final RuleGroupWithRendererEndpointParticipation ruleGroupWithParticipation) {
296         final TenantId tenantId = ruleGroupWithParticipation.getTenantId();
297         final ContractId contractId = ruleGroupWithParticipation.getContractId();
298         final SubjectName subjectName = ruleGroupWithParticipation.getSubjectName();
299         for (RuleGroup ruleGroup : data.getRuleGroups().getRuleGroup()) {
300             if (!ruleGroup.getTenantId().equals(tenantId)) {
301                 continue;
302             }
303             if (!ruleGroup.getContractId().equals(contractId)) {
304                 continue;
305             }
306             if (ruleGroup.getSubjectName().equals(subjectName)) {
307                 return ruleGroup;
308             }
309         }
310         return null;
311     }
312 }