transcriber: consolidate crud logic
[neutron.git] / transcriber / src / main / java / org / opendaylight / neutron / transcriber / NeutronSubnetInterface.java
1 /*
2  * Copyright (c) 2013, 2015 IBM Corporation 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.neutron.transcriber;
10
11 import java.util.ArrayList;
12 import java.util.HashSet;
13 import java.util.List;
14 import java.util.Map.Entry;
15 import java.util.Set;
16
17 import org.opendaylight.controller.sal.binding.api.BindingAwareBroker.ProviderContext;
18 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
19 import org.opendaylight.neutron.spi.INeutronPortCRUD;
20 import org.opendaylight.neutron.spi.INeutronSubnetCRUD;
21 import org.opendaylight.neutron.spi.Neutron_IPs;
22 import org.opendaylight.neutron.spi.NeutronCRUDInterfaces;
23 import org.opendaylight.neutron.spi.NeutronNetwork;
24 import org.opendaylight.neutron.spi.NeutronPort;
25 import org.opendaylight.neutron.spi.NeutronSubnet;
26 import org.opendaylight.neutron.spi.NeutronSubnetIPAllocationPool;
27 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.inet.types.rev100924.IpAddress;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Base;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Off;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Slaac;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Stateful;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.Dhcpv6Stateless;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.IpVersionBase;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.IpVersionV4;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.constants.rev160807.IpVersionV6;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150325.Neutron;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnet.attributes.AllocationPools;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnet.attributes.AllocationPoolsBuilder;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnets.attributes.Subnets;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnets.attributes.subnets.Subnet;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev141002.subnets.attributes.subnets.SubnetBuilder;
42 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
43 import org.osgi.framework.BundleContext;
44 import org.osgi.framework.ServiceRegistration;
45 import org.slf4j.Logger;
46 import org.slf4j.LoggerFactory;
47
48 import com.google.common.collect.ImmutableBiMap;
49
50 public class NeutronSubnetInterface extends AbstractNeutronInterface<Subnet, NeutronSubnet> implements INeutronSubnetCRUD {
51     private static final Logger LOGGER = LoggerFactory.getLogger(NeutronSubnetInterface.class);
52
53     private static final ImmutableBiMap<Class<? extends IpVersionBase>,Integer> IPV_MAP
54             = new ImmutableBiMap.Builder<Class<? extends IpVersionBase>,Integer>()
55             .put(IpVersionV4.class,Integer.valueOf(4))
56             .put(IpVersionV6.class,Integer.valueOf(6))
57             .build();
58
59     private static final ImmutableBiMap<Class<? extends Dhcpv6Base>,String> DHCPV6_MAP
60             = new ImmutableBiMap.Builder<Class<? extends Dhcpv6Base>,String>()
61             .put(Dhcpv6Off.class,"off")
62             .put(Dhcpv6Stateful.class,"dhcpv6-stateful")
63             .put(Dhcpv6Slaac.class,"slaac")
64             .put(Dhcpv6Stateless.class,"dhcpv6-stateless")
65             .build();
66
67     NeutronSubnetInterface(ProviderContext providerContext) {
68         super(providerContext);
69     }
70
71     // IfNBSubnetCRUD methods
72
73     @Override
74     public boolean subnetExists(String uuid) {
75         return exists(uuid);
76     }
77
78     @Override
79     public NeutronSubnet getSubnet(String uuid) {
80         return get(uuid);
81     }
82
83     @Override
84     public List<NeutronSubnet> getAll() {
85         Set<NeutronSubnet> allSubnets = new HashSet<NeutronSubnet>();
86         Subnets subnets = readMd(createInstanceIdentifier());
87         if (subnets != null) {
88             for (Subnet subnet: subnets.getSubnet()) {
89                 allSubnets.add(fromMd(subnet));
90             }
91         }
92         LOGGER.debug("Exiting getAllSubnets, Found {} OpenStackSubnets", allSubnets.size());
93         List<NeutronSubnet> ans = new ArrayList<NeutronSubnet>();
94         ans.addAll(allSubnets);
95         return ans;
96     }
97
98     @Override
99     public List<NeutronSubnet> getAllSubnets() {
100         return getAll();
101     }
102
103     @Override
104     public boolean addSubnet(NeutronSubnet input) {
105         String id = input.getID();
106         if (subnetExists(id)) {
107             return false;
108         }
109         addMd(input);
110         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
111             .fetchINeutronNetworkCRUD(this);
112         INeutronNetworkCRUD networkIf = interfaces.getNetworkInterface();
113
114         NeutronNetwork targetNet = networkIf.getNetwork(input.getNetworkUUID());
115         targetNet.addSubnet(id);
116         return true;
117     }
118
119     @Override
120     public boolean removeSubnet(String uuid) {
121         NeutronSubnet target = getSubnet(uuid);
122         if (target == null) {
123             return false;
124         }
125         removeMd(toMd(uuid));
126         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
127             .fetchINeutronNetworkCRUD(this);
128         INeutronNetworkCRUD networkIf = interfaces.getNetworkInterface();
129
130         NeutronNetwork targetNet = networkIf.getNetwork(target.getNetworkUUID());
131         targetNet.removeSubnet(uuid);
132         return true;
133     }
134
135     @Override
136     public boolean updateSubnet(String uuid, NeutronSubnet delta) {
137 /* note: because what we get is *not* a delta but (at this point) the updated
138  * object, this is much simpler - just replace the value and update the mdsal
139  * with it */
140         return update(uuid, delta);
141     }
142
143 // note: this is being set to false in preparation for deprecation and removal
144     @Override
145     public boolean subnetInUse(String subnetUUID) {
146         return false;
147     }
148
149     protected NeutronSubnet fromMd(Subnet subnet) {
150         NeutronSubnet result = new NeutronSubnet();
151         result.setName(subnet.getName());
152         result.setTenantID(String.valueOf(subnet.getTenantId().getValue()).replace("-",""));
153         result.setNetworkUUID(subnet.getNetworkId().getValue());
154         result.setIpVersion(IPV_MAP.get(subnet.getIpVersion()));
155         result.setCidr(subnet.getCidr());
156         result.setGatewayIP(String.valueOf(subnet.getGatewayIp().getValue()));
157         result.setIpV6RaMode(DHCPV6_MAP.get(subnet.getIpv6RaMode()));
158         result.setIpV6AddressMode(DHCPV6_MAP.get(subnet.getIpv6AddressMode()));
159         result.setEnableDHCP(subnet.isEnableDhcp());
160         if (subnet.getAllocationPools() != null) {
161             List<NeutronSubnetIPAllocationPool> allocationPools = new ArrayList<NeutronSubnetIPAllocationPool>();
162             for (AllocationPools allocationPool : subnet.getAllocationPools()) {
163                 NeutronSubnetIPAllocationPool pool = new NeutronSubnetIPAllocationPool();
164                 pool.setPoolStart(allocationPool.getStart());
165                 pool.setPoolEnd(allocationPool.getEnd());
166                 allocationPools.add(pool);
167             }
168             result.setAllocationPools(allocationPools);
169         }
170         if (subnet.getDnsNameservers() != null) {
171             List<String> dnsNameServers = new ArrayList<String>();
172             for (IpAddress dnsNameServer : subnet.getDnsNameservers()) {
173                 dnsNameServers.add(String.valueOf(dnsNameServer.getValue()));
174             }
175             result.setDnsNameservers(dnsNameServers);
176         }
177         result.setID(subnet.getUuid().getValue());
178 // read through the ports and put the ones in this subnet into the internal
179 // myPorts object.
180 // @deprecated and will be removed in Boron
181         Set<NeutronPort> allPorts = new HashSet<NeutronPort>();
182         NeutronCRUDInterfaces interfaces = new NeutronCRUDInterfaces()
183             .fetchINeutronPortCRUD(this);
184         INeutronPortCRUD portIf = interfaces.getPortInterface();
185         for (NeutronPort port : portIf.getAllPorts()) {
186             if (port.getFixedIPs() != null) {
187                 for (Neutron_IPs ip : port.getFixedIPs()) {
188                     if (ip.getSubnetUUID().equals(result.getID())) {
189                         allPorts.add(port);
190                     }
191                 }
192             }
193         }
194         List<NeutronPort> ports = new ArrayList<NeutronPort>();
195         ports.addAll(allPorts);
196         result.setPorts(ports);
197         return result;
198     }
199
200     protected Subnet toMd(NeutronSubnet subnet) {
201         SubnetBuilder subnetBuilder = new SubnetBuilder();
202         if (subnet.getName() != null) {
203             subnetBuilder.setName(subnet.getName());
204         }
205         if (subnet.getTenantID() != null) {
206             subnetBuilder.setTenantId(toUuid(subnet.getTenantID()));
207         }
208         if (subnet.getNetworkUUID() != null) {
209             subnetBuilder.setNetworkId(toUuid(subnet.getNetworkUUID()));
210         }
211         if (subnet.getIpVersion() != null) {
212             ImmutableBiMap<Integer, Class<? extends IpVersionBase>> mapper =
213                     IPV_MAP.inverse();
214             subnetBuilder.setIpVersion((Class<? extends IpVersionBase>) mapper.get(subnet
215                     .getIpVersion()));
216         }
217         if (subnet.getCidr() != null) {
218             subnetBuilder.setCidr(subnet.getCidr());
219         }
220         if (subnet.getGatewayIP() != null) {
221             IpAddress ipAddress = new IpAddress(subnet.getGatewayIP()
222                     .toCharArray());
223             subnetBuilder.setGatewayIp(ipAddress);
224         }
225         if (subnet.getIpV6RaMode() != null) {
226             ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
227                     DHCPV6_MAP.inverse();
228             subnetBuilder.setIpv6RaMode((Class<? extends Dhcpv6Base>) mapper.get(subnet.getIpV6RaMode()));
229         }
230         if (subnet.getIpV6AddressMode() != null) {
231             ImmutableBiMap<String, Class<? extends Dhcpv6Base>> mapper =
232                     DHCPV6_MAP.inverse();
233             subnetBuilder.setIpv6AddressMode((Class<? extends Dhcpv6Base>) mapper.get(subnet.getIpV6AddressMode()));
234         }
235         subnetBuilder.setEnableDhcp(subnet.getEnableDHCP());
236         if (subnet.getAllocationPools() != null) {
237             List<AllocationPools> allocationPools = new ArrayList<AllocationPools>();
238             for (NeutronSubnetIPAllocationPool allocationPool : subnet
239                     .getAllocationPools()) {
240                 AllocationPoolsBuilder builder = new AllocationPoolsBuilder();
241                 builder.setStart(allocationPool.getPoolStart());
242                 builder.setEnd(allocationPool.getPoolEnd());
243                 AllocationPools temp = builder.build();
244                 allocationPools.add(temp);
245             }
246             subnetBuilder.setAllocationPools(allocationPools);
247         }
248         if (subnet.getDnsNameservers() != null) {
249             List<IpAddress> dnsNameServers = new ArrayList<IpAddress>();
250             for (String dnsNameServer : subnet.getDnsNameservers()) {
251                 IpAddress ipAddress = new IpAddress(dnsNameServer.toCharArray());
252                 dnsNameServers.add(ipAddress);
253             }
254             subnetBuilder.setDnsNameservers(dnsNameServers);
255         }
256         if (subnet.getID() != null) {
257             subnetBuilder.setUuid(toUuid(subnet.getID()));
258         } else {
259             LOGGER.warn("Attempting to write neutron subnet without UUID");
260         }
261         return subnetBuilder.build();
262     }
263
264     @Override
265     protected InstanceIdentifier<Subnet> createInstanceIdentifier(Subnet subnet) {
266         return InstanceIdentifier.create(Neutron.class).child(Subnets.class)
267                 .child(Subnet.class, subnet.getKey());
268     }
269
270     protected InstanceIdentifier<Subnets> createInstanceIdentifier() {
271         return InstanceIdentifier.create(Neutron.class)
272                 .child(Subnets.class);
273     }
274
275     @Override
276     protected Subnet toMd(String uuid) {
277         SubnetBuilder subnetBuilder = new SubnetBuilder();
278         subnetBuilder.setUuid(toUuid(uuid));
279         return subnetBuilder.build();
280     }
281
282     public static void registerNewInterface(BundleContext context,
283                                             ProviderContext providerContext,
284                                             List<ServiceRegistration<?>> registrations) {
285         NeutronSubnetInterface neutronSubnetInterface = new NeutronSubnetInterface(providerContext);
286         ServiceRegistration<INeutronSubnetCRUD> neutronSubnetInterfaceRegistration = context.registerService(INeutronSubnetCRUD.class, neutronSubnetInterface, null);
287         if(neutronSubnetInterfaceRegistration != null) {
288             registrations.add(neutronSubnetInterfaceRegistration);
289         }
290     }
291 }