Exemple #1
0
    def test_nexus_delete_port_rollback(self):
        """Test for proper rollback for nexus plugin delete port failure.

        Test for rollback (i.e. restoration) of a VLAN entry in the
        nexus database whenever the nexus plugin fails to reconfigure the
        nexus switch during a delete_port operation.

        """
        with self._create_resources() as port:
            # Check that there is only one binding in the nexus database
            # for this VLAN/nexus switch.
            start_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START,
                                                           NEXUS_IP_ADDR)
            self.assertEqual(len(start_rows), 1)

            # Simulate a Nexus switch configuration error during
            # port deletion.
            with self._patch_ncclient(
                'connect.return_value.edit_config.side_effect',
                AttributeError):
                self._delete('ports', port['port']['id'],
                             wexc.HTTPInternalServerError.code)

            # Confirm that the binding has been restored (rolled back).
            end_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START,
                                                         NEXUS_IP_ADDR)
            self.assertEqual(start_rows, end_rows)
Exemple #2
0
    def test_nexus_delete_port_rollback(self):
        """Test for proper rollback for nexus plugin delete port failure.

        Test for rollback (i.e. restoration) of a VLAN entry in the
        nexus database whenever the nexus plugin fails to reconfigure the
        nexus switch during a delete_port operation.

        """
        with self._create_resources() as port:
            # Check that there is only one binding in the nexus database
            # for this VLAN/nexus switch.
            start_rows = nexus_db_v2.get_nexusvlan_binding(
                VLAN_START, NEXUS_IP_ADDR)
            self.assertEqual(len(start_rows), 1)

            # Simulate a Nexus switch configuration error during
            # port deletion.
            with self._patch_ncclient(
                    'connect.return_value.edit_config.side_effect',
                    AttributeError):
                self._delete('ports', port['port']['id'],
                             wexc.HTTPInternalServerError.code)

            # Confirm that the binding has been restored (rolled back).
            end_rows = nexus_db_v2.get_nexusvlan_binding(
                VLAN_START, NEXUS_IP_ADDR)
            self.assertEqual(start_rows, end_rows)
Exemple #3
0
    def _manage_port(self, vlan_name, vlan_id, host, instance):
        """Called during create and update port events.

        Create a VLAN in the appropriate switch/port and configure the
        appropriate interfaces for this VLAN.
        """

        # Grab the switch IP and port for this host
        for switch_ip, attr in self._nexus_switches:
            if str(attr) == str(host):
                port_id = self._nexus_switches[switch_ip, attr]
                break
        else:
            raise excep.NexusComputeHostNotConfigured(host=host)

        # Check if this network is already in the DB
        vlan_created = False
        vlan_trunked = False

        try:
            nxos_db.get_port_vlan_switch_binding(port_id, vlan_id, switch_ip)
        except excep.NexusPortBindingNotFound:
            # Check for vlan/switch binding
            try:
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
            except excep.NexusPortBindingNotFound:
                # Create vlan and trunk vlan on the port
                LOG.debug(_("Nexus: create & trunk vlan %s"), vlan_name)
                self.driver.create_and_trunk_vlan(switch_ip, vlan_id,
                                                  vlan_name, port_id)
                vlan_created = True
                vlan_trunked = True
            else:
                # Only trunk vlan on the port
                LOG.debug(_("Nexus: trunk vlan %s"), vlan_name)
                self.driver.enable_vlan_on_trunk_int(switch_ip, vlan_id,
                                                     port_id)
                vlan_trunked = True

        try:
            nxos_db.add_nexusport_binding(port_id, str(vlan_id),
                                          switch_ip, instance)
        except Exception:
            with excutils.save_and_reraise_exception():
                # Add binding failed, roll back any vlan creation/enabling
                if vlan_created and vlan_trunked:
                    LOG.debug(_("Nexus: delete & untrunk vlan %s"), vlan_name)
                    self.driver.delete_and_untrunk_vlan(switch_ip, vlan_id,
                                                        port_id)
                elif vlan_created:
                    LOG.debug(_("Nexus: delete vlan %s"), vlan_name)
                    self.driver.delete_vlan(switch_ip, vlan_id)
                elif vlan_trunked:
                    LOG.debug(_("Nexus: untrunk vlan %s"), vlan_name)
                    self.driver.disable_vlan_on_trunk_int(switch_ip, vlan_id,
                                                          port_id)
Exemple #4
0
    def _manage_port(self, vlan_name, vlan_id, host, instance):
        """Called during create and update port events.

        Create a VLAN in the appropriate switch/port and configure the
        appropriate interfaces for this VLAN.
        """

        # Grab the switch IP and port for this host
        for switch_ip, attr in self._nexus_switches:
            if str(attr) == str(host):
                port_id = self._nexus_switches[switch_ip, attr]
                break
        else:
            raise excep.NexusComputeHostNotConfigured(host=host)

        # Check if this network is already in the DB
        vlan_created = False
        vlan_trunked = False

        try:
            nxos_db.get_port_vlan_switch_binding(port_id, vlan_id, switch_ip)
        except excep.NexusPortBindingNotFound:
            # Check for vlan/switch binding
            try:
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
            except excep.NexusPortBindingNotFound:
                # Create vlan and trunk vlan on the port
                LOG.debug(_("Nexus: create & trunk vlan %s"), vlan_name)
                self.driver.create_and_trunk_vlan(switch_ip, vlan_id,
                                                  vlan_name, port_id)
                vlan_created = True
                vlan_trunked = True
            else:
                # Only trunk vlan on the port
                LOG.debug(_("Nexus: trunk vlan %s"), vlan_name)
                self.driver.enable_vlan_on_trunk_int(switch_ip, vlan_id,
                                                     port_id)
                vlan_trunked = True

        try:
            nxos_db.add_nexusport_binding(port_id, str(vlan_id), switch_ip,
                                          instance)
        except Exception:
            with excutils.save_and_reraise_exception():
                # Add binding failed, roll back any vlan creation/enabling
                if vlan_created and vlan_trunked:
                    LOG.debug(_("Nexus: delete & untrunk vlan %s"), vlan_name)
                    self.driver.delete_and_untrunk_vlan(
                        switch_ip, vlan_id, port_id)
                elif vlan_created:
                    LOG.debug(_("Nexus: delete vlan %s"), vlan_name)
                    self.driver.delete_vlan(switch_ip, vlan_id)
                elif vlan_trunked:
                    LOG.debug(_("Nexus: untrunk vlan %s"), vlan_name)
                    self.driver.disable_vlan_on_trunk_int(
                        switch_ip, vlan_id, port_id)
Exemple #5
0
    def delete_port_precommit(self, context):
        """Delete port pre-database commit event.

        Delete port bindings from the database and scan whether the network
        is still required on the interfaces trunked.
        """

        if not self._is_deviceowner_compute(context.current):
            return

        port = context.current
        device_id = port['device_id']
        vlan_id = self._get_vlanid(context)

        if not vlan_id or not device_id:
            return

        # Delete DB row for this port
        try:
            row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
        except excep.NexusPortBindingNotFound:
            return

        switch_ip = row.switch_ip
        nexus_port = None
        if row.port_id != 'router':
            nexus_port = row.port_id

        nxos_db.remove_nexusport_binding(row.port_id, row.vlan_id,
                                         row.switch_ip, row.instance_id)

        # Check for any other bindings with the same vlan_id and switch_ip
        try:
            nxos_db.get_nexusvlan_binding(row.vlan_id, row.switch_ip)
        except excep.NexusPortBindingNotFound:
            try:
                # Delete this vlan from this switch
                if nexus_port:
                    self.driver.disable_vlan_on_trunk_int(switch_ip,
                                                          row.vlan_id,
                                                          nexus_port)
                self.driver.delete_vlan(switch_ip, row.vlan_id)
            except Exception:
                # The delete vlan operation on the Nexus failed,
                # so this delete_port request has failed. For
                # consistency, roll back the Nexus database to what
                # it was before this request.
                with excutils.save_and_reraise_exception():
                    nxos_db.add_nexusport_binding(row.port_id,
                                                  row.vlan_id,
                                                  row.switch_ip,
                                                  row.instance_id)
Exemple #6
0
    def delete_port_precommit(self, context):
        """Delete port pre-database commit event.

        Delete port bindings from the database and scan whether the network
        is still required on the interfaces trunked.
        """

        if not self._is_deviceowner_compute(context.current):
            return

        port = context.current
        device_id = port['device_id']
        vlan_id = self._get_vlanid(context)

        if not vlan_id or not device_id:
            return

        # Delete DB row for this port
        try:
            row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
        except excep.NexusPortBindingNotFound:
            return

        switch_ip = row.switch_ip
        nexus_port = None
        if row.port_id != 'router':
            nexus_port = row.port_id

        nxos_db.remove_nexusport_binding(row.port_id, row.vlan_id,
                                         row.switch_ip, row.instance_id)

        # Check for any other bindings with the same vlan_id and switch_ip
        try:
            nxos_db.get_nexusvlan_binding(row.vlan_id, row.switch_ip)
        except excep.NexusPortBindingNotFound:
            try:
                # Delete this vlan from this switch
                if nexus_port:
                    self.driver.disable_vlan_on_trunk_int(
                        switch_ip, row.vlan_id, nexus_port)
                self.driver.delete_vlan(switch_ip, row.vlan_id)
            except Exception:
                # The delete vlan operation on the Nexus failed,
                # so this delete_port request has failed. For
                # consistency, roll back the Nexus database to what
                # it was before this request.
                with excutils.save_and_reraise_exception():
                    nxos_db.add_nexusport_binding(row.port_id, row.vlan_id,
                                                  row.switch_ip,
                                                  row.instance_id)
Exemple #7
0
    def test_nexusvlanbinding_get(self):
        """Test get of port bindings based on vlan and switch."""
        npb11 = self._npb_test_obj(10, 100)
        npb21 = self._npb_test_obj(20, 100)
        npb22 = self._npb_test_obj(20, 200)
        self._add_bindings_to_db([npb11, npb21, npb22])

        npb_all_v100 = self._get_nexusvlan_binding(npb11)
        self.assertEqual(len(npb_all_v100), 2)
        npb_v200 = self._get_nexusvlan_binding(npb22)
        self.assertEqual(len(npb_v200), 1)
        self._assert_bindings_match(npb_v200[0], npb22)

        with testtools.ExpectedException(exceptions.NexusPortBindingNotFound):
            nexus_db_v2.get_nexusvlan_binding(npb21.vlan, "dummySwitch")
Exemple #8
0
    def test_nexusbinding_update(self):
        """Tests update of vlan IDs for port bindings."""
        npb11 = self._npb_test_obj(10, 100, switch='1.1.1.1', instance='test')
        npb21 = self._npb_test_obj(20, 100, switch='1.1.1.1', instance='test')
        self._add_bindings_to_db([npb11, npb21])

        npb_all_v100 = nexus_db_v2.get_nexusvlan_binding(100, '1.1.1.1')
        self.assertEqual(len(npb_all_v100), 2)

        npb22 = self._npb_test_obj(20, 200, switch='1.1.1.1', instance='test')
        npb = nexus_db_v2.update_nexusport_binding(npb21.port, 200)
        self._assert_bindings_match(npb, npb22)

        npb_all_v100 = nexus_db_v2.get_nexusvlan_binding(100, '1.1.1.1')
        self.assertEqual(len(npb_all_v100), 1)
        self._assert_bindings_match(npb_all_v100[0], npb11)

        npb = nexus_db_v2.update_nexusport_binding(npb21.port, 0)
        self.assertIsNone(npb)

        npb33 = self._npb_test_obj(30, 300, switch='1.1.1.1', instance='test')
        with testtools.ExpectedException(exceptions.NexusPortBindingNotFound):
            nexus_db_v2.update_nexusport_binding(npb33.port, 200)
Exemple #9
0
 def _get_nexusvlan_binding(self, npb):
     """Gets port bindings based on vlan and switch."""
     return nexus_db_v2.get_nexusvlan_binding(npb.vlan, npb.switch)