]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Enabled Cisco ML2 driver to use new upstream ncclient
authorJuergen Brendel <jbrendel@cisco.com>
Wed, 6 Aug 2014 01:23:52 +0000 (01:23 +0000)
committerJuergen Brendel <jbrendel@cisco.com>
Thu, 7 Aug 2014 01:11:55 +0000 (01:11 +0000)
The code is still able to handle the old, custom ncclient that
we used before. It uses the different function signatures
for the ncclient's connect() function to detect which version
is installed.

Change-Id: I09d81b424d86f4cd35ca048507f06471246b91d8
Closes-Bug: 1352635

neutron/plugins/ml2/drivers/cisco/nexus/nexus_network_driver.py
neutron/tests/unit/ml2/drivers/cisco/nexus/test_cisco_mech.py

index 983678d1122f101849cb35e61bf69c68a83dbdbe..33ba85e980d989ad244c4ab274faddcce7495375 100644 (file)
@@ -65,7 +65,7 @@ class CiscoNexusDriver(object):
             allowed_exc_strs = []
         mgr = self.nxos_connect(nexus_host)
         try:
-            mgr.edit_config(target, config=config)
+            mgr.edit_config(target=target, config=config)
         except Exception as e:
             for exc_str in allowed_exc_strs:
                 if exc_str in str(e):
@@ -86,16 +86,26 @@ class CiscoNexusDriver(object):
         nexus_user = self.nexus_switches[nexus_host, const.USERNAME]
         nexus_password = self.nexus_switches[nexus_host, const.PASSWORD]
         try:
-            man = self.ncclient.connect(host=nexus_host,
-                                        port=nexus_ssh_port,
-                                        username=nexus_user,
-                                        password=nexus_password)
-            self.connections[nexus_host] = man
+            try:
+                # With new ncclient version, we can pass device_params...
+                man = self.ncclient.connect(host=nexus_host,
+                                            port=nexus_ssh_port,
+                                            username=nexus_user,
+                                            password=nexus_password,
+                                            device_params={"name": "nexus"})
+            except TypeError:
+                # ... but if that causes an error, we appear to have the old
+                # ncclient installed, which doesn't understand this parameter.
+                man = self.ncclient.connect(host=nexus_host,
+                                            port=nexus_ssh_port,
+                                            username=nexus_user,
+                                            password=nexus_password)
         except Exception as e:
             # Raise a Neutron exception. Include a description of
             # the original ncclient exception.
             raise cexc.NexusConnectFailed(nexus_host=nexus_host, exc=e)
 
+        self.connections[nexus_host] = man
         return self.connections[nexus_host]
 
     def create_xml_snippet(self, customized_config):
index 5968d2422d7df8453d4915bcec1c8d2ad79d3781..43d6b41adff15c0c51c9af82b01cd5f4e34e556c 100644 (file)
@@ -408,6 +408,45 @@ class TestCiscoPortsV2(CiscoML2MechanismTestCase,
                     self._is_in_last_nexus_cfg(['allowed', 'vlan']))
                 self.assertFalse(self._is_in_last_nexus_cfg(['name']))
 
+    def test_ncclient_version_detect(self):
+        """Test ability to handle connection to old and new-style ncclient.
+
+        We used to require a custom version of the ncclient library. However,
+        recent contributions to the ncclient make this unnecessary. Our
+        driver was modified to be able to establish a connection via both
+        the old and new type of ncclient.
+
+        The new style ncclient.connect() function takes one additional
+        parameter.
+
+        The ML2 driver uses this to detect whether we are dealing with an
+        old or new ncclient installation.
+
+        """
+        # The code we are exercising calls connect() twice, if there is a
+        # TypeError on the first call (if the old ncclient is installed).
+        # The second call should succeed. That's what we are simulating here.
+        connect = self.mock_ncclient.connect
+        with self._patch_ncclient('connect.side_effect',
+                                  [TypeError, connect]):
+            with self._create_resources() as result:
+                self.assertEqual(result.status_int,
+                                 wexc.HTTPOk.code)
+
+    def test_ncclient_fail_on_second_connect(self):
+        """Test that other errors during connect() sequences are still handled.
+
+        If the old ncclient is installed, we expect to get a TypeError first,
+        but should still handle other errors in the usual way, whether they
+        appear on the first or second call to connect().
+
+        """
+        with self._patch_ncclient('connect.side_effect',
+                                  [TypeError, IOError]):
+            with self._create_resources() as result:
+                self._assertExpectedHTTP(result.status_int,
+                                         c_exc.NexusConnectFailed)
+
     def test_nexus_connect_fail(self):
         """Test failure to connect to a Nexus switch.