3acc5ce43b90c8ca480945b7110a2f34266a497d
[vpnservice.git] / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / vpnservice / neutronvpn / NeutronvpnUtils.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. 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.vpnservice.neutronvpn;
10
11 import com.google.common.base.Optional;
12
13 import org.opendaylight.controller.md.sal.binding.api.DataBroker;
14 import org.opendaylight.controller.md.sal.binding.api.ReadOnlyTransaction;
15 import org.opendaylight.controller.md.sal.common.api.data.LogicalDatastoreType;
16 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.VpnInterfaces;
17 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterface;
18 import org.opendaylight.yang.gen.v1.urn.huawei.params.xml.ns.yang.l3vpn.rev140815.vpn.interfaces.VpnInterfaceKey;
19 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.Interfaces;
20 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.Interface;
21 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.interfaces.rev140508.interfaces.InterfaceKey;
22 import org.opendaylight.yang.gen.v1.urn.ietf.params.xml.ns.yang.ietf.yang.types.rev130715.Uuid;
23 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.binding.rev150712.PortBindingExtension;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.Routers;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeBase;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.NetworkTypeVxlan;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.NetworkProviderExtension;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.provider.ext.rev150712.neutron.networks.network.Segments;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.LockManagerService;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TimeUnits;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInput;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.TryLockInputBuilder;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInput;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.lockmanager.rev150819.UnlockInputBuilder;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NetworkMaps;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.NeutronPortData;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.Subnetmaps;
50 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.VpnMaps;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMap;
52 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.networkmaps.NetworkMapKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
54         .PortFixedipToPortName;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.neutron.port.data
56         .PortFixedipToPortNameKey;
57 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.Subnetmap;
58 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
59 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMap;
60 import org.opendaylight.yang.gen.v1.urn.opendaylight.vpnservice.neutronvpn.rev150602.vpnmaps.VpnMapKey;
61 import org.opendaylight.yangtools.yang.binding.DataObject;
62 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
63 import org.opendaylight.yangtools.yang.common.RpcResult;
64 import org.slf4j.Logger;
65 import org.slf4j.LoggerFactory;
66
67 import java.util.ArrayList;
68 import java.util.List;
69 import java.util.concurrent.ExecutionException;
70 import java.util.concurrent.Future;
71
72 public class NeutronvpnUtils {
73
74     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnUtils.class);
75     public static final String VNIC_TYPE_NORMAL = "normal";
76
77     protected static Subnetmap getSubnetmap(DataBroker broker, Uuid subnetId) {
78         InstanceIdentifier id = buildSubnetMapIdentifier(subnetId);
79         Optional<Subnetmap> sn = read(broker, LogicalDatastoreType.CONFIGURATION, id);
80
81         if (sn.isPresent()) {
82             return sn.get();
83         }
84         return null;
85     }
86
87     protected static VpnMap getVpnMap(DataBroker broker, Uuid id) {
88         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class).child(VpnMap.class,
89                 new VpnMapKey(id)).build();
90         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
91         if (optionalVpnMap.isPresent()) {
92             return optionalVpnMap.get();
93         }
94         logger.error("getVpnMap failed, VPN {} not present", id.getValue());
95         return null;
96     }
97
98     protected static Uuid getVpnForNetwork(DataBroker broker, Uuid network) {
99         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
100         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapsIdentifier);
101         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
102             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
103             for (VpnMap vpnMap : allMaps) {
104                 List<Uuid> netIds = vpnMap.getNetworkIds();
105                 if ((netIds != null) && (netIds.contains(network))) {
106                     return vpnMap.getVpnId();
107                 }
108             }
109         }
110         return null;
111     }
112
113     // true for external vpn, false for internal vpn
114     protected static Uuid getVpnForRouter(DataBroker broker, Uuid routerId, Boolean externalVpn) {
115         InstanceIdentifier<VpnMaps> vpnMapsIdentifier = InstanceIdentifier.builder(VpnMaps.class).build();
116         Optional<VpnMaps> optionalVpnMaps = read(broker, LogicalDatastoreType.CONFIGURATION,
117                 vpnMapsIdentifier);
118         if (optionalVpnMaps.isPresent() && optionalVpnMaps.get().getVpnMap() != null) {
119             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
120             if (routerId != null) {
121                 for (VpnMap vpnMap : allMaps) {
122                     if (routerId.equals(vpnMap.getRouterId())) {
123                         if (externalVpn == true) {
124                             if (!routerId.equals(vpnMap.getVpnId())) {
125                                 return vpnMap.getVpnId();
126                             }
127                         } else {
128                             if (routerId.equals(vpnMap.getVpnId())) {
129                                 return vpnMap.getVpnId();
130                             }
131                         }
132                     }
133                 }
134             }
135         }
136         return null;
137     }
138
139     protected static Uuid getRouterforVpn(DataBroker broker, Uuid vpnId) {
140         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
141                 .child(VpnMap.class, new VpnMapKey(vpnId)).build();
142         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
143         if (optionalVpnMap.isPresent()) {
144             VpnMap vpnMap = optionalVpnMap.get();
145             return vpnMap.getRouterId();
146         }
147         return null;
148     }
149
150     protected static String getNeutronPortNamefromPortFixedIp(DataBroker broker, String fixedIp) {
151         InstanceIdentifier id = buildFixedIpToPortNameIdentifier(fixedIp);
152         Optional<PortFixedipToPortName> portFixedipToPortNameData = read(broker, LogicalDatastoreType.CONFIGURATION,
153                 id);
154         if (portFixedipToPortNameData.isPresent()) {
155             return portFixedipToPortNameData.get().getPortName();
156         }
157         return null;
158     }
159
160     protected static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
161         InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
162         Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
163         if (optionalNetworkMap.isPresent()) {
164             return optionalNetworkMap.get().getSubnetIdList();
165         }
166         return null;
167     }
168
169     protected static Router getNeutronRouter(DataBroker broker, Uuid routerId) {
170
171         InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
172                 .class, new RouterKey(routerId));
173         Optional<Router> rtr = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
174         if (rtr.isPresent()) {
175             return rtr.get();
176         }
177         return null;
178     }
179
180     protected static Network getNeutronNetwork(DataBroker broker, Uuid networkId) {
181         logger.debug("getNeutronNetwork for {}", networkId.getValue());
182         InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class).child
183                 (Network.class, new NetworkKey(networkId));
184         Optional<Network> net = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
185         if (net.isPresent()) {
186             return net.get();
187         }
188         return null;
189     }
190
191     protected static String getSegmentationIdFromNeutronNetwork(Network network) {
192         String segmentationId = null;
193         NetworkProviderExtension providerExtension = network.getAugmentation(NetworkProviderExtension.class);
194         if (providerExtension != null) {
195             segmentationId = providerExtension.getSegmentationId();
196             if (segmentationId == null) {
197                 List<Segments> providerSegments = providerExtension.getSegments();
198                 if (providerSegments != null && providerSegments.size() > 0) {
199                     for (Segments providerSegment: providerSegments) {
200                         if (isNetworkSegmentTypeVxlan(providerSegment)) {
201                             segmentationId = providerSegment.getSegmentationId();
202                             break;
203                         }
204                     }
205                 }
206             }
207         }
208         return segmentationId;
209     }
210
211     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
212         logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
213
214         List<Uuid> subnetIdList = new ArrayList<Uuid>();
215         Router router = getNeutronRouter(broker, routerId);
216         if (router != null) {
217             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
218                     .Interfaces> interfacesList = router.getInterfaces();
219             if (interfacesList != null) {
220                 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
221                         .router.Interfaces interfaces : interfacesList) {
222                     subnetIdList.add(interfaces.getSubnetId());
223                 }
224             }
225         }
226         logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
227         return subnetIdList;
228     }
229
230     protected static Port getNeutronPort(DataBroker broker, Uuid portId) {
231         logger.debug("getNeutronPort for {}", portId.getValue());
232         InstanceIdentifier<Port> inst = InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class,
233                 new PortKey(portId));
234         Optional<Port> port = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
235         if (port.isPresent()) {
236             return port.get();
237         }
238         return null;
239     }
240
241     protected static String uuidToTapPortName(Uuid id) {
242         String tapId = id.getValue().substring(0, 11);
243         return new StringBuilder().append("tap").append(tapId).toString();
244     }
245
246     protected static boolean isPortVnicTypeNormal(Port port) {
247         PortBindingExtension portBinding = port.getAugmentation(PortBindingExtension.class);
248         if(portBinding == null || portBinding.getVnicType() == null) {
249             // By default, VNIC_TYPE is NORMAL
250             return true;
251         }
252         String vnicType = portBinding.getVnicType().trim().toLowerCase();
253         return vnicType.equals(VNIC_TYPE_NORMAL);
254     }
255
256     protected static boolean lock(LockManagerService lockManager, String lockName) {
257         TryLockInput input = new TryLockInputBuilder().setLockName(lockName).setTime(5L).setTimeUnit
258                 (TimeUnits.Milliseconds).build();
259         boolean islockAcquired = false;
260         try {
261             Future<RpcResult<Void>> result = lockManager.tryLock(input);
262             if ((result != null) && (result.get().isSuccessful())) {
263                 logger.debug("Acquired lock for {}", lockName);
264                 islockAcquired = true;
265             } else {
266                 logger.error("Unable to acquire lock for  {}", lockName);
267             }
268         } catch (InterruptedException | ExecutionException e) {
269             logger.error("Unable to acquire lock for  {}", lockName);
270             throw new RuntimeException(String.format("Unable to acquire lock for %s", lockName), e.getCause());
271         }
272         return islockAcquired;
273     }
274
275     protected static boolean unlock(LockManagerService lockManager, String lockName) {
276         UnlockInput input = new UnlockInputBuilder().setLockName(lockName).build();
277         boolean islockAcquired = false;
278         try {
279             Future<RpcResult<Void>> result = lockManager.unlock(input);
280             if ((result != null) && (result.get().isSuccessful())) {
281                 logger.debug("Unlocked {}", lockName);
282                 islockAcquired = true;
283             } else {
284                 logger.error("Unable to unlock {}", lockName);
285             }
286         } catch (InterruptedException | ExecutionException e) {
287             logger.error("Unable to unlock {}", lockName);
288             throw new RuntimeException(String.format("Unable to unlock %s", lockName), e.getCause());
289         }
290         return islockAcquired;
291     }
292
293     protected static Short getIPPrefixFromPort(DataBroker broker, Port port) {
294         Short prefix = new Short((short) 0);
295         String cidr = "";
296         try {
297             Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
298
299             SubnetKey subnetkey = new SubnetKey(subnetUUID);
300             InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
301                     .class).child(Subnet.class, subnetkey);
302             Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier);
303             if (subnet.isPresent()) {
304                 cidr = subnet.get().getCidr();
305                 // Extract the prefix length from cidr
306                 String[] parts = cidr.split("/");
307                 if ((parts.length == 2)) {
308                     prefix = Short.valueOf(parts[1]);
309                     return prefix;
310                 } else {
311                     logger.trace("Could not retrieve prefix from subnet CIDR");
312                     System.out.println("Could not retrieve prefix from subnet CIDR");
313                 }
314             } else {
315                 logger.trace("Unable to read on subnet datastore");
316             }
317         } catch (Exception e) {
318             logger.error("Failed to retrieve IP prefix from port : ", e);
319             System.out.println("Failed to retrieve IP prefix from port : " + e.getMessage());
320         }
321         return null;
322     }
323
324     static InstanceIdentifier<PortFixedipToPortName> buildFixedIpToPortNameIdentifier(String fixedIp) {
325         InstanceIdentifier<PortFixedipToPortName> id = InstanceIdentifier.builder(NeutronPortData.class).child
326                 (PortFixedipToPortName.class, new PortFixedipToPortNameKey(fixedIp)).build();
327         return id;
328     }
329
330     static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
331         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
332                 NetworkMapKey(networkId)).build();
333         return id;
334     }
335
336     static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
337         InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).
338                 child(VpnInterface.class, new VpnInterfaceKey(ifName)).build();
339         return id;
340     }
341
342     static InstanceIdentifier<Subnetmap> buildSubnetMapIdentifier(Uuid subnetId) {
343         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
344                 SubnetmapKey(subnetId)).build();
345         return id;
346     }
347
348     static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
349         InstanceIdentifier<Interface> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new
350                 InterfaceKey(interfaceName)).build();
351         return id;
352     }
353
354     static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
355                                                    InstanceIdentifier<T> path) {
356
357         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
358
359         Optional<T> result = Optional.absent();
360         try {
361             result = tx.read(datastoreType, path).get();
362         } catch (Exception e) {
363             throw new RuntimeException(e);
364         }
365
366         return result;
367     }
368
369     static boolean isNetworkSegmentTypeVxlan(Segments providerSegment) {
370         Class<? extends NetworkTypeBase> networkType = providerSegment.getNetworkType();
371         return (networkType != null && networkType.isAssignableFrom(NetworkTypeVxlan.class));
372     }
373 }