c7d7ca2b0a015c3748b96a5fca24346ed8ea0b72
[groupbasedpolicy.git] / neutron-mapper / src / main / java / org / opendaylight / groupbasedpolicy / neutron / mapper / mapping / NeutronNetworkAware.java
1 /*
2  * Copyright (c) 2015 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 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
9
10 import static com.google.common.base.Preconditions.checkNotNull;
11
12 import java.util.HashSet;
13 import java.util.Set;
14
15 import javax.annotation.Nullable;
16
17 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
18 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
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.domain_extension.l2_l3.util.L2L3IidFactory;
22 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
23 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
26 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NetworkUtils;
27 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
28 import org.opendaylight.groupbasedpolicy.util.IidFactory;
29 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev130715.IpPrefix;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContext;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.forwarding.rev160427.forwarding.forwarding.by.tenant.ForwardingContextBuilder;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomain;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2BridgeDomainBuilder;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomain;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L2FloodDomainBuilder;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3Context;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.forwarding.context.L3ContextBuilder;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
49 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
50 import org.slf4j.Logger;
51 import org.slf4j.LoggerFactory;
52
53 import com.google.common.base.Optional;
54 import com.google.common.base.Strings;
55
56 public class NeutronNetworkAware implements NeutronAware<Network> {
57
58     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
59     public static final InstanceIdentifier<Network> NETWORK_WILDCARD_IID =
60             InstanceIdentifier.builder(Neutron.class).child(Networks.class).child(Network.class).build();
61     private final DataBroker dataProvider;
62     private final Set<TenantId> tenantsWithRouterAndNetworkServiceEntities = new HashSet<>();
63     private final IpPrefix metadataIpPrefix;
64     private final long metadataPort;
65
66     public NeutronNetworkAware(DataBroker dataProvider, @Nullable IpPrefix metadataIpPrefix, long metadataPort) {
67         this.dataProvider = checkNotNull(dataProvider);
68         this.metadataIpPrefix = metadataIpPrefix;
69         this.metadataPort = metadataPort;
70     }
71
72     @Override
73     public void onCreated(Network network, Neutron neutron) {
74         LOG.trace("created network - {}", network);
75         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
76         TenantId tenantId = new TenantId(network.getTenantId().getValue());
77         Name name;
78         ContextId ctxId = new ContextId(network.getUuid().getValue());
79         ForwardingContextBuilder fwdCtxBuilder = new ForwardingContextBuilder()
80         .setContextId(ctxId)
81         .setContextType(MappingUtils.L3_CONTEXT);
82         if (!Strings.isNullOrEmpty(network.getName())) {
83             try {
84                 name = new Name(network.getName());
85                 fwdCtxBuilder.setName(name);
86             } catch (Exception e) {
87                 LOG.info("Name of Neutron Network '{}' is ignored.", network.getName());
88                 LOG.debug("Name exception", e);
89             }
90         }
91
92         ForwardingContext l3Context = fwdCtxBuilder.build();
93
94         fwdCtxBuilder.setContextType(MappingUtils.L2_BRDIGE_DOMAIN)
95
96         .setParent(MappingUtils.createParent(ctxId, MappingUtils.L3_CONTEXT));
97         ForwardingContext l2Bd = fwdCtxBuilder.build();
98
99         fwdCtxBuilder.setContextType(MappingUtils.L2_FLOOD_DOMAIN).setParent(
100                 MappingUtils.createParent(ctxId, MappingUtils.L2_BRDIGE_DOMAIN));
101         ForwardingContext l2Fd = fwdCtxBuilder.build();
102
103         rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l3ContextIid(tenantId, ctxId), l3Context, true);
104         rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2BridgeDomainIid(tenantId, ctxId), l2Bd, true);
105         rwTx.put(LogicalDatastoreType.CONFIGURATION, L2L3IidFactory.l2FloodDomainIid(tenantId, ctxId), l2Fd, true);
106
107         createTenantNetworkDomains(network, tenantId, rwTx);
108
109         if (!tenantsWithRouterAndNetworkServiceEntities.contains(tenantId)) {
110             tenantsWithRouterAndNetworkServiceEntities.add(tenantId);
111             NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx, metadataPort);
112             NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
113             NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
114             NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
115             NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
116             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
117             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
118             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
119             if (metadataIpPrefix != null) {
120                 NetworkService.writeMetadataClauseWithConsProvEic(tenantId, metadataIpPrefix, rwTx);
121                 NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.METADATA_CONTRACT_CONSUMER_SELECTOR,
122                     rwTx);
123             }
124         }
125         if (!NetworkUtils.getPhysicalNetwork(network).isEmpty() && !NetworkUtils.getSegmentationId(network).isEmpty()) {
126             addProviderPhysicalNetworkMapping(tenantId, ctxId, NetworkUtils.getSegmentationId(network), rwTx);
127             addProviderPhysicalNetworkMapping(tenantId, new L2FloodDomainId(ctxId.getValue()),
128                     NetworkUtils.getSegmentationId(network), rwTx);
129         }
130         DataStoreHelper.submitToDs(rwTx);
131     }
132
133     @Deprecated
134     private void createTenantNetworkDomains(Network network, TenantId tenantId, ReadWriteTransaction rwTx) {
135         Name name;
136         L3ContextBuilder l3CtxBuilder = new L3ContextBuilder();
137         L2FloodDomainBuilder l2FdBuilder = new L2FloodDomainBuilder();
138         L2BridgeDomainBuilder l2BdBuilder = new L2BridgeDomainBuilder();
139         if (!Strings.isNullOrEmpty(network.getName())) {
140             try {
141                 name = new Name(network.getName());
142                 l3CtxBuilder.setName(name);
143                 l2FdBuilder.setName(name);
144                 l2BdBuilder.setName(name);
145             } catch (Exception e) {
146                 name = null;
147                 LOG.info("Name of Neutron Network '{}' is ignored.", network.getName());
148                 LOG.debug("Name exception", e);
149             }
150         }
151         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
152         L3ContextId l3ContextId = new L3ContextId(l2FdId);
153         L3Context l3Context = l3CtxBuilder.setId(l3ContextId).build();
154         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3Context.getId()), l3Context, true);
155
156         L2BridgeDomainId l2BdId = new L2BridgeDomainId(l2FdId);
157         L2BridgeDomain l2Bd = l2BdBuilder.setId(l2BdId).setParent(l3Context.getId()).build();
158         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
159
160         L2FloodDomain l2Fd = l2FdBuilder.setId(l2FdId).setParent(l2BdId).build();
161         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
162     }
163
164     private void addProviderPhysicalNetworkMapping(TenantId tenantId, ContextId ctxId, String segmentationId,
165             WriteTransaction wTx) {
166         ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new ProviderPhysicalNetworkAsL2FloodDomainBuilder().setTenantId(
167                 tenantId)
168             .setL2FloodDomainId(ctxId)
169             .setSegmentationId(segmentationId)
170             .build();
171         wTx.put(LogicalDatastoreType.OPERATIONAL,
172                 NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, ctxId), provNetAsL2Fd);
173     }
174
175     @Deprecated
176     private void addProviderPhysicalNetworkMapping(TenantId tenantId, L2FloodDomainId l2FdId, String segmentationId,
177             WriteTransaction wTx) {
178         org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomain provNetAsL2Fd = new org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.provider.physical.networks.as.l2.flood.domains.ProviderPhysicalNetworkAsL2FloodDomainBuilder().setTenantId(
179                 tenantId)
180             .setL2FloodDomainId(new L2FloodDomainId(l2FdId.getValue()))
181             .setSegmentationId(segmentationId)
182             .build();
183         wTx.put(LogicalDatastoreType.OPERATIONAL,
184                 NeutronGbpIidFactory.providerPhysicalNetworkAsL2FloodDomainIid(tenantId, l2FdId), provNetAsL2Fd);
185     }
186
187     @Override
188     public void onUpdated(Network oldItem, Network newItem, Neutron oldNeutron, Neutron newNeutron) {
189         LOG.trace("updated network - OLD: {} \nNEW: {}", oldItem, newItem);
190         // TODO only name can be updated
191     }
192
193     @Override
194     public void onDeleted(Network network, Neutron oldNeutron, Neutron newNeutron) {
195         LOG.trace("deleted network - {}", network);
196         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
197         TenantId tenantId = new TenantId(network.getTenantId().getValue());
198         ContextId id = new ContextId(network.getUuid().getValue());
199         Optional<ForwardingContext> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
200                 L2L3IidFactory.l2FloodDomainIid(tenantId, id), rwTx);
201         if (!potentialL2Fd.isPresent()) {
202             LOG.warn("Illegal state - l2-flood-domain {} does not exist.", id.getValue());
203             return;
204         }
205         Optional<ForwardingContext> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
206                 L2L3IidFactory.l2BridgeDomainIid(tenantId, id), rwTx);
207         if (!potentialL2Bd.isPresent()) {
208             LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", id.getValue());
209             return;
210         }
211         Optional<ForwardingContext> potentialL3Ctx = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
212                 L2L3IidFactory.l3ContextIid(tenantId, id), rwTx);
213         if (!potentialL3Ctx.isPresent()) {
214             LOG.warn("Illegal state - l3-context {} does not exist.", id.getValue());
215             return;
216         }
217         removeTenantNetworkDomains(network, tenantId, rwTx);
218         DataStoreHelper.submitToDs(rwTx);
219     }
220
221     @Deprecated
222     private void removeTenantNetworkDomains(Network network, TenantId tenantId, ReadWriteTransaction rwTx) {
223         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getUuid().getValue());
224         Optional<L2FloodDomain> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
225                 IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx);
226         if (!potentialL2Fd.isPresent()) {
227             LOG.warn("Illegal state - l2-flood-domain {} does not exist.", l2FdId.getValue());
228             return;
229         }
230
231         L2BridgeDomainId l2BdId = new L2BridgeDomainId(l2FdId);
232         Optional<L2BridgeDomain> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
233                 IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
234         if (!potentialL2Bd.isPresent()) {
235             LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue());
236             return;
237         }
238         L3ContextId l3CtxId = new L3ContextId(l2FdId);
239         Optional<L3Context> potentialL3Ctx = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
240                 IidFactory.l3ContextIid(tenantId, l3CtxId), rwTx);
241         if (!potentialL3Ctx.isPresent()) {
242             LOG.warn("Illegal state - l3-context {} does not exist.", l3CtxId.getValue());
243             return;
244         }
245     }
246 }