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