Bug 5212 - Neutron-mapper has dependency on Ofoverlay renderer
[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 import java.util.UUID;
15
16 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
17 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
18 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
19 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkClient;
20 import org.opendaylight.groupbasedpolicy.neutron.mapper.infrastructure.NetworkService;
21 import org.opendaylight.groupbasedpolicy.neutron.mapper.mapping.group.NeutronSecurityGroupAware;
22 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
23 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronMapperIidFactory;
24 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.NeutronUtils;
25 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
26 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
27 import org.opendaylight.groupbasedpolicy.util.IidFactory;
28 import org.opendaylight.neutron.spi.INeutronNetworkAware;
29 import org.opendaylight.neutron.spi.NeutronNetwork;
30 import org.opendaylight.neutron.spi.NeutronSecurityGroup;
31 import org.opendaylight.neutron.spi.NeutronSecurityRule;
32 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2BridgeDomainId;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L3ContextId;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMapping;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.mapper.rev150223.mappings.network.mappings.NetworkMappingBuilder;
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.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroup;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.policy.ExternalImplicitGroupBuilder;
48 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
49 import org.slf4j.Logger;
50 import org.slf4j.LoggerFactory;
51
52 import com.google.common.base.Optional;
53 import com.google.common.collect.ImmutableList;
54
55 public class NeutronNetworkAware implements INeutronNetworkAware {
56
57     private static final Logger LOG = LoggerFactory.getLogger(NeutronNetworkAware.class);
58     private final DataBroker dataProvider;
59     private final Set<TenantId> tenantsWithRouterAndNetworkSeviceEntities = new HashSet<>();
60     private final NeutronSecurityGroupAware secGrpAware;
61     private final NeutronNetworkDao networkDao;
62
63     public NeutronNetworkAware(DataBroker dataProvider, NeutronSecurityGroupAware secGrpAware, NeutronNetworkDao networkDao) {
64         this.dataProvider = checkNotNull(dataProvider);
65         this.secGrpAware = checkNotNull(secGrpAware);
66         this.networkDao = checkNotNull(networkDao);
67     }
68
69     /**
70      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canCreateNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
71      */
72     @Override
73     public int canCreateNetwork(NeutronNetwork network) {
74         LOG.trace("canCreateNetwork - {}", network);
75         // nothing to consider
76         return StatusCode.OK;
77     }
78
79     /**
80      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkCreated(org.opendaylight.neutron.spi.NeutronNetwork)
81      */
82     @Override
83     public void neutronNetworkCreated(NeutronNetwork network) {
84         LOG.trace("neutronNetworkCreated - {}", network);
85         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
86         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
87         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
88         Name name = null;
89         if (network.getNetworkName() != null) {
90             try {
91                 name = new Name(network.getNetworkName());
92             } catch (Exception e) {
93                 name = null;
94                 LOG.info("Name of Neutron Network '{}' is ignored.", network.getNetworkName());
95                 LOG.debug("Name exception", e);
96             }
97         }
98
99         L3ContextId l3ContextId = new L3ContextId(UUID.randomUUID().toString());
100         L3Context l3Context = new L3ContextBuilder().setId(l3ContextId).setName(name).build();
101         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l3ContextIid(tenantId, l3ContextId), l3Context, true);
102
103         L2BridgeDomainId l2BdId = new L2BridgeDomainId(UUID.randomUUID().toString());
104         L2BridgeDomain l2Bd = new L2BridgeDomainBuilder().setId(l2BdId).setParent(l3ContextId).setName(name).build();
105         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2BridgeDomainIid(tenantId, l2BdId), l2Bd, true);
106
107         L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId).setParent(l2BdId).setName(name).build();
108         rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
109
110         NetworkMapping networkMapping = new NetworkMappingBuilder().setNetworkId(l2FdId)
111             .setL2BridgeDomainId(l2BdId)
112             .setL3ContextId(l3ContextId)
113             .build();
114         rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping,
115                 true);
116
117         if (!tenantsWithRouterAndNetworkSeviceEntities.contains(tenantId)) {
118             tenantsWithRouterAndNetworkSeviceEntities.add(tenantId);
119             NetworkService.writeNetworkServiceEntitiesToTenant(tenantId, rwTx);
120             NetworkService.writeDhcpClauseWithConsProvEic(tenantId, null, rwTx);
121             NetworkService.writeDnsClauseWithConsProvEic(tenantId, null, rwTx);
122             NetworkService.writeMgmtClauseWithConsProvEic(tenantId, null, rwTx);
123             NetworkClient.writeNetworkClientEntitiesToTenant(tenantId, rwTx);
124             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DHCP_CONTRACT_CONSUMER_SELECTOR, rwTx);
125             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.DNS_CONTRACT_CONSUMER_SELECTOR, rwTx);
126             NetworkClient.writeConsumerNamedSelector(tenantId, NetworkService.MGMT_CONTRACT_CONSUMER_SELECTOR, rwTx);
127         }
128         networkDao.addNetwork(network);
129         if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
130             addEigEpgExternalWithContracts(tenantId, rwTx);
131         }
132         DataStoreHelper.submitToDs(rwTx);
133     }
134
135     private void addEigEpgExternalWithContracts(TenantId tenantId, ReadWriteTransaction rwTx) {
136         Uuid tenantUuid = new Uuid(tenantId.getValue());
137         NeutronSecurityRule inIpv4 = new NeutronSecurityRule();
138         inIpv4.setID("19b85ad2-bdfc-11e5-9912-ba0be0483c18");
139         inIpv4.setSecurityRuleDirection(NeutronUtils.INGRESS);
140         inIpv4.setSecurityRuleEthertype(NeutronUtils.IPv4);
141         inIpv4.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
142         inIpv4.setTenantID(tenantUuid);
143         NeutronSecurityRule outIpv4 = new NeutronSecurityRule();
144         outIpv4.setID("19b85eba-bdfc-11e5-9912-ba0be0483c18");
145         outIpv4.setSecurityRuleDirection(NeutronUtils.EGRESS);
146         outIpv4.setSecurityRuleEthertype(NeutronUtils.IPv4);
147         outIpv4.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
148         outIpv4.setTenantID(tenantUuid);
149         NeutronSecurityRule inIpv6 = new NeutronSecurityRule();
150         inIpv6.setID("19b86180-bdfc-11e5-9912-ba0be0483c18");
151         inIpv6.setSecurityRuleDirection(NeutronUtils.INGRESS);
152         inIpv6.setSecurityRuleEthertype(NeutronUtils.IPv6);
153         inIpv6.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
154         inIpv6.setTenantID(tenantUuid);
155         NeutronSecurityRule outIpv6 = new NeutronSecurityRule();
156         outIpv6.setID("19b86270-bdfc-11e5-9912-ba0be0483c18");
157         outIpv6.setSecurityRuleDirection(NeutronUtils.EGRESS);
158         outIpv6.setSecurityRuleEthertype(NeutronUtils.IPv6);
159         outIpv6.setSecurityRuleGroupID(MappingUtils.EPG_EXTERNAL_ID.getValue());
160         outIpv6.setTenantID(tenantUuid);
161         NeutronSecurityGroup externalSecGrp = new NeutronSecurityGroup();
162         externalSecGrp.setID(MappingUtils.EPG_EXTERNAL_ID.getValue());
163         externalSecGrp.setSecurityGroupName("EXTERNAL_group");
164         externalSecGrp.setTenantID(tenantUuid);
165         externalSecGrp.setSecurityRules(ImmutableList.of(inIpv4, outIpv4, inIpv6, outIpv6));
166         boolean isAddedNeutronSecurityGroup = secGrpAware.addNeutronSecurityGroup(externalSecGrp, rwTx);
167         if (!isAddedNeutronSecurityGroup) {
168             LOG.error("Problem with adding External Neutron Security Group representing External Implicit Group. {}", externalSecGrp);
169             return;
170         }
171         ExternalImplicitGroup eig = new ExternalImplicitGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build();
172         rwTx.put(LogicalDatastoreType.CONFIGURATION,
173                 IidFactory.externalImplicitGroupIid(tenantId, eig.getId()), eig, true);
174     }
175
176     /**
177      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
178      *      org.opendaylight.neutron.spi.NeutronNetwork)
179      */
180     @Override
181     public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original) {
182         LOG.trace("canUpdateNetwork - delta: {} original: {}", delta, original);
183         // nothing to consider
184         return StatusCode.OK;
185     }
186
187     /**
188      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkUpdated(org.opendaylight.neutron.spi.NeutronNetwork)
189      */
190     @Override
191     public void neutronNetworkUpdated(NeutronNetwork network) {
192         LOG.trace("neutronNetworkUpdated - {}", network);
193         // TODO we could update just name
194     }
195
196     /**
197      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canDeleteNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
198      */
199     @Override
200     public int canDeleteNetwork(NeutronNetwork network) {
201         LOG.trace("canDeleteNetwork - {}", network);
202         // nothing to consider
203         return StatusCode.OK;
204     }
205
206     /**
207      * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkDeleted(org.opendaylight.neutron.spi.NeutronNetwork)
208      */
209     @Override
210     public void neutronNetworkDeleted(NeutronNetwork network) {
211         LOG.trace("neutronNetworkDeleted - {}", network);
212         ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
213         TenantId tenantId = new TenantId(Utils.normalizeUuid(network.getTenantID()));
214         L2FloodDomainId l2FdId = new L2FloodDomainId(network.getID());
215         InstanceIdentifier<NetworkMapping> networkMappingIid = NeutronMapperIidFactory.networkMappingIid(l2FdId);
216         Optional<NetworkMapping> potentionalNetworkMapping =
217                 DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL, networkMappingIid, rwTx);
218         if (!potentionalNetworkMapping.isPresent()) {
219             LOG.warn("Illegal state - network-mapping {} does not exist.", l2FdId.getValue());
220             rwTx.cancel();
221             return;
222         }
223
224         NetworkMapping networkMapping = potentionalNetworkMapping.get();
225         L2BridgeDomainId l2BdId = networkMapping.getL2BridgeDomainId();
226         L3ContextId l3ContextId = networkMapping.getL3ContextId();
227         if (l2BdId == null || l3ContextId == null) {
228             LOG.warn("Illegal state - network-mapping {} is not valid.", networkMapping);
229             rwTx.cancel();
230             return;
231         }
232
233         Optional<L2FloodDomain> potentialL2Fd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
234                 IidFactory.l2FloodDomainIid(tenantId, l2FdId), rwTx);
235         if (!potentialL2Fd.isPresent()) {
236             LOG.warn("Illegal state - l2-flood-domain {} does not exist.", l2FdId.getValue());
237             rwTx.cancel();
238             return;
239         }
240
241         Optional<L2BridgeDomain> potentialL2Bd = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
242                 IidFactory.l2BridgeDomainIid(tenantId, l2BdId), rwTx);
243         if (!potentialL2Bd.isPresent()) {
244             LOG.warn("Illegal state - l2-bridge-domain {} does not exist.", l2BdId.getValue());
245             rwTx.cancel();
246             return;
247         }
248
249         Optional<L3Context> potentialL3Context = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
250                 IidFactory.l3ContextIid(tenantId, l3ContextId), rwTx);
251         if (!potentialL3Context.isPresent()) {
252             LOG.warn("Illegal state - l3-context {} does not exist.", l3ContextId.getValue());
253             rwTx.cancel();
254             return;
255         }
256
257         rwTx.delete(LogicalDatastoreType.OPERATIONAL, networkMappingIid);
258
259         DataStoreHelper.submitToDs(rwTx);
260     }
261 }