Fix odlparent 3 Checkstyle issues
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / rule / SecRuleEntityDecoder.java
1 /*
2  * Copyright (c) 2014 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.neutron.mapper.mapping.rule;
10
11 import static com.google.common.base.Preconditions.checkNotNull;
12
13 import com.google.common.collect.ImmutableList;
14 import java.util.ArrayList;
15 import java.util.List;
16 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
17 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
18 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
21 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
22 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.ActionChoice;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.AllowActionCase;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.change.action.of.security.group.rules.input.action.action.choice.SfcActionCase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionBase;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionEgress;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.DirectionIngress;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeBase;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV4;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.EthertypeV6;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmp;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolIcmpV6;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolTcp;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev150712.ProtocolUdp;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.SecurityRuleAttributes;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.secgroups.rev150712.security.rules.attributes.security.rules.SecurityRule;
59
60 public final class SecRuleEntityDecoder {
61
62     private SecRuleEntityDecoder() {
63         throw new UnsupportedOperationException("Cannot create an instance.");
64     }
65
66     public static ContractId getContractId(SecurityRule secRule) {
67         return new ContractId(secRule.getUuid().getValue());
68     }
69
70     public static ClassifierInstance getClassifierInstance(SecurityRule secRule) {
71         ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();
72         List<ParameterValue> params = new ArrayList<>();
73         Integer portMin = secRule.getPortRangeMin();
74         Integer portMax = secRule.getPortRangeMax();
75         if (portMin != null && portMax != null) {
76             classifierBuilder.setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId());
77             if (portMin.equals(portMax)) {
78                 params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
79                     .setIntValue(portMin.longValue())
80                     .build());
81             } else {
82                 params.add(new ParameterValueBuilder()
83                     .setName(new ParameterName(L4ClassifierDefinition.DST_PORT_RANGE_PARAM))
84                     .setRangeValue(
85                             new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())
86                     .build());
87             }
88         }
89         Long protocol = getProtocol(secRule);
90         if (protocol != null) {
91             if (classifierBuilder.getClassifierDefinitionId() == null) {
92                 classifierBuilder.setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId());
93             }
94             params.add(new ParameterValueBuilder()
95                 .setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
96                 .setIntValue(protocol)
97                 .build());
98         }
99         Long ethertype = getEtherType(secRule);
100         if (ethertype != null) {
101             if (classifierBuilder.getClassifierDefinitionId() == null) {
102                 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifierDefinition.DEFINITION.getId());
103             }
104             params.add(new ParameterValueBuilder()
105                 .setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
106                 .setIntValue(ethertype)
107                 .build());
108         }
109         ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
110         return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();
111     }
112
113     public static ActionRef createActionRefFromActionChoice(ActionChoice action) {
114         if (action instanceof SfcActionCase) {
115             return MappingUtils.createSfcActionRef(((SfcActionCase) action).getSfcChainName());
116         } else if (action instanceof AllowActionCase) {
117             return MappingUtils.ACTION_REF_ALLOW;
118         }
119         return null;
120     }
121
122     public static ClassifierRef getClassifierRef(SecurityRule secRule) {
123         checkNotNull(secRule);
124         ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);
125         ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()
126             .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);
127         Direction direction = getDirection(secRule);
128         classifierRefBuilder.setDirection(direction);
129         ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);
130         return classifierRefBuilder.setName(classifierRefName).build();
131     }
132
133     /**
134      * Resolves Direction for provided secRule.
135      *
136      * @param secRule rule for which Direction is resolved.
137      * @return direction resolved from {@link SecurityRule#getDirection()}
138      * @throws IllegalArgumentException if return value of
139      *         {@link SecurityRule#getDirection()} is other than {@link DirectionIngress} or
140      *         {@link DirectionEgress}
141      */
142     public static Direction getDirection(SecurityRule secRule) {
143         Class<? extends DirectionBase> direction = secRule.getDirection();
144         if (direction == null) {
145             throw new IllegalArgumentException("Direction cannot be null.");
146         }
147         if (direction.isAssignableFrom(DirectionIngress.class)) {
148             return Direction.In;
149         }
150         if (direction.isAssignableFrom(DirectionEgress.class)) {
151             return Direction.Out;
152         }
153         throw new IllegalArgumentException("Direction " + direction + " from security group rule "
154                 + secRule + " is not supported. Direction can be only 'ingress' or 'egress'.");
155     }
156
157     /**
158      * Resolves Clause for provided secRule.
159      *
160      * @param secRule {@link SecurityRule#getRemoteIpPrefix()} is used for EIC
161      *        and subject selection
162      * @return clause with the subject and with a consumer matcher containing EIC
163      */
164     public static Clause getClause(SecurityRule secRule) {
165         checkNotNull(secRule);
166         SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);
167         ClauseBuilder clauseBuilder = new ClauseBuilder()
168             .setSubjectRefs(ImmutableList.of(subjectName))
169             .setName(SecRuleNameDecoder
170                 .getClauseName(secRule));
171         IpPrefix remoteIpPrefix = secRule.getRemoteIpPrefix();
172         if (remoteIpPrefix != null) {
173             clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));
174         }
175         return clauseBuilder.build();
176     }
177
178     private static ConsumerMatchers createConsumerMatchersWithEic(IpPrefix ipPrefix) {
179         PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();
180         EndpointIdentificationConstraints eic =
181                 new EndpointIdentificationConstraintsBuilder()
182                     .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
183                         .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())
184                     .build();
185         return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();
186     }
187
188     public static boolean isEtherTypeOfOneWithinTwo(SecurityRule one, SecurityRule two) {
189         Long oneEtherType = getEtherType(one);
190         Long twoEtherType = getEtherType(two);
191         return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);
192     }
193
194     public static boolean isProtocolOfOneWithinTwo(SecurityRule one, SecurityRule two) {
195         Long oneProtocol = getProtocol(one);
196         Long twoProtocol = getProtocol(two);
197         return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);
198     }
199
200     private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {
201         if (two == null) {
202             return true;
203         }
204         if (two.equals(one)) {
205             return true;
206         }
207         return false;
208     }
209
210     public static boolean isPortsOfOneWithinTwo(SecurityRule one, SecurityRule two) {
211         Integer onePortMin = one.getPortRangeMin();
212         Integer onePortMax = one.getPortRangeMax();
213         Integer twoPortMin = two.getPortRangeMin();
214         Integer twoPortMax = two.getPortRangeMax();
215         if (twoPortMin == null && twoPortMax == null) {
216             return true;
217         }
218         if (onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin
219                 && onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax) {
220             return true;
221         }
222         return false;
223     }
224
225     /**
226      * Resolves EtherType for provided secRule.
227      *
228      * @param secRule rule for which EtherType is resolved.
229      * @return {@code null} if {@link SecurityRule#getEthertype()} is null; Otherwise ethertype
230      *         number
231      * @throws IllegalArgumentException if return value of
232      *         {@link SecurityRule#getEthertype()} is other {@link EthertypeV4} or
233      *         {@link EthertypeV6}
234      */
235     public static Long getEtherType(SecurityRule secRule) {
236         Class<? extends EthertypeBase> ethertype = secRule.getEthertype();
237         if (ethertype == null) {
238             return null;
239         }
240         if (ethertype.isAssignableFrom(EthertypeV4.class)) {
241             return EtherTypeClassifierDefinition.IPv4_VALUE;
242         }
243         if (ethertype.isAssignableFrom(EthertypeV6.class)) {
244             return EtherTypeClassifierDefinition.IPv6_VALUE;
245         }
246         throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");
247     }
248
249     /**
250      * Resolves Protocol for provided secRule.
251      *
252      * @param secRule rule for which Protocol is resolved.
253      * @return {@code null} if {@link SecurityRule#getProtocol()} is null; Otherwise protocol number
254      * @throws IllegalArgumentException if return value of
255      *         {@link SecurityRule#getProtocol()} is other than {@link ProtocolTcp},
256      *         {@link ProtocolUdp}, {@link ProtocolIcmp}, {@link ProtocolIcmpV6}
257      */
258     public static Long getProtocol(SecurityRule secRule) {
259         SecurityRuleAttributes.Protocol protocol = secRule.getProtocol();
260         if (protocol == null) {
261             return null;
262         }
263         if (protocol.getUint8() != null) {
264             return protocol.getUint8().longValue();
265         }
266         if (protocol.getIdentityref() != null) {
267             if (protocol.getIdentityref().equals(ProtocolTcp.class)) {
268                 return IpProtoClassifierDefinition.TCP_VALUE;
269             }
270             if (protocol.getIdentityref().equals(ProtocolUdp.class)) {
271                 return IpProtoClassifierDefinition.UDP_VALUE;
272             }
273             if (protocol.getIdentityref().equals(ProtocolIcmp.class)) {
274                 return IpProtoClassifierDefinition.ICMP_VALUE;
275             }
276             if (protocol.getIdentityref().equals(ProtocolIcmpV6.class)) {
277                 return IpProtoClassifierDefinition.ICMPv6_VALUE;
278             }
279         }
280         throw new IllegalArgumentException("Neutron Security Rule Protocol value " + protocol + " is not supported.");
281     }
282 }