New tests are being adding to the Diablo code (Cisco L2-Network plugin), and some fixes in the case where the tests were failing.

All changes contained within the Cisco L2-Network plugin and extensions.

Change-Id: I696a2aebeb9027f3b0ce0b6673910e02e304673f
This commit is contained in:
Sumit Naiksatam 2011-10-22 20:03:22 -07:00
parent 8052bf68d4
commit 0a7015b928
23 changed files with 612 additions and 227 deletions

View File

@ -45,3 +45,7 @@ class ViewBuilder(object):
def build_vif(self, vif_data): def build_vif(self, vif_data):
"""Return VIF description.""" """Return VIF description."""
return dict(vif_desc=vif_data[const.VIF_DESC]) return dict(vif_desc=vif_data[const.VIF_DESC])
def build_result(self, result_data):
"""Return result True/False"""
return dict(result=result_data)

View File

@ -64,7 +64,8 @@ class Novatenant(object):
parent_resource = dict(member_name="tenant", parent_resource = dict(member_name="tenant",
collection_name="extensions/csco/tenants") collection_name="extensions/csco/tenants")
member_actions = {'schedule_host': "PUT", member_actions = {'schedule_host': "PUT",
'associate_port': "PUT"} 'associate_port': "PUT",
'detach_port': "PUT"}
controller = NovatenantsController(QuantumManager.get_plugin()) controller = NovatenantsController(QuantumManager.get_plugin())
return [extensions.ResourceExtension('novatenants', controller, return [extensions.ResourceExtension('novatenants', controller,
parent=parent_resource, parent=parent_resource,
@ -154,3 +155,24 @@ class NovatenantsController(common.QuantumController):
return result return result
except qexception.PortNotFound as exp: except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp)) return faults.Fault(faults.PortNotFound(exp))
def detach_port(self, request, tenant_id, id):
content_type = request.best_match_content_type()
try:
req_params = \
self._parse_request_params(request,
self._schedule_host_ops_param_list)
except exc.HTTPError as exp:
return faults.Fault(exp)
instance_id = req_params['instance_id']
instance_desc = req_params['instance_desc']
try:
vif = self._plugin. \
detach_port(tenant_id, instance_id, instance_desc)
builder = novatenant_view.get_view_builder(request)
result = builder.build_result(True)
return result
except qexception.PortNotFound as exp:
return faults.Fault(faults.PortNotFound(exp))

View File

@ -205,7 +205,9 @@ password=mySecretPasswordForNexus
quantum/plugins/cisco/conf/ucs_inventory.ini file. You can configure multiple quantum/plugins/cisco/conf/ucs_inventory.ini file. You can configure multiple
UCSMs per deployment, multiple chassis per UCSM, and multiple blades per UCSMs per deployment, multiple chassis per UCSM, and multiple blades per
chassis. Chassis ID and blade ID can be obtained from the UCSM (they will chassis. Chassis ID and blade ID can be obtained from the UCSM (they will
typically be numbers like 1, 2, 3, etc.) typically be numbers like 1, 2, 3, etc.). Also make sure that you put the exact
hostname as nova sees it (the host column in the services table of the nova
DB will give you that information).
[ucsm-1] [ucsm-1]
ip_address = <put_ucsm_ip_address_here> ip_address = <put_ucsm_ip_address_here>
@ -241,8 +243,8 @@ host_name = <put_hostname_here>
Multi NIC support for VMs Multi NIC support for VMs
------------------------- -------------------------
As indicated earlier, if your Nova setup has a project with more than one network, As indicated earlier, if your Nova setup has a project with more than one network,
Nova will try to create a vritual network interface (VIF) on the VM for each of those Nova will try to create a virtual network interface (VIF) on the VM for each of those
networks. That implies that, networks. That implies -
(1) You should create the same number of networks in Quantum as in your Nova (1) You should create the same number of networks in Quantum as in your Nova
project. project.
@ -325,12 +327,18 @@ for Tenant: demo
Note that when using UCS and the 802.1Qbh features, the association of the Note that when using UCS and the 802.1Qbh features, the association of the
VIF-ID (also referred to as interface ID) on the VM's NIC with a port will VIF-ID (also referred to as interface ID) on the VM's NIC with a port will
happen automatically when the VM is instantiated. At this point, doing a happen automatically when the VM is instantiated. At this point, doing a
show_port will reveal the VIF-ID associated with the port. show_port will reveal the VIF-ID associated with the port. To indicate that
this VIF-ID is still detached from the network it would eventually be on, you
will see the suffix "(detached)" on the VIF-ID. This indicates that although
the VIF-ID and the port have been associated, the VIF still does not have
connectivity to the network on which the port resides. That connectivity
will be established only after the plug/attach operation is performed (as
described in the next step).
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py show_port demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae # PYTHONPATH=. python quantum/plugins/cisco/client/cli.py show_port demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
Logical Port ID: 118ac473-294d-480e-8f6d-425acbbe81ae Logical Port ID: 118ac473-294d-480e-8f6d-425acbbe81ae
administrative State: ACTIVE administrative State: ACTIVE
interface: b73e3585-d074-4379-8dde-931c0fc4db0e interface: b73e3585-d074-4379-8dde-931c0fc4db0e(detached)
on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a
for Tenant: demo for Tenant: demo
@ -347,17 +355,23 @@ for Tenant: demo
8. Unplug an interface and port from the network 8. Unplug an interface and port from the network
Note: Before unplugging, make a note of the interface ID (you can use the
show_port CLI as before). While the VM, which has a VIF with this interface
ID still exists, you can only plug that same interface back into this port.
So the subsequent plug interface operation on this port will have to make
use of the same interface ID.
# PYTHONPATH=. python quantum/plugins/cisco/client/cli.py unplug_iface demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae # PYTHONPATH=. python quantum/plugins/cisco/client/cli.py unplug_iface demo c4a2bea7-a528-4caf-b16e-80397cd1663a 118ac473-294d-480e-8f6d-425acbbe81ae
Unplugged interface from Logical Port: 118ac473-294d-480e-8f6d-425acbbe81ae Unplugged interface from Logical Port: 118ac473-294d-480e-8f6d-425acbbe81ae
on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a on Virtual Network: c4a2bea7-a528-4caf-b16e-80397cd1663a
for Tenant: demo for Tenant: demo
Note: After unplugging, if you check the details of the port, you will
see the VIF-IF associated with the port (but now suffixed with the state
"detached"). At this point, it is possible to plug the VIF into the network
again making use of the same VIF-ID. In general, once associated, the VIF-ID
cannot be disassociated with the port until the VM is terminated. After the
VM is terminated, the VIF-ID will be automatically disassociated from the
port. To summarize, association and disassociation of the VIF-ID with a port
happens automatically at the time of creating and terminating the VM. The
connectivity of the VIF to the network is controlled by the user via the
plug and unplug operations.
How to test the installation How to test the installation
---------------------------- ----------------------------

View File

@ -19,13 +19,9 @@
# #
""" """
import logging as LOG
from configobj import ConfigObj from configobj import ConfigObj
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class CiscoConfigParser(ConfigObj): class CiscoConfigParser(ConfigObj):
"""Config Parser based on the ConfigObj module""" """Config Parser based on the ConfigObj module"""

View File

@ -153,3 +153,13 @@ NETWORK_ADMIN = 'network_admin'
NETID_LIST = 'net_id_list' NETID_LIST = 'net_id_list'
DELIMITERS = "[,;:\b\s]" DELIMITERS = "[,;:\b\s]"
UUID_LENGTH = 36
UNPLUGGED = '(detached)'
ASSOCIATION_STATUS = 'association_status'
ATTACHED = 'attached'
DETACHED = 'detached'

View File

@ -19,7 +19,6 @@
# #
""" """
import logging as LOG
import os import os
from quantum.plugins.cisco.common import cisco_configparser as confp from quantum.plugins.cisco.common import cisco_configparser as confp
@ -27,9 +26,6 @@ from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_exceptions as cexc from quantum.plugins.cisco.common import cisco_exceptions as cexc
from quantum.plugins.cisco.db import l2network_db as cdb from quantum.plugins.cisco.db import l2network_db as cdb
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
TENANT = const.NETWORK_ADMIN TENANT = const.NETWORK_ADMIN
CREDENTIALS_FILE = "../conf/credentials.ini" CREDENTIALS_FILE = "../conf/credentials.ini"

View File

@ -176,6 +176,14 @@ class PortVnicNotFound(exceptions.QuantumException):
message = _("PortVnic Binding %(port_id) is not present") message = _("PortVnic Binding %(port_id) is not present")
class InvalidAttach(exceptions.QuantumException):
message = _("Unable to plug the attachment %(att_id)s into port " \
"%(port_id)s for network %(net_id)s. Association of " \
"attachment ID with port ID happens implicitly when " \
"VM is instantiated; attach operation can be " \
"performed subsequently.")
try: try:
_("test") _("test")
except NameError: except NameError:

View File

@ -20,7 +20,7 @@
""" """
import hashlib import hashlib
import logging as LOG import logging
import MySQLdb import MySQLdb
import traceback import traceback
@ -28,8 +28,7 @@ from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import api as db from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as cdb from quantum.plugins.cisco.db import l2network_db as cdb
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
def get16ByteUUID(uuid): def get16ByteUUID(uuid):

View File

@ -120,6 +120,8 @@ def reserve_vlanid():
rvlan = session.query(l2network_models.VlanID).\ rvlan = session.query(l2network_models.VlanID).\
filter_by(vlan_used=False).\ filter_by(vlan_used=False).\
first() first()
if not rvlan:
raise exc.NoResultFound
rvlanid = session.query(l2network_models.VlanID).\ rvlanid = session.query(l2network_models.VlanID).\
filter_by(vlan_id=rvlan["vlan_id"]).\ filter_by(vlan_id=rvlan["vlan_id"]).\
one() one()

View File

@ -117,6 +117,38 @@ def update_portbinding(port_id, blade_intf_dn=None, portprofile_name=None,
raise c_exc.PortVnicNotFound(port_id=port_id) raise c_exc.PortVnicNotFound(port_id=port_id)
def update_portbinding_instance_id(port_id, instance_id):
"""Updates port binding for the instance ID"""
LOG.debug("db update_portbinding_instance_id() called")
session = db.get_session()
try:
port_binding = session.query(ucs_models.PortBinding).\
filter_by(port_id=port_id).\
one()
port_binding.instance_id = instance_id
session.merge(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def update_portbinding_vif_id(port_id, vif_id):
"""Updates port binding for the VIF ID"""
LOG.debug("db update_portbinding_vif_id() called")
session = db.get_session()
try:
port_binding = session.query(ucs_models.PortBinding).\
filter_by(port_id=port_id).\
one()
port_binding.vif_id = vif_id
session.merge(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def get_portbinding_dn(blade_intf_dn): def get_portbinding_dn(blade_intf_dn):
"""Lists a port binding""" """Lists a port binding"""
LOG.debug("get_portbinding_dn() called") LOG.debug("get_portbinding_dn() called")

View File

@ -20,7 +20,7 @@
""" """
import inspect import inspect
import logging as LOG import logging
import re import re
from quantum.common import exceptions as exc from quantum.common import exceptions as exc
@ -35,8 +35,7 @@ from quantum.plugins.cisco.common import cisco_utils as cutil
from quantum.plugins.cisco.db import api as db from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as cdb from quantum.plugins.cisco.db import l2network_db as cdb
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class L2Network(QuantumPluginBase): class L2Network(QuantumPluginBase):
@ -246,35 +245,50 @@ class L2Network(QuantumPluginBase):
def plug_interface(self, tenant_id, net_id, port_id, def plug_interface(self, tenant_id, net_id, port_id,
remote_interface_id): remote_interface_id):
""" """
Attaches a remote interface to the specified port on the Provides connectivity to a remote interface to the
specified Virtual Network. specified Virtual Network.
""" """
LOG.debug("plug_interface() called\n") LOG.debug("plug_interface() called\n")
network = db.network_get(net_id) network = db.network_get(net_id)
port = db.port_get(net_id, port_id) port = db.port_get(net_id, port_id)
attachment_id = port[const.INTERFACEID] attachment_id = port[const.INTERFACEID]
if attachment_id and remote_interface_id != attachment_id: if attachment_id == None:
raise cexc.InvalidAttach(port_id=port_id, net_id=net_id,
att_id=remote_interface_id)
attachment_id = attachment_id[:const.UUID_LENGTH]
remote_interface_id = remote_interface_id[:const.UUID_LENGTH]
if remote_interface_id != attachment_id:
LOG.debug("Existing attachment_id:%s, remote_interface_id:%s" % \
(attachment_id, remote_interface_id))
raise exc.PortInUse(port_id=port_id, net_id=net_id, raise exc.PortInUse(port_id=port_id, net_id=net_id,
att_id=attachment_id) att_id=attachment_id)
self._invoke_device_plugins(self._func_name(), [tenant_id, self._invoke_device_plugins(self._func_name(), [tenant_id,
net_id, port_id, net_id, port_id,
remote_interface_id]) attachment_id])
if attachment_id == None: db.port_unset_attachment(net_id, port_id)
db.port_set_attachment(net_id, port_id, remote_interface_id) db.port_set_attachment(net_id, port_id, attachment_id)
#Note: The remote_interface_id gets associated with the port #Note: The remote_interface_id gets associated with the port
# when the VM is instantiated. The plug interface call results # when the VM is instantiated. The plug interface call results
# in putting the port on the VLAN associated with this network # in putting the port on the VLAN associated with this network
def unplug_interface(self, tenant_id, net_id, port_id): def unplug_interface(self, tenant_id, net_id, port_id):
""" """
Detaches a remote interface from the specified port on the Removes connectivity of a remote interface to the
specified Virtual Network. specified Virtual Network.
""" """
LOG.debug("unplug_interface() called\n") LOG.debug("unplug_interface() called\n")
network = db.network_get(net_id) network = db.network_get(net_id)
port = db.port_get(net_id, port_id)
attachment_id = port[const.INTERFACEID]
if attachment_id == None:
raise exc.InvalidDetach(port_id=port_id, net_id=net_id,
att_id=remote_interface_id)
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id, self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id]) port_id])
attachment_id = attachment_id[:const.UUID_LENGTH]
attachment_id = attachment_id + const.UNPLUGGED
db.port_unset_attachment(net_id, port_id) db.port_unset_attachment(net_id, port_id)
db.port_set_attachment(net_id, port_id, attachment_id)
""" """
Extension API implementation Extension API implementation
@ -473,13 +487,22 @@ class L2Network(QuantumPluginBase):
def associate_port(self, tenant_id, instance_id, instance_desc): def associate_port(self, tenant_id, instance_id, instance_desc):
""" """
Get the portprofile name and the device namei for the dynamic vnic Get the portprofile name and the device name for the dynamic vnic
""" """
LOG.debug("associate_port() called\n") LOG.debug("associate_port() called\n")
return self._invoke_device_plugins(self._func_name(), [tenant_id, return self._invoke_device_plugins(self._func_name(), [tenant_id,
instance_id, instance_id,
instance_desc]) instance_desc])
def detach_port(self, tenant_id, instance_id, instance_desc):
"""
Remove the association of the VIF with the dynamic vnic
"""
LOG.debug("detach_port() called\n")
return self._invoke_device_plugins(self._func_name(), [tenant_id,
instance_id,
instance_desc])
def create_multiport(self, tenant_id, net_id_list, port_state, ports_desc): def create_multiport(self, tenant_id, net_id_list, port_state, ports_desc):
""" """
Creates multiple ports on the specified Virtual Network. Creates multiple ports on the specified Virtual Network.

View File

@ -21,7 +21,7 @@
from copy import deepcopy from copy import deepcopy
import inspect import inspect
import logging as LOG import logging
import platform import platform
from quantum.common import exceptions as exc from quantum.common import exceptions as exc
@ -31,8 +31,7 @@ from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_exceptions as cexc from quantum.plugins.cisco.common import cisco_exceptions as cexc
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(__name__)
class L2NetworkMultiBlade(L2NetworkModelBase): class L2NetworkMultiBlade(L2NetworkModelBase):
@ -182,12 +181,20 @@ class L2NetworkMultiBlade(L2NetworkModelBase):
def associate_port(self, args): def associate_port(self, args):
""" """
Get the portprofile name and the device namei for the dynamic vnic Get the portprofile name and the device name for the dynamic vnic
""" """
LOG.debug("associate_port() called\n") LOG.debug("associate_port() called\n")
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(), return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
args) args)
def detach_port(self, args):
"""
Remove the association of the VIF with the dynamic vnic
"""
LOG.debug("detach_port() called\n")
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
def create_multiport(self, args): def create_multiport(self, args):
"""Support for extension API call""" """Support for extension API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(), self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),

View File

@ -21,7 +21,7 @@
from copy import deepcopy from copy import deepcopy
import inspect import inspect
import logging as LOG import logging
import platform import platform
from quantum.common import exceptions as exc from quantum.common import exceptions as exc
@ -31,8 +31,7 @@ from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_exceptions as cexc from quantum.plugins.cisco.common import cisco_exceptions as cexc
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(__name__)
class L2NetworkSingleBlade(L2NetworkModelBase): class L2NetworkSingleBlade(L2NetworkModelBase):
@ -163,6 +162,14 @@ class L2NetworkSingleBlade(L2NetworkModelBase):
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(), return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
args) args)
def detach_port(self, args):
"""
Remove the association of the VIF with the dynamic vnic
"""
LOG.debug("detach_port() called\n")
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
def create_multiport(self, args): def create_multiport(self, args):
"""Support for extension API call""" """Support for extension API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(), self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),

View File

@ -26,6 +26,8 @@ from quantum.common import exceptions as exc
from quantum.common import utils from quantum.common import utils
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_credentials as cred from quantum.plugins.cisco.common import cisco_credentials as cred
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco.db import nexus_db as nxos_db from quantum.plugins.cisco.db import nexus_db as nxos_db
from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase
from quantum.plugins.cisco.nexus import cisco_nexus_configuration as conf from quantum.plugins.cisco.nexus import cisco_nexus_configuration as conf
@ -94,13 +96,12 @@ class NexusPlugin(L2DevicePluginBase):
ports_id = nxos_db.get_nexusport_binding(vlan_id) ports_id = nxos_db.get_nexusport_binding(vlan_id)
LOG.debug("NexusPlugin: Interfaces to be disassociated: %s" % ports_id) LOG.debug("NexusPlugin: Interfaces to be disassociated: %s" % ports_id)
nxos_db.remove_nexusport_binding(vlan_id) nxos_db.remove_nexusport_binding(vlan_id)
net = self._networks.get(net_id) net = self._get_network(tenant_id, net_id)
if net: if net:
self._client.delete_vlan(str(vlan_id), self._nexus_ip, self._client.delete_vlan(str(vlan_id), self._nexus_ip,
self._nexus_username, self._nexus_password, self._nexus_username, self._nexus_password,
self._nexus_first_port, self._nexus_second_port, self._nexus_first_port, self._nexus_second_port,
self._nexus_ssh_port) self._nexus_ssh_port)
self._networks.pop(net_id)
return net return net
# Network not found # Network not found
raise exc.NetworkNotFound(net_id=net_id) raise exc.NetworkNotFound(net_id=net_id)
@ -185,7 +186,11 @@ class NexusPlugin(L2DevicePluginBase):
""" """
Gets the NETWORK ID Gets the NETWORK ID
""" """
network = self._networks.get(network_id) network = db.network_get(network_id)
if not network: if not network:
raise exc.NetworkNotFound(net_id=network_id) raise exc.NetworkNotFound(net_id=network_id)
return network 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}

View File

@ -45,11 +45,12 @@ ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
'/extensions/csco/tenants/{tenant_id}' '/extensions/csco/tenants/{tenant_id}'
TENANT_ID = 'nova' TENANT_ID = 'nova'
CSCO_EXT_NAME = 'Cisco Nova Tenant' CSCO_EXT_NAME = 'Cisco Nova Tenant'
ACTION = '/associate_port' ASSOCIATE_ACTION = '/associate_port'
DETACH_ACTION = '/detach_port'
class Libvirt802dot1QbhDriver(VIFDriver): class Libvirt802dot1QbhDriver(VIFDriver):
"""VIF driver for Linux bridge.""" """VIF driver for 802.1Qbh"""
def __init__(self): def __init__(self):
# We have to send a dummy tenant name here since the client # We have to send a dummy tenant name here since the client
# needs some tenant name, but the tenant name will not be used # needs some tenant name, but the tenant name will not be used
@ -70,7 +71,7 @@ class Libvirt802dot1QbhDriver(VIFDriver):
% CSCO_EXT_NAME) % CSCO_EXT_NAME)
raise excp.ServiceUnavailable() raise excp.ServiceUnavailable()
def _get_configurations(self, instance, network, mapping): def _update_configurations(self, instance, network, mapping, action):
"""Gets the device name and the profile name from Quantum""" """Gets the device name and the profile name from Quantum"""
instance_id = instance['id'] instance_id = instance['id']
@ -88,26 +89,31 @@ class Libvirt802dot1QbhDriver(VIFDriver):
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID, client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
action_prefix=ACTION_PREFIX_CSCO) action_prefix=ACTION_PREFIX_CSCO)
request_url = "/novatenants/" + project_id + ACTION request_url = "/novatenants/" + project_id + action
data = client.do_request('PUT', request_url, body=instance_data_dict) data = client.do_request('PUT', request_url, body=instance_data_dict)
device = data['vif_desc']['device'] if action == ASSOCIATE_ACTION:
portprofile = data['vif_desc']['portprofile'] device = data['vif_desc']['device']
LOG.debug(_("Quantum provided the device: %s") % device) portprofile = data['vif_desc']['portprofile']
LOG.debug(_("Quantum provided the portprofile: %s") % portprofile) LOG.debug(_("Quantum provided the device: %s") % device)
mac_id = mapping['mac'].replace(':', '') LOG.debug(_("Quantum provided the portprofile: %s") % portprofile)
mac_id = mapping['mac'].replace(':', '')
result = { result = {
'id': mac_id, 'id': mac_id,
'mac_address': mapping['mac'], 'mac_address': mapping['mac'],
'device_name': device, 'device_name': device,
'profile_name': portprofile, 'profile_name': portprofile,
} }
return result return result
else:
return data
def plug(self, instance, network, mapping): def plug(self, instance, network, mapping):
return self._get_configurations(instance, network, mapping) return self._update_configurations(instance, network, mapping,
ASSOCIATE_ACTION)
def unplug(self, instance, network, mapping): def unplug(self, instance, network, mapping):
pass self._update_configurations(instance, network, mapping,
DETACH_ACTION)

View File

@ -19,15 +19,14 @@
# #
""" """
import logging as LOG import logging
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import l2network_db as cdb from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco.l2network_segmentation_base \ from quantum.plugins.cisco.l2network_segmentation_base \
import L2NetworkSegmentationMgrBase import L2NetworkSegmentationMgrBase
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class L2NetworkVLANMgr(L2NetworkSegmentationMgrBase): class L2NetworkVLANMgr(L2NetworkSegmentationMgrBase):

View File

@ -88,7 +88,11 @@ class CoreAPITestFunc(unittest.TestCase):
tenant_id, net_id) tenant_id, net_id)
LOG.debug("test_delete_network_not_found - END") LOG.debug("test_delete_network_not_found - END")
def test_delete_networkInUse(self, tenant_id='test_network'): def test_delete_networkInUse(
self, tenant_id='test_tenant', instance_tenant_id='nova',
nova_user_id='novaadmin', instance_id=10,
vif_id='fe701ddf-26a2-42ea-b9e6-7313d1c522cc'):
""" """
Tests deletion of a Virtual Network when Network is in Use. Tests deletion of a Virtual Network when Network is in Use.
""" """
@ -98,15 +102,24 @@ class CoreAPITestFunc(unittest.TestCase):
tenant_id, self.network_name) tenant_id, self.network_name)
port_dict = self._l2network_plugin.create_port( port_dict = self._l2network_plugin.create_port(
tenant_id, new_net_dict[const.NET_ID], self.port_state) tenant_id, new_net_dict[const.NET_ID], self.port_state)
self._l2network_plugin.plug_interface( instance_desc = {'project_id': tenant_id,
tenant_id, new_net_dict[const.NET_ID], 'user_id': nova_user_id}
port_dict[const.PORT_ID], self.remote_interface) host_list = self._l2network_plugin.schedule_host(instance_tenant_id,
instance_id,
instance_desc)
instance_vif_desc = {'project_id': tenant_id,
'user_id': nova_user_id,
'vif_id': vif_id}
vif_description = self._l2network_plugin.associate_port(
instance_tenant_id, instance_id,
instance_vif_desc)
self.assertRaises(exc.NetworkInUse, self.assertRaises(exc.NetworkInUse,
self._l2network_plugin.delete_network, tenant_id, self._l2network_plugin.delete_network, tenant_id,
new_net_dict[const.NET_ID]) new_net_dict[const.NET_ID])
self.tearDownNetworkPortInterface( self.tearDownNetworkPortInterface(
tenant_id, new_net_dict[const.NET_ID], tenant_id, instance_tenant_id, instance_id, instance_vif_desc,
port_dict[const.PORT_ID]) new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
LOG.debug("test_delete_networkInUse - END") LOG.debug("test_delete_networkInUse - END")
def test_show_network(self, net_tenant_id=None): def test_show_network(self, net_tenant_id=None):
@ -330,7 +343,10 @@ class CoreAPITestFunc(unittest.TestCase):
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_delete_portDNE - END") LOG.debug("test_delete_portDNE - END")
def test_delete_portInUse(self, tenant_id='test_tenant'): def test_delete_portInUse(
self, tenant_id='test_tenant', instance_tenant_id='nova',
nova_user_id='novaadmin', instance_id=10,
vif_id='fe701ddf-26a2-42ea-b9e6-7313d1c522cc'):
""" """
Tests deletion of Ports when port is in Use. Tests deletion of Ports when port is in Use.
""" """
@ -341,14 +357,23 @@ class CoreAPITestFunc(unittest.TestCase):
port_dict = self._l2network_plugin.create_port( port_dict = self._l2network_plugin.create_port(
tenant_id, new_net_dict[const.NET_ID], tenant_id, new_net_dict[const.NET_ID],
self.port_state) self.port_state)
self._l2network_plugin.plug_interface( instance_desc = {'project_id': tenant_id,
tenant_id, new_net_dict[const.NET_ID], 'user_id': nova_user_id}
port_dict[const.PORT_ID], self.remote_interface) host_list = self._l2network_plugin.schedule_host(instance_tenant_id,
instance_id,
instance_desc)
instance_vif_desc = {'project_id': tenant_id,
'user_id': nova_user_id,
'vif_id': vif_id}
vif_description = self._l2network_plugin.associate_port(
instance_tenant_id, instance_id,
instance_vif_desc)
self.assertRaises(exc.PortInUse, self.assertRaises(exc.PortInUse,
self._l2network_plugin.delete_port, tenant_id, self._l2network_plugin.delete_port, tenant_id,
new_net_dict[const.NET_ID], port_dict[const.PORT_ID]) new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
self.tearDownNetworkPortInterface( self.tearDownNetworkPortInterface(
tenant_id, new_net_dict[const.NET_ID], port_dict[const.PORT_ID]) tenant_id, instance_tenant_id, instance_id, instance_vif_desc,
new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
LOG.debug("test_delete_portInUse - END") LOG.debug("test_delete_portInUse - END")
def test_update_port(self, tenant_id='test_tenant', def test_update_port(self, tenant_id='test_tenant',
@ -446,8 +471,10 @@ class CoreAPITestFunc(unittest.TestCase):
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_show_portDNE - END") LOG.debug("test_show_portDNE - END")
def test_plug_interface(self, tenant_id='test_tenant', def test_plug_interface(
remote_interface='new_interface'): self, tenant_id='test_tenant', instance_tenant_id='nova',
nova_user_id='novaadmin', instance_id=10,
vif_id='fe701ddf-26a2-42ea-b9e6-7313d1c522cc'):
""" """
Tests attachment of interface to the port Tests attachment of interface to the port
""" """
@ -457,15 +484,28 @@ class CoreAPITestFunc(unittest.TestCase):
tenant_id, self.network_name) tenant_id, self.network_name)
port_dict = self._l2network_plugin.create_port( port_dict = self._l2network_plugin.create_port(
tenant_id, new_net_dict[const.NET_ID], self.port_state) tenant_id, new_net_dict[const.NET_ID], self.port_state)
instance_desc = {'project_id': tenant_id,
'user_id': nova_user_id}
host_list = self._l2network_plugin.schedule_host(instance_tenant_id,
instance_id,
instance_desc)
instance_vif_desc = {'project_id': tenant_id,
'user_id': nova_user_id,
'vif_id': vif_id}
vif_description = self._l2network_plugin.associate_port(
instance_tenant_id, instance_id,
instance_vif_desc)
self._l2network_plugin.plug_interface( self._l2network_plugin.plug_interface(
tenant_id, new_net_dict[const.NET_ID], tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORT_ID], remote_interface) port_dict[const.PORT_ID], vif_id)
port = db.port_get(new_net_dict[const.NET_ID], port = db.port_get(new_net_dict[const.NET_ID],
port_dict[const.PORT_ID]) port_dict[const.PORT_ID])
self.assertEqual(port[const.INTERFACEID], remote_interface) self.assertEqual(port[const.INTERFACEID], vif_id)
self.tearDownNetworkPortInterface( self.tearDownNetworkPortInterface(
tenant_id, new_net_dict[const.NET_ID], tenant_id, instance_tenant_id, instance_id, instance_vif_desc,
port_dict[const.PORT_ID]) new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
LOG.debug("test_plug_interface - END") LOG.debug("test_plug_interface - END")
def test_plug_interface_networkDNE( def test_plug_interface_networkDNE(
@ -497,8 +537,11 @@ class CoreAPITestFunc(unittest.TestCase):
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_plug_interface_portDNE - END") LOG.debug("test_plug_interface_portDNE - END")
def test_plug_interface_portInUse(self, tenant_id='test_tenant', def test_plug_interface_portInUse(
remote_interface='new_interface'): self, tenant_id='test_tenant', instance_tenant_id='nova',
nova_user_id='novaadmin', instance_id=10,
vif_id='fe701ddf-26a2-42ea-b9e6-7313d1c522cc',
remote_interface='new_interface'):
""" """
Tests attachment of new interface to the port when there is an Tests attachment of new interface to the port when there is an
@ -506,24 +549,37 @@ class CoreAPITestFunc(unittest.TestCase):
""" """
LOG.debug("test_plug_interface_portInUse - START") LOG.debug("test_plug_interface_portInUse - START")
current_interface = "current_interface"
new_net_dict = self._l2network_plugin.create_network( new_net_dict = self._l2network_plugin.create_network(
tenant_id, self.network_name) tenant_id, self.network_name)
port_dict = self._l2network_plugin.create_port( port_dict = self._l2network_plugin.create_port(
tenant_id, new_net_dict[const.NET_ID], self.port_state) tenant_id, new_net_dict[const.NET_ID], self.port_state)
self._l2network_plugin.plug_interface( instance_desc = {'project_id': tenant_id,
tenant_id, new_net_dict[const.NET_ID], 'user_id': nova_user_id}
port_dict[const.PORT_ID], current_interface) host_list = self._l2network_plugin.schedule_host(instance_tenant_id,
instance_id,
instance_desc)
instance_vif_desc = {'project_id': tenant_id,
'user_id': nova_user_id,
'vif_id': vif_id}
vif_description = self._l2network_plugin.associate_port(
instance_tenant_id, instance_id,
instance_vif_desc)
self.assertRaises(exc.PortInUse, self.assertRaises(exc.PortInUse,
self._l2network_plugin.plug_interface, tenant_id, self._l2network_plugin.plug_interface, tenant_id,
new_net_dict[const.NET_ID], new_net_dict[const.NET_ID],
port_dict[const.PORT_ID], remote_interface) port_dict[const.PORT_ID], remote_interface)
self.tearDownNetworkPortInterface( self.tearDownNetworkPortInterface(
tenant_id, new_net_dict[const.NET_ID], tenant_id, instance_tenant_id, instance_id, instance_vif_desc,
port_dict[const.PORT_ID]) new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
LOG.debug("test_plug_interface_portInUse - END") LOG.debug("test_plug_interface_portInUse - END")
def test_unplug_interface(self, tenant_id='test_tenant'): def test_unplug_interface(
self, tenant_id='test_tenant', instance_tenant_id='nova',
nova_user_id='novaadmin', instance_id=10,
vif_id='fe701ddf-26a2-42ea-b9e6-7313d1c522cc'):
""" """
Tests detaachment of an interface to a port Tests detaachment of an interface to a port
""" """
@ -534,17 +590,32 @@ class CoreAPITestFunc(unittest.TestCase):
port_dict = self._l2network_plugin.create_port( port_dict = self._l2network_plugin.create_port(
tenant_id, new_net_dict[const.NET_ID], tenant_id, new_net_dict[const.NET_ID],
self.port_state) self.port_state)
instance_desc = {'project_id': tenant_id,
'user_id': nova_user_id}
host_list = self._l2network_plugin.schedule_host(instance_tenant_id,
instance_id,
instance_desc)
instance_vif_desc = {'project_id': tenant_id,
'user_id': nova_user_id,
'vif_id': vif_id}
vif_description = self._l2network_plugin.associate_port(
instance_tenant_id, instance_id,
instance_vif_desc)
self._l2network_plugin.plug_interface( self._l2network_plugin.plug_interface(
tenant_id, new_net_dict[const.NET_ID], tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORT_ID], self.remote_interface) port_dict[const.PORT_ID], vif_id)
self._l2network_plugin.unplug_interface( self._l2network_plugin.unplug_interface(
tenant_id, new_net_dict[const.NET_ID], tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORT_ID]) port_dict[const.PORT_ID])
port = db.port_get(new_net_dict[const.NET_ID], port = db.port_get(new_net_dict[const.NET_ID],
port_dict[const.PORT_ID]) port_dict[const.PORT_ID])
self.assertEqual(port[const.INTERFACEID], None) vif_id_unplugged = vif_id + '(detached)'
self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID], self.assertEqual(port[const.INTERFACEID], vif_id_unplugged)
port_dict[const.PORT_ID]) self.tearDownNetworkPortInterface(
tenant_id, instance_tenant_id, instance_id, instance_vif_desc,
new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
LOG.debug("test_unplug_interface - END") LOG.debug("test_unplug_interface - END")
def test_unplug_interface_networkDNE(self, tenant_id='test_tenant', def test_unplug_interface_networkDNE(self, tenant_id='test_tenant',
@ -926,13 +997,14 @@ class CoreAPITestFunc(unittest.TestCase):
self._l2network_plugin.delete_port(tenant_id, network_dict_id, port_id) self._l2network_plugin.delete_port(tenant_id, network_dict_id, port_id)
self.tearDownNetwork(tenant_id, network_dict_id) self.tearDownNetwork(tenant_id, network_dict_id)
def tearDownNetworkPortInterface(self, tenant_id, network_dict_id, def tearDownNetworkPortInterface(self, tenant_id, instance_tenant_id,
port_id): instance_id, instance_desc, network_dict_id,
port_id):
""" """
Tear down Network Port Interface Tear down Network Port Interface
""" """
self._l2network_plugin.unplug_interface(tenant_id, self._l2network_plugin.detach_port(instance_tenant_id, instance_id,
network_dict_id, port_id) instance_desc)
self.tearDownNetworkPort(tenant_id, network_dict_id, port_id) self.tearDownNetworkPort(tenant_id, network_dict_id, port_id)
def tearDownPortProfile(self, tenant_id, port_profile_id): def tearDownPortProfile(self, tenant_id, port_profile_id):

View File

@ -20,6 +20,7 @@ from quantum.common import exceptions as exc
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import l2network_db as cdb from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco.db import api as db from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.common import cisco_credentials as cred
from quantum.plugins.cisco.nexus import cisco_nexus_plugin from quantum.plugins.cisco.nexus import cisco_nexus_plugin
LOG = logging.getLogger('quantum.tests.test_nexus') LOG = logging.getLogger('quantum.tests.test_nexus')
@ -31,7 +32,6 @@ class TestNexusPlugin(unittest.TestCase):
""" """
Set up function Set up function
""" """
self.tenant_id = "test_tenant_cisco1" self.tenant_id = "test_tenant_cisco1"
self.net_name = "test_network_cisco1" self.net_name = "test_network_cisco1"
self.net_id = 000007 self.net_id = 000007
@ -39,11 +39,11 @@ class TestNexusPlugin(unittest.TestCase):
self.vlan_id = 267 self.vlan_id = 267
self.port_id = "9" self.port_id = "9"
cdb.initialize() cdb.initialize()
cred.Store.initialize()
self._cisco_nexus_plugin = cisco_nexus_plugin.NexusPlugin() self._cisco_nexus_plugin = cisco_nexus_plugin.NexusPlugin()
def test_create_network(self, net_tenant_id=None, network_name=None, def test_create_network(self, net_tenant_id=None, network_name=None,
network_id=None, net_vlan_name=None, net_vlan_name=None, net_vlan_id=None):
net_vlan_id=None):
""" """
Tests creation of new Virtual Network. Tests creation of new Virtual Network.
""" """
@ -57,10 +57,6 @@ class TestNexusPlugin(unittest.TestCase):
net_name = network_name net_name = network_name
else: else:
net_name = self.net_name net_name = self.net_name
if network_id:
net_id = network_id
else:
net_id = self.net_id
if net_vlan_name: if net_vlan_name:
vlan_name = net_vlan_name vlan_name = net_vlan_name
else: else:
@ -70,18 +66,20 @@ class TestNexusPlugin(unittest.TestCase):
else: else:
vlan_id = self.vlan_id vlan_id = self.vlan_id
network_created = self.create_network(tenant_id, net_id) network_created = self.create_network(tenant_id, net_name)
cdb.add_vlan_binding(vlan_id, vlan_name, network_created["net-id"]) cdb.add_vlan_binding(vlan_id, vlan_name, network_created["net-id"])
new_net_dict = self._cisco_nexus_plugin.create_network( new_net_dict = self._cisco_nexus_plugin.create_network(
tenant_id, net_name, net_id, vlan_name, vlan_id) tenant_id, net_name, network_created["net-id"],
self.assertEqual(new_net_dict[const.NET_ID], self.net_id) vlan_name, vlan_id)
self.assertEqual(new_net_dict[const.NET_ID],
network_created["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)
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_create_network - END") LOG.debug("test_create_network - END")
def test_delete_network(self, net_tenant_id=None, network_id=None): def test_delete_network(self, net_tenant_id=None, network_name=None):
""" """
Tests deletion of a Virtual Network. Tests deletion of a Virtual Network.
""" """
@ -92,16 +90,21 @@ class TestNexusPlugin(unittest.TestCase):
tenant_id = net_tenant_id tenant_id = net_tenant_id
else: else:
tenant_id = self.tenant_id tenant_id = self.tenant_id
if network_id: if network_name:
net_id = network_id net_name = network_name
else: else:
net_id = self.net_id net_name = self.net_name
network_created = self.create_network(tenant_id, net_name)
cdb.add_vlan_binding(self.vlan_id, self.vlan_name,
network_created["net-id"])
new_net_dict = self._cisco_nexus_plugin.create_network( new_net_dict = self._cisco_nexus_plugin.create_network(
tenant_id, self.net_name, net_id, self.vlan_name, self.vlan_id) tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id)
deleted_net_dict = self._cisco_nexus_plugin.delete_network( deleted_net_dict = self._cisco_nexus_plugin.delete_network(
tenant_id, new_net_dict[const.NET_ID]) tenant_id, new_net_dict[const.NET_ID])
self.assertEqual(deleted_net_dict[const.NET_ID], net_id) self.assertEqual(deleted_net_dict[const.NET_ID],
network_created["net-id"])
LOG.debug("test_delete_network - END") LOG.debug("test_delete_network - END")
def test_delete_network_DNE(self, net_tenant_id=None, net_id='0005'): def test_delete_network_DNE(self, net_tenant_id=None, net_id='0005'):
@ -122,7 +125,7 @@ class TestNexusPlugin(unittest.TestCase):
LOG.debug("test_delete_network_DNE - END") LOG.debug("test_delete_network_DNE - END")
def test_get_network_details(self, net_tenant_id=None, network_id=None): def test_get_network_details(self, net_tenant_id=None, network_name=None):
""" """
Tests displays details of a Virtual Network . Tests displays details of a Virtual Network .
""" """
@ -133,17 +136,21 @@ class TestNexusPlugin(unittest.TestCase):
tenant_id = net_tenant_id tenant_id = net_tenant_id
else: else:
tenant_id = self.tenant_id tenant_id = self.tenant_id
if network_id: if network_name:
net_id = network_id net_name = network_name
else: else:
net_id = self.net_id net_name = self.net_name
network_created = self.create_network(tenant_id, net_name)
cdb.add_vlan_binding(self.vlan_id, self.vlan_name,
network_created["net-id"])
new_net_dict = self._cisco_nexus_plugin.create_network( new_net_dict = self._cisco_nexus_plugin.create_network(
tenant_id, self.net_name, net_id, self.vlan_name, self.vlan_id) tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id)
check_net_dict = self._cisco_nexus_plugin.get_network_details( check_net_dict = self._cisco_nexus_plugin.get_network_details(
tenant_id, net_id) tenant_id, network_created["net-id"])
self.assertEqual(check_net_dict[const.NET_ID],
self.assertEqual(check_net_dict[const.NET_ID], net_id) network_created["net-id"])
self.assertEqual(check_net_dict[const.NET_NAME], self.net_name) self.assertEqual(check_net_dict[const.NET_NAME], self.net_name)
self.assertEqual(check_net_dict[const.NET_VLAN_NAME], self.vlan_name) self.assertEqual(check_net_dict[const.NET_VLAN_NAME], self.vlan_name)
self.assertEqual(check_net_dict[const.NET_VLAN_ID], self.vlan_id) self.assertEqual(check_net_dict[const.NET_VLAN_ID], self.vlan_id)
@ -169,7 +176,7 @@ class TestNexusPlugin(unittest.TestCase):
LOG.debug("test_get_network_details_network_does_not_exist - END") LOG.debug("test_get_network_details_network_does_not_exist - END")
def test_rename_network(self, new_name="new_network_name", def test_rename_network(self, new_name="new_network_name",
net_tenant_id=None, network_id=None): net_tenant_id=None, network_name=None):
""" """
Tests rename of a Virtual Network . Tests rename of a Virtual Network .
""" """
@ -180,14 +187,17 @@ class TestNexusPlugin(unittest.TestCase):
tenant_id = net_tenant_id tenant_id = net_tenant_id
else: else:
tenant_id = self.tenant_id tenant_id = self.tenant_id
if network_id: if network_name:
net_id = network_id net_name = network_name
else: else:
net_id = self.net_id net_name = self.net_name
network_created = self.create_network(tenant_id, net_name)
cdb.add_vlan_binding(self.vlan_id, self.vlan_name,
network_created["net-id"])
new_net_dict = self._cisco_nexus_plugin.create_network( new_net_dict = self._cisco_nexus_plugin.create_network(
tenant_id, self.net_name, net_id, self.vlan_name, tenant_id, self.net_name, network_created["net-id"],
self.vlan_id) self.vlan_name, self.vlan_id)
rename_net_dict = self._cisco_nexus_plugin.rename_network( rename_net_dict = self._cisco_nexus_plugin.rename_network(
tenant_id, new_net_dict[const.NET_ID], new_name) tenant_id, new_net_dict[const.NET_ID], new_name)
self.assertEqual(rename_net_dict[const.NET_NAME], new_name) self.assertEqual(rename_net_dict[const.NET_NAME], new_name)
@ -227,23 +237,28 @@ class TestNexusPlugin(unittest.TestCase):
tenant_id = net_tenant_id tenant_id = net_tenant_id
else: else:
tenant_id = self.tenant_id tenant_id = self.tenant_id
network_created = self.create_network(tenant_id, self.net_name)
cdb.add_vlan_binding(self.vlan_id, self.vlan_name,
network_created["net-id"])
new_net_dict1 = self._cisco_nexus_plugin.create_network( new_net_dict1 = self._cisco_nexus_plugin.create_network(
tenant_id, self.net_name, self.net_id, tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id) self.vlan_name, self.vlan_id)
network_created2 = self.create_network(tenant_id, 'test_network2')
cdb.add_vlan_binding(265, 'second_vlan', network_created2["net-id"])
new_net_dict2 = self._cisco_nexus_plugin.create_network( new_net_dict2 = self._cisco_nexus_plugin.create_network(
tenant_id, "New_Network2", "0011", tenant_id, "New_Network2",
"second_vlan", "2003") network_created2["net-id"], "second_vlan", "2003")
list_net_dict = self._cisco_nexus_plugin.get_all_networks(tenant_id) list_net_dict = self._cisco_nexus_plugin.get_all_networks(tenant_id)
net_temp_list = [new_net_dict1, new_net_dict2] net_temp_list = [new_net_dict1, new_net_dict2]
self.assertEqual(len(list_net_dict), 2) self.assertTrue(net_temp_list[0] in list_net_dict)
self.assertTrue(list_net_dict[0] in net_temp_list) self.assertTrue(net_temp_list[1] in list_net_dict)
self.assertTrue(list_net_dict[1] in net_temp_list)
self.tearDownNetwork(tenant_id, new_net_dict1[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict1[const.NET_ID])
self.tearDownNetwork(tenant_id, new_net_dict2[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict2[const.NET_ID])
LOG.debug("test_list_all_networks - END") LOG.debug("test_list_all_networks - END")
def test_get_vlan_id_for_network(self, net_tenant_id=None, def test_get_vlan_id_for_network(self, net_tenant_id=None,
network_id=None): network_name=None):
""" """
Tests retrieval of vlan id for a Virtual Networks . Tests retrieval of vlan id for a Virtual Networks .
""" """
@ -253,15 +268,19 @@ class TestNexusPlugin(unittest.TestCase):
tenant_id = net_tenant_id tenant_id = net_tenant_id
else: else:
tenant_id = self.tenant_id tenant_id = self.tenant_id
if network_id: if network_name:
net_id = network_id net_name = network_name
else: else:
net_id = self.net_id net_name = self.net_name
network_created = self.create_network(tenant_id, net_name)
cdb.add_vlan_binding(self.vlan_id, self.vlan_name,
network_created["net-id"])
new_net_dict = self._cisco_nexus_plugin.create_network( new_net_dict = self._cisco_nexus_plugin.create_network(
tenant_id, self.net_name, net_id, self.vlan_name, tenant_id, self.net_name, network_created["net-id"],
self.vlan_id) self.vlan_name, self.vlan_id)
result_vlan_id = self._cisco_nexus_plugin._get_vlan_id_for_network( result_vlan_id = self._cisco_nexus_plugin._get_vlan_id_for_network(
tenant_id, net_id) tenant_id, network_created["net-id"])
self.assertEqual(result_vlan_id, self.vlan_id) self.assertEqual(result_vlan_id, self.vlan_id)
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID]) self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_get_vlan_id_for_network - END") LOG.debug("test_get_vlan_id_for_network - END")
@ -284,3 +303,8 @@ class TestNexusPlugin(unittest.TestCase):
Clean up functions after the tests Clean up functions after the tests
""" """
self._cisco_nexus_plugin.delete_network(tenant_id, network_dict_id) self._cisco_nexus_plugin.delete_network(tenant_id, network_dict_id)
def tearDown(self):
"""Clear the test environment"""
# Remove database contents
db.clear_db()

View File

@ -35,6 +35,9 @@ LOG.getLogger("cisco_ucs_plugin")
class UCSVICTestPlugin(unittest.TestCase): class UCSVICTestPlugin(unittest.TestCase):
"""
Unit Tests for the UCS Plugin functions
"""
def setUp(self): def setUp(self):
@ -49,10 +52,14 @@ class UCSVICTestPlugin(unittest.TestCase):
self._cisco_ucs_plugin = cisco_ucs_plugin.UCSVICPlugin() self._cisco_ucs_plugin = cisco_ucs_plugin.UCSVICPlugin()
self.device_ip = conf.UCSM_IP_ADDRESS self.device_ip = conf.UCSM_IP_ADDRESS
self._ucs_inventory = ucsinv.UCSInventory() self._ucs_inventory = ucsinv.UCSInventory()
self.chassis_id = '1' self._ucs_inventory._load_inventory()
self.blade_id = '5' self.chassis_id_list = self._ucs_inventory._inventory[\
self.blade_intf_distinguished_name = 'sys/chassis-1/blade-5/'\ self.device_ip].keys()
'adaptor-1/host-eth-6' self.chassis_id = self.chassis_id_list[0]
self.blade_id_list = self._ucs_inventory._inventory[\
self.device_ip][self.chassis_id]
self.blade_id = self._ucs_inventory._inventory[\
self.device_ip][self.chassis_id][0]
def test_create_network(self): def test_create_network(self):
""" """
@ -69,7 +76,7 @@ class UCSVICTestPlugin(unittest.TestCase):
self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID]) self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID])
self.assertEqual(new_net_dict[const.NET_NAME], self.assertEqual(new_net_dict[const.NET_NAME],
new_network[const.NETWORKNAME]) new_network[const.NETWORKNAME])
self.tearDownNetwork(self.tenant_id, new_network[const.UUID]) self.tear_down_network(self.tenant_id, new_network[const.UUID])
def test_delete_network(self): def test_delete_network(self):
""" """
@ -107,7 +114,7 @@ class UCSVICTestPlugin(unittest.TestCase):
self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID]) self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID])
self.assertEqual(new_net_dict[const.NET_NAME], self.assertEqual(new_net_dict[const.NET_NAME],
new_network[const.NETWORKNAME]) new_network[const.NETWORKNAME])
self.tearDownNetwork(self.tenant_id, new_network[const.UUID]) self.tear_down_network(self.tenant_id, new_network[const.UUID])
def test_get_all_networks(self): def test_get_all_networks(self):
""" """
@ -136,8 +143,8 @@ class UCSVICTestPlugin(unittest.TestCase):
self.assertTrue(net_list[0] in net_id_list) self.assertTrue(net_list[0] in net_id_list)
self.assertTrue(net_list[1] in net_id_list) self.assertTrue(net_list[1] in net_id_list)
self.tearDownNetwork(self.tenant_id, new_network1[const.UUID]) self.tear_down_network(self.tenant_id, new_network1[const.UUID])
self.tearDownNetwork(self.tenant_id, new_network2[const.UUID]) self.tear_down_network(self.tenant_id, new_network2[const.UUID])
def test_get_all_ports(self): def test_get_all_ports(self):
""" """
@ -178,16 +185,18 @@ class UCSVICTestPlugin(unittest.TestCase):
self.assertTrue(str(ports_on_net[0]) == str(port_list[1]) or self.assertTrue(str(ports_on_net[0]) == str(port_list[1]) or
str(ports_on_net[0]) == str(port_list[0])) str(ports_on_net[0]) == str(port_list[0]))
blade_intf_details = self._ucs_inventory._get_rsvd_blade_intf_by_port(
self.tenant_id, port_dict1[const.PORTID])
self._cisco_ucs_plugin.delete_port( self._cisco_ucs_plugin.delete_port(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
port_dict1[const.PORTID], device_ip=self.device_ip, port_dict1[const.PORTID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory, ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id, chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=self.\ blade_intf_distinguished_name=blade_intf_details[\
blade_intf_distinguished_name, const.BLADE_INTF_DN],
least_rsvd_blade_dict=self._ucs_inventory.\ least_rsvd_blade_dict=self._ucs_inventory.\
_get_least_reserved_blade()) _get_least_reserved_blade())
self.tearDownNetworkPort( self.tear_down_network_port(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
port_dict2[const.PORTID]) port_dict2[const.PORTID])
@ -215,7 +224,7 @@ class UCSVICTestPlugin(unittest.TestCase):
profile_name = self._cisco_ucs_plugin.\ profile_name = self._cisco_ucs_plugin.\
_get_profile_name(port_dict[const.PORTID]) _get_profile_name(port_dict[const.PORTID])
self.assertTrue(profile_name != None) self.assertTrue(profile_name != None)
self.tearDownNetworkPort( self.tear_down_network_port(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID]) port_dict[const.PORTID])
@ -241,18 +250,21 @@ class UCSVICTestPlugin(unittest.TestCase):
ucs_inventory=self._ucs_inventory, ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=self._ucs_inventory.\ least_rsvd_blade_dict=self._ucs_inventory.\
_get_least_reserved_blade()) _get_least_reserved_blade())
blade_intf_details = self._ucs_inventory._get_rsvd_blade_intf_by_port(
self.tenant_id, port_dict[const.PORTID])
port_bind = self._cisco_ucs_plugin.delete_port( port_bind = self._cisco_ucs_plugin.delete_port(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], device_ip=self.device_ip, port_dict[const.PORTID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory, ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id, chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=self.\ blade_intf_distinguished_name=blade_intf_details[\
blade_intf_distinguished_name, const.BLADE_INTF_DN],
least_rsvd_blade_dict=self._ucs_inventory.\ least_rsvd_blade_dict=self._ucs_inventory.\
_get_least_reserved_blade()) _get_least_reserved_blade())
self.assertEqual(port_bind[const.PORTID], new_port[const.UUID]) self.assertEqual(port_bind[const.PORTID], new_port[const.UUID])
self.tearDownNetwork(self.tenant_id, new_net_dict[const.NET_ID]) self.tear_down_network(self.tenant_id, new_net_dict[const.NET_ID])
def _test_get_port_details(self, port_state): def _test_get_port_details(self, port_state):
""" """
@ -279,17 +291,26 @@ class UCSVICTestPlugin(unittest.TestCase):
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], device_ip=self.device_ip) port_dict[const.PORTID], device_ip=self.device_ip)
self.assertEqual(str(port_dict), str(port_detail)) self.assertEqual(str(port_dict), str(port_detail))
self.tearDownNetworkPort( self.tear_down_network_port(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID]) port_dict[const.PORTID])
def test_get_port_details_state_up(self): def test_get_port_details_state_up(self):
"""
Tests if the port details is retrieved when port is up
"""
self._test_get_port_details(const.PORT_UP) self._test_get_port_details(const.PORT_UP)
def test_show_port_state_down(self): def test_show_port_state_down(self):
"""
Tests if the port details is retrieved when port is down
"""
self._test_get_port_details(const.PORT_DOWN) self._test_get_port_details(const.PORT_DOWN)
def test_create_port_profile(self): def test_create_port_profile(self):
"""
Tests creation of port profile
"""
LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n") LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n")
new_network = db.network_create(self.tenant_id, self.net_name) new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name, cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
@ -310,6 +331,9 @@ class UCSVICTestPlugin(unittest.TestCase):
profile_name) profile_name)
def test_delete_port_profile(self): def test_delete_port_profile(self):
"""
Tests deletion of port profile
"""
LOG.debug("UCSVICTestPlugin:test_delete_port_profile() called\n") LOG.debug("UCSVICTestPlugin:test_delete_port_profile() called\n")
new_network = db.network_create(self.tenant_id, self.net_name) new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name, cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
@ -359,7 +383,7 @@ class UCSVICTestPlugin(unittest.TestCase):
device_ip=self.device_ip) device_ip=self.device_ip)
self.assertEqual(port_bind[const.VLANNAME], new_vlan_name) self.assertEqual(port_bind[const.VLANNAME], new_vlan_name)
self.assertEqual(port_bind[const.VLANID], new_vlanid) self.assertEqual(port_bind[const.VLANID], new_vlanid)
self.tearDownNetworkPortInterface( self.tear_down_network_port_interface(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
new_port[const.UUID]) new_port[const.UUID])
@ -397,11 +421,14 @@ class UCSVICTestPlugin(unittest.TestCase):
port_dict[const.PORTID], device_ip=self.device_ip) port_dict[const.PORTID], device_ip=self.device_ip)
self.assertEqual(port_bind[const.VLANNAME], self.vlan_name) self.assertEqual(port_bind[const.VLANNAME], self.vlan_name)
self.assertEqual(port_bind[const.VLANID], self.vlan_id) self.assertEqual(port_bind[const.VLANID], self.vlan_id)
self.tearDownNetworkPortInterface( self.tear_down_network_port_interface(
self.tenant_id, new_net_dict[const.NET_ID], self.tenant_id, new_net_dict[const.NET_ID],
new_port[const.UUID]) new_port[const.UUID])
def test_get_vlan_name_for_network(self): def test_get_vlan_name_for_network(self):
"""
Tests retrieval of vlan name
"""
LOG.debug("UCSVICTestPlugin:test_get_vlan_name_for_network() called\n") LOG.debug("UCSVICTestPlugin:test_get_vlan_name_for_network() called\n")
new_network = db.network_create(self.tenant_id, self.net_name) new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name, cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
@ -412,6 +439,9 @@ class UCSVICTestPlugin(unittest.TestCase):
self.assertEqual(vlan_bind_name, self.vlan_name) self.assertEqual(vlan_bind_name, self.vlan_name)
def test_get_vlan_id_for_network(self): def test_get_vlan_id_for_network(self):
"""
Tests retrieval of vlan id
"""
LOG.debug("UCSVICTestPlugin:test_get_vlan_id_for_network() called\n") LOG.debug("UCSVICTestPlugin:test_get_vlan_id_for_network() called\n")
new_network = db.network_create(self.tenant_id, self.net_name) new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name, cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
@ -420,19 +450,28 @@ class UCSVICTestPlugin(unittest.TestCase):
self.tenant_id, new_network[const.UUID]) self.tenant_id, new_network[const.UUID])
self.assertEqual(str(vlan_bind_id), self.vlan_id) self.assertEqual(str(vlan_bind_id), self.vlan_id)
def test_show_network_NetworkNotFound(self): def test_show_network_not_found(self):
"""
Negative Test for show network details when network not found
"""
self.assertRaises(exc.NetworkNotFound, self.assertRaises(exc.NetworkNotFound,
self._cisco_ucs_plugin.get_network_details, self._cisco_ucs_plugin.get_network_details,
self.tenant_id, self.net_id, self.tenant_id, self.net_id,
device_ip=self.device_ip) device_ip=self.device_ip)
def test_delete_network_NetworkNotFound(self): def test_delete_network_not_found(self):
"""
Negative Test for delete network when network not found
"""
self.assertRaises(exc.NetworkNotFound, self.assertRaises(exc.NetworkNotFound,
self._cisco_ucs_plugin.delete_network, self._cisco_ucs_plugin.delete_network,
self.tenant_id, self.net_id, self.tenant_id, self.net_id,
device_ip=self.device_ip) device_ip=self.device_ip)
def test_delete_port_PortNotFound(self): def test_delete_port_PortNotFound(self):
"""
Negative Test for delete port when port not found
"""
new_network = db.network_create(self.tenant_id, self.net_name) new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name, cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID]) new_network[const.UUID])
@ -447,35 +486,36 @@ class UCSVICTestPlugin(unittest.TestCase):
self.port_id, device_ip=self.device_ip, self.port_id, device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory, ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id, chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=self.\ blade_intf_distinguished_name=None,
blade_intf_distinguished_name,
least_rsvd_blade_dict=self._ucs_inventory.\ least_rsvd_blade_dict=self._ucs_inventory.\
_get_least_reserved_blade()) _get_least_reserved_blade())
self.tearDownNetwork(self.tenant_id, new_net_dict[const.NET_ID]) self.tear_down_network(self.tenant_id, new_net_dict[const.NET_ID])
def tearDown(self): def tearDown(self):
"""Clear the test environment""" """Clear the test environment"""
# Remove database contents # Remove database contents
db.clear_db() db.clear_db()
def tearDownNetwork(self, tenant_id, net_id): def tear_down_network(self, tenant_id, net_id):
self._cisco_ucs_plugin.delete_network(tenant_id, net_id, self._cisco_ucs_plugin.delete_network(tenant_id, net_id,
device_ip=self.device_ip) device_ip=self.device_ip)
def tearDownNetworkPort(self, tenant_id, net_id, port_id): def tear_down_network_port(self, tenant_id, net_id, port_id):
blade_intf_details = self._ucs_inventory._get_rsvd_blade_intf_by_port(
tenant_id, port_id)
self._cisco_ucs_plugin.delete_port( self._cisco_ucs_plugin.delete_port(
tenant_id, net_id, port_id, device_ip=self.device_ip, tenant_id, net_id, port_id, device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory, ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id, chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=self.\ blade_intf_distinguished_name=blade_intf_details[\
blade_intf_distinguished_name, const.BLADE_INTF_DN],
least_rsvd_blade_dict=self._ucs_inventory.\ least_rsvd_blade_dict=self._ucs_inventory.\
_get_least_reserved_blade()) _get_least_reserved_blade())
self.tearDownNetwork(tenant_id, net_id) self.tear_down_network(tenant_id, net_id)
def tearDownNetworkPortInterface(self, tenant_id, net_id, port_id): def tear_down_network_port_interface(self, tenant_id, net_id, port_id):
self._cisco_ucs_plugin.unplug_interface( self._cisco_ucs_plugin.unplug_interface(
tenant_id, net_id, port_id, tenant_id, net_id, port_id,
device_ip=self.device_ip) device_ip=self.device_ip)
self.tearDownNetworkPort(tenant_id, net_id, port_id) self.tear_down_network_port(tenant_id, net_id, port_id)

View File

@ -0,0 +1,94 @@
"""
# 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: Peter Strunk, Cisco Systems, Inc.
#
"""
import unittest
import logging as LOG
from quantum.common import exceptions as exc
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.common import cisco_credentials as creds
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco.segmentation.l2network_vlan_mgr \
import L2NetworkVLANMgr
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger(__name__)
class Test_L2Network_Vlan_Mgr(unittest.TestCase):
_plugins = {}
_inventory = {}
def setUp(self):
db.configure_db({'sql_connection': 'sqlite:///:memory:'})
cdb.initialize()
creds.Store.initialize()
self.tenant_id = "network_admin"
self.net_name = "TestNetwork1"
self.vlan_name = "TestVlan1"
self.vlan_id = 300
self.net_id = 100
self.vlan_mgr = L2NetworkVLANMgr()
self.plugin_key = "quantum.plugins.cisco.ucs.cisco_ucs_plugin" +\
".UCSVICPlugin"
def tearDown(self):
db.clear_db()
def test_reserve_segmentation_id(self):
LOG.debug("test_reserve_segmentation_id - START")
db.network_create(self.tenant_id, self.net_name)
vlan_id = self.vlan_mgr.reserve_segmentation_id(self.tenant_id,
self.net_name)
self.assertEqual(vlan_id, int(conf.VLAN_START))
LOG.debug("test_reserve_segmentation_id - END")
def test_reserve_segmentation_id_NA(self):
LOG.debug("test_reserve_segmentation_id - START")
db.clear_db()
self.assertRaises(c_exc.VlanIDNotAvailable,
self.vlan_mgr.reserve_segmentation_id,
self.tenant_id,
self.net_name)
LOG.debug("test_reserve_segmentation_id - END")
def test_release_segmentation_id(self):
LOG.debug("test_release_segmentation_id - START")
db.network_create(self.tenant_id, self.net_name)
vlan_id = self.vlan_mgr.reserve_segmentation_id(self.tenant_id,
self.net_name)
cdb.add_vlan_binding(vlan_id, self.vlan_name, self.net_id)
release_return = self.vlan_mgr.release_segmentation_id(self.tenant_id,
self.net_id)
self.assertEqual(release_return, False)
LOG.debug("test_release_segmentation_id - END")
def test_release_segmentation_id_idDNE(self):
LOG.debug("test_release_segmentation_idDNE - START")
db.network_create(self.tenant_id, self.net_name)
self.assertRaises(exc.NetworkNotFound,
self.vlan_mgr.release_segmentation_id,
self.tenant_id,
self.net_id)
LOG.debug("test_release_segmentation_idDNE - END")

View File

@ -19,7 +19,7 @@
# #
""" """
from copy import deepcopy from copy import deepcopy
import logging as LOG import logging
from quantum.common import exceptions as exc from quantum.common import exceptions as exc
from quantum.plugins.cisco.l2device_inventory_base \ from quantum.plugins.cisco.l2device_inventory_base \
@ -34,8 +34,7 @@ from quantum.plugins.cisco.ucs \
import cisco_ucs_inventory_configuration as conf import cisco_ucs_inventory_configuration as conf
from quantum.plugins.cisco.ucs import cisco_ucs_network_driver from quantum.plugins.cisco.ucs import cisco_ucs_network_driver
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(__name__)
""" """
The _inventory data strcuture contains a nested disctioary: The _inventory data strcuture contains a nested disctioary:
@ -208,7 +207,6 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
port_binding[const.INSTANCE_ID] port_binding[const.INSTANCE_ID]
intf_data[const.VIF_ID] = \ intf_data[const.VIF_ID] = \
port_binding[const.VIF_ID] port_binding[const.VIF_ID]
host_name = self._get_host_name(ucsm_ip, chassis_id, blade_id) host_name = self._get_host_name(ucsm_ip, chassis_id, blade_id)
blade_data = {const.BLADE_INTF_DATA: blade_intf_data, blade_data = {const.BLADE_INTF_DATA: blade_intf_data,
const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter, const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter,
@ -328,7 +326,8 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
port_id = port_binding[const.PORTID] port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id, instance_id=instance_id, udb.update_portbinding(port_id, instance_id=instance_id,
vif_id=vif_id) vif_id=vif_id)
db.port_set_attachment_by_id(port_id, vif_id) db.port_set_attachment_by_id(port_id, vif_id +
const.UNPLUGGED)
device_name = intf_data[const.BLADE_INTF_RHEL_DEVICE_NAME] device_name = intf_data[const.BLADE_INTF_RHEL_DEVICE_NAME]
profile_name = port_binding[const.PORTPROFILENAME] profile_name = port_binding[const.PORTPROFILENAME]
dynamicnic_details = \ dynamicnic_details = \
@ -336,7 +335,7 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
const.UCSPROFILE: profile_name} const.UCSPROFILE: profile_name}
LOG.debug("Found reserved dynamic nic: %s" \ LOG.debug("Found reserved dynamic nic: %s" \
"associated with port %s" % "associated with port %s" %
(blade_intf_data[blade_intf], port_id)) (intf_data, port_id))
LOG.debug("Returning dynamic nic details: %s" % LOG.debug("Returning dynamic nic details: %s" %
dynamicnic_details) dynamicnic_details)
return dynamicnic_details return dynamicnic_details
@ -345,9 +344,10 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
tenant_id) tenant_id)
return None return None
def _disassociate_vifid_from_port(self, tenant_id, port_id): def _disassociate_vifid_from_port(self, tenant_id, instance_id, vif_id):
""" """
Return the device name for a reserved interface Disassociate a VIF-ID from a port, this happens when a
VM is destroyed
""" """
for ucsm_ip in self._inventory_state.keys(): for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip] ucsm = self._inventory_state[ucsm_ip]
@ -360,17 +360,24 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
if intf_data[const.BLADE_INTF_RESERVATION] == \ if intf_data[const.BLADE_INTF_RESERVATION] == \
const.BLADE_INTF_RESERVED and \ const.BLADE_INTF_RESERVED and \
intf_data[const.TENANTID] == tenant_id and \ intf_data[const.TENANTID] == tenant_id and \
intf_data[const.PORTID] == port_id: blade_intf_data[blade_intf][const.INSTANCE_ID] == \
vif_id = intf_data[const.VIF_ID] instance_id and \
intf_data[const.VIF_ID][:const.UUID_LENGTH] == \
vif_id:
intf_data[const.VIF_ID] = None intf_data[const.VIF_ID] = None
intf_data[const.INSTANCE_ID] = None intf_data[const.INSTANCE_ID] = None
port_binding = udb.get_portbinding_dn(blade_intf)
port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id, instance_id=None, udb.update_portbinding(port_id, instance_id=None,
vif_id=None) vif_id=None)
db.port_unset_attachment_by_id(port_id)
LOG.debug("Disassociated VIF-ID: %s " \ LOG.debug("Disassociated VIF-ID: %s " \
"from port: %s" \ "from port: %s" \
"in UCS inventory state for blade: %s" % "in UCS inventory state for blade: %s" %
(vif_id, port_id, intf_data)) (vif_id, port_id, intf_data))
return device_params = {const.DEVICE_IP: [ucsm_ip],
const.PORTID: port_id}
return device_params
LOG.warn("Disassociating VIF-ID in UCS inventory failed. " \ LOG.warn("Disassociating VIF-ID in UCS inventory failed. " \
"Could not find a reserved dynamic nic for tenant: %s" % "Could not find a reserved dynamic nic for tenant: %s" %
tenant_id) tenant_id)
@ -641,9 +648,6 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
on which a dynamic vnic was reserved for this port on which a dynamic vnic was reserved for this port
""" """
LOG.debug("unplug_interface() called\n") LOG.debug("unplug_interface() called\n")
tenant_id = args[0]
port_id = args[2]
self._disassociate_vifid_from_port(tenant_id, port_id)
return self._get_blade_for_port(args) return self._get_blade_for_port(args)
def schedule_host(self, args): def schedule_host(self, args):
@ -666,9 +670,24 @@ class UCSInventory(L2NetworkDeviceInventoryBase):
vif_id = args[2][const.VIF_ID] vif_id = args[2][const.VIF_ID]
vif_info = self._get_instance_port(tenant_id, instance_id, vif_id) vif_info = self._get_instance_port(tenant_id, instance_id, vif_id)
vif_desc = {const.VIF_DESC: vif_info} vif_desc = {const.VIF_DESC: vif_info}
LOG.debug("vif_desc is: %s" % vif_desc) LOG.debug("vif_desc is: %s" % vif_desc)
return vif_desc return vif_desc
def detach_port(self, args):
"""
Remove the VIF-ID and instance name association
with the port
"""
LOG.debug("detach_port() called\n")
instance_id = args[1]
tenant_id = args[2][const.PROJECT_ID]
vif_id = args[2][const.VIF_ID]
device_params = self._disassociate_vifid_from_port(tenant_id,
instance_id,
vif_id)
return device_params
def create_multiport(self, args): def create_multiport(self, args):
""" """
Create multiple ports for a VM Create multiple ports for a VM

View File

@ -24,16 +24,14 @@ Implements a UCSM XML API Client
""" """
import httplib import httplib
import logging as LOG import logging
from xml.etree import ElementTree as et from xml.etree import ElementTree as et
from quantum.plugins.cisco.common import cisco_exceptions as cexc from quantum.plugins.cisco.common import cisco_exceptions as cexc
from quantum.plugins.cisco.common import cisco_constants as const from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.ucs import cisco_getvif as gvif from quantum.plugins.cisco.ucs import cisco_getvif as gvif
LOG = logging.getLogger(__name__)
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
COOKIE_VALUE = "cookie_placeholder" COOKIE_VALUE = "cookie_placeholder"
PROFILE_NAME = "profilename_placeholder" PROFILE_NAME = "profilename_placeholder"

View File

@ -19,7 +19,7 @@
# #
""" """
import logging as LOG import logging
from quantum.common import exceptions as exc from quantum.common import exceptions as exc
from quantum.common import utils from quantum.common import utils
@ -33,8 +33,7 @@ from quantum.plugins.cisco.db import ucs_db as udb
from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase
from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf
LOG.basicConfig(level=LOG.WARN) LOG = logging.getLogger(__name__)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
class UCSVICPlugin(L2DevicePluginBase): class UCSVICPlugin(L2DevicePluginBase):
@ -255,6 +254,48 @@ class UCSVICPlugin(L2DevicePluginBase):
return udb.update_portbinding(port_id, vlan_name=new_vlan_name, return udb.update_portbinding(port_id, vlan_name=new_vlan_name,
vlan_id=conf.DEFAULT_VLAN_ID) vlan_id=conf.DEFAULT_VLAN_ID)
def create_multiport(self, tenant_id, net_id_list, ports_num, port_id_list,
**kwargs):
"""
Creates a port on the specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:create_multiport() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
qos = None
ucs_inventory = kwargs[const.UCS_INVENTORY]
least_rsvd_blade_dict = kwargs[const.LEAST_RSVD_BLADE_DICT]
chassis_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_CHASSIS]
blade_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_ID]
blade_data_dict = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_DATA]
port_binding_list = []
for port_id, net_id in zip(port_id_list, net_id_list):
new_port_profile = \
self._create_port_profile(tenant_id, net_id, port_id,
conf.DEFAULT_VLAN_NAME,
conf.DEFAULT_VLAN_ID)
profile_name = new_port_profile[const.PROFILE_NAME]
rsvd_nic_dict = ucs_inventory.\
reserve_blade_interface(self._ucsm_ip, chassis_id,
blade_id, blade_data_dict,
tenant_id, port_id,
profile_name)
port_binding = udb.update_portbinding(port_id,
portprofile_name=profile_name,
vlan_name=conf.DEFAULT_VLAN_NAME,
vlan_id=conf.DEFAULT_VLAN_ID,
qos=qos)
port_binding_list.append(port_binding)
return port_binding_list
def detach_port(self, tenant_id, instance_id, instance_desc, **kwargs):
"""
Remove the association of the VIF with the dynamic vnic
"""
LOG.debug("detach_port() called\n")
port_id = kwargs[const.PORTID]
kwargs.pop(const.PORTID)
return self.unplug_interface(tenant_id, None, port_id, **kwargs)
def _get_profile_name(self, port_id): def _get_profile_name(self, port_id):
"""Returns the port profile name based on the port UUID""" """Returns the port profile name based on the port UUID"""
profile_name = conf.PROFILE_NAME_PREFIX \ profile_name = conf.PROFILE_NAME_PREFIX \
@ -296,36 +337,3 @@ class UCSVICPlugin(L2DevicePluginBase):
self._ucsm_ip = ucsm_ip self._ucsm_ip = ucsm_ip
self._ucsm_username = cred.Store.getUsername(conf.UCSM_IP_ADDRESS) self._ucsm_username = cred.Store.getUsername(conf.UCSM_IP_ADDRESS)
self._ucsm_password = cred.Store.getPassword(conf.UCSM_IP_ADDRESS) self._ucsm_password = cred.Store.getPassword(conf.UCSM_IP_ADDRESS)
def create_multiport(self, tenant_id, net_id_list, ports_num, port_id_list,
**kwargs):
"""
Creates a port on the specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:create_multiport() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
qos = None
ucs_inventory = kwargs[const.UCS_INVENTORY]
least_rsvd_blade_dict = kwargs[const.LEAST_RSVD_BLADE_DICT]
chassis_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_CHASSIS]
blade_id = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_ID]
blade_data_dict = least_rsvd_blade_dict[const.LEAST_RSVD_BLADE_DATA]
port_binding_list = []
for port_id, net_id in zip(port_id_list, net_id_list):
new_port_profile = \
self._create_port_profile(tenant_id, net_id, port_id,
conf.DEFAULT_VLAN_NAME,
conf.DEFAULT_VLAN_ID)
profile_name = new_port_profile[const.PROFILE_NAME]
rsvd_nic_dict = ucs_inventory.\
reserve_blade_interface(self._ucsm_ip, chassis_id,
blade_id, blade_data_dict,
tenant_id, port_id,
profile_name)
port_binding = udb.update_portbinding(port_id,
portprofile_name=profile_name,
vlan_name=conf.DEFAULT_VLAN_NAME,
vlan_id=conf.DEFAULT_VLAN_ID,
qos=qos)
port_binding_list.append(port_binding)
return port_binding_list