2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
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
8 package org.opendaylight.groupbasedpolicy.neutron.mapper.mapping;
10 import static com.google.common.base.Preconditions.checkNotNull;
12 import java.util.HashSet;
14 import java.util.UUID;
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;
52 import com.google.common.base.Optional;
53 import com.google.common.collect.ImmutableList;
55 public class NeutronNetworkAware implements INeutronNetworkAware {
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;
63 public NeutronNetworkAware(DataBroker dataProvider, NeutronSecurityGroupAware secGrpAware, NeutronNetworkDao networkDao) {
64 this.dataProvider = checkNotNull(dataProvider);
65 this.secGrpAware = checkNotNull(secGrpAware);
66 this.networkDao = checkNotNull(networkDao);
70 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canCreateNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
73 public int canCreateNetwork(NeutronNetwork network) {
74 LOG.trace("canCreateNetwork - {}", network);
75 // nothing to consider
80 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkCreated(org.opendaylight.neutron.spi.NeutronNetwork)
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()));
89 if (network.getNetworkName() != null) {
91 name = new Name(network.getNetworkName());
92 } catch (Exception e) {
94 LOG.info("Name of Neutron Network '{}' is ignored.", network.getNetworkName());
95 LOG.debug("Name exception", e);
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);
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);
107 L2FloodDomain l2Fd = new L2FloodDomainBuilder().setId(l2FdId).setParent(l2BdId).setName(name).build();
108 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.l2FloodDomainIid(tenantId, l2FdId), l2Fd, true);
110 NetworkMapping networkMapping = new NetworkMappingBuilder().setNetworkId(l2FdId)
111 .setL2BridgeDomainId(l2BdId)
112 .setL3ContextId(l3ContextId)
114 rwTx.put(LogicalDatastoreType.OPERATIONAL, NeutronMapperIidFactory.networkMappingIid(l2FdId), networkMapping,
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);
128 networkDao.addNetwork(network);
129 if (network.getRouterExternal() != null && network.getRouterExternal() == true) {
130 addEigEpgExternalWithContracts(tenantId, rwTx);
132 DataStoreHelper.submitToDs(rwTx);
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);
171 ExternalImplicitGroup eig = new ExternalImplicitGroupBuilder().setId(MappingUtils.EPG_EXTERNAL_ID).build();
172 rwTx.put(LogicalDatastoreType.CONFIGURATION,
173 IidFactory.externalImplicitGroupIid(tenantId, eig.getId()), eig, true);
177 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canUpdateNetwork(org.opendaylight.neutron.spi.NeutronNetwork,
178 * org.opendaylight.neutron.spi.NeutronNetwork)
181 public int canUpdateNetwork(NeutronNetwork delta, NeutronNetwork original) {
182 LOG.trace("canUpdateNetwork - delta: {} original: {}", delta, original);
183 // nothing to consider
184 return StatusCode.OK;
188 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkUpdated(org.opendaylight.neutron.spi.NeutronNetwork)
191 public void neutronNetworkUpdated(NeutronNetwork network) {
192 LOG.trace("neutronNetworkUpdated - {}", network);
193 // TODO we could update just name
197 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#canDeleteNetwork(org.opendaylight.neutron.spi.NeutronNetwork)
200 public int canDeleteNetwork(NeutronNetwork network) {
201 LOG.trace("canDeleteNetwork - {}", network);
202 // nothing to consider
203 return StatusCode.OK;
207 * @see org.opendaylight.neutron.spi.INeutronNetworkAware#neutronNetworkDeleted(org.opendaylight.neutron.spi.NeutronNetwork)
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());
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);
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());
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());
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());
257 rwTx.delete(LogicalDatastoreType.OPERATIONAL, networkMappingIid);
259 DataStoreHelper.submitToDs(rwTx);