def add_router_interface(self, vlan_name, vlan_id, subnet_id, gateway_ip,
                             router_id):
        """Create VLAN SVI on the Nexus switch."""
        # Find a switch to create the SVI on
        switch_ip = self._find_switch_for_svi()
        if not switch_ip:
            raise cisco_exc.NoNexusSviSwitch()

        # Check if this vlan exists on the switch already
        try:
            nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
        except cisco_exc.NexusPortBindingNotFound:
            # Create vlan and trunk vlan on the port
            self._client.create_and_trunk_vlan(switch_ip,
                                               vlan_id,
                                               vlan_name,
                                               nexus_port=None)
        # Check if a router interface has already been created
        try:
            nxos_db.get_nexusvm_binding(vlan_id, router_id)
            raise cisco_exc.SubnetInterfacePresent(subnet_id=subnet_id,
                                                   router_id=router_id)
        except cisco_exc.NexusPortBindingNotFound:
            self._client.create_vlan_svi(switch_ip, vlan_id, gateway_ip)
            nxos_db.add_nexusport_binding('router', str(vlan_id), switch_ip,
                                          router_id)

            return True
Esempio n. 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_port_res() as res:

            port = self.deserialize(self.fmt, res)

            # Check that there is only one binding in the nexus database
            # for this VLAN/nexus switch.
            start_rows = nexus_db_v2.get_nexusvlan_binding(
                self.vlan_start, self.switch_ip)
            self.assertEqual(len(start_rows), 1)

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

            # Confirm that the binding has been restored (rolled back).
            end_rows = nexus_db_v2.get_nexusvlan_binding(
                self.vlan_start, self.switch_ip)
            self.assertEqual(start_rows, end_rows)
Esempio n. 3
0
    def add_router_interface(self, vlan_name, vlan_id, subnet_id,
                             gateway_ip, router_id):
        """Create VLAN SVI on the Nexus switch."""
        # Find a switch to create the SVI on
        switch_ip = self._find_switch_for_svi()
        if not switch_ip:
            raise cisco_exc.NoNexusSviSwitch()

        # Check if this vlan exists on the switch already
        try:
            nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
        except cisco_exc.NexusPortBindingNotFound:
            # Create vlan and trunk vlan on the port
            self._client.create_and_trunk_vlan(
                switch_ip, vlan_id, vlan_name, etype=None, nexus_port=None)
        # Check if a router interface has already been created
        try:
            nxos_db.get_nexusvm_bindings(vlan_id, router_id)
            raise cisco_exc.SubnetInterfacePresent(subnet_id=subnet_id,
                                                   router_id=router_id)
        except cisco_exc.NexusPortBindingNotFound:
            self._client.create_vlan_svi(switch_ip, vlan_id, gateway_ip)
            nxos_db.add_nexusport_binding('router', str(vlan_id),
                                          switch_ip, router_id)

            return True
Esempio n. 4
0
    def test_model_delete_port_rollback(self):
        """Test for proper rollback for OVS plugin delete port failure.

        Test that the nexus port configuration is rolled back (restored)
        by the Cisco model plugin when there is a failure in the OVS
        plugin for a delete port operation.

        """
        with self._create_port_res() as res:

            # After port is created, we should have one binding for this
            # vlan/nexus switch.
            port = self.deserialize(self.fmt, res)
            start_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START, NEXUS_IP_ADDR)
            self.assertEqual(len(start_rows), 1)

            # Inject an exception in the OVS plugin delete_port
            # processing, and attempt a port deletion.
            inserted_exc = q_exc.Conflict
            expected_http = base.FAULT_MAP[inserted_exc].code
            with mock.patch.object(l3_db.L3_NAT_db_mixin, "disassociate_floatingips", side_effect=inserted_exc):
                self._delete("ports", port["port"]["id"], expected_code=expected_http)

            # Confirm that the Cisco model plugin has restored
            # the nexus configuration for this port after deletion failure.
            end_rows = nexus_db_v2.get_nexusvlan_binding(VLAN_START, NEXUS_IP_ADDR)
            self.assertEqual(start_rows, end_rows)
Esempio n. 5
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_port_res() as res:

            port = self.deserialize(self.fmt, res)

            # 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("manager.connect.return_value.edit_config.side_effect", AttributeError):
                self._delete("ports", port["port"]["id"], base.FAULT_MAP[c_exc.NexusConfigFailed].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)
Esempio n. 6
0
    def test_model_delete_port_rollback(self):
        """Test for proper rollback for OVS plugin delete port failure.

        Test that the nexus port configuration is rolled back (restored)
        by the Cisco model plugin when there is a failure in the OVS
        plugin for a delete port operation.

        """
        with self._create_port_res() as res:

            # After port is created, we should have one binding for this
            # vlan/nexus switch.
            port = self.deserialize(self.fmt, res)
            start_rows = nexus_db_v2.get_nexusvlan_binding(
                self.vlan_start, self.switch_ip)
            self.assertEqual(len(start_rows), 1)

            # Inject an exception in the OVS plugin delete_port
            # processing, and attempt a port deletion.
            inserted_exc = q_exc.Conflict
            expected_http = base.FAULT_MAP[inserted_exc].code
            with mock.patch.object(l3_db.L3_NAT_db_mixin,
                                   'disassociate_floatingips',
                                   side_effect=inserted_exc):
                self._delete('ports',
                             port['port']['id'],
                             expected_code=expected_http)

            # Confirm that the Cisco model plugin has restored
            # the nexus configuration for this port after deletion failure.
            end_rows = nexus_db_v2.get_nexusvlan_binding(
                self.vlan_start, self.switch_ip)
            self.assertEqual(start_rows, end_rows)
Esempio n. 7
0
    def delete_port(self, device_id, vlan_id):
        """Delete port.

        Delete port bindings from the database and scan whether the network
        is still required on the interfaces trunked.
        """
        LOG.debug(_("NexusPlugin:delete_port() called"))
        # Delete DB row(s) for this port
        try:
            rows = nxos_db.get_nexusvm_bindings(vlan_id, device_id)
        except cisco_exc.NexusPortBindingNotFound:
            return

        auto_delete = True
        auto_untrunk = True
        if cdb.is_provider_vlan(vlan_id):
            auto_delete = conf.CISCO.provider_vlan_auto_create
            auto_untrunk = conf.CISCO.provider_vlan_auto_trunk
            LOG.debug(_("delete_network(): provider vlan %s"), vlan_id)

        instance_id = False
        for row in rows:
            instance_id = row["instance_id"]
            switch_ip = row.switch_ip
            etype, nexus_port = "", ""
            if row["port_id"] == "router":
                etype, nexus_port = "vlan", row["port_id"]
                auto_untrunk = False
            else:
                etype, nexus_port = row["port_id"].split(":")

            nxos_db.remove_nexusport_binding(row.port_id, row.vlan_id, row.switch_ip, row.instance_id)
            # Check whether there are any remaining instances using this
            # vlan on this Nexus port.
            try:
                nxos_db.get_port_vlan_switch_binding(row.port_id, row.vlan_id, row.switch_ip)
            except cisco_exc.NexusPortBindingNotFound:
                try:
                    if nexus_port and auto_untrunk:
                        # Untrunk the vlan from this Nexus interface
                        self._client.disable_vlan_on_trunk_int(switch_ip, row.vlan_id, etype, nexus_port)

                    # Check whether there are any remaining instances
                    # using this vlan on the Nexus switch.
                    if auto_delete:
                        try:
                            nxos_db.get_nexusvlan_binding(row.vlan_id, row.switch_ip)
                        except cisco_exc.NexusPortBindingNotFound:
                            # Delete this vlan from this switch
                            self._client.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)

        return instance_id
    def delete_port(self, device_id, vlan_id):
        """Delete port.

        Delete port bindings from the database and scan whether the network
        is still required on the interfaces trunked.
        """
        LOG.debug(_("NexusPlugin:delete_port() called"))
        # Delete DB row(s) for this port
        try:
            rows = nxos_db.get_nexusvm_bindings(vlan_id, device_id)
        except cisco_exc.NexusPortBindingNotFound:
            return

        auto_delete = True
        auto_untrunk = True
        if cdb.is_provider_vlan(vlan_id):
            auto_delete = conf.CISCO.provider_vlan_auto_create
            auto_untrunk = conf.CISCO.provider_vlan_auto_trunk
            LOG.debug("delete_network(): provider vlan %s" % vlan_id)

        instance_id = False
        for row in rows:
            instance_id = row['instance_id']
            switch_ip = row.switch_ip
            etype, nexus_port = '', ''
            if row['port_id'] == 'router':
                etype, nexus_port = 'vlan', row['port_id']
            else:
                etype, nexus_port = row['port_id'].split(':')

            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 cisco_exc.NexusPortBindingNotFound:
                try:
                    # Delete this vlan from this switch
                    if nexus_port and auto_untrunk:
                        self._client.disable_vlan_on_trunk_int(
                            switch_ip, row.vlan_id, etype, nexus_port)
                    if auto_delete:
                        self._client.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)

        return instance_id
Esempio n. 9
0
    def delete_port(self, device_id, vlan_id):
        """Delete port.

        Delete port bindings from the database and scan whether the network
        is still required on the interfaces trunked.
        """
        LOG.debug(_("NexusPlugin:delete_port() called"))
        # Delete DB row(s) for this port
        try:
            rows = nxos_db.get_nexusvm_bindings(vlan_id, device_id)
        except cisco_exc.NexusPortBindingNotFound:
            return

        auto_delete = True
        auto_untrunk = True
        if cdb.is_provider_vlan(vlan_id):
            auto_delete = conf.CISCO.provider_vlan_auto_create
            auto_untrunk = conf.CISCO.provider_vlan_auto_trunk
            LOG.debug(_("delete_network(): provider vlan %s"), vlan_id)

        instance_id = False
        for row in rows:
            instance_id = row['instance_id']
            switch_ip = row.switch_ip
            etype, nexus_port = '', ''
            if row['port_id'] == 'router':
                etype, nexus_port = 'vlan', row['port_id']
                auto_untrunk = False
            else:
                etype, nexus_port = row['port_id'].split(':')

            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 cisco_exc.NexusPortBindingNotFound:
                try:
                    # Delete this vlan from this switch
                    if nexus_port and auto_untrunk:
                        self._client.disable_vlan_on_trunk_int(
                            switch_ip, row.vlan_id, etype, nexus_port)
                    if auto_delete:
                        self._client.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)

        return instance_id
Esempio n. 10
0
    def test_nexusvlanbinding_get(self):
        npb11 = self._npb_test_obj(10, 100)
        npb21 = self._npb_test_obj(20, 100)
        npb22 = self._npb_test_obj(20, 200)
        self._add_to_db([npb11, npb21, npb22])

        npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, npb11.switch)
        self.assertEqual(len(npb_all_v100), 2)
        npb_v200 = nxdb.get_nexusvlan_binding(npb22.vlan, npb22.switch)
        self.assertEqual(len(npb_v200), 1)
        self._assert_equal(npb_v200[0], npb22)

        with testtools.ExpectedException(c_exc.NexusPortBindingNotFound):
            nxdb.get_nexusvlan_binding(npb21.vlan, "dummySwitch")
Esempio n. 11
0
    def test_nexusvlanbinding_get(self):
        npb11 = self._npb_test_obj(10, 100)
        npb21 = self._npb_test_obj(20, 100)
        npb22 = self._npb_test_obj(20, 200)
        self._add_to_db([npb11, npb21, npb22])

        npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, npb11.switch)
        self.assertEqual(len(npb_all_v100), 2)
        npb_v200 = nxdb.get_nexusvlan_binding(npb22.vlan, npb22.switch)
        self.assertEqual(len(npb_v200), 1)
        self._assert_equal(npb_v200[0], npb22)

        with testtools.ExpectedException(c_exc.NexusPortBindingNotFound):
            nxdb.get_nexusvlan_binding(npb21.vlan, "dummySwitch")
    def delete_port(self, device_id, vlan_id):
        """Delete port.

        Delete port bindings from the database and scan whether the network
        is still required on the interfaces trunked.
        """
        LOG.debug(_("NexusPlugin:delete_port() called"))
        # Delete DB row for this port
        try:
            row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
        except cisco_exc.NexusPortBindingNotFound:
            return

        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 cisco_exc.NexusPortBindingNotFound:
            try:
                # Delete this vlan from this switch
                _nexus_ip = row['switch_ip']
                _nexus_ports = ()
                if row['port_id'] != 'router':
                    _nexus_ports = (row['port_id'],)
                _nexus_ssh_port = (self._nexus_switches[_nexus_ip,
                                                        'ssh_port'])
                _nexus_creds = self.get_credential(_nexus_ip)
                _nexus_username = _nexus_creds['username']
                _nexus_password = _nexus_creds['password']
                self._client.delete_vlan(
                    str(row['vlan_id']), _nexus_ip,
                    _nexus_username, _nexus_password,
                    _nexus_ports, _nexus_ssh_port)
            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'])

        return row['instance_id']
Esempio n. 13
0
    def test_nexusbinding_update(self):
        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_to_db([npb11, npb21])

        npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, "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 = nxdb.update_nexusport_binding(npb21.port, 200)
        self._assert_equal(npb, npb22)

        npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, "1.1.1.1")
        self.assertEqual(len(npb_all_v100), 1)
        self._assert_equal(npb_all_v100[0], npb11)

        npb = nxdb.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(c_exc.NexusPortBindingNotFound):
            nxdb.update_nexusport_binding(npb33.port, 200)
Esempio n. 14
0
    def test_nexusbinding_update(self):
        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_to_db([npb11, npb21])

        npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, '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 = nxdb.update_nexusport_binding(npb21.port, 200)
        self._assert_equal(npb, npb22)

        npb_all_v100 = nxdb.get_nexusvlan_binding(npb11.vlan, '1.1.1.1')
        self.assertEqual(len(npb_all_v100), 1)
        self._assert_equal(npb_all_v100[0], npb11)

        npb = nxdb.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(c_exc.NexusPortBindingNotFound):
            nxdb.update_nexusport_binding(npb33.port, 200)
    def add_router_interface(self, vlan_name, vlan_id, subnet_id,
                             gateway_ip, router_id):
        """Create VLAN SVI on the Nexus switch."""
        # Find a switch to create the SVI on
        switch_ip = self._find_switch_for_svi()
        if not switch_ip:
            raise cisco_exc.NoNexusSwitch()

        _nexus_ip = switch_ip
        _nexus_ssh_port = self._nexus_switches[switch_ip, 'ssh_port']
        _nexus_creds = self.get_credential(_nexus_ip)
        _nexus_username = _nexus_creds['username']
        _nexus_password = _nexus_creds['password']

        # Check if this vlan exists on the switch already
        try:
            nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
        except cisco_exc.NexusPortBindingNotFound:
            # Create vlan and trunk vlan on the port
            self._client.create_vlan(
                vlan_name, str(vlan_id), _nexus_ip,
                _nexus_username, _nexus_password,
                [], _nexus_ssh_port, vlan_id)

        # Check if a router interface has already been created
        try:
            nxos_db.get_nexusvm_binding(vlan_id, router_id)
            raise cisco_exc.SubnetInterfacePresent(subnet_id=subnet_id,
                                                   router_id=router_id)
        except cisco_exc.NexusPortBindingNotFound:
            self._client.create_vlan_svi(vlan_id, _nexus_ip, _nexus_username,
                                         _nexus_password, _nexus_ssh_port,
                                         gateway_ip)
            nxos_db.add_nexusport_binding('router', str(vlan_id),
                                          switch_ip, router_id)

            return True
Esempio n. 16
0
    def create_network(self, network, attachment):
        """Create or update a network when an attachment is changed.

        This method is not invoked at the usual plugin create_network() time.
        Instead, it is invoked on create/update port.

        :param network: Network on which the port operation is happening
        :param attachment: Details about the owner of the port

        Create a VLAN in the appropriate switch/port, and configure the
        appropriate interfaces for this VLAN.
        """
        LOG.debug(_("NexusPlugin:create_network() called"))
        # Grab the switch IPs and ports for this host
        host_connections = []
        host = attachment['host_name']
        for switch_type, switch_ip, attr in self._nexus_switches:
            if str(attr) == str(host):
                port = self._nexus_switches[switch_type, switch_ip, attr]
                # Get ether type for port, assume an ethernet type
                # if none specified.
                if ':' in port:
                    etype, port_id = port.split(':')
                else:
                    etype, port_id = 'ethernet', port
                host_connections.append((switch_ip, etype, port_id))
        if not host_connections:
            raise cisco_exc.NexusComputeHostNotConfigured(host=host)

        vlan_id = network[const.NET_VLAN_ID]
        vlan_name = network[const.NET_VLAN_NAME]
        auto_create = True
        auto_trunk = True
        if cdb.is_provider_vlan(vlan_id):
            vlan_name = ''.join([conf.CISCO.provider_vlan_name_prefix,
                                 str(vlan_id)])
            auto_create = conf.CISCO.provider_vlan_auto_create
            auto_trunk = conf.CISCO.provider_vlan_auto_trunk

        # Check if this network is already in the DB
        for switch_ip, etype, port_id in host_connections:
            vlan_created = False
            vlan_trunked = False
            eport_id = '%s:%s' % (etype, port_id)
            # Check for switch vlan bindings
            try:
                # This vlan has already been created on this switch
                # via another operation, like SVI bindings.
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
                vlan_created = True
                auto_create = False
            except cisco_exc.NexusPortBindingNotFound:
                # No changes, proceed as normal
                pass

            try:
                nxos_db.get_port_vlan_switch_binding(eport_id, vlan_id,
                                                     switch_ip)
            except cisco_exc.NexusPortBindingNotFound:
                if auto_create and auto_trunk:
                    # Create vlan and trunk vlan on the port
                    LOG.debug(_("Nexus: create & trunk vlan %s"), vlan_name)
                    self._client.create_and_trunk_vlan(
                        switch_ip, vlan_id, vlan_name, etype, port_id)
                    vlan_created = True
                    vlan_trunked = True
                elif auto_create:
                    # Create vlan but do not trunk it on the port
                    LOG.debug(_("Nexus: create vlan %s"), vlan_name)
                    self._client.create_vlan(switch_ip, vlan_id, vlan_name)
                    vlan_created = True
                elif auto_trunk:
                    # Only trunk vlan on the port
                    LOG.debug(_("Nexus: trunk vlan %s"), vlan_name)
                    self._client.enable_vlan_on_trunk_int(
                        switch_ip, vlan_id, etype, port_id)
                    vlan_trunked = True

            try:
                instance = attachment[const.INSTANCE_ID]
                nxos_db.add_nexusport_binding(eport_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._client.delete_and_untrunk_vlan(switch_ip,
                                                             vlan_id,
                                                             etype, port_id)
                    elif vlan_created:
                        LOG.debug(_("Nexus: delete vlan %s"), vlan_name)
                        self._client.delete_vlan(switch_ip, vlan_id)
                    elif vlan_trunked:
                        LOG.debug(_("Nexus: untrunk vlan %s"), vlan_name)
                        self._client.disable_vlan_on_trunk_int(switch_ip,
                                                               vlan_id,
                                                               etype,
                                                               port_id)

        net_id = network[const.NET_ID]
        new_net_dict = {const.NET_ID: net_id,
                        const.NET_NAME: network[const.NET_NAME],
                        const.NET_PORTS: {},
                        const.NET_VLAN_NAME: vlan_name,
                        const.NET_VLAN_ID: vlan_id}
        self._networks[net_id] = new_net_dict
        return new_net_dict
    def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id,
                       host, instance):
        """Create network.

        Create a VLAN in the appropriate switch/port, and configure the
        appropriate interfaces for this VLAN.
        """
        LOG.debug(_("NexusPlugin:create_network() called"))
        # 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 cisco_exc.NexusComputeHostNotConfigured(host=host)

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

        try:
            nxos_db.get_port_vlan_switch_binding(port_id, vlan_id, switch_ip)
        except cisco_exc.NexusPortBindingNotFound:
            _nexus_ip = switch_ip
            _nexus_ports = (port_id,)
            _nexus_ssh_port = \
                self._nexus_switches[switch_ip, 'ssh_port']
            _nexus_creds = self.get_credential(_nexus_ip)
            _nexus_username = _nexus_creds['username']
            _nexus_password = _nexus_creds['password']
            # Check for vlan/switch binding
            try:
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
            except cisco_exc.NexusPortBindingNotFound:
                # Create vlan and trunk vlan on the port
                self._client.create_vlan(
                    vlan_name, str(vlan_id), _nexus_ip,
                    _nexus_username, _nexus_password,
                    _nexus_ports, _nexus_ssh_port, vlan_id)
                vlan_created = True
            else:
                # Only trunk vlan on the port
                man = self._client.nxos_connect(_nexus_ip,
                                                int(_nexus_ssh_port),
                                                _nexus_username,
                                                _nexus_password)
                self._client.enable_vlan_on_trunk_int(man,
                                                      _nexus_ip,
                                                      port_id,
                                                      vlan_id)
                vlan_enabled = 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:
                    self._client.delete_vlan(
                        str(vlan_id), _nexus_ip,
                        _nexus_username, _nexus_password,
                        _nexus_ports, _nexus_ssh_port)
                if vlan_enabled:
                    self._client.disable_vlan_on_trunk_int(man,
                                                           port_id,
                                                           vlan_id)

        new_net_dict = {const.NET_ID: net_id,
                        const.NET_NAME: net_name,
                        const.NET_PORTS: {},
                        const.NET_VLAN_NAME: vlan_name,
                        const.NET_VLAN_ID: vlan_id}
        self._networks[net_id] = new_net_dict
        return new_net_dict
    def create_network(self, network, attachment):
        """Create or update a network when an attachment is changed.

        This method is not invoked at the usual plugin create_network() time.
        Instead, it is invoked on create/update port.

        :param network: Network on which the port operation is happening
        :param attachment: Details about the owner of the port

        Create a VLAN in the appropriate switch/port, and configure the
        appropriate interfaces for this VLAN.
        """
        LOG.debug(_("NexusPlugin:create_network() called"))
        # Grab the switch IPs and ports for this host
        host_connections = []
        host = attachment['host_name']
        for switch_type, switch_ip, attr in self._nexus_switches:
            if str(attr) == str(host):
                port = self._nexus_switches[switch_type, switch_ip, attr]
                # Get ether type for port, assume an ethernet type
                # if none specified.
                if ':' in port:
                    etype, port_id = port.split(':')
                else:
                    etype, port_id = 'ethernet', port
                host_connections.append((switch_ip, etype, port_id))
        if not host_connections:
            raise cisco_exc.NexusComputeHostNotConfigured(host=host)

        vlan_id = network[const.NET_VLAN_ID]
        vlan_name = network[const.NET_VLAN_NAME]
        auto_create = True
        auto_trunk = True
        if cdb.is_provider_vlan(vlan_id):
            vlan_name = ''.join([conf.CISCO.provider_vlan_name_prefix,
                                 str(vlan_id)])
            auto_create = conf.CISCO.provider_vlan_auto_create
            auto_trunk = conf.CISCO.provider_vlan_auto_trunk

        # Check if this network is already in the DB
        for switch_ip, etype, port_id in host_connections:
            vlan_created = False
            vlan_trunked = False
            eport_id = '%s:%s' % (etype, port_id)
            # Check for switch vlan bindings
            try:
                # This vlan has already been created on this switch
                # via another operation, like SVI bindings.
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
                vlan_created = True
                auto_create = False
            except cisco_exc.NexusPortBindingNotFound:
                # No changes, proceed as normal
                pass

            try:
                nxos_db.get_port_vlan_switch_binding(eport_id, vlan_id,
                                                     switch_ip)
            except cisco_exc.NexusPortBindingNotFound:
                if auto_create and auto_trunk:
                    # Create vlan and trunk vlan on the port
                    LOG.debug(_("Nexus: create & trunk vlan %s"), vlan_name)
                    self._client.create_and_trunk_vlan(
                        switch_ip, vlan_id, vlan_name, etype, port_id)
                    vlan_created = True
                    vlan_trunked = True
                elif auto_create:
                    # Create vlan but do not trunk it on the port
                    LOG.debug(_("Nexus: create vlan %s"), vlan_name)
                    self._client.create_vlan(switch_ip, vlan_id, vlan_name)
                    vlan_created = True
                elif auto_trunk:
                    # Only trunk vlan on the port
                    LOG.debug(_("Nexus: trunk vlan %s"), vlan_name)
                    self._client.enable_vlan_on_trunk_int(
                        switch_ip, vlan_id, etype, port_id)
                    vlan_trunked = True

            try:
                instance = attachment[const.INSTANCE_ID]
                nxos_db.add_nexusport_binding(eport_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._client.delete_and_untrunk_vlan(switch_ip,
                                                             vlan_id,
                                                             etype, port_id)
                    elif vlan_created:
                        LOG.debug(_("Nexus: delete vlan %s"), vlan_name)
                        self._client.delete_vlan(switch_ip, vlan_id)
                    elif vlan_trunked:
                        LOG.debug(_("Nexus: untrunk vlan %s"), vlan_name)
                        self._client.disable_vlan_on_trunk_int(switch_ip,
                                                               vlan_id,
                                                               etype,
                                                               port_id)

        net_id = network[const.NET_ID]
        new_net_dict = {const.NET_ID: net_id,
                        const.NET_NAME: network[const.NET_NAME],
                        const.NET_PORTS: {},
                        const.NET_VLAN_NAME: vlan_name,
                        const.NET_VLAN_ID: vlan_id}
        self._networks[net_id] = new_net_dict
        return new_net_dict
Esempio n. 19
0
    def create_network(self, network, attachment):
        """Create or update a network when an attachment is changed.

        This method is not invoked at the usual plugin create_network() time.
        Instead, it is invoked on create/update port.

        :param network: Network on which the port operation is happening
        :param attachment: Details about the owner of the port

        Create a VLAN in the appropriate switch/port, and configure the
        appropriate interfaces for this VLAN.
        """
        LOG.debug(_("NexusPlugin:create_network() called"))
        # Grab the switch IP and port for this host
        host = str(attachment[const.HOST_NAME])
        switch_ip, port_id = self._client.get_switch_and_port_id(host)
        if not switch_ip and not port_id:
            raise cisco_exc.NexusComputeHostNotConfigured(host=host)

        vlan_id = network[const.NET_VLAN_ID]
        vlan_name = network[const.NET_VLAN_NAME]
        auto_create = True
        auto_trunk = True
        if cdb.is_provider_vlan(vlan_id):
            vlan_name = ''.join(
                [conf.CISCO.provider_vlan_name_prefix,
                 str(vlan_id)])
            auto_create = conf.CISCO.provider_vlan_auto_create
            auto_trunk = conf.CISCO.provider_vlan_auto_trunk

        # 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 cisco_exc.NexusPortBindingNotFound:
            # Check for vlan/switch binding
            try:
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
            except cisco_exc.NexusPortBindingNotFound:
                if auto_create and auto_trunk:
                    # Create vlan and trunk vlan on the port
                    LOG.debug("Nexus: create & trunk vlan %s" % vlan_name)
                    self._client.create_and_trunk_vlan(switch_ip, vlan_id,
                                                       vlan_name, port_id)
                    vlan_created = True
                    vlan_trunked = True
                elif auto_create:
                    # Create vlan but do not trunk it on the port
                    LOG.debug("Nexus: create vlan %s" % vlan_name)
                    self._client.create_vlan(switch_ip, vlan_id, vlan_name)
                    vlan_created = True
            else:
                if auto_trunk:
                    # Only trunk vlan on the port
                    LOG.debug("Nexus: trunk vlan %s" % vlan_name)
                    self._client.enable_vlan_on_trunk_int(
                        switch_ip, vlan_id, port_id)
                    vlan_trunked = True

        try:
            instance = attachment[const.INSTANCE_ID]
            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._client.delete_and_untrunk_vlan(
                        switch_ip, vlan_id, port_id)
                elif vlan_created:
                    LOG.debug("Nexus: delete vlan %s" % vlan_name)
                    self._client.delete_vlan(switch_ip, vlan_id)
                elif vlan_trunked:
                    LOG.debug("Nexus: untrunk vlan %s" % vlan_name)
                    self._client.disable_vlan_on_trunk_int(
                        switch_ip, vlan_id, port_id)

        net_id = network[const.NET_ID]
        new_net_dict = {
            const.NET_ID: net_id,
            const.NET_NAME: network[const.NET_NAME],
            const.NET_PORTS: {},
            const.NET_VLAN_NAME: vlan_name,
            const.NET_VLAN_ID: vlan_id
        }
        self._networks[net_id] = new_net_dict
        return new_net_dict
    def create_network(self, network, attachment):
        """Create or update a network when an attachment is changed.

        This method is not invoked at the usual plugin create_network() time.
        Instead, it is invoked on create/update port.

        :param network: Network on which the port operation is happening
        :param attachment: Details about the owner of the port

        Create a VLAN in the appropriate switch/port, and configure the
        appropriate interfaces for this VLAN.
        """
        LOG.debug(_("NexusPlugin:create_network() called"))
        # Grab the switch IP and port for this host
        host = str(attachment[const.HOST_NAME])
        switch_ip, port_id = self._client.get_switch_and_port_id(host)
        if not switch_ip and not port_id:
            raise cisco_exc.NexusComputeHostNotConfigured(host=host)

        vlan_id = network[const.NET_VLAN_ID]
        vlan_name = network[const.NET_VLAN_NAME]
        auto_create = True
        auto_trunk = True
        if cdb.is_provider_vlan(vlan_id):
            vlan_name = ''.join([conf.CISCO.provider_vlan_name_prefix,
                                 str(vlan_id)])
            auto_create = conf.CISCO.provider_vlan_auto_create
            auto_trunk = conf.CISCO.provider_vlan_auto_trunk

        # 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 cisco_exc.NexusPortBindingNotFound:
            # Check for vlan/switch binding
            try:
                nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
            except cisco_exc.NexusPortBindingNotFound:
                if auto_create and auto_trunk:
                    # Create vlan and trunk vlan on the port
                    LOG.debug("Nexus: create & trunk vlan %s" % vlan_name)
                    self._client.create_and_trunk_vlan(
                        switch_ip, vlan_id, vlan_name, port_id)
                    vlan_created = True
                    vlan_trunked = True
                elif auto_create:
                    # Create vlan but do not trunk it on the port
                    LOG.debug("Nexus: create vlan %s" % vlan_name)
                    self._client.create_vlan(switch_ip, vlan_id, vlan_name)
                    vlan_created = True
            else:
                if auto_trunk:
                    # Only trunk vlan on the port
                    LOG.debug("Nexus: trunk vlan %s" % vlan_name)
                    self._client.enable_vlan_on_trunk_int(
                        switch_ip, vlan_id, port_id)
                    vlan_trunked = True

        try:
            instance = attachment[const.INSTANCE_ID]
            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._client.delete_and_untrunk_vlan(switch_ip, vlan_id,
                                                         port_id)
                elif vlan_created:
                    LOG.debug("Nexus: delete vlan %s" % vlan_name)
                    self._client.delete_vlan(switch_ip, vlan_id)
                elif vlan_trunked:
                    LOG.debug("Nexus: untrunk vlan %s" % vlan_name)
                    self._client.disable_vlan_on_trunk_int(switch_ip, vlan_id,
                                                           port_id)

        net_id = network[const.NET_ID]
        new_net_dict = {const.NET_ID: net_id,
                        const.NET_NAME: network[const.NET_NAME],
                        const.NET_PORTS: {},
                        const.NET_VLAN_NAME: vlan_name,
                        const.NET_VLAN_ID: vlan_id}
        self._networks[net_id] = new_net_dict
        return new_net_dict