Adding multi switch support to the Cisco Nexus plugin
This commit adds intelligent multiple nexus physical switch support for the Cisco plugin. The plugin also has been modified to scan for the host when an instance is created and selectively trunk VLAN's for the port for that host only. It also deletes VLANs from nexus switches when no longer required. Implements: blueprint cisco-plugin-enhancements Change-Id: I6275eb1815310d0d5a8123ca2edbc0a0937718e9
This commit is contained in:
parent
bc5e98710f
commit
830820184a
@ -4,7 +4,13 @@ username=<put_user_name_here>
|
|||||||
password=<put_password_here>
|
password=<put_password_here>
|
||||||
|
|
||||||
#Provide the Nexus credentials, if you are using Nexus
|
#Provide the Nexus credentials, if you are using Nexus
|
||||||
[1.1.1.1]
|
[<put_nexus_switch_ip_address_here>]
|
||||||
username=abc
|
username=<put_user_name_here>
|
||||||
password=def
|
password=<put_password_here>
|
||||||
|
|
||||||
|
# Provide credentials and endpoint
|
||||||
|
# for keystone here
|
||||||
|
[keystone]
|
||||||
|
auth_url=<put_keystone_endpoint_here>
|
||||||
|
username=<put_user_name_here>
|
||||||
|
password=<put_password_here>
|
||||||
|
@ -18,3 +18,7 @@ model_class=quantum.plugins.cisco.models.virt_phy_sw_v2.VirtualPhysicalSwitchMod
|
|||||||
|
|
||||||
[SEGMENTATION]
|
[SEGMENTATION]
|
||||||
manager_class=quantum.plugins.cisco.segmentation.l2network_vlan_mgr_v2.L2NetworkVLANMgr
|
manager_class=quantum.plugins.cisco.segmentation.l2network_vlan_mgr_v2.L2NetworkVLANMgr
|
||||||
|
|
||||||
|
# IMPORTANT: Comment the following lines for production deployments
|
||||||
|
[TEST]
|
||||||
|
host=testhost
|
||||||
|
@ -1,10 +1,13 @@
|
|||||||
[SWITCH]
|
[SWITCH]
|
||||||
# Change the following to reflect the Nexus switch details
|
# Ip address of the switch
|
||||||
nexus_ip_address=<put_nexus_switch_ip_address_here>
|
[[<put_nexus_switch_ip_address_here>]]
|
||||||
#Interfaces connected from the Nexus Switch to the compute hosts ports, e.g.: 1/10 and 1/11
|
# Hostname of the node
|
||||||
ports=<put_interfaces_names_here_separated_by_commas>
|
[[[<put_hostname_here>]]]
|
||||||
#Port number where the SSH will be running at the Nexus Switch, e.g.: 22 (Default)
|
# Port this node is connected to on the nexus switch
|
||||||
nexus_ssh_port=22
|
ports=<put_port_id_here>
|
||||||
|
# Port number where the SSH will be running at the Nexus Switch, e.g.: 22 (Default)
|
||||||
|
[[[ssh_port]]]
|
||||||
|
ssh_port=<put_port_number_here>
|
||||||
|
|
||||||
[DRIVER]
|
[DRIVER]
|
||||||
#name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver_v2.CiscoNEXUSDriver
|
#name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver_v2.CiscoNEXUSDriver
|
||||||
|
@ -13,18 +13,22 @@
|
|||||||
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
# License for the specific language governing permissions and limitations
|
# License for the specific language governing permissions and limitations
|
||||||
# under the License.
|
# under the License.
|
||||||
|
#
|
||||||
# @author: Rohit Agarwalla, Cisco Systems, Inc.
|
# @author: Rohit Agarwalla, Cisco Systems, Inc.
|
||||||
|
# @author: Arvind Somya, Cisco Systems, Inc. (asomya@cisco.com)
|
||||||
import logging as LOG
|
#
|
||||||
|
|
||||||
from sqlalchemy.orm import exc
|
from sqlalchemy.orm import exc
|
||||||
|
|
||||||
import quantum.db.api as db
|
import quantum.db.api as db
|
||||||
|
from quantum.openstack.common import log as logging
|
||||||
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
|
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
|
||||||
from quantum.plugins.cisco.db import nexus_models_v2
|
from quantum.plugins.cisco.db import nexus_models_v2
|
||||||
|
|
||||||
|
|
||||||
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
def get_all_nexusport_bindings():
|
def get_all_nexusport_bindings():
|
||||||
"""Lists all the nexusport bindings"""
|
"""Lists all the nexusport bindings"""
|
||||||
LOG.debug("get_all_nexusport_bindings() called")
|
LOG.debug("get_all_nexusport_bindings() called")
|
||||||
@ -36,35 +40,54 @@ def get_all_nexusport_bindings():
|
|||||||
return []
|
return []
|
||||||
|
|
||||||
|
|
||||||
def get_nexusport_binding(vlan_id):
|
def get_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
|
||||||
"""Lists a nexusport binding"""
|
"""Lists a nexusport binding"""
|
||||||
LOG.debug("get_nexusport_binding() called")
|
LOG.debug("get_nexusport_binding() called")
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
try:
|
try:
|
||||||
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
filter_by(vlan_id=vlan_id).all())
|
filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
|
||||||
|
filter_by(port_id=port_id).
|
||||||
|
filter_by(instance_id=instance_id).all())
|
||||||
return binding
|
return binding
|
||||||
except exc.NoResultFound:
|
except exc.NoResultFound:
|
||||||
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
|
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
|
||||||
|
|
||||||
|
|
||||||
def add_nexusport_binding(port_id, vlan_id):
|
def get_nexusvlan_binding(vlan_id, switch_ip):
|
||||||
|
"""Lists a vlan and switch binding"""
|
||||||
|
LOG.debug("get_nexusvlan_binding() called")
|
||||||
|
session = db.get_session()
|
||||||
|
try:
|
||||||
|
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
|
filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
|
||||||
|
all())
|
||||||
|
return binding
|
||||||
|
except exc.NoResultFound:
|
||||||
|
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
|
||||||
|
|
||||||
|
|
||||||
|
def add_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
|
||||||
"""Adds a nexusport binding"""
|
"""Adds a nexusport binding"""
|
||||||
LOG.debug("add_nexusport_binding() called")
|
LOG.debug("add_nexusport_binding() called")
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
binding = nexus_models_v2.NexusPortBinding(port_id, vlan_id)
|
binding = nexus_models_v2.NexusPortBinding(
|
||||||
|
port_id, vlan_id, switch_ip, instance_id)
|
||||||
session.add(binding)
|
session.add(binding)
|
||||||
session.flush()
|
session.flush()
|
||||||
return binding
|
return binding
|
||||||
|
|
||||||
|
|
||||||
def remove_nexusport_binding(vlan_id):
|
def remove_nexusport_binding(port_id, vlan_id, switch_ip, instance_id):
|
||||||
"""Removes a nexusport binding"""
|
"""Removes a nexusport binding"""
|
||||||
LOG.debug("remove_nexusport_binding() called")
|
LOG.debug("remove_nexusport_binding() called")
|
||||||
session = db.get_session()
|
session = db.get_session()
|
||||||
try:
|
try:
|
||||||
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
filter_by(vlan_id=vlan_id).all())
|
filter_by(vlan_id=vlan_id).filter_by(switch_ip=switch_ip).
|
||||||
|
filter_by(port_id=port_id).
|
||||||
|
filter_by(instance_id=instance_id).all())
|
||||||
|
|
||||||
for bind in binding:
|
for bind in binding:
|
||||||
session.delete(bind)
|
session.delete(bind)
|
||||||
session.flush()
|
session.flush()
|
||||||
@ -87,3 +110,29 @@ def update_nexusport_binding(port_id, new_vlan_id):
|
|||||||
return binding
|
return binding
|
||||||
except exc.NoResultFound:
|
except exc.NoResultFound:
|
||||||
raise c_exc.NexusPortBindingNotFound()
|
raise c_exc.NexusPortBindingNotFound()
|
||||||
|
|
||||||
|
|
||||||
|
def get_nexusvm_binding(vlan_id, instance_id):
|
||||||
|
"""Lists nexusvm bindings"""
|
||||||
|
LOG.debug("get_nexusvm_binding() called")
|
||||||
|
session = db.get_session()
|
||||||
|
try:
|
||||||
|
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
|
filter_by(instance_id=instance_id).
|
||||||
|
filter_by(vlan_id=vlan_id).first())
|
||||||
|
return binding
|
||||||
|
except exc.NoResultFound:
|
||||||
|
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
|
||||||
|
|
||||||
|
|
||||||
|
def get_port_vlan_switch_binding(port_id, vlan_id, switch_ip):
|
||||||
|
"""Lists nexusvm bindings"""
|
||||||
|
LOG.debug("get_port_vlan_switch_binding() called")
|
||||||
|
session = db.get_session()
|
||||||
|
try:
|
||||||
|
binding = (session.query(nexus_models_v2.NexusPortBinding).
|
||||||
|
filter_by(port_id=port_id).filter_by(switch_ip=switch_ip).
|
||||||
|
filter_by(vlan_id=vlan_id).all())
|
||||||
|
return binding
|
||||||
|
except exc.NoResultFound:
|
||||||
|
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
|
||||||
|
@ -22,16 +22,21 @@ from quantum.plugins.cisco.db.l2network_models import L2NetworkBase
|
|||||||
|
|
||||||
|
|
||||||
class NexusPortBinding(model_base.BASEV2, L2NetworkBase):
|
class NexusPortBinding(model_base.BASEV2, L2NetworkBase):
|
||||||
"""Represents a binding of nexus port to vlan_id"""
|
"""Represents a binding of VM's to nexus ports"""
|
||||||
__tablename__ = 'nexusport_bindings'
|
__tablename__ = "nexusport_bindings"
|
||||||
|
|
||||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||||
port_id = Column(String(255))
|
port_id = Column(String(255))
|
||||||
vlan_id = Column(Integer, nullable=False)
|
vlan_id = Column(Integer, nullable=False)
|
||||||
|
switch_ip = Column(String(255))
|
||||||
|
instance_id = Column(String(255))
|
||||||
|
|
||||||
def __init__(self, port_id, vlan_id):
|
def __init__(self, port_id, vlan_id, switch_ip, instance_id):
|
||||||
self.port_id = port_id
|
self.port_id = port_id
|
||||||
self.vlan_id = vlan_id
|
self.vlan_id = vlan_id
|
||||||
|
self.switch_ip = switch_ip
|
||||||
|
self.instance_id = instance_id
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<NexusPortBinding (%s,%d)>" % (self.port_id, self.vlan_id)
|
return "<NexusPortBinding (%s,%d, %s, %s)>" % \
|
||||||
|
(self.port_id, self.vlan_id, self.switch_ip, self.instance_id)
|
||||||
|
@ -43,6 +43,9 @@ MAX_NETWORKS = SECTION_CONF['max_networks']
|
|||||||
SECTION_CONF = CONF_PARSER_OBJ['MODEL']
|
SECTION_CONF = CONF_PARSER_OBJ['MODEL']
|
||||||
MODEL_CLASS = SECTION_CONF['model_class']
|
MODEL_CLASS = SECTION_CONF['model_class']
|
||||||
|
|
||||||
|
if 'TEST' in CONF_PARSER_OBJ.keys():
|
||||||
|
TEST = CONF_PARSER_OBJ['TEST']
|
||||||
|
|
||||||
CONF_FILE = find_config_file({'plugin': 'cisco'}, "cisco_plugins.ini")
|
CONF_FILE = find_config_file({'plugin': 'cisco'}, "cisco_plugins.ini")
|
||||||
|
|
||||||
SECTION_CONF = CONF_PARSER_OBJ['SEGMENTATION']
|
SECTION_CONF = CONF_PARSER_OBJ['SEGMENTATION']
|
||||||
@ -51,7 +54,6 @@ MANAGER_CLASS = SECTION_CONF['manager_class']
|
|||||||
|
|
||||||
CONF_PARSER_OBJ = confp.CiscoConfigParser(CONF_FILE)
|
CONF_PARSER_OBJ = confp.CiscoConfigParser(CONF_FILE)
|
||||||
|
|
||||||
|
|
||||||
# Read the config for the device plugins
|
# Read the config for the device plugins
|
||||||
PLUGINS = CONF_PARSER_OBJ.walk(CONF_PARSER_OBJ.dummy)
|
PLUGINS = CONF_PARSER_OBJ.walk(CONF_PARSER_OBJ.dummy)
|
||||||
|
|
||||||
|
@ -21,6 +21,10 @@ from copy import deepcopy
|
|||||||
import inspect
|
import inspect
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
from keystoneclient.v2_0 import client as keystone_client
|
||||||
|
from novaclient.v1_1 import client as nova_client
|
||||||
|
|
||||||
|
from quantum.db import l3_db
|
||||||
from quantum.manager import QuantumManager
|
from quantum.manager import QuantumManager
|
||||||
from quantum.openstack.common import importutils
|
from quantum.openstack.common import importutils
|
||||||
from quantum.plugins.cisco.common import cisco_constants as const
|
from quantum.plugins.cisco.common import cisco_constants as const
|
||||||
@ -30,7 +34,6 @@ from quantum.plugins.cisco import l2network_plugin_configuration as conf
|
|||||||
from quantum.plugins.openvswitch import ovs_db_v2 as odb
|
from quantum.plugins.openvswitch import ovs_db_v2 as odb
|
||||||
from quantum import quantum_plugin_base_v2
|
from quantum import quantum_plugin_base_v2
|
||||||
|
|
||||||
|
|
||||||
LOG = logging.getLogger(__name__)
|
LOG = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -46,11 +49,11 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
_plugins = {}
|
_plugins = {}
|
||||||
_inventory = {}
|
_inventory = {}
|
||||||
_methods_to_delegate = ['get_network', 'get_networks',
|
_methods_to_delegate = ['get_network', 'get_networks',
|
||||||
'create_port', 'create_port_bulk', 'delete_port',
|
'create_port_bulk', 'update_port',
|
||||||
'update_port', 'get_port', 'get_ports',
|
'get_port', 'get_ports',
|
||||||
'create_subnet', 'create_subnet_bulk',
|
'create_subnet', 'create_subnet_bulk',
|
||||||
'delete_subnet', 'update_subnet', 'get_subnet',
|
'delete_subnet', 'update_subnet',
|
||||||
'get_subnets', ]
|
'get_subnet', 'get_subnets', ]
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
"""
|
"""
|
||||||
@ -181,6 +184,25 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
def _get_instance_host(self, tenant_id, instance_id):
|
||||||
|
keystone = cred._creds_dictionary['keystone']
|
||||||
|
kc = keystone_client.Client(username=keystone['username'],
|
||||||
|
password=keystone['password'],
|
||||||
|
tenant_id=tenant_id,
|
||||||
|
auth_url=keystone['auth_url'])
|
||||||
|
tenant = kc.tenants.get(tenant_id)
|
||||||
|
tenant_name = tenant.name
|
||||||
|
|
||||||
|
nc = nova_client.Client(keystone['username'],
|
||||||
|
keystone['password'],
|
||||||
|
tenant_name,
|
||||||
|
keystone['auth_url'],
|
||||||
|
no_cache=True)
|
||||||
|
serv = nc.servers.get(instance_id)
|
||||||
|
host = serv.__getattr__('OS-EXT-SRV-ATTR:host')
|
||||||
|
|
||||||
|
return host
|
||||||
|
|
||||||
def create_network(self, context, network):
|
def create_network(self, context, network):
|
||||||
"""
|
"""
|
||||||
Perform this operation in the context of the configured device
|
Perform this operation in the context of the configured device
|
||||||
@ -200,9 +222,6 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
args = [ovs_output[0]['tenant_id'], ovs_output[0]['name'],
|
args = [ovs_output[0]['tenant_id'], ovs_output[0]['name'],
|
||||||
ovs_output[0]['id'], vlan_name, vlan_id,
|
ovs_output[0]['id'], vlan_name, vlan_id,
|
||||||
{'vlan_ids': vlanids}]
|
{'vlan_ids': vlanids}]
|
||||||
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
|
|
||||||
self._func_name(),
|
|
||||||
args)
|
|
||||||
return ovs_output[0]
|
return ovs_output[0]
|
||||||
except:
|
except:
|
||||||
# TODO (Sumit): Check if we need to perform any rollback here
|
# TODO (Sumit): Check if we need to perform any rollback here
|
||||||
@ -221,14 +240,6 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
LOG.debug("ovs_output: %s\n " % ovs_output)
|
LOG.debug("ovs_output: %s\n " % ovs_output)
|
||||||
vlanids = self._get_all_segmentation_ids()
|
vlanids = self._get_all_segmentation_ids()
|
||||||
ovs_networks = ovs_output
|
ovs_networks = ovs_output
|
||||||
for ovs_network in ovs_networks:
|
|
||||||
vlan_id = self._get_segmentation_id(ovs_network['id'])
|
|
||||||
vlan_name = conf.VLAN_NAME_PREFIX + str(vlan_id)
|
|
||||||
args = [ovs_network['tenant_id'], ovs_network['name'],
|
|
||||||
ovs_network['id'], vlan_name, vlan_id,
|
|
||||||
{'vlan_ids': vlanids}]
|
|
||||||
nexus_output = self._invoke_plugin_per_device(
|
|
||||||
const.NEXUS_PLUGIN, "create_network", args)
|
|
||||||
return ovs_output
|
return ovs_output
|
||||||
except:
|
except:
|
||||||
# TODO (Sumit): Check if we need to perform any rollback here
|
# TODO (Sumit): Check if we need to perform any rollback here
|
||||||
@ -289,8 +300,41 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
def create_port(self, context, port):
|
def create_port(self, context, port):
|
||||||
"""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("create_port() called\n")
|
||||||
|
try:
|
||||||
|
args = [context, port]
|
||||||
|
ovs_output = self._invoke_plugin_per_device(const.VSWITCH_PLUGIN,
|
||||||
|
self._func_name(),
|
||||||
|
args)
|
||||||
|
net_id = port['port']['network_id']
|
||||||
|
instance_id = port['port']['device_id']
|
||||||
|
tenant_id = port['port']['tenant_id']
|
||||||
|
|
||||||
|
net_dict = self.get_network(context, net_id)
|
||||||
|
net_name = net_dict['name']
|
||||||
|
|
||||||
|
vlan_id = self._get_segmentation_id(net_id)
|
||||||
|
host = ''
|
||||||
|
if hasattr(conf, 'TEST'):
|
||||||
|
host = conf.TEST['host']
|
||||||
|
else:
|
||||||
|
host = self._get_instance_host(tenant_id, instance_id)
|
||||||
|
|
||||||
|
# Trunk segmentation id for only this host
|
||||||
|
vlan_name = conf.VLAN_NAME_PREFIX + str(vlan_id)
|
||||||
|
n_args = [tenant_id, net_name, net_id,
|
||||||
|
vlan_name, vlan_id, host, instance_id]
|
||||||
|
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
|
||||||
|
'create_network',
|
||||||
|
n_args)
|
||||||
|
return ovs_output[0]
|
||||||
|
except:
|
||||||
|
# TODO (asomya): Check if we need to perform any rollback here
|
||||||
|
raise
|
||||||
|
|
||||||
def get_port(self, context, id, fields=None):
|
def get_port(self, context, id, fields=None):
|
||||||
"""For this model this method will be delegated to vswitch plugin"""
|
"""For this model this method will be delegated to vswitch plugin"""
|
||||||
@ -304,9 +348,27 @@ class VirtualPhysicalSwitchModelV2(quantum_plugin_base_v2.QuantumPluginBaseV2):
|
|||||||
"""For this model this method will be delegated to vswitch plugin"""
|
"""For this model this method will be delegated to vswitch plugin"""
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def delete_port(self, context, id, kwargs):
|
def delete_port(self, context, id):
|
||||||
"""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("delete_port() called\n")
|
||||||
|
try:
|
||||||
|
args = [context, id]
|
||||||
|
port = self.get_port(context, id)
|
||||||
|
vlan_id = self._get_segmentation_id(port['network_id'])
|
||||||
|
n_args = [port['device_id'], vlan_id]
|
||||||
|
ovs_output = self._invoke_plugin_per_device(const.VSWITCH_PLUGIN,
|
||||||
|
self._func_name(),
|
||||||
|
args)
|
||||||
|
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
|
||||||
|
self._func_name(),
|
||||||
|
n_args)
|
||||||
|
return ovs_output[0]
|
||||||
|
except:
|
||||||
|
# TODO (asomya): Check if we need to perform any rollback here
|
||||||
|
raise
|
||||||
|
|
||||||
def create_subnet(self, context, subnet):
|
def create_subnet(self, context, subnet):
|
||||||
"""For this model this method will be delegated to vswitch plugin"""
|
"""For this model this method will be delegated to vswitch plugin"""
|
||||||
|
@ -30,10 +30,7 @@ from quantum.plugins.cisco.common import cisco_configparser as confp
|
|||||||
CP = confp.CiscoConfigParser(find_config_file({'plugin': 'cisco'},
|
CP = confp.CiscoConfigParser(find_config_file({'plugin': 'cisco'},
|
||||||
"nexus.ini"))
|
"nexus.ini"))
|
||||||
|
|
||||||
SECTION = CP['SWITCH']
|
NEXUS_DETAILS = CP['SWITCH']
|
||||||
NEXUS_IP_ADDRESS = SECTION['nexus_ip_address']
|
|
||||||
NEXUS_PORTS = SECTION['ports']
|
|
||||||
NEXUS_SSH_PORT = SECTION['nexus_ssh_port']
|
|
||||||
|
|
||||||
SECTION = CP['DRIVER']
|
SECTION = CP['DRIVER']
|
||||||
NEXUS_DRIVER = SECTION['name']
|
NEXUS_DRIVER = SECTION['name']
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
Implements a Nexus-OS NETCONF over SSHv2 API Client
|
Implements a Nexus-OS NETCONF over SSHv2 API Client
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import eventlet
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
from ncclient import manager
|
from ncclient import manager
|
||||||
@ -116,14 +117,14 @@ class CiscoNEXUSDriver():
|
|||||||
Creates a VLAN and Enable on trunk mode an interface on Nexus Switch
|
Creates a VLAN and Enable on trunk mode an interface on Nexus Switch
|
||||||
given the VLAN ID and Name and Interface Number
|
given the VLAN ID and Name and Interface Number
|
||||||
"""
|
"""
|
||||||
with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
|
man = self.nxos_connect(nexus_host, int(nexus_ssh_port),
|
||||||
nexus_password) as man:
|
nexus_user, nexus_password)
|
||||||
self.enable_vlan(man, vlan_id, vlan_name)
|
self.enable_vlan(man, vlan_id, vlan_name)
|
||||||
if vlan_ids is '':
|
if vlan_ids is '':
|
||||||
vlan_ids = self.build_vlans_cmd()
|
vlan_ids = self.build_vlans_cmd()
|
||||||
LOG.debug("NexusDriver VLAN IDs: %s" % vlan_ids)
|
LOG.debug("NexusDriver VLAN IDs: %s" % vlan_ids)
|
||||||
for ports in nexus_ports:
|
for ports in nexus_ports:
|
||||||
self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
|
self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
|
||||||
|
|
||||||
def delete_vlan(self, vlan_id, nexus_host, nexus_user, nexus_password,
|
def delete_vlan(self, vlan_id, nexus_host, nexus_user, nexus_password,
|
||||||
nexus_ports, nexus_ssh_port):
|
nexus_ports, nexus_ssh_port):
|
||||||
@ -131,11 +132,11 @@ class CiscoNEXUSDriver():
|
|||||||
Delete a VLAN and Disables trunk mode an interface on Nexus Switch
|
Delete a VLAN and Disables trunk mode an interface on Nexus Switch
|
||||||
given the VLAN ID and Interface Number
|
given the VLAN ID and Interface Number
|
||||||
"""
|
"""
|
||||||
with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
|
man = self.nxos_connect(nexus_host, int(nexus_ssh_port),
|
||||||
nexus_password) as man:
|
nexus_user, nexus_password)
|
||||||
self.disable_vlan(man, vlan_id)
|
self.disable_vlan(man, vlan_id)
|
||||||
for ports in nexus_ports:
|
for ports in nexus_ports:
|
||||||
self.disable_vlan_on_trunk_int(man, ports, vlan_id)
|
self.disable_vlan_on_trunk_int(man, ports, vlan_id)
|
||||||
|
|
||||||
def build_vlans_cmd(self):
|
def build_vlans_cmd(self):
|
||||||
"""
|
"""
|
||||||
@ -154,19 +155,19 @@ class CiscoNEXUSDriver():
|
|||||||
"""
|
"""
|
||||||
Adds a vlan from interfaces on the Nexus switch given the VLAN ID
|
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,
|
man = self.nxos_connect(nexus_host, int(nexus_ssh_port),
|
||||||
nexus_password) as man:
|
nexus_user, nexus_password)
|
||||||
if not vlan_ids:
|
if not vlan_ids:
|
||||||
vlan_ids = self.build_vlans_cmd()
|
vlan_ids = self.build_vlans_cmd()
|
||||||
for ports in nexus_ports:
|
for ports in nexus_ports:
|
||||||
self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
|
self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
|
||||||
|
|
||||||
def remove_vlan_int(self, vlan_id, nexus_host, nexus_user, nexus_password,
|
def remove_vlan_int(self, vlan_id, nexus_host, nexus_user, nexus_password,
|
||||||
nexus_ports, nexus_ssh_port):
|
nexus_ports, nexus_ssh_port):
|
||||||
"""
|
"""
|
||||||
Removes a vlan from interfaces on the Nexus switch given the VLAN ID
|
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,
|
man = self.nxos_connect(nexus_host, int(nexus_ssh_port),
|
||||||
nexus_password) as man:
|
nexus_user, nexus_password)
|
||||||
for ports in nexus_ports:
|
for ports in nexus_ports:
|
||||||
self.disable_vlan_on_trunk_int(man, ports, vlan_id)
|
self.disable_vlan_on_trunk_int(man, ports, vlan_id)
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
#
|
#
|
||||||
# @author: Sumit Naiksatam, Cisco Systems, Inc.
|
# @author: Sumit Naiksatam, Cisco Systems, Inc.
|
||||||
# @author: Edgar Magana, Cisco Systems, Inc.
|
# @author: Edgar Magana, Cisco Systems, Inc.
|
||||||
|
# @author: Arvind Somya, Cisco Systems, Inc. (asomya@cisco.com)
|
||||||
#
|
#
|
||||||
"""
|
"""
|
||||||
PlugIn for Nexus OS driver
|
PlugIn for Nexus OS driver
|
||||||
@ -48,11 +49,18 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
"""
|
"""
|
||||||
self._client = importutils.import_object(conf.NEXUS_DRIVER)
|
self._client = importutils.import_object(conf.NEXUS_DRIVER)
|
||||||
LOG.debug("Loaded driver %s\n" % conf.NEXUS_DRIVER)
|
LOG.debug("Loaded driver %s\n" % conf.NEXUS_DRIVER)
|
||||||
self._nexus_ip = conf.NEXUS_IP_ADDRESS
|
self._nexus_switches = conf.NEXUS_DETAILS
|
||||||
self._nexus_username = cred.Store.get_username(conf.NEXUS_IP_ADDRESS)
|
self.credentials = {}
|
||||||
self._nexus_password = cred.Store.get_password(conf.NEXUS_IP_ADDRESS)
|
|
||||||
self._nexus_ports = conf.NEXUS_PORTS
|
def get_credential(self, nexus_ip):
|
||||||
self._nexus_ssh_port = conf.NEXUS_SSH_PORT
|
if not nexus_ip in self.credentials.keys():
|
||||||
|
_nexus_username = cred.Store.get_username(nexus_ip)
|
||||||
|
_nexus_password = cred.Store.get_password(nexus_ip)
|
||||||
|
self.credentials[nexus_ip] = {
|
||||||
|
'username': _nexus_username,
|
||||||
|
'password': _nexus_password
|
||||||
|
}
|
||||||
|
return self.credentials[nexus_ip]
|
||||||
|
|
||||||
def get_all_networks(self, tenant_id):
|
def get_all_networks(self, tenant_id):
|
||||||
"""
|
"""
|
||||||
@ -64,26 +72,52 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
return self._networks.values()
|
return self._networks.values()
|
||||||
|
|
||||||
def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id,
|
def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id,
|
||||||
**kwargs):
|
host, instance):
|
||||||
"""
|
"""
|
||||||
Create a VLAN in the switch, and configure the appropriate interfaces
|
Create a VLAN in the appropriate switch/port,
|
||||||
|
and configure the appropriate interfaces
|
||||||
for this VLAN
|
for this VLAN
|
||||||
"""
|
"""
|
||||||
LOG.debug("NexusPlugin:create_network() called\n")
|
LOG.debug("NexusPlugin:create_network() called\n")
|
||||||
vlan_ids = ''
|
# Grab the switch IP and port for this host
|
||||||
for key in kwargs:
|
switch_ip = ''
|
||||||
if key == 'vlan_ids':
|
port_id = ''
|
||||||
vlan_ids = kwargs['vlan_ids']
|
for switch in self._nexus_switches.keys():
|
||||||
self._client.create_vlan(
|
for hostname in self._nexus_switches[switch].keys():
|
||||||
vlan_name, str(vlan_id), self._nexus_ip,
|
if str(hostname) == str(host):
|
||||||
self._nexus_username, self._nexus_password,
|
switch_ip = switch
|
||||||
self._nexus_ports, self._nexus_ssh_port, vlan_ids)
|
port_id = self._nexus_switches[switch][hostname]['ports']
|
||||||
for ports in self._nexus_ports:
|
# Check if this network is already in the DB
|
||||||
try:
|
binding = nxos_db.get_port_vlan_switch_binding(
|
||||||
nxos_db.add_nexusport_binding(ports, str(vlan_id))
|
port_id, vlan_id, switch_ip)
|
||||||
except:
|
if not binding:
|
||||||
raise excep.NexusPortBindingAlreadyExists(port_id=ports)
|
_nexus_ip = switch_ip
|
||||||
|
_nexus_ports = (port_id,)
|
||||||
|
_nexus_ssh_port = \
|
||||||
|
self._nexus_switches[switch_ip]['ssh_port']['ssh_port']
|
||||||
|
_nexus_creds = self.get_credential(_nexus_ip)
|
||||||
|
_nexus_username = _nexus_creds['username']
|
||||||
|
_nexus_password = _nexus_creds['password']
|
||||||
|
# Check for vlan/switch binding
|
||||||
|
vbinding = nxos_db.get_nexusvlan_binding(vlan_id, switch_ip)
|
||||||
|
if not vbinding:
|
||||||
|
# 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)
|
||||||
|
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,
|
||||||
|
port_id,
|
||||||
|
vlan_id)
|
||||||
|
|
||||||
|
nxos_db.add_nexusport_binding(port_id, str(vlan_id),
|
||||||
|
switch_ip, instance)
|
||||||
new_net_dict = {const.NET_ID: net_id,
|
new_net_dict = {const.NET_ID: net_id,
|
||||||
const.NET_NAME: net_name,
|
const.NET_NAME: net_name,
|
||||||
const.NET_PORTS: {},
|
const.NET_PORTS: {},
|
||||||
@ -94,32 +128,10 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
|
|
||||||
def delete_network(self, tenant_id, net_id, **kwargs):
|
def delete_network(self, tenant_id, net_id, **kwargs):
|
||||||
"""
|
"""
|
||||||
Deletes a VLAN in the switch, and removes the VLAN configuration
|
Deletes the VLAN in all switches, and removes the VLAN configuration
|
||||||
from the relevant interfaces
|
from the relevant interfaces
|
||||||
"""
|
"""
|
||||||
LOG.debug("NexusPlugin:delete_network() called\n")
|
LOG.debug("NexusPlugin:delete_network() called\n")
|
||||||
vlan_id = None
|
|
||||||
for key in kwargs:
|
|
||||||
if key == const.CONTEXT:
|
|
||||||
context = kwargs[const.CONTEXT]
|
|
||||||
elif key == const.BASE_PLUGIN_REF:
|
|
||||||
base_plugin_ref = kwargs[const.BASE_PLUGIN_REF]
|
|
||||||
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,
|
|
||||||
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)
|
|
||||||
if net_id:
|
|
||||||
self._client.delete_vlan(
|
|
||||||
str(vlan_id), self._nexus_ip,
|
|
||||||
self._nexus_username, self._nexus_password,
|
|
||||||
self._nexus_ports, self._nexus_ssh_port)
|
|
||||||
return net_id
|
|
||||||
# Network not found
|
|
||||||
raise exc.NetworkNotFound(net_id=net_id)
|
|
||||||
|
|
||||||
def get_network_details(self, tenant_id, net_id, **kwargs):
|
def get_network_details(self, tenant_id, net_id, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -135,22 +147,6 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
Virtual Network.
|
Virtual Network.
|
||||||
"""
|
"""
|
||||||
LOG.debug("NexusPlugin:update_network() called\n")
|
LOG.debug("NexusPlugin:update_network() called\n")
|
||||||
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):
|
def get_all_ports(self, tenant_id, net_id, **kwargs):
|
||||||
"""
|
"""
|
||||||
@ -166,12 +162,38 @@ class NexusPlugin(L2DevicePluginBase):
|
|||||||
"""
|
"""
|
||||||
LOG.debug("NexusPlugin:create_port() called\n")
|
LOG.debug("NexusPlugin:create_port() called\n")
|
||||||
|
|
||||||
def delete_port(self, tenant_id, net_id, port_id, **kwargs):
|
def delete_port(self, device_id, vlan_id):
|
||||||
"""
|
"""
|
||||||
This is probably not applicable to the Nexus plugin.
|
Delete port bindings from the database and scan
|
||||||
Delete if not required.
|
whether the network is still required on
|
||||||
|
the interfaces trunked
|
||||||
"""
|
"""
|
||||||
LOG.debug("NexusPlugin:delete_port() called\n")
|
LOG.debug("NexusPlugin:delete_port() called\n")
|
||||||
|
# Delete DB row for this port
|
||||||
|
row = nxos_db.get_nexusvm_binding(vlan_id, device_id)
|
||||||
|
if row:
|
||||||
|
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
|
||||||
|
bindings = nxos_db.get_nexusvlan_binding(
|
||||||
|
row['vlan_id'], row['switch_ip'])
|
||||||
|
|
||||||
|
if not bindings:
|
||||||
|
# Delete this vlan from this switch
|
||||||
|
_nexus_ip = row['switch_ip']
|
||||||
|
_nexus_ports = (row['port_id'],)
|
||||||
|
_nexus_ssh_port = \
|
||||||
|
self._nexus_switches[_nexus_ip]['ssh_port']['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)
|
||||||
|
|
||||||
|
return row['instance_id']
|
||||||
|
|
||||||
def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs):
|
def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs):
|
||||||
"""
|
"""
|
||||||
|
@ -27,7 +27,9 @@ from quantum.plugins.cisco.nexus import cisco_nexus_plugin_v2
|
|||||||
NEXUS_IP_ADDRESS = '1.1.1.1'
|
NEXUS_IP_ADDRESS = '1.1.1.1'
|
||||||
NEXUS_USERNAME = 'username'
|
NEXUS_USERNAME = 'username'
|
||||||
NEXUS_PASSWORD = 'password'
|
NEXUS_PASSWORD = 'password'
|
||||||
NEXUS_PORTS = ['1/10']
|
HOSTNAME = 'testhost'
|
||||||
|
INSTANCE = 'testvm'
|
||||||
|
NEXUS_PORTS = '1/10'
|
||||||
NEXUS_SSH_PORT = '22'
|
NEXUS_SSH_PORT = '22'
|
||||||
NEXUS_DRIVER = ('quantum.plugins.cisco.tests.unit.v2.nexus.'
|
NEXUS_DRIVER = ('quantum.plugins.cisco.tests.unit.v2.nexus.'
|
||||||
'fake_nexus_driver.CiscoNEXUSFakeDriver')
|
'fake_nexus_driver.CiscoNEXUSFakeDriver')
|
||||||
@ -48,6 +50,17 @@ class TestCiscoNexusPlugin(unittest.TestCase):
|
|||||||
self.second_net_id = 000005
|
self.second_net_id = 000005
|
||||||
self.second_vlan_name = "q-" + str(self.second_net_id) + "vlan"
|
self.second_vlan_name = "q-" + str(self.second_net_id) + "vlan"
|
||||||
self.second_vlan_id = 265
|
self.second_vlan_id = 265
|
||||||
|
self._nexus_switches = {
|
||||||
|
NEXUS_IP_ADDRESS: {
|
||||||
|
HOSTNAME: {
|
||||||
|
'ports': NEXUS_PORTS,
|
||||||
|
},
|
||||||
|
'ssh_port': {
|
||||||
|
'ssh_port': NEXUS_SSH_PORT
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self._hostname = HOSTNAME
|
||||||
|
|
||||||
def new_cdb_init():
|
def new_cdb_init():
|
||||||
db.configure_db()
|
db.configure_db()
|
||||||
@ -59,14 +72,21 @@ class TestCiscoNexusPlugin(unittest.TestCase):
|
|||||||
self._nexus_password = NEXUS_PASSWORD
|
self._nexus_password = NEXUS_PASSWORD
|
||||||
self._nexus_ports = NEXUS_PORTS
|
self._nexus_ports = NEXUS_PORTS
|
||||||
self._nexus_ssh_port = NEXUS_SSH_PORT
|
self._nexus_ssh_port = NEXUS_SSH_PORT
|
||||||
|
self.credentials = {
|
||||||
|
self._nexus_ip: {
|
||||||
|
'username': self._nexus_username,
|
||||||
|
'password': self._nexus_password
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
with mock.patch.object(cdb, 'initialize', new=new_cdb_init):
|
with mock.patch.object(cdb, 'initialize', new=new_cdb_init):
|
||||||
cdb.initialize()
|
cdb.initialize()
|
||||||
with mock.patch.object(cisco_nexus_plugin_v2.NexusPlugin,
|
with mock.patch.object(cisco_nexus_plugin_v2.NexusPlugin,
|
||||||
'__init__', new=new_nexus_init):
|
'__init__', new=new_nexus_init):
|
||||||
self._cisco_nexus_plugin = cisco_nexus_plugin_v2.NexusPlugin()
|
self._cisco_nexus_plugin = cisco_nexus_plugin_v2.NexusPlugin()
|
||||||
|
self._cisco_nexus_plugin._nexus_switches = self._nexus_switches
|
||||||
|
|
||||||
def test_a_create_delete_network(self):
|
def test_a_create_network(self):
|
||||||
"""
|
"""
|
||||||
Tests creation of two new Virtual Network.
|
Tests creation of two new Virtual Network.
|
||||||
Tests deletion of one Virtual Network.
|
Tests deletion of one Virtual Network.
|
||||||
@ -90,18 +110,16 @@ class TestCiscoNexusPlugin(unittest.TestCase):
|
|||||||
|
|
||||||
new_net_dict = self._cisco_nexus_plugin.create_network(
|
new_net_dict = self._cisco_nexus_plugin.create_network(
|
||||||
tenant_id, net_name, net_id,
|
tenant_id, net_name, net_id,
|
||||||
vlan_name, vlan_id, vlan_ids=str(vlan_id))
|
vlan_name, vlan_id, self._hostname, INSTANCE)
|
||||||
|
|
||||||
self.assertEqual(new_net_dict[const.NET_ID], net_id)
|
self.assertEqual(new_net_dict[const.NET_ID], net_id)
|
||||||
self.assertEqual(new_net_dict[const.NET_NAME], self.net_name)
|
self.assertEqual(new_net_dict[const.NET_NAME], self.net_name)
|
||||||
self.assertEqual(new_net_dict[const.NET_VLAN_NAME], self.vlan_name)
|
self.assertEqual(new_net_dict[const.NET_VLAN_NAME], self.vlan_name)
|
||||||
self.assertEqual(new_net_dict[const.NET_VLAN_ID], self.vlan_id)
|
self.assertEqual(new_net_dict[const.NET_VLAN_ID], self.vlan_id)
|
||||||
|
|
||||||
vlan_ids = str(vlan_id) + "," + str(second_vlan_id)
|
|
||||||
new_net_dict = self._cisco_nexus_plugin.create_network(
|
new_net_dict = self._cisco_nexus_plugin.create_network(
|
||||||
tenant_id, second_net_name, second_net_id,
|
tenant_id, second_net_name, second_net_id,
|
||||||
second_vlan_name, second_vlan_id,
|
second_vlan_name, second_vlan_id, self._hostname,
|
||||||
vlan_ids=vlan_ids)
|
INSTANCE)
|
||||||
|
|
||||||
self.assertEqual(new_net_dict[const.NET_ID], second_net_id)
|
self.assertEqual(new_net_dict[const.NET_ID], second_net_id)
|
||||||
self.assertEqual(new_net_dict[const.NET_NAME], self.second_net_name)
|
self.assertEqual(new_net_dict[const.NET_NAME], self.second_net_name)
|
||||||
@ -109,106 +127,20 @@ class TestCiscoNexusPlugin(unittest.TestCase):
|
|||||||
self.second_vlan_name)
|
self.second_vlan_name)
|
||||||
self.assertEqual(new_net_dict[const.NET_VLAN_ID], self.second_vlan_id)
|
self.assertEqual(new_net_dict[const.NET_VLAN_ID], self.second_vlan_id)
|
||||||
|
|
||||||
expected_net_id = self._cisco_nexus_plugin.delete_network(
|
def test_b_nexus_delete_port(self):
|
||||||
tenant_id, net_id, vlan_id=str(vlan_id))
|
|
||||||
|
|
||||||
self.assertEqual(expected_net_id, net_id)
|
|
||||||
|
|
||||||
def test_b_nexus_clear_vlan(self):
|
|
||||||
"""
|
"""
|
||||||
Test to clean up second vlan of nexus device
|
Test to clean up second vlan of nexus device
|
||||||
created by test_create_delete_network. This
|
created by test_create_delete_network. This
|
||||||
test will fail if it is run individually.
|
test will fail if it is run individually.
|
||||||
"""
|
"""
|
||||||
tenant_id = self.tenant_id
|
expected_instance_id = self._cisco_nexus_plugin.delete_port(
|
||||||
second_net_id = self.second_net_id
|
INSTANCE, self.second_vlan_id
|
||||||
second_vlan_id = self.second_vlan_id
|
)
|
||||||
|
|
||||||
expected_second_net_id = self._cisco_nexus_plugin.delete_network(
|
self.assertEqual(expected_instance_id, INSTANCE)
|
||||||
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(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)
|
|
||||||
|
|
||||||
self.test_d_nexus_clean_vlan_update()
|
|
||||||
|
|
||||||
def tearDown(self):
|
def tearDown(self):
|
||||||
"""Clear the test environment"""
|
"""Clear the test environment"""
|
||||||
|
pass
|
||||||
# Remove database contents
|
# Remove database contents
|
||||||
db.clear_db(network_models_v2.model_base.BASEV2)
|
#db.clear_db(network_models_v2.model_base.BASEV2)
|
||||||
|
@ -17,3 +17,7 @@ sqlalchemy==0.7.9
|
|||||||
webob>=1.0.8
|
webob>=1.0.8
|
||||||
python-keystoneclient>=0.2.0
|
python-keystoneclient>=0.2.0
|
||||||
alembic>=0.4.1
|
alembic>=0.4.1
|
||||||
|
|
||||||
|
# Cisco plugin dependencies
|
||||||
|
python-novaclient
|
||||||
|
# End Cisco dependencies
|
||||||
|
Loading…
Reference in New Issue
Block a user