Migrate net-virt from adsal Node to mdsal Node
[netvirt.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / impl / TenantNetworkManagerImpl.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc. and others...
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  * Authors : Madhu Venugopal, Brent Salisbury, Dave Tucker
9  */
10 package org.opendaylight.ovsdb.openstack.netvirt.impl;
11
12 import org.opendaylight.neutron.spi.INeutronNetworkCRUD;
13 import org.opendaylight.neutron.spi.INeutronPortCRUD;
14 import org.opendaylight.neutron.spi.NeutronNetwork;
15 import org.opendaylight.neutron.spi.NeutronPort;
16 import org.opendaylight.ovsdb.lib.notation.OvsdbSet;
17 import org.opendaylight.ovsdb.lib.notation.Row;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.Constants;
19 import org.opendaylight.ovsdb.openstack.netvirt.api.NetworkingProviderManager;
20 import org.opendaylight.ovsdb.openstack.netvirt.api.TenantNetworkManager;
21 import org.opendaylight.ovsdb.openstack.netvirt.api.VlanConfigurationCache;
22 import org.opendaylight.ovsdb.plugin.api.OvsdbConfigurationService;
23 import org.opendaylight.ovsdb.plugin.api.OvsdbConnectionService;
24 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
25 import org.opendaylight.ovsdb.schema.openvswitch.Port;
26 import org.opendaylight.yang.gen.v1.urn.opendaylight.inventory.rev130819.nodes.Node;
27
28 import com.google.common.base.Preconditions;
29 import org.slf4j.Logger;
30 import org.slf4j.LoggerFactory;
31
32 import java.util.List;
33 import java.util.Map;
34
35 public class TenantNetworkManagerImpl implements TenantNetworkManager {
36     static final Logger logger = LoggerFactory.getLogger(TenantNetworkManagerImpl.class);
37
38     // The implementation for each of these services is resolved by the OSGi Service Manager
39     private volatile NetworkingProviderManager networkingProviderManager;
40     private volatile OvsdbConfigurationService ovsdbConfigurationService;
41     private volatile OvsdbConnectionService connectionService;
42     private volatile INeutronNetworkCRUD neutronNetworkCache;
43     private volatile INeutronPortCRUD neutronPortCache;
44     private volatile VlanConfigurationCache vlanConfigurationCache;
45
46     public TenantNetworkManagerImpl() {
47     }
48
49     @Override
50     public int getInternalVlan(Node node, String networkId) {
51         Integer vlan = vlanConfigurationCache.getInternalVlan(node, networkId);
52         if (vlan == null) return 0;
53         return vlan;
54     }
55
56     @Override
57     public void reclaimInternalVlan(Node node, String portUUID, NeutronNetwork network) {
58         int vlan = vlanConfigurationCache.reclaimInternalVlan(node, network.getID());
59         if (vlan <= 0) {
60             logger.debug("Unable to get an internalVlan for Network {}", network);
61             return;
62         }
63         logger.debug("Removed Vlan {} on {}", vlan, portUUID);
64     }
65
66     @Override
67     public void programInternalVlan(Node node, String portUUID, NeutronNetwork network) {
68         Preconditions.checkNotNull(ovsdbConfigurationService);
69
70         int vlan = vlanConfigurationCache.getInternalVlan(node, network.getID());
71         logger.debug("Programming Vlan {} on {}", vlan, portUUID);
72         if (vlan <= 0) {
73             logger.debug("Unable to get an internalVlan for Network {}", network);
74             return;
75         }
76
77         Port port = ovsdbConfigurationService.createTypedRow(node, Port.class);
78         OvsdbSet<Long> tags = new OvsdbSet<>();
79         tags.add((long) vlan);
80         port.setTag(tags);
81         ovsdbConfigurationService.updateRow(node, port.getSchema().getName(), null, portUUID, port.getRow());
82     }
83
84     @Override
85     public boolean isTenantNetworkPresentInNode(Node node, String segmentationId) {
86         Preconditions.checkNotNull(ovsdbConfigurationService);
87
88         String networkId = this.getNetworkId(segmentationId);
89         if (networkId == null) {
90             logger.debug("Tenant Network not found with Segmenation-id {}",segmentationId);
91             return false;
92         }
93         if (networkingProviderManager.getProvider(node).hasPerTenantTunneling()) {
94             int internalVlan = vlanConfigurationCache.getInternalVlan(node, networkId);
95             if (internalVlan == 0) {
96                 logger.debug("No InternalVlan provisioned for Tenant Network {}",networkId);
97                 return false;
98             }
99         }
100
101         try {
102             /*
103             // Vlan Tag based identification
104             Map<String, Row> portTable = ovsdbConfigService.getRows(node, Port.NAME.getName());
105             if (portTable == null) {
106                 logger.debug("Port table is null for Node {} ", node);
107                 return false;
108             }
109
110             for (Row row : portTable.values()) {
111                 Port port = (Port)row;
112                 Set<BigInteger> tags = port.getTag();
113                 if (tags.contains(internalVlan)) {
114                     logger.debug("Tenant Network {} with Segmenation-id {} is present in Node {} / Port {}",
115                                   networkId, segmentationId, node, port);
116                     return true;
117                 }
118             }
119              */
120             // External-id based more accurate VM Location identification
121             Map<String, Row> ifTable = ovsdbConfigurationService.getRows(node, ovsdbConfigurationService.getTableName(node, Interface.class));
122             if (ifTable == null) {
123                 logger.debug("Interface table is null for Node {} ", node);
124                 return false;
125             }
126
127             for (Row row : ifTable.values()) {
128                 Interface intf = ovsdbConfigurationService.getTypedRow(node, Interface.class, row);
129                 Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
130                 if (externalIds != null && externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID) != null) {
131                     if (this.isInterfacePresentInTenantNetwork(externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID), networkId)) {
132                         logger.debug("Tenant Network {} with Segmentation-id {} is present in Node {} / Interface {}",
133                                       networkId, segmentationId, node, intf);
134                         return true;
135                     }
136                 }
137             }
138
139         } catch (Exception e) {
140             logger.error("Error while trying to determine if network is present on node", e);
141             return false;
142         }
143
144         logger.debug("Tenant Network {} with Segmenation-id {} is NOT present in Node {}",
145                 networkId, segmentationId, node);
146
147         return false;
148     }
149
150     @Override
151     public String getNetworkId(String segmentationId) {
152         List <NeutronNetwork> networks = neutronNetworkCache.getAllNetworks();
153         for (NeutronNetwork network : networks) {
154             if (network.getProviderSegmentationID().equalsIgnoreCase(segmentationId)) return network.getNetworkUUID();
155         }
156         return null;
157     }
158
159     @Override
160     public NeutronNetwork getTenantNetwork(Interface intf) {
161         logger.trace("getTenantNetwork for {}", intf);
162         if (intf == null) return null;
163         Map<String, String> externalIds = intf.getExternalIdsColumn().getData();
164         logger.trace("externalIds {}", externalIds);
165         if (externalIds == null) return null;
166         String neutronPortId = externalIds.get(Constants.EXTERNAL_ID_INTERFACE_ID);
167         if (neutronPortId == null) return null;
168         NeutronPort neutronPort = neutronPortCache.getPort(neutronPortId);
169         logger.trace("neutronPort {}", neutronPort);
170         if (neutronPort == null) return null;
171         NeutronNetwork neutronNetwork = neutronNetworkCache.getNetwork(neutronPort.getNetworkUUID());
172         logger.debug("{} mapped to {}", intf, neutronNetwork);
173         return neutronNetwork;
174     }
175
176     @Override
177     public void networkCreated (String networkId) {
178         List<Node> nodes = connectionService.getNodes();
179
180         for (Node node : nodes) {
181             this.networkCreated(node, networkId);
182         }
183
184     }
185
186     @Override
187     public int networkCreated (Node node, String networkId) {
188         return vlanConfigurationCache.assignInternalVlan(node, networkId);
189     }
190
191     @Override
192     public void networkDeleted(String id) {
193         //ToDo: Delete? This method does nothing how we dropped container support...
194     }
195
196     private boolean isInterfacePresentInTenantNetwork (String portId, String networkId) {
197         NeutronPort neutronPort = neutronPortCache.getPort(portId);
198         return neutronPort != null && neutronPort.getNetworkUUID().equalsIgnoreCase(networkId);
199     }
200
201 }