Fix copyright header
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / rule / SecRuleEntityDecoder.java
1 /*\r
2  * Copyright (c) 2014 Cisco Systems, Inc. and others. All rights reserved.\r
3  *\r
4  * This program and the accompanying materials are made available under the\r
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,\r
6  * and is available at http://www.eclipse.org/legal/epl-v10.html\r
7  */\r
8 \r
9 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.rule;\r
10 \r
11 import static com.google.common.base.Preconditions.checkNotNull;\r
12 \r
13 import java.util.ArrayList;\r
14 import java.util.List;\r
15 \r
16 import javax.annotation.Nullable;\r
17 \r
18 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;\r
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;\r
20 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.EtherTypeClassifier;\r
21 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.IpProtoClassifier;\r
22 import org.opendaylight.groupbasedpolicy.renderer.ofoverlay.sf.L4Classifier;\r
23 import org.opendaylight.neutron.spi.NeutronSecurityRule;\r
24 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpPrefix;\r
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;\r
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;\r
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;\r
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;\r
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;\r
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;\r
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;\r
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;\r
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef.ConnectionTracking;\r
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;\r
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraints;\r
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;\r
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;\r
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraint;\r
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;\r
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;\r
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;\r
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.parameter.value.RangeValueBuilder;\r
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.Clause;\r
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.ClauseBuilder;\r
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchers;\r
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.contract.clause.ConsumerMatchersBuilder;\r
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstance;\r
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.subject.feature.instances.ClassifierInstanceBuilder;\r
49 \r
50 import com.google.common.base.Strings;\r
51 import com.google.common.collect.ImmutableList;\r
52 \r
53 public class SecRuleEntityDecoder {\r
54 \r
55     private SecRuleEntityDecoder() {\r
56         throw new UnsupportedOperationException("Cannot create an instace.");\r
57     }\r
58 \r
59     public static TenantId getTenantId(NeutronSecurityRule secRule) {\r
60         return new TenantId(Utils.normalizeUuid(secRule.getSecurityRuleTenantID()));\r
61     }\r
62 \r
63     public static EndpointGroupId getProviderEpgId(NeutronSecurityRule secRule) {\r
64         return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRuleGroupID()));\r
65     }\r
66 \r
67     /**\r
68      * @return {@code null} if {@link NeutronSecurityRule#getSecurityRemoteGroupID()} is null\r
69      */\r
70     public static @Nullable EndpointGroupId getConsumerEpgId(NeutronSecurityRule secRule) {\r
71         if (Strings.isNullOrEmpty(secRule.getSecurityRemoteGroupID())) {\r
72             return null;\r
73         }\r
74         return new EndpointGroupId(Utils.normalizeUuid(secRule.getSecurityRemoteGroupID()));\r
75     }\r
76 \r
77     public static ContractId getContractId(NeutronSecurityRule secRule) {\r
78         return new ContractId(Utils.normalizeUuid(secRule.getSecurityRuleUUID()));\r
79     }\r
80 \r
81     public static ClassifierInstance getClassifierInstance(NeutronSecurityRule secRule) {\r
82         ClassifierInstanceBuilder classifierBuilder = new ClassifierInstanceBuilder();\r
83         List<ParameterValue> params = new ArrayList<>();\r
84         Integer portMin = secRule.getSecurityRulePortMin();\r
85         Integer portMax = secRule.getSecurityRulePortMax();\r
86         if (portMin != null && portMax != null) {\r
87             classifierBuilder.setClassifierDefinitionId(L4Classifier.DEFINITION.getId());\r
88             if (portMin.equals(portMax)) {\r
89                 params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_PARAM))\r
90                     .setIntValue(portMin.longValue())\r
91                     .build());\r
92             } else {\r
93                 params.add(new ParameterValueBuilder().setName(new ParameterName(L4Classifier.DST_PORT_RANGE_PARAM))\r
94                     .setRangeValue(\r
95                             new RangeValueBuilder().setMin(portMin.longValue()).setMax(portMax.longValue()).build())\r
96                     .build());\r
97             }\r
98         }\r
99         Long protocol = getProtocol(secRule);\r
100         if (protocol != null) {\r
101             if (classifierBuilder.getClassifierDefinitionId() == null) {\r
102                 classifierBuilder.setClassifierDefinitionId(IpProtoClassifier.DEFINITION.getId());\r
103             }\r
104             params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifier.PROTO_PARAM))\r
105                 .setIntValue(protocol)\r
106                 .build());\r
107         }\r
108         Long ethertype = getEtherType(secRule);\r
109         if (ethertype != null) {\r
110             if (classifierBuilder.getClassifierDefinitionId() == null) {\r
111                 classifierBuilder.setClassifierDefinitionId(EtherTypeClassifier.DEFINITION.getId());\r
112             }\r
113             params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifier.ETHERTYPE_PARAM))\r
114                 .setIntValue(ethertype)\r
115                 .build());\r
116         }\r
117         ClassifierName classifierName = SecRuleNameDecoder.getClassifierInstanceName(secRule);\r
118         return classifierBuilder.setParameterValue(params).setName(new ClassifierName(classifierName)).build();\r
119     }\r
120 \r
121     public static ClassifierRef getClassifierRef(NeutronSecurityRule secRule) {\r
122         checkNotNull(secRule);\r
123         ClassifierName classifierInstanceName = SecRuleNameDecoder.getClassifierInstanceName(secRule);\r
124         ClassifierRefBuilder classifierRefBuilder = new ClassifierRefBuilder()\r
125             .setConnectionTracking(ConnectionTracking.Reflexive).setInstanceName(classifierInstanceName);\r
126         Direction direction = getDirection(secRule);\r
127         classifierRefBuilder.setDirection(direction);\r
128         ClassifierName classifierRefName = SecRuleNameDecoder.getClassifierRefName(secRule);\r
129         return classifierRefBuilder.setName(classifierRefName).build();\r
130     }\r
131 \r
132     /**\r
133      * @param secRule\r
134      * @return direction resolved from {@link NeutronSecurityRule#getSecurityRuleDirection()}\r
135      * @throws IllegalArgumentException if return value of\r
136      *         {@link NeutronSecurityRule#getSecurityRuleDirection()} is other than "ingress" or\r
137      *         "egress"\r
138      */\r
139     public static Direction getDirection(NeutronSecurityRule secRule) {\r
140         String direction = secRule.getSecurityRuleDirection();\r
141         if (NeutronUtils.INGRESS.equals(direction)) {\r
142             return Direction.In;\r
143         }\r
144         if (NeutronUtils.EGRESS.equals(direction)) {\r
145             return Direction.Out;\r
146         }\r
147         throw new IllegalArgumentException("Direction " + direction + " from security group rule "\r
148                 + secRule.getSecurityRuleUUID() + " is not supported. Direction can be only 'ingress' or 'egress'.");\r
149     }\r
150 \r
151     /**\r
152      * @param secRule {@link NeutronSecurityRule#getSecurityRuleRemoteIpPrefix()} is used for EIC\r
153      *        and subject selection\r
154      * @return clause with the subject and with a consumer matcher containing EIC\r
155      */\r
156     public static Clause getClause(NeutronSecurityRule secRule) {\r
157         checkNotNull(secRule);\r
158         SubjectName subjectName = SecRuleNameDecoder.getSubjectName(secRule);\r
159         ClauseBuilder clauseBuilder =\r
160                 new ClauseBuilder().setSubjectRefs(ImmutableList.of(subjectName)).setName(SecRuleNameDecoder.getClauseName(secRule));\r
161         String remoteIpPrefix = secRule.getSecurityRuleRemoteIpPrefix();\r
162         if (!Strings.isNullOrEmpty(remoteIpPrefix)) {\r
163             clauseBuilder.setConsumerMatchers(createConsumerMatchersWithEic(remoteIpPrefix));\r
164         }\r
165         return clauseBuilder.build();\r
166     }\r
167 \r
168     private static ConsumerMatchers createConsumerMatchersWithEic(String remoteIpPrefix) {\r
169         IpPrefix ipPrefix = Utils.createIpPrefix(remoteIpPrefix);\r
170         PrefixConstraint consumerPrefixConstraint = new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build();\r
171         EndpointIdentificationConstraints eic =\r
172                 new EndpointIdentificationConstraintsBuilder()\r
173                     .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()\r
174                         .setPrefixConstraint(ImmutableList.<PrefixConstraint>of(consumerPrefixConstraint)).build())\r
175                     .build();\r
176         return new ConsumerMatchersBuilder().setEndpointIdentificationConstraints(eic).build();\r
177     }\r
178 \r
179     public static boolean isEtherTypeOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {\r
180         Long oneEtherType = getEtherType(one);\r
181         Long twoEtherType = getEtherType(two);\r
182         return twoIsNullOrEqualsOne(oneEtherType, twoEtherType);\r
183     }\r
184 \r
185     public static boolean isProtocolOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {\r
186         Long oneProtocol = getProtocol(one);\r
187         Long twoProtocol = getProtocol(two);\r
188         return twoIsNullOrEqualsOne(oneProtocol, twoProtocol);\r
189     }\r
190 \r
191     private static <T> boolean twoIsNullOrEqualsOne(T one, T two) {\r
192         if (two == null)\r
193             return true;\r
194         if (two.equals(one))\r
195             return true;\r
196         return false;\r
197     }\r
198 \r
199     public static boolean isPortsOfOneWithinTwo(NeutronSecurityRule one, NeutronSecurityRule two) {\r
200         Integer onePortMin = one.getSecurityRulePortMin();\r
201         Integer onePortMax = one.getSecurityRulePortMax();\r
202         Integer twoPortMin = two.getSecurityRulePortMin();\r
203         Integer twoPortMax = two.getSecurityRulePortMax();\r
204         if (twoPortMin == null && twoPortMax == null) {\r
205             return true;\r
206         }\r
207         if ((onePortMin != null && twoPortMin != null && onePortMin >= twoPortMin)\r
208                 && (onePortMax != null && twoPortMax != null && onePortMax <= twoPortMax)) {\r
209             return true;\r
210         }\r
211         return false;\r
212     }\r
213 \r
214     /**\r
215      * @param secRule\r
216      * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleEthertype()} is null or\r
217      *         empty; value of {@link EtherTypeClassifier#IPv4_VALUE} or\r
218      *         {@link EtherTypeClassifier#IPv6_VALUE}\r
219      * @throws IllegalArgumentException if return value of\r
220      *         {@link NeutronSecurityRule#getSecurityRuleEthertype()} is not empty/null and is other\r
221      *         than "IPv4" or "IPv6"\r
222      */\r
223     public static Long getEtherType(NeutronSecurityRule secRule) {\r
224         String ethertype = secRule.getSecurityRuleEthertype();\r
225         if (Strings.isNullOrEmpty(ethertype)) {\r
226             return null;\r
227         }\r
228         if (NeutronUtils.IPv4.equals(ethertype)) {\r
229             return EtherTypeClassifier.IPv4_VALUE;\r
230         }\r
231         if (NeutronUtils.IPv6.equals(ethertype)) {\r
232             return EtherTypeClassifier.IPv6_VALUE;\r
233         }\r
234         throw new IllegalArgumentException("Ethertype " + ethertype + " is not supported.");\r
235     }\r
236 \r
237     /**\r
238      * @param secRule\r
239      * @return {@code null} if {@link NeutronSecurityRule#getSecurityRuleProtocol()} is null or\r
240      *         empty; Otherwise protocol number\r
241      * @throws IllegalArgumentException if return value of\r
242      *         {@link NeutronSecurityRule#getSecurityRuleProtocol()} is not empty/null and is other\r
243      *         than "tcp", "udp", "icmp"\r
244      */\r
245     public static Long getProtocol(NeutronSecurityRule secRule) {\r
246         String protocol = secRule.getSecurityRuleProtocol();\r
247         if (Strings.isNullOrEmpty(protocol)) {\r
248             return null;\r
249         }\r
250         if (NeutronUtils.TCP.equals(protocol)) {\r
251             return IpProtoClassifier.TCP_VALUE;\r
252         }\r
253         if (NeutronUtils.UDP.equals(protocol)) {\r
254             return IpProtoClassifier.UDP_VALUE;\r
255         }\r
256         if (NeutronUtils.ICMP.equals(protocol)) {\r
257             return IpProtoClassifier.ICMP_VALUE;\r
258         }\r
259         throw new IllegalArgumentException("Protocol " + protocol + " is not supported.");\r
260     }\r
261 \r
262 }\r