nexus_ssh_port=22
[DRIVER]
-#name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver
+#name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver_v2.CiscoNEXUSDriver
name=quantum.plugins.cisco.tests.unit.v2.nexus.fake_nexus_driver.CiscoNEXUSFakeDriver
(Note that you should not be using the create port core API in the above case.)
+Using an independent plugin as a device sub-plugin
+-------------------------------------------------
+
+If you would like to use an independent virtual switch plugin as one of the sub-plugins
+(for eg: the OpenVSwitch plugin) with the nexus device sub-plugin perform the following steps:
+
+(The following instructions are with respect to the OpenVSwitch plugin)
+1. Update etc/quantum/plugins/cisco/l2network_plugin.ini
+ In the [MODEL] section of the configuration file put the following configuration
+ (note that this should be the only configuration in this section, all other configuration
+ should be either removed or commented)
+
+ model_class=quantum.plugins.cisco.models.virt_phy_sw_v2.VirtualPhysicalSwitchModelV2
+
+2. Update etc/quantum/plugins/cisco/cisco_plugins.ini
+ In the [PLUGINS] section of the configuration file put the following configuration:
+
+ vswitch_plugin=quantum.plugins.openvswitch.ovs_quantum_plugin.OVSQuantumPluginV2
+
+3. Set the DB name, the same name has to be configured in three places:
+ In etc/quantum/plugins/cisco/conf/db_conn.ini set the "name" value
+ In /etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini set the "sql_connection"
+ In /etc/quantum/dhcp_agent.ini set the "db_connection"
+
+4. The range of VLAN IDs has to be set in the OpenVSwitch configuration file:
+ In /etc/quantum/plugins/openvswitch/ovs_quantum_plugin.ini
+ Set:
+ vlan_min = <lower_id>
+ vlan_max = <higher_id>
+ enable_tunneling = False
+
+5. For Nexus device sub-plugin configuration refer to the above sections
How to test the installation
----------------------------
NEXUS_PLUGIN = 'nexus_plugin'
UCS_INVENTORY = 'ucs_inventory'
NEXUS_INVENTORY = 'nexus_inventory'
+VSWITCH_PLUGIN = 'vswitch_plugin'
PLUGIN_OBJ_REF = 'plugin-obj-ref'
PARAM_LIST = 'param-list'
LOG.debug("get_all_vlan_bindings() called")
session = db.get_session()
try:
- bindings = session.query(network_models_v2.VlanBinding).all()
+ bindings = session.query(network_models_v2.Vlan_Binding).all()
return bindings
except exc.NoResultFound:
return []
LOG.debug("get_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(network_models_v2.VlanBinding).
+ binding = (session.query(network_models_v2.Vlan_Binding).
filter_by(network_id=netid).one())
return binding
except exc.NoResultFound:
LOG.debug("add_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(network_models_v2.VlanBinding).
+ binding = (session.query(network_models_v2.Vlan_Binding).
filter_by(vlan_id=vlanid).one())
raise c_exc.NetworkVlanBindingAlreadyExists(vlan_id=vlanid,
network_id=netid)
except exc.NoResultFound:
- binding = network_models_v2.VlanBinding(vlanid, vlanname, netid)
+ binding = network_models_v2.Vlan_Binding(vlanid, vlanname, netid)
session.add(binding)
session.flush()
return binding
LOG.debug("remove_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(network_models_v2.VlanBinding).
+ binding = (session.query(network_models_v2.Vlan_Binding).
filter_by(network_id=netid).one())
session.delete(binding)
session.flush()
LOG.debug("update_vlan_binding() called")
session = db.get_session()
try:
- binding = (session.query(network_models_v2.VlanBinding).
+ binding = (session.query(network_models_v2.Vlan_Binding).
filter_by(network_id=netid).one())
if newvlanid:
binding["vlan_id"] = newvlanid
class VlanID(model_base.BASEV2, L2NetworkBase):
"""Represents a vlan_id usage"""
- __tablename__ = 'vlan_ids'
+ __tablename__ = 'cisco_vlan_ids'
vlan_id = Column(Integer, primary_key=True)
vlan_used = Column(Boolean)
return "<VlanID(%d,%s)>" % (self.vlan_id, self.vlan_used)
-class VlanBinding(model_base.BASEV2, L2NetworkBase):
+class Vlan_Binding(model_base.BASEV2, L2NetworkBase):
"""Represents a binding of vlan_id to network_id"""
- __tablename__ = 'vlan_bindings'
+ __tablename__ = 'cisco_vlan_bindings'
vlan_id = Column(Integer, primary_key=True)
vlan_name = Column(String(255))
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2012 Cisco Systems, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+# @author: Sumit Naiksatam, Cisco Systems, Inc.
+# @author: Rohit Agarwalla, Cisco Systems, Inc.
+
+from copy import deepcopy
+import inspect
+import logging
+
+from quantum.manager import QuantumManager
+from quantum.openstack.common import importutils
+from quantum.plugins.cisco.common import cisco_constants as const
+from quantum.plugins.cisco.common import cisco_credentials_v2 as cred
+from quantum.plugins.cisco.db import network_db_v2 as cdb
+from quantum.plugins.cisco import l2network_plugin_configuration as conf
+from quantum.plugins.openvswitch import ovs_db_v2 as odb
+from quantum import quantum_plugin_base_v2
+
+
+LOG = logging.getLogger(__name__)
+
+
+class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
+ """
+ This implementation works with OVS and Nexus plugin for the
+ following topology:
+ One or more servers to a nexus switch.
+ """
+ MANAGE_STATE = True
+ supported_extension_aliases = []
+ _plugins = {}
+ _inventory = {}
+ _methods_to_delegate = ['update_network', 'get_network', 'get_networks',
+ 'create_port', 'delete_port', 'update_port',
+ 'get_port', 'get_ports',
+ 'create_subnet', 'delete_subnet', 'update_subnet',
+ 'get_subnet', 'get_subnets']
+
+ def __init__(self):
+ """
+ Initialize the segmentation manager, check which device plugins are
+ configured, and load the inventories those device plugins for which the
+ inventory is configured
+ """
+ cdb.initialize()
+ cred.Store.initialize()
+ for key in conf.PLUGINS[const.PLUGINS].keys():
+ plugin_obj = conf.PLUGINS[const.PLUGINS][key]
+ self._plugins[key] = importutils.import_object(plugin_obj)
+ LOG.debug("Loaded device plugin %s\n" %
+ conf.PLUGINS[const.PLUGINS][key])
+ if key in conf.PLUGINS[const.INVENTORY].keys():
+ inventory_obj = conf.PLUGINS[const.INVENTORY][key]
+ self._inventory[key] = importutils.import_object(inventory_obj)
+ LOG.debug("Loaded device inventory %s\n" %
+ conf.PLUGINS[const.INVENTORY][key])
+
+ LOG.debug("%s.%s init done" % (__name__, self.__class__.__name__))
+
+ def __getattribute__(self, name):
+ methods = object.__getattribute__(self, "_methods_to_delegate")
+ if name in methods:
+ return getattr(object.__getattribute__(self, "_plugins")
+ [const.VSWITCH_PLUGIN], name)
+ else:
+ return object.__getattribute__(self, name)
+
+ def _func_name(self, offset=0):
+ """Get the name of the calling function"""
+ frame_record = inspect.stack()[1 + offset]
+ func_name = frame_record[3]
+ return func_name
+
+ def _invoke_plugin_per_device(self, plugin_key, function_name, args):
+ """
+ Invokes a device plugin's relevant functions (on the it's
+ inventory and plugin implementation) for completing this operation.
+ """
+ if not plugin_key in self._plugins.keys():
+ LOG.info("No %s Plugin loaded" % plugin_key)
+ LOG.info("%s: %s with args %s ignored" %
+ (plugin_key, function_name, args))
+ return
+ device_params = self._invoke_inventory(plugin_key, function_name,
+ args)
+ device_ips = device_params[const.DEVICE_IP]
+ if not device_ips:
+ return [self._invoke_plugin(plugin_key, function_name, args,
+ device_params)]
+ else:
+ output = []
+ for device_ip in device_ips:
+ new_device_params = deepcopy(device_params)
+ new_device_params[const.DEVICE_IP] = device_ip
+ output.append(self._invoke_plugin(plugin_key, function_name,
+ args, new_device_params))
+ return output
+
+ def _invoke_inventory(self, plugin_key, function_name, args):
+ """
+ Invokes the relevant function on a device plugin's
+ inventory for completing this operation.
+ """
+ if not plugin_key in self._inventory.keys():
+ LOG.info("No %s inventory loaded" % plugin_key)
+ LOG.info("%s: %s with args %s ignored" %
+ (plugin_key, function_name, args))
+ return {const.DEVICE_IP: []}
+ else:
+ return getattr(self._inventory[plugin_key], function_name)(args)
+
+ def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
+ """
+ Invokes the relevant function on a device plugin's
+ implementation for completing this operation.
+ """
+ func = getattr(self._plugins[plugin_key], function_name)
+ func_args_len = int(inspect.getargspec(func).args.__len__()) - 1
+ fargs, varargs, varkw, defaults = inspect.getargspec(func)
+ if args.__len__() > func_args_len:
+ func_args = args[:func_args_len]
+ extra_args = args[func_args_len:]
+ for dict_arg in extra_args:
+ for k, v in dict_arg.iteritems():
+ kwargs[k] = v
+ return func(*func_args, **kwargs)
+ else:
+ if (varkw == 'kwargs'):
+ return func(*args, **kwargs)
+ else:
+ return func(*args)
+
+ def create_network(self, context, network):
+ """
+ Perform this operation in the context of the configured device
+ plugins.
+ """
+ LOG.debug("create_network() called\n")
+ try:
+ args = [context, 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_name = conf.VLAN_NAME_PREFIX + str(vlan_id)
+ vlan_ids = odb.get_vlans()
+ vlanids = ''
+ for v_id in vlan_ids:
+ vlanids = str(v_id[0]) + ',' + vlanids
+ vlanids = vlanids.strip(',')
+ args = [ovs_output[0]['tenant_id'], ovs_output[0]['name'],
+ ovs_output[0]['id'], vlan_name, vlan_id,
+ {'vlan_ids':vlanids}]
+ nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+ self._func_name(),
+ args)
+ return ovs_output[0]
+ except:
+ # TODO (Sumit): Check if we need to perform any rollback here
+ raise
+
+ def update_network(self, context, id, network):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def delete_network(self, context, id):
+ """
+ Perform this operation in the context of the configured device
+ plugins.
+ """
+ try:
+ base_plugin_ref = QuantumManager.get_plugin()
+ n = base_plugin_ref.get_network(context, id)
+ tenant_id = n['tenant_id']
+ vlan_id = odb.get_vlan(id)
+ output = []
+ args = [tenant_id, id, {const.VLANID:vlan_id},
+ {const.CONTEXT:context},
+ {const.BASE_PLUGIN_REF:base_plugin_ref}]
+ nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
+ self._func_name(),
+ args)
+ args = [context, id]
+ ovs_output = self._invoke_plugin_per_device(const.VSWITCH_PLUGIN,
+ self._func_name(),
+ args)
+ return ovs_output[0]
+ except:
+ raise
+
+ def get_network(self, context, id, fields=None, verbose=None):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def get_networks(self, context, filters=None, fields=None, verbose=None):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def create_port(self, context, port):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def get_port(self, context, id, fields=None, verbose=None):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def get_ports(self, context, filters=None, fields=None, verbose=None):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def update_port(self, context, id, port):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def delete_port(self, context, id, kwargs):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def create_subnet(self, context, subnet):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def update_subnet(self, context, id, subnet):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def get_subnet(self, context, id, fields=None, verbose=None):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def delete_subnet(self, context, id, kwargs):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
+
+ def get_subnets(self, context, filters=None, fields=None, verbose=None):
+ """For this model this method will be delegated to vswitch plugin"""
+ pass
from quantum.plugins.cisco.common import cisco_utils as cutil
from quantum.plugins.cisco.db import network_db_v2 as cdb
from quantum.plugins.cisco import l2network_plugin_configuration as conf
-from quantum.quantum_plugin_base_v2 import QuantumPluginBaseV2
LOG = logging.getLogger(__name__)
class PluginV2(db_base_plugin_v2.QuantumDbPluginV2):
"""
- Plugin with v2 API support for multiple sub-plugins
+ Meta-Plugin with v2 API support for multiple sub-plugins.
"""
supported_extension_aliases = ["Cisco Credential", "Cisco Port Profile",
"Cisco qos", "Cisco Nova Tenant",
"Cisco Multiport"]
+ _methods_to_delegate = ['create_network', 'delete_network',
+ 'update_network', 'get_network', 'get_networks',
+ 'create_port', 'delete_port', 'update_port',
+ 'get_port', 'get_ports',
+ 'create_subnet', 'delete_subnet', 'update_subnet',
+ 'get_subnet', 'get_subnets']
+ _master = True
- """
- Core API implementation
- """
def __init__(self):
"""
- Initializes the DB, and credential store.
+ Loads the model class, initializes the DB, and credential store.
"""
- cdb.initialize()
- cred.Store.initialize()
self._model = importutils.import_object(conf.MODEL_CLASS)
+ if hasattr(self._model, "MANAGE_STATE") and self._model.MANAGE_STATE:
+ self._master = False
+ LOG.debug("Model %s manages state" % conf.MODEL_CLASS)
+ else:
+ cdb.initialize()
+ cred.Store.initialize()
+
+ if hasattr(self._model, "supported_extension_aliases"):
+ self.supported_extension_aliases.extend(
+ self._model.supported_extension_aliases)
+
super(PluginV2, self).__init__()
LOG.debug("Plugin initialization complete")
+ def __getattribute__(self, name):
+ """
+ When the configured model class offers to manage the state of the
+ logical resources, we delegate the core API calls directly to it.
+ """
+ master = object.__getattribute__(self, "_master")
+ methods = object.__getattribute__(self, "_methods_to_delegate")
+ if not master and name in methods:
+ return getattr(object.__getattribute__(self, "_model"),
+ name)
+ else:
+ return object.__getattribute__(self, name)
+
+ def __getattr__(self, name):
+ """
+ This delegates the calls to the extensions explicitly implemented by
+ the model.
+ """
+ if hasattr(self._model, name):
+ return getattr(self._model, name)
+
+ """
+ Core API implementation
+ """
def create_network(self, context, network):
"""
Creates a new Virtual Network, and assigns it
a symbolic name.
"""
LOG.debug("create_network() called\n")
- new_network = super(PluginV2, self).create_network(context, network)
+ new_network = super(PluginV2, self).create_network(context,
+ network)
try:
self._invoke_device_plugins(self._func_name(), [context,
new_network])
return new_network
except:
- super(PluginV2, self).delete_network(context, new_network['id'])
+ super(PluginV2, self).delete_network(context,
+ new_network['id'])
raise
def update_network(self, context, id, network):
try:
self._invoke_device_plugins(self._func_name(), [context, id,
network])
- return super(PluginV2, self).update_network(context, id, network)
+ return super(PluginV2, self).update_network(context, id,
+ network)
except:
raise
#We first need to check if there are any ports on this network
with context.session.begin():
network = self._get_network(context, id)
-
filter = {'network_id': [id]}
ports = self.get_ports(context, filters=filter)
if ports:
except:
raise
+ def get_network(self, context, id, fields=None, verbose=None):
+ """
+ Gets a particular network
+ """
+ LOG.debug("get_network() called\n")
+ return super(PluginV2, self).get_network(context, id,
+ fields, verbose)
+
+ def get_networks(self, context, filters=None, fields=None, verbose=None):
+ """
+ Gets all networks
+ """
+ LOG.debug("get_networks() called\n")
+ return super(PluginV2, self).get_networks(context, filters,
+ fields, verbose)
+
def create_port(self, context, port):
"""
Creates a port on the specified Virtual Network.
"""
def _invoke_device_plugins(self, function_name, args):
"""
- All device-specific calls are delegated to the model
+ Device-specific calls including core API and extensions are
+ delegated to the model.
"""
- return getattr(self._model, function_name)(*args)
+ if hasattr(self._model, function_name):
+ return getattr(self._model, function_name)(*args)
def _func_name(self, offset=0):
"""Getting the name of the calling funciton"""
--- /dev/null
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+#
+# Copyright 2011 Cisco Systems, Inc. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+#
+# @author: Debojyoti Dutta, Cisco Systems, Inc.
+# @author: Edgar Magana, Cisco Systems Inc.
+#
+"""
+Implements a Nexus-OS NETCONF over SSHv2 API Client
+"""
+
+import logging
+
+from ncclient import manager
+
+from quantum.plugins.cisco.db import network_db_v2 as cdb
+from quantum.plugins.cisco.nexus import cisco_nexus_snippets as snipp
+
+
+LOG = logging.getLogger(__name__)
+
+
+class CiscoNEXUSDriver():
+ """
+ Nexus Driver Main Class
+ """
+ def __init__(self):
+ pass
+
+ def nxos_connect(self, nexus_host, nexus_ssh_port, nexus_user,
+ nexus_password):
+ """
+ Makes the SSH connection to the Nexus Switch
+ """
+ man = manager.connect(host=nexus_host, port=nexus_ssh_port,
+ username=nexus_user, password=nexus_password)
+ return man
+
+ def create_xml_snippet(self, cutomized_config):
+ """
+ Creates the Proper XML structure for the Nexus Switch Configuration
+ """
+ conf_xml_snippet = snipp.EXEC_CONF_SNIPPET % (cutomized_config)
+ return conf_xml_snippet
+
+ def enable_vlan(self, mgr, vlanid, vlanname):
+ """
+ Creates a VLAN on Nexus Switch given the VLAN ID and Name
+ """
+ confstr = snipp.CMD_VLAN_CONF_SNIPPET % (vlanid, vlanname)
+ confstr = self.create_xml_snippet(confstr)
+ mgr.edit_config(target='running', config=confstr)
+
+ def disable_vlan(self, mgr, vlanid):
+ """
+ Delete a VLAN on Nexus Switch given the VLAN ID
+ """
+ confstr = snipp.CMD_NO_VLAN_CONF_SNIPPET % vlanid
+ confstr = self.create_xml_snippet(confstr)
+ mgr.edit_config(target='running', config=confstr)
+
+ def enable_port_trunk(self, mgr, interface):
+ """
+ Enables trunk mode an interface on Nexus Switch
+ """
+ confstr = snipp.CMD_PORT_TRUNK % (interface)
+ confstr = self.create_xml_snippet(confstr)
+ LOG.debug("NexusDriver: %s" % confstr)
+ mgr.edit_config(target='running', config=confstr)
+
+ def disable_switch_port(self, mgr, interface):
+ """
+ Disables trunk mode an interface on Nexus Switch
+ """
+ confstr = snipp.CMD_NO_SWITCHPORT % (interface)
+ confstr = self.create_xml_snippet(confstr)
+ LOG.debug("NexusDriver: %s" % confstr)
+ mgr.edit_config(target='running', config=confstr)
+
+ def enable_vlan_on_trunk_int(self, mgr, interface, vlanid):
+ """
+ Enables trunk mode vlan access an interface on Nexus Switch given
+ VLANID
+ """
+ confstr = snipp.CMD_VLAN_INT_SNIPPET % (interface, vlanid)
+ confstr = self.create_xml_snippet(confstr)
+ LOG.debug("NexusDriver: %s" % confstr)
+ mgr.edit_config(target='running', config=confstr)
+
+ def disable_vlan_on_trunk_int(self, mgr, interface, vlanid):
+ """
+ Enables trunk mode vlan access an interface on Nexus Switch given
+ VLANID
+ """
+ confstr = snipp.CMD_NO_VLAN_INT_SNIPPET % (interface, vlanid)
+ confstr = self.create_xml_snippet(confstr)
+ LOG.debug("NexusDriver: %s" % confstr)
+ mgr.edit_config(target='running', config=confstr)
+
+ def create_vlan(self, vlan_name, vlan_id, nexus_host, nexus_user,
+ nexus_password, nexus_ports,
+ nexus_ssh_port, vlan_ids=None):
+ """
+ Creates a VLAN and Enable on trunk mode an interface on Nexus Switch
+ given the VLAN ID and Name and Interface Number
+ """
+ with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
+ nexus_password) as man:
+ self.enable_vlan(man, vlan_id, vlan_name)
+ if vlan_ids is '':
+ vlan_ids = self.build_vlans_cmd()
+ LOG.debug("NexusDriver VLAN IDs: %s" % vlan_ids)
+ for ports in nexus_ports:
+ self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
+
+ def delete_vlan(self, vlan_id, nexus_host, nexus_user, nexus_password,
+ nexus_ports, nexus_ssh_port):
+ """
+ Delete a VLAN and Disables trunk mode an interface on Nexus Switch
+ given the VLAN ID and Interface Number
+ """
+ with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
+ nexus_password) as man:
+ self.disable_vlan(man, vlan_id)
+ for ports in nexus_ports:
+ self.disable_vlan_on_trunk_int(man, ports, vlan_id)
+
+ def build_vlans_cmd(self):
+ """
+ Builds a string with all the VLANs on the same Switch
+ """
+ assigned_vlan = cdb.get_all_vlanids_used()
+ vlans = ''
+ for vlanid in assigned_vlan:
+ vlans = str(vlanid["vlan_id"]) + ',' + vlans
+ if vlans == '':
+ vlans = 'none'
+ return vlans.strip(',')
for this VLAN
"""
LOG.debug("NexusPlugin:create_network() called\n")
+ vlan_ids = ''
+ for key in kwargs:
+ if key == 'vlan_ids':
+ vlan_ids = kwargs['vlan_ids']
self._client.create_vlan(
vlan_name, str(vlan_id), self._nexus_ip,
self._nexus_username, self._nexus_password,
- self._nexus_ports, self._nexus_ssh_port)
+ self._nexus_ports, self._nexus_ssh_port, vlan_ids)
for ports in self._nexus_ports:
try:
nxos_db.add_nexusport_binding(ports, str(vlan_id))
from the relevant interfaces
"""
LOG.debug("NexusPlugin:delete_network() called\n")
+ vlan_id = None
context = kwargs[const.CONTEXT]
base_plugin_ref = kwargs[const.BASE_PLUGIN_REF]
- vlan_id = self._get_vlan_id_for_network(tenant_id, net_id,
- context, base_plugin_ref)
+ for key in kwargs:
+ if 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,
+ context, base_plugin_ref)
ports_id = nxos_db.get_nexusport_binding(vlan_id)
LOG.debug("NexusPlugin: Interfaces to be disassociated: %s" % ports_id)
nxos_db.remove_nexusport_binding(vlan_id)
"""
Obtain the VLAN ID given the Network ID
"""
- net = self._get_network(tenant_id, network_id, context,
- base_plugin_ref)
- vlan_id = net[const.NET_VLAN_ID]
- return vlan_id
+ vlan = cdb.get_vlan_binding(network_id)
+ return vlan.vlan_id
def _get_network(self, tenant_id, network_id, context, base_plugin_ref):
"""
network = base_plugin_ref._get_network(context, network_id)
if not network:
raise exc.NetworkNotFound(net_id=network_id)
- vlan = cdb.get_vlan_binding(network_id)
return {const.NET_ID: network_id, const.NET_NAME: network.name,
- const.NET_PORTS: network.ports,
- const.NET_VLAN_NAME: vlan.vlan_name,
- const.NET_VLAN_ID: vlan.vlan_id}
+ const.NET_PORTS: network.ports}
# The following are standard strings, messages used to communicate with Nexus,
EXEC_CONF_SNIPPET = """
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
- <configure xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
+ <configure>
<__XML__MODE__exec_configure>%s
</__XML__MODE__exec_configure>
</configure>
from quantum.api.v2.router import APIRouter
from quantum.common import config
from quantum.db import api as db
+from quantum.manager import QuantumManager
from quantum.plugins.cisco.db import network_models_v2
from quantum.openstack.common import cfg
from quantum.tests.unit import test_db_plugin
def setUp(self):
db._ENGINE = None
db._MAKER = None
-
+ QuantumManager._instance = None
self._tenant_id = 'test-tenant'
json_deserializer = JSONDeserializer()