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 org.opendaylight.controller.md.sal.binding.api.DataBroker;
13 import org.opendaylight.controller.md.sal.binding.api.ReadWriteTransaction;
14 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
15 import org.opendaylight.groupbasedpolicy.neutron.gbp.util.NeutronGbpIidFactory;
16 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils;
17 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.MappingUtils.ForwardingCtx;
18 import org.opendaylight.groupbasedpolicy.neutron.mapper.util.Utils;
19 import org.opendaylight.groupbasedpolicy.util.DataStoreHelper;
20 import org.opendaylight.groupbasedpolicy.util.IidFactory;
21 import org.opendaylight.neutron.spi.INeutronSubnetAware;
22 import org.opendaylight.neutron.spi.NeutronSubnet;
23 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.ContextId;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.L2FloodDomainId;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.Name;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.NetworkDomainId;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.SubnetId;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.common.rev140421.TenantId;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.neutron.gbp.mapper.rev150513.mappings.neutron.by.gbp.mappings.external.networks.by.l2.flood.domains.ExternalNetworkByL2FloodDomain;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.Subnet;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.groupbasedpolicy.policy.rev140421.tenants.tenant.SubnetBuilder;
33 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
34 import org.slf4j.Logger;
35 import org.slf4j.LoggerFactory;
37 import com.google.common.base.Optional;
38 import com.google.common.base.Strings;
40 public class NeutronSubnetAware implements INeutronSubnetAware {
42 private final static Logger LOG = LoggerFactory.getLogger(NeutronSubnetAware.class);
43 private final DataBroker dataProvider;
45 public NeutronSubnetAware(DataBroker dataProvider) {
46 this.dataProvider = checkNotNull(dataProvider);
50 * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canCreateSubnet(org.opendaylight.neutron.spi.NeutronSubnet)
53 public int canCreateSubnet(NeutronSubnet subnet) {
54 LOG.trace("canCreateSubnet - {}", subnet);
55 // nothing to consider
60 * @see org.opendaylight.neutron.spi.INeutronSubnetAware#neutronSubnetCreated(org.opendaylight.neutron.spi.NeutronSubnet)
63 public void neutronSubnetCreated(NeutronSubnet neutronSubnet) {
64 LOG.trace("neutronSubnetCreated - {}", neutronSubnet);
65 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
66 SubnetId subnetId = new SubnetId(Utils.normalizeUuid(neutronSubnet.getID()));
67 TenantId tenantId = new TenantId(Utils.normalizeUuid(neutronSubnet.getTenantID()));
68 Subnet subnet = createSubnet(neutronSubnet);
69 rwTx.put(LogicalDatastoreType.CONFIGURATION, IidFactory.subnetIid(tenantId, subnetId), subnet, true);
70 DataStoreHelper.submitToDs(rwTx);
72 rwTx = dataProvider.newReadWriteTransaction();
73 if (isExternalNetwork(subnet.getParent(), rwTx)) {
74 LOG.trace("neutronSubnetCreated - adding L3 Endpoint");
75 L2FloodDomainId l2FdId = new L2FloodDomainId(subnet.getParent().getValue());
76 ForwardingCtx fwCtx = MappingUtils.createForwardingContext(tenantId, l2FdId, rwTx);
77 IpAddress defaultGateway = Utils.createIpAddress(neutronSubnet.getGatewayIP());
78 //Create L3Endpoint for defaultGateway and write to externalGateways to L3Endpoints in neutron-gbp datastore
79 NetworkDomainId containment = new NetworkDomainId(neutronSubnet.getID());
80 NeutronPortAware.addL3EndpointForExternalGateway(tenantId, fwCtx.getL3Context().getId(), defaultGateway, containment ,rwTx);
81 DataStoreHelper.submitToDs(rwTx);
85 private Subnet createSubnet(NeutronSubnet neutronSubnet) {
86 SubnetBuilder subnetBuilder = new SubnetBuilder();
87 subnetBuilder.setId(new SubnetId(neutronSubnet.getID()));
88 subnetBuilder.setParent(new ContextId(neutronSubnet.getNetworkUUID()));
89 if (!Strings.isNullOrEmpty(neutronSubnet.getName())) {
90 subnetBuilder.setName(new Name(neutronSubnet.getName()));
92 subnetBuilder.setIpPrefix(Utils.createIpPrefix(neutronSubnet.getCidr()));
93 return subnetBuilder.build();
97 private boolean isExternalNetwork(ContextId context, ReadWriteTransaction rwTx) {
98 L2FloodDomainId l2FdId = new L2FloodDomainId(context.getValue());
99 LOG.trace("neutronSubnetCreated - Looking up L2FD: {}", l2FdId);
100 InstanceIdentifier<ExternalNetworkByL2FloodDomain> iid = NeutronGbpIidFactory.externalNetworkByL2FloodDomain(l2FdId);
101 Optional<ExternalNetworkByL2FloodDomain> external = DataStoreHelper.readFromDs(LogicalDatastoreType.OPERATIONAL,
103 if (external.isPresent()) {
110 * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canUpdateSubnet(org.opendaylight.neutron.spi.NeutronSubnet,
111 * org.opendaylight.neutron.spi.NeutronSubnet)
114 public int canUpdateSubnet(NeutronSubnet delta, NeutronSubnet original) {
115 LOG.trace("canUpdateSubnet - delta: {} original: {}", delta, original);
116 // nothing to consider
117 return StatusCode.OK;
121 * @see org.opendaylight.neutron.spi.INeutronSubnetAware#neutronSubnetUpdated(org.opendaylight.neutron.spi.NeutronSubnet)
124 public void neutronSubnetUpdated(NeutronSubnet subnet) {
125 LOG.trace("neutronSubnetUpdated - {}", subnet);
126 neutronSubnetCreated(subnet);
130 * @see org.opendaylight.neutron.spi.INeutronSubnetAware#canDeleteSubnet(org.opendaylight.neutron.spi.NeutronSubnet)
133 public int canDeleteSubnet(NeutronSubnet subnet) {
134 LOG.trace("canDeleteSubnet - {}", subnet);
135 // nothing to consider
136 return StatusCode.OK;
140 * @see org.opendaylight.neutron.spi.INeutronSubnetAware#neutronSubnetDeleted(org.opendaylight.neutron.spi.NeutronSubnet)
143 public void neutronSubnetDeleted(NeutronSubnet neutronSubnet) {
144 LOG.trace("neutronSubnetDeleted - {}", neutronSubnet);
145 ReadWriteTransaction rwTx = dataProvider.newReadWriteTransaction();
146 SubnetId subnetId = new SubnetId(Utils.normalizeUuid(neutronSubnet.getID()));
147 TenantId tenantId = new TenantId(Utils.normalizeUuid(neutronSubnet.getTenantID()));
148 Optional<Subnet> potentialSubnet = DataStoreHelper.removeIfExists(LogicalDatastoreType.CONFIGURATION,
149 IidFactory.subnetIid(tenantId, subnetId), rwTx);
150 if (!potentialSubnet.isPresent()) {
151 LOG.warn("Illegal state - subnet {} does not exist.", subnetId.getValue());
155 DataStoreHelper.submitToDs(rwTx);