Merge "Enhance host config to add multiple configs per host"
[netvirt.git] / vpnservice / neutronvpn / neutronvpn-impl / src / main / java / org / opendaylight / netvirt / 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.netvirt.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.l3.rev150712.routers.attributes.Routers;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.Router;
25 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.RouterKey;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.Networks;
27 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.Network;
28 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.networks.rev150712.networks.attributes.networks.NetworkKey;
29 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.port.attributes.FixedIps;
30 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.Ports;
31 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.Port;
32 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.ports.rev150712.ports.attributes.ports.PortKey;
33 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.rev150712.Neutron;
34 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.Subnets;
35 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.Subnet;
36 import org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.subnets.rev150712.subnets.attributes.subnets.SubnetKey;
37 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.LockManagerService;
38 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TimeUnits;
39 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInput;
40 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.TryLockInputBuilder;
41 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInput;
42 import org.opendaylight.yang.gen.v1.urn.opendaylight.genius.lockmanager.rev160413.UnlockInputBuilder;
43 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NetworkMaps;
44 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.NeutronPortData;
45 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.Subnetmaps;
46 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.VpnMaps;
47 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMap;
48 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.networkmaps.NetworkMapKey;
49 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.port.data
50         .PortFixedipToPortName;
51 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.neutron.port.data
52         .PortFixedipToPortNameKey;
53 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.Subnetmap;
54 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.subnetmaps.SubnetmapKey;
55 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMap;
56 import org.opendaylight.yang.gen.v1.urn.opendaylight.netvirt.neutronvpn.rev150602.vpnmaps.VpnMapKey;
57 import org.opendaylight.yangtools.yang.binding.DataObject;
58 import org.opendaylight.yangtools.yang.binding.InstanceIdentifier;
59 import org.opendaylight.yangtools.yang.common.RpcResult;
60 import org.slf4j.Logger;
61 import org.slf4j.LoggerFactory;
62
63 import java.util.ArrayList;
64 import java.util.List;
65 import java.util.concurrent.ExecutionException;
66 import java.util.concurrent.Future;
67
68 public class NeutronvpnUtils {
69
70     private static final Logger logger = LoggerFactory.getLogger(NeutronvpnUtils.class);
71     public static final String DEVICE_OWNER_ROUTER_INF = "network:router_interface";
72     public static final String VNIC_TYPE_NORMAL = "normal";
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() && optionalVpnMaps.get().getVpnMap() != null) {
99             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
100             for (VpnMap vpnMap : allMaps) {
101                 List<Uuid> netIds = vpnMap.getNetworkIds();
102                 if ((netIds != null) && (netIds.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() && optionalVpnMaps.get().getVpnMap() != null) {
116             List<VpnMap> allMaps = optionalVpnMaps.get().getVpnMap();
117             if (routerId != null) {
118                 for (VpnMap vpnMap : allMaps) {
119                     if (routerId.equals(vpnMap.getRouterId())) {
120                         if (externalVpn) {
121                             if (!routerId.equals(vpnMap.getVpnId())) {
122                                 return vpnMap.getVpnId();
123                             }
124                         } else {
125                             if (routerId.equals(vpnMap.getVpnId())) {
126                                 return vpnMap.getVpnId();
127                             }
128                         }
129                     }
130                 }
131             }
132         }
133         return null;
134     }
135
136     protected static Uuid getRouterforVpn(DataBroker broker, Uuid vpnId) {
137         InstanceIdentifier<VpnMap> vpnMapIdentifier = InstanceIdentifier.builder(VpnMaps.class)
138                 .child(VpnMap.class, new VpnMapKey(vpnId)).build();
139         Optional<VpnMap> optionalVpnMap = read(broker, LogicalDatastoreType.CONFIGURATION, vpnMapIdentifier);
140         if (optionalVpnMap.isPresent()) {
141             VpnMap vpnMap = optionalVpnMap.get();
142             return vpnMap.getRouterId();
143         }
144         return null;
145     }
146
147     protected static String getNeutronPortNamefromPortFixedIp(DataBroker broker, String fixedIp) {
148         InstanceIdentifier id = buildFixedIpToPortNameIdentifier(fixedIp);
149         Optional<PortFixedipToPortName> portFixedipToPortNameData = read(broker, LogicalDatastoreType.CONFIGURATION,
150                 id);
151         if (portFixedipToPortNameData.isPresent()) {
152             return portFixedipToPortNameData.get().getPortName();
153         }
154         return null;
155     }
156
157     protected static List<Uuid> getSubnetIdsFromNetworkId(DataBroker broker, Uuid networkId) {
158         InstanceIdentifier id = buildNetworkMapIdentifier(networkId);
159         Optional<NetworkMap> optionalNetworkMap = read(broker, LogicalDatastoreType.CONFIGURATION, id);
160         if (optionalNetworkMap.isPresent()) {
161             return optionalNetworkMap.get().getSubnetIdList();
162         }
163         return null;
164     }
165
166     protected static Router getNeutronRouter(DataBroker broker, Uuid routerId) {
167
168         InstanceIdentifier<Router> inst = InstanceIdentifier.create(Neutron.class).child(Routers.class).child(Router
169                 .class, new RouterKey(routerId));
170         Optional<Router> rtr = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
171         if (rtr.isPresent()) {
172             return rtr.get();
173         }
174         return null;
175     }
176
177     protected static Network getNeutronNetwork(DataBroker broker, Uuid networkId) {
178         logger.debug("getNeutronNetwork for {}", networkId.getValue());
179         InstanceIdentifier<Network> inst = InstanceIdentifier.create(Neutron.class).child(Networks.class).child
180                 (Network.class, new NetworkKey(networkId));
181         Optional<Network> net = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
182         if (net.isPresent()) {
183             return net.get();
184         }
185         return null;
186     }
187
188     protected static List<Uuid> getNeutronRouterSubnetIds(DataBroker broker, Uuid routerId) {
189         logger.info("getNeutronRouterSubnetIds for {}", routerId.getValue());
190
191         List<Uuid> subnetIdList = new ArrayList<Uuid>();
192         Ports ports = getNeutrounPorts(broker);
193         if(ports != null && ports.getPort() != null) {
194             for (Port port: ports.getPort()) {
195                 if ((port.getDeviceOwner() != null) && (port.getDeviceId() != null)) {
196                     if (port.getDeviceOwner().equals(DEVICE_OWNER_ROUTER_INF) &&
197                             port.getDeviceId().equals(routerId.getValue())) {
198                         for (FixedIps portIp: port.getFixedIps()) {
199                             subnetIdList.add(portIp.getSubnetId());
200                         }
201                     }
202                 }
203             }
204         }
205         /*Router router = getNeutronRouter(broker, routerId);
206         if (router != null) {
207             List<org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers.router
208                     .Interfaces> interfacesList = router.getInterfaces();
209             if (interfacesList != null) {
210                 for (org.opendaylight.yang.gen.v1.urn.opendaylight.neutron.l3.rev150712.routers.attributes.routers
211                         .router.Interfaces interfaces : interfacesList) {
212                     subnetIdList.add(interfaces.getSubnetId());
213                 }
214             }
215         }*/
216         logger.info("returning from getNeutronRouterSubnetIds for {}", routerId.getValue());
217         return subnetIdList;
218     }
219
220     protected static Ports getNeutrounPorts(DataBroker broker) {
221         InstanceIdentifier<Ports> inst = InstanceIdentifier.create(Neutron.class).child(Ports.class);
222         Optional<Ports> ports = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
223         if(ports.isPresent()) {
224             return ports.get();
225         }
226         return null;
227     }
228
229     protected static Port getNeutronPort(DataBroker broker, Uuid portId) {
230         logger.debug("getNeutronPort for {}", portId.getValue());
231         InstanceIdentifier<Port> inst = InstanceIdentifier.create(Neutron.class).child(Ports.class).child(Port.class,
232                 new PortKey(portId));
233         Optional<Port> port = read(broker, LogicalDatastoreType.CONFIGURATION, inst);
234         if (port.isPresent()) {
235             return port.get();
236         }
237         return null;
238     }
239
240     protected static String uuidToTapPortName(Uuid id) {
241         String tapId = id.getValue().substring(0, 11);
242         return new StringBuilder().append("tap").append(tapId).toString();
243     }
244
245     protected static boolean lock(LockManagerService lockManager, String lockName) {
246         TryLockInput input = new TryLockInputBuilder().setLockName(lockName).setTime(5L).setTimeUnit
247                 (TimeUnits.Milliseconds).build();
248         boolean islockAcquired = false;
249         try {
250             Future<RpcResult<Void>> result = lockManager.tryLock(input);
251             if ((result != null) && (result.get().isSuccessful())) {
252                 logger.debug("Acquired lock for {}", lockName);
253                 islockAcquired = true;
254             } else {
255                 logger.error("Unable to acquire lock for  {}", lockName);
256             }
257         } catch (InterruptedException | ExecutionException e) {
258             logger.error("Unable to acquire lock for  {}", lockName);
259             throw new RuntimeException(String.format("Unable to acquire lock for %s", lockName), e.getCause());
260         }
261         return islockAcquired;
262     }
263
264     protected static boolean unlock(LockManagerService lockManager, String lockName) {
265         UnlockInput input = new UnlockInputBuilder().setLockName(lockName).build();
266         boolean islockAcquired = false;
267         try {
268             Future<RpcResult<Void>> result = lockManager.unlock(input);
269             if ((result != null) && (result.get().isSuccessful())) {
270                 logger.debug("Unlocked {}", lockName);
271                 islockAcquired = true;
272             } else {
273                 logger.error("Unable to unlock {}", lockName);
274             }
275         } catch (InterruptedException | ExecutionException e) {
276             logger.error("Unable to unlock {}", lockName);
277             throw new RuntimeException(String.format("Unable to unlock %s", lockName), e.getCause());
278         }
279         return islockAcquired;
280     }
281
282     protected static Short getIPPrefixFromPort(DataBroker broker, Port port) {
283         Short prefix = new Short((short) 0);
284         String cidr = "";
285         try {
286             Uuid subnetUUID = port.getFixedIps().get(0).getSubnetId();
287
288             SubnetKey subnetkey = new SubnetKey(subnetUUID);
289             InstanceIdentifier<Subnet> subnetidentifier = InstanceIdentifier.create(Neutron.class).child(Subnets
290                     .class).child(Subnet.class, subnetkey);
291             Optional<Subnet> subnet = read(broker, LogicalDatastoreType.CONFIGURATION,subnetidentifier);
292             if (subnet.isPresent()) {
293                 cidr = subnet.get().getCidr();
294                 // Extract the prefix length from cidr
295                 String[] parts = cidr.split("/");
296                 if ((parts.length == 2)) {
297                     prefix = Short.valueOf(parts[1]);
298                     return prefix;
299                 } else {
300                     logger.trace("Could not retrieve prefix from subnet CIDR");
301                     System.out.println("Could not retrieve prefix from subnet CIDR");
302                 }
303             } else {
304                 logger.trace("Unable to read on subnet datastore");
305             }
306         } catch (Exception e) {
307             logger.error("Failed to retrieve IP prefix from port : ", e);
308             System.out.println("Failed to retrieve IP prefix from port : " + e.getMessage());
309         }
310         return null;
311     }
312
313     static InstanceIdentifier<PortFixedipToPortName> buildFixedIpToPortNameIdentifier(String fixedIp) {
314         InstanceIdentifier<PortFixedipToPortName> id = InstanceIdentifier.builder(NeutronPortData.class).child
315                 (PortFixedipToPortName.class, new PortFixedipToPortNameKey(fixedIp)).build();
316         return id;
317     }
318
319     static InstanceIdentifier<NetworkMap> buildNetworkMapIdentifier(Uuid networkId) {
320         InstanceIdentifier<NetworkMap> id = InstanceIdentifier.builder(NetworkMaps.class).child(NetworkMap.class, new
321                 NetworkMapKey(networkId)).build();
322         return id;
323     }
324
325     static InstanceIdentifier<VpnInterface> buildVpnInterfaceIdentifier(String ifName) {
326         InstanceIdentifier<VpnInterface> id = InstanceIdentifier.builder(VpnInterfaces.class).
327                 child(VpnInterface.class, new VpnInterfaceKey(ifName)).build();
328         return id;
329     }
330
331     static InstanceIdentifier<Subnetmap> buildSubnetMapIdentifier(Uuid subnetId) {
332         InstanceIdentifier<Subnetmap> id = InstanceIdentifier.builder(Subnetmaps.class).child(Subnetmap.class, new
333                 SubnetmapKey(subnetId)).build();
334         return id;
335     }
336
337     static InstanceIdentifier<Interface> buildVlanInterfaceIdentifier(String interfaceName) {
338         InstanceIdentifier<Interface> id = InstanceIdentifier.builder(Interfaces.class).child(Interface.class, new
339                 InterfaceKey(interfaceName)).build();
340         return id;
341     }
342
343     static <T extends DataObject> Optional<T> read(DataBroker broker, LogicalDatastoreType datastoreType,
344                                                    InstanceIdentifier<T> path) {
345
346         ReadOnlyTransaction tx = broker.newReadOnlyTransaction();
347
348         Optional<T> result = Optional.absent();
349         try {
350             result = tx.read(datastoreType, path).get();
351         } catch (Exception e) {
352             throw new RuntimeException(e);
353         }
354
355         return result;
356     }
357 }