Remove OvsdbConfigurationService
[ovsdb.git] / openstack / net-virt / src / main / java / org / opendaylight / ovsdb / openstack / netvirt / impl / BridgeConfigurationManagerImpl.java
1 /*
2  * Copyright (C) 2013 Red Hat, Inc.
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, Sam Hague
9  */
10 package org.opendaylight.ovsdb.openstack.netvirt.impl;
11
12 import java.net.InetAddress;
13 import java.net.UnknownHostException;
14 import org.opendaylight.neutron.spi.NeutronNetwork;
15 import org.opendaylight.ovsdb.lib.notation.Row;
16 import org.opendaylight.ovsdb.lib.notation.UUID;
17 import org.opendaylight.ovsdb.openstack.netvirt.NetworkHandler;
18 import org.opendaylight.ovsdb.openstack.netvirt.api.*;
19 import org.opendaylight.ovsdb.schema.openvswitch.Bridge;
20 import org.opendaylight.ovsdb.schema.openvswitch.Interface;
21 import org.opendaylight.ovsdb.schema.openvswitch.OpenVSwitch;
22 import org.opendaylight.ovsdb.schema.openvswitch.Port;
23 import org.opendaylight.ovsdb.utils.config.ConfigProperties;
24 import org.opendaylight.yang.gen.v1.urn.opendaylight.params.xml.ns.yang.ovsdb.rev150105.OvsdbBridgeAugmentation;
25 import org.opendaylight.yang.gen.v1.urn.tbd.params.xml.ns.yang.network.topology.rev131021.network.topology.topology.Node;
26
27 import com.google.common.base.Preconditions;
28 import com.google.common.collect.Lists;
29 import com.google.common.collect.Maps;
30 import org.apache.commons.lang3.tuple.ImmutablePair;
31 import org.slf4j.Logger;
32 import org.slf4j.LoggerFactory;
33
34 import java.util.List;
35 import java.util.Map;
36 import java.util.Set;
37
38 public class BridgeConfigurationManagerImpl implements BridgeConfigurationManager {
39     static final Logger LOGGER = LoggerFactory.getLogger(BridgeConfigurationManagerImpl.class);
40
41     // The implementation for each of these services is resolved by the OSGi Service Manager
42     private volatile ConfigurationService configurationService;
43     private volatile NetworkingProviderManager networkingProviderManager;
44
45     void init() {
46         LOGGER.info(">>>>>> init {}", this.getClass());
47     }
48
49     @Override
50     public String getBridgeUuid(Node node, String bridgeName) {
51         return MdsalUtils.getBridgeUuid(node, bridgeName).toString();
52     }
53
54     @Override
55     public boolean isNodeNeutronReady(Node node) {
56         Preconditions.checkNotNull(configurationService);
57         return MdsalUtils.getBridge(node, configurationService.getIntegrationBridgeName()) != null;
58     }
59
60     @Override
61     public boolean isNodeOverlayReady(Node node) {
62         Preconditions.checkNotNull(configurationService);
63         return isNodeNeutronReady(node)
64                 && MdsalUtils.getBridge(node, configurationService.getNetworkBridgeName()) != null;
65     }
66
67     @Override
68     public boolean isPortOnBridge (Node node, Bridge bridge, String portName) {
69         return MdsalUtils.getPort(node, portName) != null;
70     }
71
72     @Override
73     public boolean isNodeTunnelReady(Node node) {
74         Preconditions.checkNotNull(configurationService);
75         return MdsalUtils.getBridge(node, configurationService.getIntegrationBridgeName()) != null;
76     }
77
78     @Override
79     public boolean isNodeVlanReady(Node node, NeutronNetwork network) {
80         Preconditions.checkNotNull(networkingProviderManager);
81
82         /* is br-int created */
83         OvsdbBridgeAugmentation intBridge = MdsalUtils.getBridge(node, configurationService.getIntegrationBridgeName());
84         if (intBridge == null) {
85             LOGGER.trace("isNodeVlanReady: node: {}, br-int missing", node);
86             return false;
87         }
88
89         /* Check if physical device is added to br-int. */
90         String phyNetName = this.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
91         if (MdsalUtils.getPort(node, phyNetName) == null) {
92             LOGGER.trace("isNodeVlanReady: node: {}, eth missing", node);
93             return false;
94         }
95
96         return true;
97     }
98
99     @Override
100     public void prepareNode(Node node) {
101         Preconditions.checkNotNull(networkingProviderManager);
102
103         try {
104             createIntegrationBridge(node);
105         } catch (Exception e) {
106             LOGGER.error("Error creating Integration Bridge on {}", node, e);
107             return;
108         }
109         networkingProviderManager.getProvider(node).initializeFlowRules(node);
110     }
111
112     /**
113      * Check if the full network setup is available. If not, create it.
114      */
115     @Override
116     public boolean createLocalNetwork (Node node, NeutronNetwork network) {
117         boolean isCreated = false;
118         if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
119             if (!isNodeVlanReady(node, network)) {
120                 try {
121                     isCreated = createBridges(node, network);
122                 } catch (Exception e) {
123                     LOGGER.error("Error creating internal net network " + node, e);
124                 }
125             } else {
126                 isCreated = true;
127             }
128         } else if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VXLAN) ||
129                    network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_GRE)) {
130             if (!isNodeTunnelReady(node)) {
131                 try {
132                     isCreated = createBridges(node, network);
133                 } catch (Exception e) {
134                     LOGGER.error("Error creating internal net network " + node, e);
135                 }
136             } else {
137                 isCreated = true;
138             }
139         }
140         return isCreated;
141     }
142
143     @Override
144     public String getPhysicalInterfaceName (Node node, String physicalNetwork) {
145         String phyIf = null;
146         String providerMaps = MdsalUtils.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
147                 configurationService.getProviderMappingsKey());
148         if (providerMaps == null) {
149             providerMaps = configurationService.getDefaultProviderMapping();
150         }
151
152         if (providerMaps != null) {
153             for (String map : providerMaps.split(",")) {
154                 String[] pair = map.split(":");
155                 if (pair[0].equals(physicalNetwork)) {
156                     phyIf = pair[1];
157                     break;
158                 }
159             }
160         }
161
162         if (phyIf == null) {
163             LOGGER.error("Physical interface not found for Node: {}, Network {}",
164                          node, physicalNetwork);
165         }
166
167         return phyIf;
168     }
169
170     @Override
171     public List<String> getAllPhysicalInterfaceNames(Node node) {
172         List<String> phyIfName = Lists.newArrayList();
173         String phyIf = null;
174         String providerMaps = MdsalUtils.getOtherConfig(node, OvsdbTables.OPENVSWITCH,
175                 configurationService.getProviderMappingsKey());
176         if (providerMaps == null) {
177             providerMaps = configurationService.getDefaultProviderMapping();
178         }
179
180         if (providerMaps != null) {
181             for (String map : providerMaps.split(",")) {
182                 String[] pair = map.split(":");
183                 phyIfName.add(pair[1]);
184             }
185         }
186
187         return phyIfName;
188     }
189
190     /**
191      * Returns true if a patch port exists between the Integration Bridge and Network Bridge
192      */
193     private boolean isNetworkPatchCreated(Node node, Bridge intBridge, Bridge netBridge) {
194         Preconditions.checkNotNull(configurationService);
195
196         boolean isPatchCreated = false;
197
198         String portName = configurationService.getPatchPortName(new ImmutablePair<>(intBridge, netBridge));
199         if (isPortOnBridge(node, intBridge, portName)) {
200             portName = configurationService.getPatchPortName(new ImmutablePair<>(netBridge, intBridge));
201             if (isPortOnBridge(node, netBridge, portName)) {
202                 isPatchCreated = true;
203             }
204         }
205
206         return isPatchCreated;
207     }
208
209     /**
210      * Creates the Integration Bridge
211      */
212     private void createIntegrationBridge(Node node) throws Exception {
213         Preconditions.checkNotNull(configurationService);
214
215         String brIntName = configurationService.getIntegrationBridgeName();
216
217         if (!addBridge(node, brIntName, null, null)) {
218             LOGGER.debug("Integration Bridge Creation failed");
219         }
220     }
221
222     /**
223      * Create and configure bridges for all network types and OpenFlow versions.
224      *
225        OF 1.0 vlan:
226        Bridge br-int
227             Port patch-net
228                 Interface patch-net
229                     type: patch
230                     options: {peer=patch-int}
231             Port br-int
232                 Interface br-int
233                     type: internal
234        Bridge br-net
235             Port "eth1"
236                 Interface "eth1"
237             Port patch-int
238                 Interface patch-int
239                     type: patch
240                     options: {peer=patch-net}
241             Port br-net
242                 Interface br-net
243                     type: internal
244
245        OF 1.0 tunnel:
246        Bridge br-int
247             Port patch-net
248                 Interface patch-net
249                     type: patch
250                     options: {peer=patch-int}
251             Port br-int
252                 Interface br-int
253                     type: internal
254        Bridge "br-net"
255             Port patch-int
256                 Interface patch-int
257                     type: patch
258                     options: {peer=patch-net}
259             Port br-net
260                 Interface br-net
261                     type: internal
262
263        OF 1.3 vlan:
264        Bridge br-int
265             Port "eth1"
266                 Interface "eth1"
267             Port br-int
268                 Interface br-int
269                     type: internal
270
271        OF 1.3 tunnel:
272        Bridge br-int
273             Port br-int
274                 Interface br-int
275                     type: internal
276      */
277     private boolean createBridges(Node node, NeutronNetwork network) throws Exception {
278         Preconditions.checkNotNull(configurationService);
279         Preconditions.checkNotNull(networkingProviderManager);
280         Status status;
281
282         LOGGER.debug("createBridges: node: {}, network type: {}", node, network.getProviderNetworkType());
283
284         String brInt = configurationService.getIntegrationBridgeName();
285         if (!addBridge(node, brInt, null, null)) {
286             LOGGER.debug("{} Bridge creation failed", brInt);
287             return false;
288         }
289
290         /* For vlan network types add physical port to br-int. */
291         if (network.getProviderNetworkType().equalsIgnoreCase(NetworkHandler.NETWORK_TYPE_VLAN)) {
292             String phyNetName = this.getPhysicalInterfaceName(node, network.getProviderPhysicalNetwork());
293             if (!addPortToBridge(node, brInt, phyNetName)) {
294                 LOGGER.debug("Add Port {} to Bridge {} failed", phyNetName, brInt);
295                 return false;
296             }
297         }
298
299         LOGGER.debug("createNetNetwork: node: {}, status: success", node);
300         return true;
301     }
302
303     /**
304      * Add a Port to a Bridge
305      */
306     private boolean addPortToBridge (Node node, String bridgeName, String portName) throws Exception {
307         boolean rv = true;
308
309         if (MdsalUtils.getPort(node, portName) == null) {
310             rv = MdsalUtils.addPort(node, bridgeName, portName);
311         }
312
313         return rv;
314     }
315
316     /**
317      * Add a Patch Port to a Bridge
318      */
319     private boolean addPatchPort (Node node, String bridgeName, String portName, String peerPortName) throws Exception {
320         boolean rv = true;
321
322         if (MdsalUtils.getPort(node, portName) == null) {
323             rv = MdsalUtils.addPatchPort(node, bridgeName, portName, peerPortName);
324         }
325
326         return rv;
327     }
328
329     /**
330      * Add Bridge to a Node
331      */
332     private boolean addBridge(Node node, String bridgeName,
333                               String localPatchName, String remotePatchName) throws Exception {
334         Preconditions.checkNotNull(networkingProviderManager);
335         //sb will also add port and interface if this is a new bridge
336         return MdsalUtils.addBridge(node, bridgeName, getControllerTarget());
337     }
338
339     private InetAddress getControllerIPAddress(/*Connection connection*/) {
340         InetAddress controllerIP = null;
341
342         String addressString = ConfigProperties.getProperty(this.getClass(), "ovsdb.controller.address");
343         if (addressString != null) {
344             try {
345                 controllerIP = InetAddress.getByName(addressString);
346                 if (controllerIP != null) {
347                     return controllerIP;
348                 }
349             } catch (UnknownHostException e) {
350                 LOGGER.error("Host {} is invalid", addressString);
351             }
352         }
353
354         addressString = ConfigProperties.getProperty(this.getClass(), "of.address");
355         if (addressString != null) {
356             try {
357                 controllerIP = InetAddress.getByName(addressString);
358                 if (controllerIP != null) {
359                     return controllerIP;
360                 }
361             } catch (UnknownHostException e) {
362                 LOGGER.error("Host {} is invalid", addressString);
363             }
364         }
365
366         /*
367         try {
368             controllerIP = connection.getClient().getConnectionInfo().getLocalAddress();
369             return controllerIP;
370         } catch (Exception e) {
371             LOGGER.debug("Invalid connection provided to getControllerIPAddresses", e);
372         }
373         */
374
375         if (addressString != null) {
376             try {
377                 controllerIP = InetAddress.getByName(addressString);
378                 if (controllerIP != null) {
379                     return controllerIP;
380                 }
381             } catch (UnknownHostException e) {
382                 LOGGER.error("Host {} is invalid", addressString);
383             }
384         }
385
386         return controllerIP;
387     }
388
389     private short getControllerOFPort() {
390         Short defaultOpenFlowPort = 6633;
391         Short openFlowPort = defaultOpenFlowPort;
392         String portString = ConfigProperties.getProperty(this.getClass(), "of.listenPort");
393         if (portString != null) {
394             try {
395                 openFlowPort = Short.decode(portString).shortValue();
396             } catch (NumberFormatException e) {
397                 LOGGER.warn("Invalid port:{}, use default({})", portString,
398                         openFlowPort);
399             }
400         }
401         return openFlowPort;
402     }
403
404     private String getControllerTarget() {
405         /* TODO SB_MIGRATION
406          * hardcoding value, need to find better way to get local ip
407          */
408         //String target = "tcp:" + getControllerIPAddress() + ":" + getControllerOFPort();
409         String target = "tcp:192.168.120.1:6633";
410         return target;
411     }
412 }