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