]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
Cisco nexus sub-plugin update_network fix
authorRohit Agarwalla <roagarwa@cisco.com>
Wed, 29 Aug 2012 08:20:06 +0000 (01:20 -0700)
committerRohit Agarwalla <roagarwa@cisco.com>
Wed, 29 Aug 2012 18:05:46 +0000 (11:05 -0700)
Fixes bug 1043147

Currently, the cisco nexus sub-plugin doesn’t handle the network admin state parameter
when it’s updated. The fix would enable the sub-plugin to handle an update of the admin
state of the network. In update_network of the nexus sub-plugin, vlan corresponding to that network
is added/removed from the nexus interfaces based on the network state. Unit tests are added as well.

Change-Id: Ia3b5400c2896c1b0160968a2c75c21247ca0c3f4

quantum/plugins/cisco/models/network_multi_blade_v2.py
quantum/plugins/cisco/models/virt_phy_sw_v2.py
quantum/plugins/cisco/network_plugin.py
quantum/plugins/cisco/nexus/cisco_nexus_network_driver_v2.py
quantum/plugins/cisco/nexus/cisco_nexus_plugin_v2.py
quantum/plugins/cisco/tests/unit/v2/nexus/fake_nexus_driver.py
quantum/tests/unit/cisco/test_nexus_plugin.py

index b0442deb507385e79d757ab3b3149f11a8dead6f..6a50121c0091c2f62284cedf3d88a655eb9da1b8 100644 (file)
@@ -157,8 +157,19 @@ class NetworkMultiBladeV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
         pass
 
     def update_network(self, context, id, network):
-        """Currently there is no processing required for the device plugins"""
-        pass
+        """
+        Perform this operation in the context of the configured device
+        plugins.
+        """
+        n = network
+        vlan = cdb.get_vlan_binding(id)
+        args = [n['tenant_id'], id, {'vlan_id': vlan.vlan_id},
+                {'net_admin_state': n['admin_state_up']},
+                {'vlan_ids': ''}]
+        nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+                                                      self._func_name(),
+                                                      args)
+        return nexus_output
 
     def delete_network(self, context, id, kwargs):
         """
index 626baeff5899304c3595f69878fb33c320a9a6be..91cdddb4c58949eab04a8e9984519ca14e7937e6 100644 (file)
@@ -45,7 +45,7 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
     supported_extension_aliases = []
     _plugins = {}
     _inventory = {}
-    _methods_to_delegate = ['update_network', 'get_network', 'get_networks',
+    _methods_to_delegate = ['get_network', 'get_networks',
                             'create_port', 'create_port_bulk', 'delete_port',
                             'update_port', 'get_port', 'get_ports',
                             'create_subnet', 'create_subnet_bulk',
@@ -223,8 +223,24 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
             raise
 
     def update_network(self, context, id, network):
-        """For this model this method will be delegated to vswitch plugin"""
-        pass
+        """
+        Perform this operation in the context of the configured device
+        plugins.
+        """
+        LOG.debug("update_network() called\n")
+        args = [context, id, network]
+        ovs_output = self._invoke_plugin_per_device(const.VSWITCH_PLUGIN,
+                                                    self._func_name(),
+                                                    args)
+        vlan_id = odb.get_vlan(ovs_output[0]['id'])
+        vlan_ids = ','.join(str(vlan[0]) for vlan in odb.get_vlans())
+        args = [ovs_output[0]['tenant_id'], id, {'vlan_id': vlan_id},
+                {'net_admin_state': ovs_output[0]['admin_state_up']},
+                {'vlan_ids': vlan_ids}]
+        nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+                                                      self._func_name(),
+                                                      args)
+        return ovs_output[0]
 
     def delete_network(self, context, id):
         """
index ddfdb624348d94c1bf319383bec7e4a4a46fa990..59fc235d5c9baade6ae1a329c77aa26749cab9dd 100644 (file)
@@ -119,13 +119,11 @@ class PluginV2(db_base_plugin_v2.QuantumDbPluginV2):
         Virtual Network.
         """
         LOG.debug("update_network() called\n")
-        try:
-            self._invoke_device_plugins(self._func_name(), [context, id,
-                                                            network])
-            return super(PluginV2, self).update_network(context, id,
-                                                        network)
-        except:
-            raise
+        upd_net_dict = super(PluginV2, self).update_network(context, id,
+                                                            network)
+        self._invoke_device_plugins(self._func_name(), [context, id,
+                                                        upd_net_dict])
+        return upd_net_dict
 
     def delete_network(self, context, id):
         """
index c3e6f6dacfc175629c536aa452276989c2426334..6f30c80bf62df4823515cff807857469fa576570 100644 (file)
@@ -148,3 +148,25 @@ class CiscoNEXUSDriver():
         if vlans == '':
             vlans = 'none'
         return vlans.strip(',')
+
+    def add_vlan_int(self, vlan_id, nexus_host, nexus_user, nexus_password,
+                     nexus_ports, nexus_ssh_port, vlan_ids=None):
+        """
+        Adds a vlan from interfaces on the Nexus switch given the VLAN ID
+        """
+        with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
+                               nexus_password) as man:
+            if not vlan_ids:
+                vlan_ids = self.build_vlans_cmd()
+            for ports in nexus_ports:
+                self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
+
+    def remove_vlan_int(self, vlan_id, nexus_host, nexus_user, nexus_password,
+                        nexus_ports, nexus_ssh_port):
+        """
+        Removes a vlan from interfaces on the Nexus switch given the VLAN ID
+        """
+        with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
+                               nexus_password) as man:
+            for ports in nexus_ports:
+                self.disable_vlan_on_trunk_int(man, ports, vlan_id)
index e9ed3812e8d4b5eb3aba8c3eba2f91e04f8d8c04..d73a70c11192b8f4d8cfb586417393ce32120ce3 100644 (file)
@@ -103,9 +103,9 @@ class NexusPlugin(L2DevicePluginBase):
         for key in kwargs:
             if key == const.CONTEXT:
                 context = kwargs[const.CONTEXT]
-            if key == const.BASE_PLUGIN_REF:
+            elif key == const.BASE_PLUGIN_REF:
                 base_plugin_ref = kwargs[const.BASE_PLUGIN_REF]
-            if key == 'vlan_id':
+            elif key == 'vlan_id':
                 vlan_id = kwargs['vlan_id']
         if vlan_id is None:
             vlan_id = self._get_vlan_id_for_network(tenant_id, net_id,
@@ -136,9 +136,22 @@ class NexusPlugin(L2DevicePluginBase):
         Virtual Network.
         """
         LOG.debug("NexusPlugin:update_network() called\n")
-        network = self._get_network(tenant_id, net_id)
-        network[const.NET_NAME] = kwargs["name"]
-        return network
+        if 'net_admin_state' in kwargs:
+            net_admin_state = kwargs['net_admin_state']
+            vlan_id = kwargs['vlan_id']
+            vlan_ids = kwargs['vlan_ids']
+            if not net_admin_state:
+                self._client.remove_vlan_int(
+                    str(vlan_id), self._nexus_ip,
+                    self._nexus_username, self._nexus_password,
+                    self._nexus_ports, self._nexus_ssh_port)
+            else:
+                self._client.add_vlan_int(
+                    str(vlan_id), self._nexus_ip,
+                    self._nexus_username, self._nexus_password,
+                    self._nexus_ports, self._nexus_ssh_port,
+                    vlan_ids)
+        return net_id
 
     def get_all_ports(self, tenant_id, net_id, **kwargs):
         """
index 206a2cc03bc8572356cc1e0ae4df44fa29629e33..598f2b118f0c66d8c75b29a8053d16052ab0925e 100644 (file)
@@ -97,3 +97,17 @@ class CiscoNEXUSFakeDriver():
         Builds a string with all the VLANs on the same Switch
         """
         pass
+
+    def add_vlan_int(self, vlan_id, nexus_host, nexus_user, nexus_password,
+                     nexus_ports, nexus_ssh_port, vlan_ids=None):
+        """
+        Adds a vlan from interfaces on the Nexus switch given the VLAN ID
+        """
+        pass
+
+    def remove_vlan_int(self, vlan_id, nexus_host, nexus_user, nexus_password,
+                        nexus_ports, nexus_ssh_port):
+        """
+        Removes a vlan from interfaces on the Nexus switch given the VLAN ID
+        """
+        pass
index 94ae5db59905f5b5cb6c80ddcd9d612f3c82518a..8130f1d3f25ad977b10554fd57c53367325f1fb4 100644 (file)
@@ -27,9 +27,6 @@ from quantum.plugins.cisco.db import network_models_v2
 from quantum.plugins.cisco.nexus import cisco_nexus_plugin_v2
 
 
-LOG = logging.getLogger(__name__)
-
-
 NEXUS_IP_ADDRESS = '1.1.1.1'
 NEXUS_USERNAME = 'username'
 NEXUS_PASSWORD = 'password'
@@ -73,7 +70,7 @@ class TestCiscoNexusPlugin(unittest.TestCase):
                                    '__init__', new=new_nexus_init):
                 self._cisco_nexus_plugin = cisco_nexus_plugin_v2.NexusPlugin()
 
-    def test_create_delete_network(self):
+    def test_a_create_delete_network(self):
         """
         Tests creation of two new Virtual Network.
         Tests deletion of one Virtual Network.
@@ -85,7 +82,6 @@ class TestCiscoNexusPlugin(unittest.TestCase):
         test_nexus_clear_vlan after this test to clean
         up the second vlan created by this test.
         """
-        LOG.debug("test_create_delete_network - START")
         tenant_id = self.tenant_id
         net_name = self.net_name
         net_id = self.net_id
@@ -117,31 +113,104 @@ class TestCiscoNexusPlugin(unittest.TestCase):
                          self.second_vlan_name)
         self.assertEqual(new_net_dict[const.NET_VLAN_ID], self.second_vlan_id)
 
-        netid = self._cisco_nexus_plugin.delete_network(
+        expected_net_id = self._cisco_nexus_plugin.delete_network(
             tenant_id, net_id, vlan_id=str(vlan_id))
 
-        self.assertEqual(netid, net_id)
-
-        LOG.debug("test_create_delete_network - END")
+        self.assertEqual(expected_net_id, net_id)
 
-    def test_nexus_clear_vlan(self):
+    def test_b_nexus_clear_vlan(self):
         """
         Test to clean up second vlan of nexus device
         created by test_create_delete_network. This
         test will fail if it is run individually.
         """
-        LOG.debug("test_nexus_clear_vlan - START")
         tenant_id = self.tenant_id
         second_net_id = self.second_net_id
         second_vlan_id = self.second_vlan_id
 
+        expected_second_net_id = self._cisco_nexus_plugin.delete_network(
+            tenant_id, second_net_id,
+            vlan_id=str(second_vlan_id))
+
+        self.assertEqual(expected_second_net_id, second_net_id)
+
+    def test_c_update_network_False(self):
+        """
+        Test to update a network state to False
+        resulting in disabling a vlan corresponding to
+        that network from the configured nexus interfaces
+        """
+        tenant_id = self.tenant_id
+        net_name = self.net_name
+        net_id = self.net_id
+        vlan_name = self.vlan_name
+        vlan_id = self.vlan_id
+        second_net_name = self.second_net_name
+        second_net_id = self.second_net_id
+        second_vlan_name = self.second_vlan_name
+        second_vlan_id = self.second_vlan_id
+
+        new_net_dict = self._cisco_nexus_plugin.create_network(
+            tenant_id, net_name, net_id,
+            vlan_name, vlan_id, vlan_ids=str(vlan_id))
+
+        vlan_ids = str(vlan_id) + "," + str(second_vlan_id)
+        new_net_dict = self._cisco_nexus_plugin.create_network(
+            tenant_id, second_net_name, second_net_id,
+            second_vlan_name, second_vlan_id,
+            vlan_ids=vlan_ids)
+
+        expected_net_id = self._cisco_nexus_plugin.update_network(
+            tenant_id, net_id, net_admin_state=False,
+            vlan_id=vlan_id, vlan_ids=str(vlan_id))
+
+        self.assertEqual(expected_net_id, net_id)
+
+    def test_d_nexus_clean_vlan_update(self):
+        """
+        Cleans up vlans on the nexus for the two
+        created networks
+        """
+        tenant_id = self.tenant_id
+        net_id = self.net_id
+        vlan_id = self.vlan_id
+        second_net_id = self.second_net_id
+        second_vlan_id = self.second_vlan_id
+
         netid = self._cisco_nexus_plugin.delete_network(
+            tenant_id, net_id, vlan_id=str(vlan_id))
+
+        self.assertEqual(netid, net_id)
+
+        expected_second_net_id = self._cisco_nexus_plugin.delete_network(
             tenant_id, second_net_id,
             vlan_id=str(second_vlan_id))
 
-        self.assertEqual(netid, second_net_id)
+        self.assertEqual(expected_second_net_id, second_net_id)
+
+    def test_e_update_network_True(self):
+        """
+        Test to update a disabled network state to True
+        resulting in enabling a vlan corresponding to
+        that network to the configured nexus interfaces
+        """
+        tenant_id = self.tenant_id
+        net_name = self.net_name
+        net_id = self.net_id
+        vlan_name = self.vlan_name
+        vlan_id = self.vlan_id
+        second_vlan_id = self.second_vlan_id
+
+        self.test_c_update_network_False()
+
+        vlan_ids = str(vlan_id) + "," + str(second_vlan_id)
+        expected_net_id = self._cisco_nexus_plugin.update_network(
+            tenant_id, net_id, net_admin_state=True,
+            vlan_id=vlan_id, vlan_ids=str(vlan_ids))
+
+        self.assertEqual(expected_net_id, net_id)
 
-        LOG.debug("test_nexus_clear_vlan - END")
+        self.test_d_nexus_clean_vlan_update()
 
     def tearDown(self):
         """Clear the test environment"""