5ce0b774c391a84edce458bce0df285baa61cbb5
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / infrastructure / NetworkService.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.infrastructure;
10
11 import java.util.ArrayList;
12 import java.util.Collections;
13 import java.util.HashSet;
14 import java.util.List;
15 import java.util.Set;
16
17 import javax.annotation.Nullable;
18
19 import org.opendaylight.controller.md.sal.binding.api.WriteTransaction;
20 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
21 import org.opendaylight.groupbasedpolicy.api.sf.EtherTypeClassifierDefinition;
22 import org.opendaylight.groupbasedpolicy.api.sf.IpProtoClassifierDefinition;
23 import org.opendaylight.groupbasedpolicy.api.sf.L4ClassifierDefinition;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
26 import org.opendaylight.groupbasedpolicy.util.IidFactory;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClassifierName;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ClauseName;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContractId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Description;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.EndpointGroupId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ParameterName;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.RuleName;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SelectorName;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubjectName;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.HasDirection.Direction;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.action.refs.ActionRef;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRef;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.classifier.refs.ClassifierRefBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.EndpointIdentificationConstraintsBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraints;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.L3EndpointIdentificationConstraintsBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.has.endpoint.identification.constraints.endpoint.identification.constraints.l3.endpoint.identification.constraints.PrefixConstraintBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValue;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.subject.feature.instance.ParameterValueBuilder;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.Contract;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ContractBuilder;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroup.IntraGroupPolicy;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.EndpointGroupBuilder;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Clause;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.ClauseBuilder;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.Subject;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.SubjectBuilder;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchers;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ConsumerMatchersBuilder;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchers;
61 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.clause.ProviderMatchersBuilder;
62 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.Rule;
63 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.contract.subject.RuleBuilder;
64 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelector;
65 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ConsumerNamedSelectorBuilder;
66 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelector;
67 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.endpoint.group.ProviderNamedSelectorBuilder;
68 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ActionInstance;
69 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstance;
70 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.subject.feature.instances.ClassifierInstanceBuilder;
71
72 import com.google.common.collect.ImmutableList;
73
74 public class NetworkService {
75
76     /**
77      * Unit tests {@link NetworkServiceTest}
78      */
79     // ########### DHCP
80     private static final long DHCP_IPV4_SERVER_PORT = 67;
81     private static final long DHCP_IPV4_CLIENT_PORT = 68;
82     private static final long DHCP_IPV6_SERVER_PORT = 547;
83     private static final long DHCP_IPV6_CLIENT_PORT = 546;
84     private static final ClassifierName DHCP_IPV4_CLIENT_SERVER_NAME =
85             new ClassifierName("DHCP_IPv4_FROM_CLIENT_TO_SERVER");
86     private static final ClassifierName DHCP_IPV4_SERVER_CLIENT_NAME =
87             new ClassifierName("DHCP_IPv4_FROM_SERVER_TO_CLIENT");
88     private static final ClassifierName DHCP_IPV6_CLIENT_SERVER_NAME =
89             new ClassifierName("DHCP_IPv6_FROM_CLIENT_TO_SERVER");
90     private static final ClassifierName DHCP_IPV6_SERVER_CLIENT_NAME =
91             new ClassifierName("DHCP_IPv6_FROM_SERVER_TO_CLIENT");
92     private static final SubjectName DHCP_SUBJECT_NAME = new SubjectName("ALLOW_DHCP");
93     private static final Description DHCP_CONTRACT_DESC =
94             new Description("Allow DHCP communication between client and server.");
95
96     /**
97      * Id of {@link #DHCP_CONTRACT}
98      */
99     public static final ContractId DHCP_CONTRACT_ID = new ContractId("11118d2e-dddd-11e5-885d-feff819cdc9f");
100     /**
101      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching DHCP communication
102      * between Client and Server.
103      */
104     public static final Contract DHCP_CONTRACT;
105     /**
106      * {@link ConsumerNamedSelector} pointing to {@link #DHCP_CONTRACT}
107      */
108     public static final ConsumerNamedSelector DHCP_CONTRACT_CONSUMER_SELECTOR;
109
110     // ########### DNS
111     private static final long DNS_SERVER_PORT = 53;
112     private static final ClassifierName DNS_UDP_IPV4_CLIENT_SERVER_NAME =
113             new ClassifierName("DNS_UDP_IPv4_FROM_CLIENT_TO_SERVER");
114     private static final ClassifierName DNS_UDP_IPV4_SERVER_CLIENT_NAME =
115             new ClassifierName("DNS_UDP_IPv4_FROM_SERVER_TO_CLIENT");
116     private static final ClassifierName DNS_UDP_IPV6_CLIENT_SERVER_NAME =
117             new ClassifierName("DNS_UDP_IPv6_FROM_CLIENT_TO_SERVER");
118     private static final ClassifierName DNS_UDP_IPV6_SERVER_CLIENT_NAME =
119             new ClassifierName("DNS_UDP_IPv6_FROM_SERVER_TO_CLIENT");
120     private static final ClassifierName DNS_TCP_IPV4_CLIENT_SERVER_NAME =
121             new ClassifierName("DNS_TCP_IPv4_FROM_CLIENT_TO_SERVER");
122     private static final ClassifierName DNS_TCP_IPV4_SERVER_CLIENT_NAME =
123             new ClassifierName("DNS_TCP_IPv4_FROM_SERVER_TO_CLIENT");
124     private static final ClassifierName DNS_TCP_IPV6_CLIENT_SERVER_NAME =
125             new ClassifierName("DNS_TCP_IPv6_FROM_CLIENT_TO_SERVER");
126     private static final ClassifierName DNS_TCP_IPV6_SERVER_CLIENT_NAME =
127             new ClassifierName("DNS_TCP_IPv6_FROM_SERVER_TO_CLIENT");
128     private static final SubjectName DNS_SUBJECT_NAME = new SubjectName("ALLOW_DNS");
129     private static final Description DNS_CONTRACT_DESC =
130             new Description("Allow DNS communication between client and server.");
131     /**
132      * ID of {@link #DNS_CONTRACT}
133      */
134     public static final ContractId DNS_CONTRACT_ID = new ContractId("22218d2e-dddd-11e5-885d-feff819cdc9f");
135     /**
136      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching DNS communication
137      * between Client and Server.
138      */
139     public static final Contract DNS_CONTRACT;
140     /**
141      * {@link ConsumerNamedSelector} pointing to {@link #DNS_CONTRACT}
142      */
143     public static final ConsumerNamedSelector DNS_CONTRACT_CONSUMER_SELECTOR;
144
145     // ########### SSH and ICMP management
146     private static final long SSH_TCP_PORT = 22;
147     private static final ClassifierName SSH_IPV4_SERVER_TO_CLIENT_NAME =
148             new ClassifierName("SSH_IPV4_FROM_SERVER_TO_CLIENT");
149     private static final ClassifierName SSH_IPV6_SERVER_TO_CLIENT_NAME =
150             new ClassifierName("SSH_IPV6_FROM_SERVER_TO_CLIENT");
151     private static final ClassifierName SSH_IPV4_CLIENT_TO_SERVER_NAME =
152             new ClassifierName("SSH_IPV4_FROM_CLIENT_TO_SERVER");
153     private static final ClassifierName SSH_IPV6_CLIENT_TO_SERVER_NAME =
154             new ClassifierName("SSH_IPV6_FROM_CLIENT_TO_SERVER");
155     private static final ClassifierName ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME =
156             new ClassifierName("ICMP_IPV4_BETWEEN_SERVER_CLIENT");
157     private static final ClassifierName ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME =
158             new ClassifierName("ICMP_IPV6_BETWEEN_SERVER_CLIENT");
159     private static final SubjectName MGMT_SUBJECT_NAME = new SubjectName("ALLOW_MGMT");
160     private static final Description MGMT_CONTRACT_DESC =
161             new Description("Allow ICMP and SSH management communication between server and client.");
162
163     /**
164      * Id of {@link #MGMT_CONTRACT}
165      */
166     public static final ContractId MGMT_CONTRACT_ID = new ContractId("33318d2e-dddd-11e5-885d-feff819cdc9f");
167     /**
168      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH
169      * communication
170      * between Client and Server.
171      */
172     public static final Contract MGMT_CONTRACT;
173     /**
174      * {@link ConsumerNamedSelector} pointing to {@link #MGMT_CONTRACT}
175      */
176     public static final ConsumerNamedSelector MGMT_CONTRACT_CONSUMER_SELECTOR;
177
178     // ########### METADATA management
179     private static final ClassifierName METADATA_SERVER_TO_CLIENT_NAME =
180         new ClassifierName("METADATA_FROM_SERVER_TO_CLIENT");
181     private static final ClassifierName METADATA_CLIENT_TO_SERVER_NAME =
182         new ClassifierName("METADATA_FROM_CLIENT_TO_SERVER");
183     private static final SubjectName METADATA_SUBJECT_NAME = new SubjectName("ALLOW_METADATA");
184     private static final Description METADATA_CONTRACT_DESC =
185         new Description("Allow METADATA management communication between server and client.");
186
187     /**
188      * Id of {@link #METADATA_CONTRACT}
189      */
190     public static final ContractId METADATA_CONTRACT_ID = new ContractId("be0675b7-b0d6-46cc-acf1-247ed31cf572");
191     /**
192      * Contains rules with action {@link MappingUtils#ACTION_REF_ALLOW} matching ICMP and SSH
193      * communication
194      * between Client and Server.
195      */
196     public static final Contract METADATA_CONTRACT;
197     /**
198      * {@link ConsumerNamedSelector} pointing to {@link #METADATA_CONTRACT}
199      */
200     public static final ConsumerNamedSelector METADATA_CONTRACT_CONSUMER_SELECTOR;
201
202     // ########### NETWORK-SERVICE ENDPOINT-GROUP
203     private static final Name NETWORK_SERVICE_EPG_NAME = new Name("NETWORK_SERVICE");
204     private static final Description NETWORK_SERVICE_EPG_DESC = new Description("Represents DHCP and DNS servers.");
205     /**
206      * ID of {@link #EPG}
207      */
208     public static final EndpointGroupId EPG_ID = new EndpointGroupId("ddd6cfe6-dfe5-11e4-8a00-1681e6b88ec1");
209     /**
210      * Network-service endpoint-group providing {@link #DHCP_CONTRACT} and {@link #DNS_CONTRACT}
211      */
212     public static final EndpointGroup EPG;
213
214     static {
215         DHCP_CONTRACT = createContractDhcp();
216         DHCP_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DHCP_CONTRACT);
217         DNS_CONTRACT = createContractDns();
218         DNS_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(DNS_CONTRACT);
219         MGMT_CONTRACT = createContractMgmt();
220         MGMT_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(MGMT_CONTRACT);
221         METADATA_CONTRACT = createContractMetadata();
222         METADATA_CONTRACT_CONSUMER_SELECTOR = createConsumerSelector(METADATA_CONTRACT);
223         EPG = createNetworkServiceEpg();
224     }
225
226     private static EndpointGroup createNetworkServiceEpg() {
227         ProviderNamedSelector dhcpProviderSelector = createProviderSelector(DHCP_CONTRACT);
228         ProviderNamedSelector dnsProviderSelector = createProviderSelector(DNS_CONTRACT);
229         ProviderNamedSelector mgmtProviderSelector = createProviderSelector(MGMT_CONTRACT);
230         ProviderNamedSelector metadataProviderSelector = createProviderSelector(METADATA_CONTRACT);
231         return new EndpointGroupBuilder().setId(EPG_ID)
232             .setName(NETWORK_SERVICE_EPG_NAME)
233             .setProviderNamedSelector(ImmutableList.of(dhcpProviderSelector, dnsProviderSelector, mgmtProviderSelector,
234                 metadataProviderSelector))
235             .setIntraGroupPolicy(IntraGroupPolicy.RequireContract)
236             .setDescription(NETWORK_SERVICE_EPG_DESC)
237             .build();
238     }
239
240     private static ProviderNamedSelector createProviderSelector(Contract contract) {
241         SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
242         return new ProviderNamedSelectorBuilder().setName(selectorName)
243             .setContract(ImmutableList.of(contract.getId()))
244             .build();
245     }
246
247     private static ConsumerNamedSelector createConsumerSelector(Contract contract) {
248         SelectorName selectorName = new SelectorName(contract.getSubject().get(0).getName().getValue());
249         return new ConsumerNamedSelectorBuilder().setName(selectorName)
250             .setContract(ImmutableList.of(contract.getId()))
251             .build();
252     }
253
254     private static Contract createContractDhcp() {
255         Rule clientServerIpv4Rule = createRuleAllow(DHCP_IPV4_CLIENT_SERVER_NAME, Direction.In);
256         Rule serverClientIpv4Rule = createRuleAllow(DHCP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
257         Rule clientServerIpv6Rule = createRuleAllow(DHCP_IPV6_CLIENT_SERVER_NAME, Direction.In);
258         Rule serverClientIpv6Rule = createRuleAllow(DHCP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
259         Subject subject = new SubjectBuilder().setName(DHCP_SUBJECT_NAME)
260             .setOrder(0)
261             .setRule(ImmutableList.of(clientServerIpv4Rule, serverClientIpv4Rule, clientServerIpv6Rule,
262                     serverClientIpv6Rule))
263             .build();
264         return new ContractBuilder().setId(DHCP_CONTRACT_ID)
265             .setSubject(ImmutableList.of(subject))
266             .setDescription(DHCP_CONTRACT_DESC)
267             .build();
268     }
269
270     private static Contract createContractDns() {
271         Rule clientServerUdpIpv4Rule = createRuleAllow(DNS_UDP_IPV4_CLIENT_SERVER_NAME, Direction.In);
272         Rule serverClientUdpIpv4Rule = createRuleAllow(DNS_UDP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
273         Rule clientServerUdpIpv6Rule = createRuleAllow(DNS_UDP_IPV6_CLIENT_SERVER_NAME, Direction.In);
274         Rule serverClientUdpIpv6Rule = createRuleAllow(DNS_UDP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
275         Rule clientServerTcpIpv4Rule = createRuleAllow(DNS_TCP_IPV4_CLIENT_SERVER_NAME, Direction.In);
276         Rule serverClientTcpIpv4Rule = createRuleAllow(DNS_TCP_IPV4_SERVER_CLIENT_NAME, Direction.Out);
277         Rule clientServerTcpIpv6Rule = createRuleAllow(DNS_TCP_IPV6_CLIENT_SERVER_NAME, Direction.In);
278         Rule serverClientTcpIpv6Rule = createRuleAllow(DNS_TCP_IPV6_SERVER_CLIENT_NAME, Direction.Out);
279         Subject subject = new SubjectBuilder().setName(DNS_SUBJECT_NAME)
280             .setOrder(0)
281             .setRule(ImmutableList.of(clientServerUdpIpv4Rule, serverClientUdpIpv4Rule, clientServerUdpIpv6Rule,
282                     serverClientUdpIpv6Rule, clientServerTcpIpv4Rule, serverClientTcpIpv4Rule, clientServerTcpIpv6Rule,
283                     serverClientTcpIpv6Rule))
284             .build();
285         return new ContractBuilder().setId(DNS_CONTRACT_ID)
286             .setSubject(ImmutableList.of(subject))
287             .setDescription(DNS_CONTRACT_DESC)
288             .build();
289     }
290
291     private static Contract createContractMgmt() {
292         Rule serverClientSshIpv4Rule = createRuleAllow(SSH_IPV4_SERVER_TO_CLIENT_NAME, Direction.Out);
293         Rule serverClientSshIpv6Rule = createRuleAllow(SSH_IPV6_SERVER_TO_CLIENT_NAME, Direction.Out);
294         Rule clientServerSshIpv4Rule = createRuleAllow(SSH_IPV4_CLIENT_TO_SERVER_NAME, Direction.In);
295         Rule clientServerSshIpv6Rule = createRuleAllow(SSH_IPV6_CLIENT_TO_SERVER_NAME, Direction.In);
296         Rule serverClientIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
297         Rule serverClientIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
298         Rule clientServerIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
299         Rule clientServerIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
300
301         Subject subject = new SubjectBuilder().setName(MGMT_SUBJECT_NAME)
302             .setOrder(0)
303             .setRule(ImmutableList.of(serverClientSshIpv4Rule, serverClientSshIpv6Rule, clientServerSshIpv4Rule,
304                     clientServerSshIpv6Rule, clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule,
305                     serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule))
306             .build();
307         return new ContractBuilder().setId(MGMT_CONTRACT_ID)
308             .setSubject(ImmutableList.of(subject))
309             .setDescription(MGMT_CONTRACT_DESC)
310             .build();
311     }
312
313     private static Contract createContractMetadata() {
314         Rule serverClientMetadataIpv4Rule = createRuleAllow(METADATA_SERVER_TO_CLIENT_NAME, Direction.Out);
315         Rule clientServerMetadataIpv4Rule = createRuleAllow(METADATA_CLIENT_TO_SERVER_NAME, Direction.In);
316         Rule serverClientIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
317         Rule serverClientIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.Out);
318         Rule clientServerIcmpIpv4Rule = createRuleAllow(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
319         Rule clientServerIcmpIpv6Rule = createRuleAllow(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME, Direction.In);
320
321         Subject subject = new SubjectBuilder().setName(METADATA_SUBJECT_NAME)
322             .setOrder(0)
323             .setRule(ImmutableList.of(serverClientMetadataIpv4Rule, clientServerMetadataIpv4Rule,
324                 clientServerIcmpIpv4Rule, clientServerIcmpIpv6Rule,
325                 serverClientIcmpIpv4Rule, serverClientIcmpIpv6Rule))
326             .build();
327         return new ContractBuilder().setId(METADATA_CONTRACT_ID)
328             .setSubject(ImmutableList.of(subject))
329             .setDescription(METADATA_CONTRACT_DESC)
330             .build();
331     }
332
333     private static Rule createRuleAllow(ClassifierName classifierName, Direction direction) {
334         ClassifierName name =
335                 new ClassifierName(direction.name() + MappingUtils.NAME_DOUBLE_DELIMETER + classifierName.getValue());
336         ClassifierRef classifierRef = new ClassifierRefBuilder().setName(name)
337             .setInstanceName(classifierName)
338             .setDirection(direction)
339             .build();
340         return new RuleBuilder().setName(new RuleName(name))
341             .setActionRef(ImmutableList.<ActionRef>of(MappingUtils.ACTION_REF_ALLOW))
342             .setClassifierRef(ImmutableList.of(classifierRef))
343             .build();
344     }
345
346     /**
347      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
348      * and {@link ProviderMatchers}. This clause points to subject in {@link #DHCP_CONTRACT}.
349      *
350      * @param tenantId location of {@link #DHCP_CONTRACT}
351      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
352      * @param wTx transaction where entities are written
353      */
354     public static void writeDhcpClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
355             WriteTransaction wTx) {
356         Clause clause = createClauseWithConsProvEic(ipPrefix, DHCP_SUBJECT_NAME);
357         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, DHCP_CONTRACT_ID, clause.getName()),
358                 clause, true);
359     }
360
361     /**
362      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
363      * and {@link ProviderMatchers}. This clause points to subject in {@link #DNS_CONTRACT}.
364      *
365      * @param tenantId location of {@link #DNS_CONTRACT}
366      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
367      * @param wTx transaction where entities are written
368      */
369     public static void writeDnsClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
370             WriteTransaction wTx) {
371         Clause clause = createClauseWithConsProvEic(ipPrefix, DNS_SUBJECT_NAME);
372         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, DNS_CONTRACT_ID, clause.getName()),
373                 clause, true);
374     }
375
376     /**
377      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
378      * and {@link ProviderMatchers}. This clause points to subject in {@link #MGMT_CONTRACT}.
379      *
380      * @param tenantId location of {@link #MGMT_CONTRACT}
381      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
382      * @param wTx transaction where entities are written
383      */
384     public static void writeMgmtClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
385             WriteTransaction wTx) {
386         Clause clause = createClauseWithConsProvEic(ipPrefix, MGMT_SUBJECT_NAME);
387         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, MGMT_CONTRACT_ID, clause.getName()),
388                 clause, true);
389     }
390
391     /**
392      * puts clause with {@link L3EndpointIdentificationConstraints} in {@link ConsumerMatchers}
393      * and {@link ProviderMatchers}. This clause points to subject in {@link #METADATA_CONTRACT}.
394      *
395      * @param tenantId location of {@link #METADATA_CONTRACT}
396      * @param ipPrefix used in {@link L3EndpointIdentificationConstraints}
397      * @param wTx transaction where entities are written
398      */
399     public static void writeMetadataClauseWithConsProvEic(TenantId tenantId, @Nullable IpPrefix ipPrefix,
400         WriteTransaction wTx) {
401         Clause clause = createClauseWithConsProvEic(ipPrefix, METADATA_SUBJECT_NAME);
402         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.clauseIid(tenantId, METADATA_CONTRACT_ID, clause.getName()),
403             clause, true);
404     }
405
406     private static Clause createClauseWithConsProvEic(@Nullable IpPrefix ipPrefix, SubjectName subjectName) {
407         ConsumerMatchers consumerMatchers = null;
408         ProviderMatchers providerMatchers = null;
409         StringBuilder clauseName = new StringBuilder();
410         clauseName.append(subjectName.getValue());
411         if (ipPrefix != null) {
412             clauseName.append(MappingUtils.NAME_DOUBLE_DELIMETER).append(Utils.getStringIpPrefix(ipPrefix));
413             consumerMatchers =
414                     new ConsumerMatchersBuilder()
415                         .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
416                             .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
417                                 .setPrefixConstraint(
418                                         ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
419                                 .build())
420                             .build())
421                         .build();
422             providerMatchers =
423                     new ProviderMatchersBuilder()
424                         .setEndpointIdentificationConstraints(new EndpointIdentificationConstraintsBuilder()
425                             .setL3EndpointIdentificationConstraints(new L3EndpointIdentificationConstraintsBuilder()
426                                 .setPrefixConstraint(
427                                         ImmutableList.of(new PrefixConstraintBuilder().setIpPrefix(ipPrefix).build()))
428                                 .build())
429                             .build())
430                         .build();
431         }
432         return new ClauseBuilder().setName(new ClauseName(clauseName.toString()))
433             .setSubjectRefs(ImmutableList.of(subjectName))
434             .setConsumerMatchers(consumerMatchers)
435             .setProviderMatchers(providerMatchers)
436             .build();
437     }
438
439     /**
440      * Puts network service entities (classifier-instances, {@link #DHCP_CONTRACT},
441      * {@link #DNS_CONTRACT}, {@link #MGMT_CONTRACT} and {@link #EPG}) to
442      * {@link LogicalDatastoreType#CONFIGURATION}
443      *
444      * @param tenantId location of network-service entities
445      * @param wTx transaction where network-service entities are written
446      */
447     public static void writeNetworkServiceEntitiesToTenant(TenantId tenantId, WriteTransaction wTx, long metadataPort) {
448         Set<ClassifierInstance> classifierInstances = getAllClassifierInstances(metadataPort);
449         for (ClassifierInstance ci : classifierInstances) {
450             wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.classifierInstanceIid(tenantId, ci.getName()), ci,
451                     true);
452         }
453         for (ActionInstance ai : Collections.singleton(MappingUtils.ACTION_ALLOW)) {
454             wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.actionInstanceIid(tenantId, ai.getName()), ai, true);
455         }
456         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, DHCP_CONTRACT_ID), DHCP_CONTRACT,
457                 true);
458         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, DNS_CONTRACT_ID), DNS_CONTRACT,
459                 true);
460         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, MGMT_CONTRACT_ID), MGMT_CONTRACT,
461                 true);
462         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.contractIid(tenantId, METADATA_CONTRACT_ID), METADATA_CONTRACT,
463                 true);
464         wTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.endpointGroupIid(tenantId, EPG_ID), EPG, true);
465     }
466
467     /**
468      * @return All classifier-instances used in {@link #DHCP_CONTRACT}, {@link #DNS_CONTRACT} and
469      *         {@link #MGMT_CONTRACT}
470      */
471     public static Set<ClassifierInstance> getAllClassifierInstances(long metadataPort) {
472         HashSet<ClassifierInstance> cis = new HashSet<>();
473         cis.add(createDhcpIpv4ClientServer());
474         cis.add(createDhcpIpv4ServerClient());
475         cis.add(createDhcpIpv6ClientServer());
476         cis.add(createDhcpIpv6ServerClient());
477         cis.add(createDnsUdpIpv4ClientServer());
478         cis.add(createDnsUdpIpv4ServerClient());
479         cis.add(createDnsUdpIpv6ClientServer());
480         cis.add(createDnsUdpIpv6ServerClient());
481         cis.add(createDnsTcpIpv4ClientServer());
482         cis.add(createDnsTcpIpv4ServerClient());
483         cis.add(createDnsTcpIpv6ClientServer());
484         cis.add(createDnsTcpIpv6ServerClient());
485         // MGMT
486         cis.add(createSshTcpIpv4ServerClient());
487         cis.add(createSshTcpIpv6ServerClient());
488         cis.add(createSshTcpIpv4ClientServer());
489         cis.add(createSshTcpIpv6ClientServer());
490         cis.add(createIcmpIpv4());
491         cis.add(createIcmpIpv6());
492         // METADATA
493         cis.add(createMetadataIpv4ClientServer(metadataPort));
494         cis.add(createMetadataIpv4ServerClient(metadataPort));
495
496         return cis;
497     }
498
499     // ###################### DHCP
500     private static ClassifierInstance createDhcpIpv4ClientServer() {
501         return new ClassifierInstanceBuilder().setName(DHCP_IPV4_CLIENT_SERVER_NAME)
502             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
503             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
504                     DHCP_IPV4_CLIENT_PORT, DHCP_IPV4_SERVER_PORT))
505             .build();
506     }
507
508     private static ClassifierInstance createDhcpIpv4ServerClient() {
509         return new ClassifierInstanceBuilder().setName(DHCP_IPV4_SERVER_CLIENT_NAME)
510             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
511             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
512                     DHCP_IPV4_SERVER_PORT, DHCP_IPV4_CLIENT_PORT))
513             .build();
514     }
515
516     private static ClassifierInstance createDhcpIpv6ClientServer() {
517         return new ClassifierInstanceBuilder().setName(DHCP_IPV6_CLIENT_SERVER_NAME)
518             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
519             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
520                     DHCP_IPV6_CLIENT_PORT, DHCP_IPV6_SERVER_PORT))
521             .build();
522     }
523
524     private static ClassifierInstance createDhcpIpv6ServerClient() {
525         return new ClassifierInstanceBuilder().setName(DHCP_IPV6_SERVER_CLIENT_NAME)
526             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
527             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE,
528                     DHCP_IPV6_SERVER_PORT, DHCP_IPV6_CLIENT_PORT))
529             .build();
530     }
531
532     // ###################### DNS UDP
533     private static ClassifierInstance createDnsUdpIpv4ClientServer() {
534         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_CLIENT_SERVER_NAME)
535             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
536             .setParameterValue(
537                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT))
538             .build();
539     }
540
541     private static ClassifierInstance createDnsUdpIpv4ServerClient() {
542         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV4_SERVER_CLIENT_NAME)
543             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
544             .setParameterValue(
545                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null))
546             .build();
547     }
548
549     private static ClassifierInstance createDnsUdpIpv6ClientServer() {
550         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_CLIENT_SERVER_NAME)
551             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
552             .setParameterValue(
553                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, null, DNS_SERVER_PORT))
554             .build();
555     }
556
557     private static ClassifierInstance createDnsUdpIpv6ServerClient() {
558         return new ClassifierInstanceBuilder().setName(DNS_UDP_IPV6_SERVER_CLIENT_NAME)
559             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
560             .setParameterValue(
561                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.UDP_VALUE, DNS_SERVER_PORT, null))
562             .build();
563     }
564
565     // ###################### DNS TCP
566     private static ClassifierInstance createDnsTcpIpv4ClientServer() {
567         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_CLIENT_SERVER_NAME)
568             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
569             .setParameterValue(
570                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT))
571             .build();
572     }
573
574     private static ClassifierInstance createDnsTcpIpv4ServerClient() {
575         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV4_SERVER_CLIENT_NAME)
576             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
577             .setParameterValue(
578                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null))
579             .build();
580     }
581
582     private static ClassifierInstance createDnsTcpIpv6ClientServer() {
583         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_CLIENT_SERVER_NAME)
584             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
585             .setParameterValue(
586                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, DNS_SERVER_PORT))
587             .build();
588     }
589
590     private static ClassifierInstance createDnsTcpIpv6ServerClient() {
591         return new ClassifierInstanceBuilder().setName(DNS_TCP_IPV6_SERVER_CLIENT_NAME)
592             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
593             .setParameterValue(
594                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, DNS_SERVER_PORT, null))
595             .build();
596     }
597
598     // ###################### SSH TCP
599     private static ClassifierInstance createSshTcpIpv4ClientServer() {
600         return new ClassifierInstanceBuilder().setName(SSH_IPV4_CLIENT_TO_SERVER_NAME)
601             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
602             .setParameterValue(
603                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null))
604             .build();
605     }
606
607     private static ClassifierInstance createSshTcpIpv4ServerClient() {
608         return new ClassifierInstanceBuilder().setName(SSH_IPV4_SERVER_TO_CLIENT_NAME)
609             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
610             .setParameterValue(
611                     createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT))
612             .build();
613     }
614
615     private static ClassifierInstance createSshTcpIpv6ClientServer() {
616         return new ClassifierInstanceBuilder().setName(SSH_IPV6_CLIENT_TO_SERVER_NAME)
617             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
618             .setParameterValue(
619                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, SSH_TCP_PORT, null))
620             .build();
621     }
622
623     private static ClassifierInstance createSshTcpIpv6ServerClient() {
624         return new ClassifierInstanceBuilder().setName(SSH_IPV6_SERVER_TO_CLIENT_NAME)
625             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
626             .setParameterValue(
627                     createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null, SSH_TCP_PORT))
628             .build();
629     }
630
631     // ###################### ICMP
632     private static ClassifierInstance createIcmpIpv4() {
633         return new ClassifierInstanceBuilder().setName(ICMP_IPV4_BETWEEN_SERVER_CLIENT_NAME)
634             .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId())
635             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null))
636             .build();
637     }
638
639     private static ClassifierInstance createIcmpIpv6() {
640         return new ClassifierInstanceBuilder().setName(ICMP_IPV6_BETWEEN_SERVER_CLIENT_NAME)
641             .setClassifierDefinitionId(IpProtoClassifierDefinition.DEFINITION.getId())
642             .setParameterValue(createParams(EtherTypeClassifierDefinition.IPv6_VALUE, IpProtoClassifierDefinition.ICMP_VALUE, null, null))
643             .build();
644     }
645
646     // ###################### METADATA
647     private static ClassifierInstance createMetadataIpv4ClientServer(long dstPort) {
648         return new ClassifierInstanceBuilder().setName(METADATA_CLIENT_TO_SERVER_NAME)
649             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
650             .setParameterValue(
651                 createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE, null,
652                     dstPort))
653             .build();
654     }
655
656     private static ClassifierInstance createMetadataIpv4ServerClient(long srcPort) {
657         return new ClassifierInstanceBuilder().setName(METADATA_SERVER_TO_CLIENT_NAME)
658             .setClassifierDefinitionId(L4ClassifierDefinition.DEFINITION.getId())
659             .setParameterValue(
660                 createParams(EtherTypeClassifierDefinition.IPv4_VALUE, IpProtoClassifierDefinition.TCP_VALUE,
661                     srcPort, null))
662             .build();
663     }
664
665     private static List<ParameterValue> createParams(long etherType, long proto, @Nullable Long srcPort,
666             @Nullable Long dstPort) {
667         List<ParameterValue> params = new ArrayList<>();
668         if (srcPort != null) {
669             params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.SRC_PORT_PARAM))
670                 .setIntValue(srcPort)
671                 .build());
672         }
673         if (dstPort != null) {
674             params.add(new ParameterValueBuilder().setName(new ParameterName(L4ClassifierDefinition.DST_PORT_PARAM))
675                 .setIntValue(dstPort)
676                 .build());
677         }
678         params.add(new ParameterValueBuilder().setName(new ParameterName(IpProtoClassifierDefinition.PROTO_PARAM))
679             .setIntValue(proto)
680             .build());
681         params.add(new ParameterValueBuilder().setName(new ParameterName(EtherTypeClassifierDefinition.ETHERTYPE_PARAM))
682             .setIntValue(etherType)
683             .build());
684         return params;
685     }
686 }