Removing unsed code for Cisco Quantum Plugin V1

Implements BP remove-v1-code-cisco-plugin all code used here
has been moved to Quantum V2 API.

Change-Id: I0c3f0b0c490e6741065b1a6109fd9cac980b1047
This commit is contained in:
Edgar Magana 2012-11-08 23:16:19 -08:00
parent f8c8f53b37
commit a37f35841c
23 changed files with 2 additions and 5780 deletions

View File

@ -1,17 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.

View File

@ -1,217 +0,0 @@
#!/usr/bin/env python
# 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.
#
# Initial structure and framework of this CLI has been borrowed from Quantum,
# written by the following authors
# @author: Somik Behera, Nicira Networks, Inc.
# @author: Brad Hall, Nicira Networks, Inc.
# @author: Salvatore Orlando, Citrix
#
# Cisco adaptation for extensions
# @author: Sumit Naiksatam, Cisco Systems, Inc.
# @author: Ying Liu, Cisco Systems, Inc.
import logging
import logging.handlers
from optparse import OptionParser
import os
import sys
import quantumclient.cli as qcli
from quantumclient import Client
LOG = logging.getLogger('quantum')
FORMAT = 'json'
#ACTION_PREFIX_EXT = '/v1.0'
#ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
# '/extensions/csco/tenants/{tenant_id}'
VERSION = '1.0'
URI_PREFIX_EXT = ''
URI_PREFIX_CSCO = '/extensions/csco/tenants/{tenant_id}'
TENANT_ID = 'nova'
CSCO_EXT_NAME = 'Cisco Nova Tenant'
DEFAULT_QUANTUM_VERSION = '1.1'
def help():
"""Help for CLI"""
print "\nCisco Extension Commands:"
for key in COMMANDS.keys():
print " %s %s" % (
key, " ".join(["<%s>" % y for y in COMMANDS[key]["args"]]))
def build_args(cmd, cmdargs, arglist):
"""Building the list of args for a particular CLI"""
args = []
orig_arglist = arglist[:]
try:
for cmdarg in cmdargs:
args.append(arglist[0])
del arglist[0]
except:
LOG.error("Not enough arguments for \"%s\" (expected: %d, got: %d)" % (
cmd, len(cmdargs), len(orig_arglist)))
print "Usage:\n %s %s" % (
cmd, " ".join(["<%s>" % y for y in COMMANDS[cmd]["args"]]))
sys.exit()
if len(arglist) > 0:
LOG.error("Too many arguments for \"%s\" (expected: %d, got: %d)" % (
cmd, len(cmdargs), len(orig_arglist)))
print "Usage:\n %s %s" % (
cmd, " ".join(["<%s>" % y for y in COMMANDS[cmd]["args"]]))
sys.exit()
return args
def list_extensions(*args):
"""Invoking the action to get the supported extensions"""
request_url = "/extensions"
client = Client(HOST, PORT, USE_SSL, format='json',
version=VERSION, uri_prefix=URI_PREFIX_EXT, tenant="dummy")
data = client.do_request('GET', request_url)
print("Obtained supported extensions from Quantum: %s" % data)
def schedule_host(tenant_id, instance_id, user_id=None):
"""Gets the host name from the Quantum service"""
project_id = tenant_id
instance_data_dict = {
'novatenant': {
'instance_id': instance_id,
'instance_desc': {
'user_id': user_id,
'project_id': project_id,
},
},
}
request_url = "/novatenants/" + project_id + "/schedule_host"
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
version=VERSION, uri_prefix=URI_PREFIX_CSCO)
data = client.do_request('PUT', request_url, body=instance_data_dict)
hostname = data["host_list"]["host_1"]
if not hostname:
print("Scheduler was unable to locate a host"
" for this request. Is the appropriate"
" service running?")
print("Quantum service returned host: %s" % hostname)
def create_multiport(tenant_id, net_id_list, *args):
"""Creates ports on a single host"""
net_list = net_id_list.split(",")
ports_info = {'multiport':
{'status': 'ACTIVE',
'net_id_list': net_list,
'ports_desc': {'key': 'value'}}}
request_url = "/multiport"
client = Client(HOST, PORT, USE_SSL, format='json', tenant=tenant_id,
version=VERSION, uri_prefix=URI_PREFIX_CSCO)
data = client.do_request('POST', request_url, body=ports_info)
print("Created ports: %s" % data)
COMMANDS = {
"create_multiport": {
"func": create_multiport,
"args": ["tenant-id",
"net-id-list (comma separated list of netword IDs)"],
},
"list_extensions": {
"func": list_extensions,
"args": [],
},
"schedule_host": {
"func": schedule_host,
"args": ["tenant-id", "instance-id"],
},
}
def main():
import cli
usagestr = "Usage: %prog [OPTIONS] <command> [args]"
PARSER = OptionParser(usage=usagestr)
PARSER.add_option("-H", "--host", dest="host",
type="string", default="127.0.0.1",
help="ip address of api host")
PARSER.add_option("-p", "--port", dest="port",
type="int", default=9696, help="api poort")
PARSER.add_option("-s", "--ssl", dest="ssl",
action="store_true", default=False, help="use ssl")
PARSER.add_option("-v", "--verbose", dest="verbose",
action="store_true", default=False,
help="turn on verbose logging")
PARSER.add_option("-f", "--logfile", dest="logfile",
type="string", default="syslog", help="log file path")
PARSER.add_option(
'--version', default=DEFAULT_QUANTUM_VERSION,
help='Accepts 1.1 and 1.0, defaults to env[QUANTUM_VERSION].')
options, args = PARSER.parse_args()
if options.verbose:
LOG.setLevel(logging.DEBUG)
else:
LOG.setLevel(logging.WARN)
if options.logfile == "syslog":
LOG.addHandler(logging.handlers.SysLogHandler(address='/dev/log'))
else:
LOG.addHandler(logging.handlers.WatchedFileHandler(options.logfile))
os.chmod(options.logfile, 0644)
version = options.version
if len(args) < 1:
PARSER.print_help()
qcli.help(version)
help()
sys.exit(1)
CMD = args[0]
if CMD in qcli.commands['1.1'].keys():
qcli.main()
sys.exit(1)
if CMD not in COMMANDS.keys():
LOG.error("Unknown command: %s" % CMD)
qcli.help(version)
help()
sys.exit(1)
args = build_args(CMD, COMMANDS[CMD]["args"], args[1:])
LOG.info("Executing command \"%s\" with args: %s" % (CMD, args))
HOST = options.host
PORT = options.port
USE_SSL = options.ssl
COMMANDS[CMD]["func"](*args)
LOG.info("Command execution completed")
sys.exit(0)
if __name__ == "__main__":
main()

View File

@ -1,82 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
import logging as LOG
from quantum.common.utils import find_config_file
from quantum.plugins.cisco.common import cisco_configparser as confp
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.common import cisco_exceptions as cexc
from quantum.plugins.cisco.db import l2network_db as cdb
LOG.basicConfig(level=LOG.WARN)
LOG.getLogger(const.LOGGER_COMPONENT_NAME)
CREDENTIALS_FILE = find_config_file({'plugin': 'cisco'},
"credentials.ini")
TENANT = const.NETWORK_ADMIN
cp = confp.CiscoConfigParser(CREDENTIALS_FILE)
_creds_dictionary = cp.walk(cp.dummy)
class Store(object):
"""Credential Store"""
@staticmethod
def initialize():
for id in _creds_dictionary.keys():
try:
cdb.add_credential(TENANT, id,
_creds_dictionary[id][const.USERNAME],
_creds_dictionary[id][const.PASSWORD])
except cexc.CredentialAlreadyExists:
# We are quietly ignoring this, since it only happens
# if this class module is loaded more than once, in which
# case, the credentials are already populated
pass
@staticmethod
def putCredential(cred_name, username, password):
"""Set the username and password"""
credential = cdb.add_credential(TENANT, cred_name, username, password)
@staticmethod
def getUsername(cred_name):
"""Get the username"""
credential = cdb.get_credential_name(TENANT, cred_name)
return credential[const.CREDENTIAL_USERNAME]
@staticmethod
def getPassword(cred_name):
"""Get the password"""
credential = cdb.get_credential_name(TENANT, cred_name)
return credential[const.CREDENTIAL_PASSWORD]
@staticmethod
def getCredential(cred_name):
"""Get the username and password"""
credential = cdb.get_credential_name(TENANT, cred_name)
return {const.USERNAME: const.CREDENTIAL_USERNAME,
const.PASSWORD: const.CREDENTIAL_PASSWORD}
@staticmethod
def deleteCredential(cred_name):
"""Delete a credential"""
cdb.remove_credential(TENANT, cred_name)

View File

@ -1,89 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Rohit Agarwalla, Cisco Systems, Inc.
import logging as LOG
from sqlalchemy.orm import exc
import quantum.plugins.cisco.db.api as db
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import nexus_models
def get_all_nexusport_bindings():
"""Lists all the nexusport bindings"""
LOG.debug("get_all_nexusport_bindings() called")
session = db.get_session()
try:
bindings = session.query(nexus_models.NexusPortBinding).all()
return bindings
except exc.NoResultFound:
return []
def get_nexusport_binding(vlan_id):
"""Lists a nexusport binding"""
LOG.debug("get_nexusport_binding() called")
session = db.get_session()
try:
binding = (session.query(nexus_models.NexusPortBinding).
filter_by(vlan_id=vlan_id).all())
return binding
except exc.NoResultFound:
raise c_exc.NexusPortBindingNotFound(vlan_id=vlan_id)
def add_nexusport_binding(port_id, vlan_id):
"""Adds a nexusport binding"""
LOG.debug("add_nexusport_binding() called")
session = db.get_session()
binding = nexus_models.NexusPortBinding(port_id, vlan_id)
session.add(binding)
session.flush()
return binding
def remove_nexusport_binding(vlan_id):
"""Removes a nexusport binding"""
LOG.debug("remove_nexusport_binding() called")
session = db.get_session()
try:
binding = (session.query(nexus_models.NexusPortBinding).
filter_by(vlan_id=vlan_id).all())
for bind in binding:
session.delete(bind)
session.flush()
return binding
except exc.NoResultFound:
pass
def update_nexusport_binding(port_id, new_vlan_id):
"""Updates nexusport binding"""
LOG.debug("update_nexusport_binding called")
session = db.get_session()
try:
binding = (session.query(nexus_models.NexusPortBinding).
filter_by(port_id=port_id).one())
if new_vlan_id:
binding["vlan_id"] = new_vlan_id
session.merge(binding)
session.flush()
return binding
except exc.NoResultFound:
raise c_exc.NexusPortBindingNotFound()

View File

@ -1,37 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Rohit Agarwalla, Cisco Systems, Inc.
from sqlalchemy import Column, Integer, String
from quantum.plugins.cisco.db.l2network_models import L2NetworkBase
from quantum.plugins.cisco.db.models import BASE
class NexusPortBinding(BASE, L2NetworkBase):
"""Represents a binding of nexus port to vlan_id"""
__tablename__ = 'nexusport_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
port_id = Column(String(255))
vlan_id = Column(Integer, nullable=False)
def __init__(self, port_id, vlan_id):
self.port_id = port_id
self.vlan_id = vlan_id
def __repr__(self):
return "<NexusPortBinding (%s,%d)>" % (self.port_id, self.vlan_id)

View File

@ -1,155 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Rohit Agarwalla, Cisco Systems, Inc.
import logging as LOG
from sqlalchemy.orm import exc
import quantum.plugins.cisco.db.api as db
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import ucs_models
def get_all_portbindings():
"""Lists all the port bindings"""
LOG.debug("db get_all_portbindings() called")
session = db.get_session()
try:
port_bindings = session.query(ucs_models.PortBinding).all()
return port_bindings
except exc.NoResultFound:
return []
def get_portbinding(port_id):
"""Lists a port binding"""
LOG.debug("get_portbinding() called")
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
return port_binding
except exc.NoResultFound:
raise c_exc.PortVnicNotFound(port_id=port_id)
def add_portbinding(port_id, blade_intf_dn, portprofile_name,
vlan_name, vlan_id, qos):
"""Adds a port binding"""
LOG.debug("add_portbinding() called")
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
raise c_exc.PortVnicBindingAlreadyExists(port_id=port_id)
except exc.NoResultFound:
port_binding = ucs_models.PortBinding(port_id, blade_intf_dn,
portprofile_name, vlan_name,
vlan_id, qos)
session.add(port_binding)
session.flush()
return port_binding
def remove_portbinding(port_id):
"""Removes a port binding"""
LOG.debug("db remove_portbinding() called")
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
session.delete(port_binding)
session.flush()
return port_binding
except exc.NoResultFound:
pass
def update_portbinding(port_id, blade_intf_dn=None, portprofile_name=None,
vlan_name=None, vlan_id=None, qos=None,
tenant_id=None, instance_id=None,
vif_id=None):
"""Updates port binding"""
LOG.debug("db update_portbinding() called")
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(port_id=port_id).one())
if blade_intf_dn:
port_binding.blade_intf_dn = blade_intf_dn
if portprofile_name:
port_binding.portprofile_name = portprofile_name
if vlan_name:
port_binding.vlan_name = vlan_name
if vlan_name:
port_binding.vlan_id = vlan_id
if qos:
port_binding.qos = qos
if tenant_id:
port_binding.tenant_id = tenant_id
if instance_id:
port_binding.instance_id = instance_id
if vif_id:
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 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):
"""Lists a port binding"""
LOG.debug("get_portbinding_dn() called")
session = db.get_session()
try:
port_binding = (session.query(ucs_models.PortBinding).
filter_by(blade_intf_dn=blade_intf_dn).one())
return port_binding
except exc.NoResultFound:
return []

View File

@ -1,55 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
# Copyright 2011, Cisco Systems, Inc.
#
# 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: Rohit Agarwalla, Cisco Systems, Inc.
from sqlalchemy import Column, Integer, String, ForeignKey
from sqlalchemy.orm import relation
from quantum.plugins.cisco.db.l2network_models import L2NetworkBase
from quantum.plugins.cisco.db import models
from quantum.plugins.cisco.db.models import BASE
class PortBinding(BASE, L2NetworkBase):
"""Represents Port binding to device interface"""
__tablename__ = 'port_bindings'
id = Column(Integer, primary_key=True, autoincrement=True)
port_id = Column(String(255), ForeignKey("ports.uuid"),
nullable=False)
blade_intf_dn = Column(String(255), nullable=False)
portprofile_name = Column(String(255))
vlan_name = Column(String(255))
vlan_id = Column(Integer)
qos = Column(String(255))
tenant_id = Column(String(255))
instance_id = Column(String(255))
vif_id = Column(String(255))
ports = relation(models.Port, uselist=False)
def __init__(self, port_id, blade_intf_dn, portprofile_name,
vlan_name, vlan_id, qos):
self.port_id = port_id
self.blade_intf_dn = blade_intf_dn
self.portprofile_name = portprofile_name
self.vlan_name = vlan_name
self.vlan_id = vlan_id
self.qos = qos
def __repr__(self):
return "<PortProfile Binding(%s,%s,%s,%s,%s,%s)>" % (
self.port_id, self.blade_intf_dn, self.portprofile_name,
self.vlan_name, self.vlan_id, self.qos)

View File

@ -1,156 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
from abc import ABCMeta, abstractmethod
import inspect
class L2NetworkModelBase(object):
"""
Base class for L2 Network Model
It relies on a pluggable network configuration module to gather
knowledge of the system, but knows which device-specific plugins
to invoke for a corresponding core API call, and what parameters to pass
to that plugin.
"""
__metaclass__ = ABCMeta
@abstractmethod
def get_all_networks(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def create_network(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def delete_network(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def get_network_details(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def update_network(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def get_all_ports(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def create_port(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def delete_port(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def update_port(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def get_port_details(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def plug_interface(self, args):
"""
:returns:
:raises:
"""
pass
@abstractmethod
def unplug_interface(self, args):
"""
:returns:
:raises:
"""
pass
@classmethod
def __subclasshook__(cls, klass):
"""
The __subclasshook__ method is a class method
that will be called everytime a class is tested
using issubclass(klass, Plugin).
In that case, it will check that every method
marked with the abstractmethod decorator is
provided by the plugin class.
"""
if cls is L2NetworkModelBase:
for method in cls.__abstractmethods__:
method_ok = False
for base in klass.__mro__:
if method in base.__dict__:
fn_obj = base.__dict__[method]
if inspect.isfunction(fn_obj):
abstract_fn_obj = cls.__dict__[method]
arg_count = fn_obj.func_code.co_argcount
expected_arg_count = \
abstract_fn_obj.func_code.co_argcount
method_ok = arg_count == expected_arg_count
if method_ok:
continue
return NotImplemented
return True
return NotImplemented

View File

@ -1,566 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
import inspect
import logging
from quantum.common import exceptions as exc
from quantum.openstack.common import importutils
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_exceptions as cexc
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 l2network_db as cdb
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.quantum_plugin_base import QuantumPluginBase
LOG = logging.getLogger(__name__)
class L2Network(QuantumPluginBase):
""" L2 Network Framework Plugin """
supported_extension_aliases = ["Cisco Multiport", "Cisco Credential",
"Cisco Port Profile", "Cisco qos",
"Cisco Nova Tenant"]
def __init__(self):
cdb.initialize()
cred.Store.initialize()
self._model = importutils.import_object(conf.MODEL_CLASS)
self._vlan_mgr = importutils.import_object(conf.MANAGER_CLASS)
LOG.debug("L2Network plugin initialization done successfully\n")
"""
Core API implementation
"""
def get_all_networks(self, tenant_id, **kwargs):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
the specified tenant.
"""
LOG.debug("get_all_networks() called\n")
self._invoke_device_plugins(self._func_name(), [tenant_id])
networks_list = db.network_list(tenant_id)
new_networks_list = []
for network in networks_list:
new_network_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
[])
new_networks_list.append(new_network_dict)
return new_networks_list
def create_network(self, tenant_id, net_name, **kwargs):
"""
Creates a new Virtual Network, and assigns it
a symbolic name.
"""
LOG.debug("create_network() called\n")
new_network = db.network_create(tenant_id, net_name)
new_net_id = new_network[const.UUID]
vlan_id = self._get_vlan_for_tenant(tenant_id, net_name)
vlan_name = self._get_vlan_name(new_net_id, str(vlan_id))
self._invoke_device_plugins(self._func_name(), [tenant_id, net_name,
new_net_id, vlan_name,
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name, new_net_id)
new_net_dict = {const.NET_ID: new_net_id,
const.NET_NAME: net_name,
const.NET_PORTS: []}
return new_net_dict
def delete_network(self, tenant_id, net_id):
"""
Deletes the network with the specified network identifier
belonging to the specified tenant.
"""
LOG.debug("delete_network() called\n")
db.validate_network_ownership(tenant_id, net_id)
net = db.network_get(net_id)
if net:
if len(net[const.NETWORKPORTS]) > 0:
ports_on_net = db.port_list(net_id)
for port in ports_on_net:
if port[const.INTERFACEID]:
raise exc.NetworkInUse(net_id=net_id)
for port in ports_on_net:
self.delete_port(tenant_id, net_id, port[const.UUID])
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
net_dict = cutil.make_net_dict(net[const.UUID],
net[const.NETWORKNAME],
[])
self._release_vlan_for_tenant(tenant_id, net_id)
cdb.remove_vlan_binding(net_id)
db.network_destroy(net_id)
return net_dict
# Network not found
raise exc.NetworkNotFound(net_id=net_id)
def get_network_details(self, tenant_id, net_id):
"""
Gets the details of a particular network
"""
LOG.debug("get_network_details() called\n")
db.validate_network_ownership(tenant_id, net_id)
network = db.network_get(net_id)
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
for port in ports_list:
new_port = cutil.make_port_dict(port[const.UUID],
port[const.PORTSTATE],
port[const.NETWORKID],
port[const.INTERFACEID])
ports_on_net.append(new_port)
new_network = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
ports_on_net)
return new_network
def update_network(self, tenant_id, net_id, **kwargs):
"""
Updates the symbolic name belonging to a particular
Virtual Network.
"""
LOG.debug("update_network() called\n")
db.validate_network_ownership(tenant_id, net_id)
network = db.network_update(net_id, tenant_id, **kwargs)
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
kwargs])
net_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
[])
return net_dict
def get_all_ports(self, tenant_id, net_id, **kwargs):
"""
Retrieves all port identifiers belonging to the
specified Virtual Network.
"""
LOG.debug("get_all_ports() called\n")
db.validate_network_ownership(tenant_id, net_id)
network = db.network_get(net_id)
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id])
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
for port in ports_list:
new_port = cutil.make_port_dict(port[const.UUID],
port[const.PORTSTATE],
port[const.NETWORKID],
port[const.INTERFACEID])
ports_on_net.append(new_port)
return ports_on_net
def create_port(self, tenant_id, net_id, port_state=None, **kwargs):
"""
Creates a port on the specified Virtual Network.
"""
LOG.debug("create_port() called\n")
db.validate_network_ownership(tenant_id, net_id)
port = db.port_create(net_id, port_state)
unique_port_id_string = port[const.UUID]
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_state,
unique_port_id_string])
new_port_dict = cutil.make_port_dict(port[const.UUID],
port[const.PORTSTATE],
port[const.NETWORKID],
port[const.INTERFACEID])
return new_port_dict
def delete_port(self, tenant_id, net_id, port_id):
"""
Deletes a port on a specified Virtual Network,
if the port contains a remote interface attachment,
the remote interface should first be un-plugged and
then the port can be deleted.
"""
LOG.debug("delete_port() called\n")
db.validate_port_ownership(tenant_id, net_id, port_id)
network = db.network_get(net_id)
port = db.port_get(net_id, port_id)
attachment_id = port[const.INTERFACEID]
if not attachment_id:
self._invoke_device_plugins(self._func_name(), [tenant_id,
net_id,
port_id])
db.port_destroy(net_id, port_id)
new_port_dict = cutil.make_port_dict(port_id, None, None, None)
return new_port_dict
else:
raise exc.PortInUse(port_id=port_id, net_id=net_id,
att_id=attachment_id)
def update_port(self, tenant_id, net_id, port_id, **kwargs):
"""
Updates the state of a port on the specified Virtual Network.
"""
LOG.debug("update_port() called\n")
db.validate_port_ownership(tenant_id, net_id, port_id)
network = db.network_get(net_id)
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id, kwargs])
self._validate_port_state(kwargs["state"])
db.port_update(port_id, net_id, **kwargs)
new_port_dict = cutil.make_port_dict(port_id, kwargs["state"], net_id,
None)
return new_port_dict
def get_port_details(self, tenant_id, net_id, port_id):
"""
This method allows the user to retrieve a remote interface
that is attached to this particular port.
"""
LOG.debug("get_port_details() called\n")
db.validate_port_ownership(tenant_id, net_id, port_id)
network = db.network_get(net_id)
self._invoke_device_plugins(self._func_name(), [tenant_id, net_id,
port_id])
port = db.port_get(net_id, port_id)
new_port_dict = cutil.make_port_dict(port[const.UUID],
port[const.PORTSTATE],
port[const.NETWORKID],
port[const.INTERFACEID])
return new_port_dict
def plug_interface(self, tenant_id, net_id, port_id,
remote_interface_id):
"""
Provides connectivity to a remote interface to the
specified Virtual Network.
"""
LOG.debug("plug_interface() called\n")
db.validate_port_ownership(tenant_id, net_id, port_id)
network = db.network_get(net_id)
port = db.port_get(net_id, port_id)
attachment_id = port[const.INTERFACEID]
if attachment_id is 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,
att_id=attachment_id)
self._invoke_device_plugins(self._func_name(), [tenant_id,
net_id, port_id,
attachment_id])
db.port_unset_attachment(net_id, port_id)
db.port_set_attachment(net_id, port_id, attachment_id)
#Note: The remote_interface_id gets associated with the port
# when the VM is instantiated. The plug interface call results
# in putting the port on the VLAN associated with this network
def unplug_interface(self, tenant_id, net_id, port_id):
"""
Removes connectivity of a remote interface to the
specified Virtual Network.
"""
LOG.debug("unplug_interface() called\n")
db.validate_port_ownership(tenant_id, net_id, port_id)
network = db.network_get(net_id)
port = db.port_get(net_id, port_id)
attachment_id = port[const.INTERFACEID]
if attachment_id is None:
raise cexc.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,
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_set_attachment(net_id, port_id, attachment_id)
"""
Extension API implementation
"""
def get_all_portprofiles(self, tenant_id):
"""Get all port profiles"""
LOG.debug("get_all_portprofiles() called\n")
pplist = cdb.get_all_portprofiles()
new_pplist = []
for portprofile in pplist:
new_pp = cutil.make_portprofile_dict(tenant_id,
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
new_pplist.append(new_pp)
return new_pplist
def get_portprofile_details(self, tenant_id, profile_id):
"""Get port profile details"""
LOG.debug("get_portprofile_details() called\n")
try:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
new_pp = cutil.make_portprofile_dict(tenant_id,
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def create_portprofile(self, tenant_id, profile_name, qos):
"""Create port profile"""
LOG.debug("create_portprofile() called\n")
portprofile = cdb.add_portprofile(tenant_id, profile_name,
const.NO_VLAN_ID, qos)
new_pp = cutil.make_portprofile_dict(tenant_id,
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def delete_portprofile(self, tenant_id, profile_id):
"""Delete portprofile"""
LOG.debug("delete_portprofile() called\n")
try:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
plist = cdb.get_pp_binding(tenant_id, profile_id)
if plist:
raise cexc.PortProfileInvalidDelete(tenant_id=tenant_id,
profile_id=profile_id)
else:
cdb.remove_portprofile(tenant_id, profile_id)
def rename_portprofile(self, tenant_id, profile_id, new_name):
"""Rename port profile"""
LOG.debug("rename_portprofile() called\n")
try:
portprofile = cdb.get_portprofile(tenant_id, profile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=profile_id)
portprofile = cdb.update_portprofile(tenant_id, profile_id, new_name)
new_pp = cutil.make_portprofile_dict(tenant_id,
portprofile[const.UUID],
portprofile[const.PPNAME],
portprofile[const.PPQOS])
return new_pp
def associate_portprofile(self, tenant_id, net_id,
port_id, portprofile_id):
"""Associate port profile"""
LOG.debug("associate_portprofile() called\n")
try:
portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=portprofile_id)
cdb.add_pp_binding(tenant_id, port_id, portprofile_id, False)
def disassociate_portprofile(self, tenant_id, net_id,
port_id, portprofile_id):
"""Disassociate port profile"""
LOG.debug("disassociate_portprofile() called\n")
try:
portprofile = cdb.get_portprofile(tenant_id, portprofile_id)
except Exception:
raise cexc.PortProfileNotFound(tenant_id=tenant_id,
portprofile_id=portprofile_id)
cdb.remove_pp_binding(tenant_id, port_id, portprofile_id)
def get_all_qoss(self, tenant_id):
"""Get all QoS levels"""
LOG.debug("get_all_qoss() called\n")
qoslist = cdb.get_all_qoss(tenant_id)
return qoslist
def get_qos_details(self, tenant_id, qos_id):
"""Get QoS Details"""
LOG.debug("get_qos_details() called\n")
try:
qos_level = cdb.get_qos(tenant_id, qos_id)
except Exception:
raise cexc.QosNotFound(tenant_id=tenant_id,
qos_id=qos_id)
return qos_level
def create_qos(self, tenant_id, qos_name, qos_desc):
"""Create a QoS level"""
LOG.debug("create_qos() called\n")
qos = cdb.add_qos(tenant_id, qos_name, str(qos_desc))
return qos
def delete_qos(self, tenant_id, qos_id):
"""Delete a QoS level"""
LOG.debug("delete_qos() called\n")
try:
qos_level = cdb.get_qos(tenant_id, qos_id)
except Exception:
raise cexc.QosNotFound(tenant_id=tenant_id,
qos_id=qos_id)
return cdb.remove_qos(tenant_id, qos_id)
def rename_qos(self, tenant_id, qos_id, new_name):
"""Rename QoS level"""
LOG.debug("rename_qos() called\n")
try:
qos_level = cdb.get_qos(tenant_id, qos_id)
except Exception:
raise cexc.QosNotFound(tenant_id=tenant_id,
qos_id=qos_id)
qos = cdb.update_qos(tenant_id, qos_id, new_name)
return qos
def get_all_credentials(self, tenant_id):
"""Get all credentials"""
LOG.debug("get_all_credentials() called\n")
credential_list = cdb.get_all_credentials(tenant_id)
return credential_list
def get_credential_details(self, tenant_id, credential_id):
"""Get a particular credential"""
LOG.debug("get_credential_details() called\n")
try:
credential = cdb.get_credential(tenant_id, credential_id)
except Exception:
raise cexc.CredentialNotFound(tenant_id=tenant_id,
credential_id=credential_id)
return credential
def create_credential(self, tenant_id, credential_name, user_name,
password):
"""Create a new credential"""
LOG.debug("create_credential() called\n")
credential = cdb.add_credential(tenant_id, credential_name,
user_name, password)
return credential
def delete_credential(self, tenant_id, credential_id):
"""Delete a credential"""
LOG.debug("delete_credential() called\n")
try:
credential = cdb.get_credential(tenant_id, credential_id)
except Exception:
raise cexc.CredentialNotFound(tenant_id=tenant_id,
credential_id=credential_id)
credential = cdb.remove_credential(tenant_id, credential_id)
return credential
def rename_credential(self, tenant_id, credential_id, new_name):
"""Rename the particular credential resource"""
LOG.debug("rename_credential() called\n")
try:
credential = cdb.get_credential(tenant_id, credential_id)
except Exception:
raise cexc.CredentialNotFound(tenant_id=tenant_id,
credential_id=credential_id)
credential = cdb.update_credential(tenant_id, credential_id, new_name)
return credential
def schedule_host(self, tenant_id, instance_id, instance_desc):
"""Provides the hostname on which a dynamic vnic is reserved"""
LOG.debug("schedule_host() called\n")
host_list = self._invoke_device_plugins(self._func_name(),
[tenant_id,
instance_id,
instance_desc])
return host_list
def associate_port(self, tenant_id, instance_id, instance_desc):
"""
Get the portprofile name and the device name for the dynamic vnic
"""
LOG.debug("associate_port() called\n")
return self._invoke_device_plugins(self._func_name(), [tenant_id,
instance_id,
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):
"""
Creates multiple ports on the specified Virtual Network.
"""
LOG.debug("create_ports() called\n")
ports_num = len(net_id_list)
ports_id_list = []
ports_dict_list = []
for net_id in net_id_list:
db.validate_network_ownership(tenant_id, net_id)
port = db.port_create(net_id, port_state)
ports_id_list.append(port[const.UUID])
port_dict = {const.PORT_ID: port[const.UUID]}
ports_dict_list.append(port_dict)
self._invoke_device_plugins(self._func_name(), [tenant_id,
net_id_list,
ports_num,
ports_id_list])
return ports_dict_list
"""
Private functions
"""
def _invoke_device_plugins(self, function_name, args):
"""
All device-specific calls are delegated to the model
"""
return getattr(self._model, function_name)(args)
def _get_vlan_for_tenant(self, tenant_id, net_name):
"""Get vlan ID"""
return self._vlan_mgr.reserve_segmentation_id(tenant_id, net_name)
def _release_vlan_for_tenant(self, tenant_id, net_id):
"""Relase VLAN"""
return self._vlan_mgr.release_segmentation_id(tenant_id, net_id)
def _get_vlan_name(self, net_id, vlan):
"""Getting the vlan name from the tenant and vlan"""
vlan_name = conf.VLAN_NAME_PREFIX + vlan
return vlan_name
def _validate_port_state(self, port_state):
"""Checking the port state"""
if port_state.upper() not in (const.PORT_UP, const.PORT_DOWN):
raise exc.StateInvalid(port_state=port_state)
return True
def _func_name(self, offset=0):
"""Getting the name of the calling funciton"""
return inspect.stack()[1 + offset][3]

View File

@ -1,202 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
from copy import deepcopy
import inspect
import logging
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.l2network_model_base import L2NetworkModelBase
from quantum.plugins.cisco import l2network_plugin_configuration as conf
LOG = logging.getLogger(__name__)
class L2NetworkMultiBlade(L2NetworkModelBase):
"""
Implements the L2NetworkModelBase
This implementation works with UCS and Nexus plugin for the
following topology:
One or more UCSM (each with one or more chasses connected)
All UCSM connected to a single Nexus Switch
"""
_plugins = {}
_inventory = {}
def __init__(self):
for key in conf.PLUGINS[const.PLUGINS].keys():
plugin_obj = conf.PLUGINS[const.PLUGINS][key]
self._plugins[key] = importutils.import_object(plugin_obj)
LOG.debug("Loaded device plugin %s\n" %
conf.PLUGINS[const.PLUGINS][key])
if key in conf.PLUGINS[const.INVENTORY].keys():
inventory_obj = conf.PLUGINS[const.INVENTORY][key]
self._inventory[key] = importutils.import_object(inventory_obj)
LOG.debug("Loaded device inventory %s\n" %
conf.PLUGINS[const.INVENTORY][key])
def _func_name(self, offset=0):
"""Get the name of the calling function"""
return inspect.stack()[1 + offset][3]
def _invoke_plugin_per_device(self, plugin_key, function_name, args):
"""Invoke only device plugin for all the devices in the system"""
if not plugin_key in self._plugins.keys():
LOG.info("No %s Plugin loaded" % plugin_key)
LOG.info("%s: %s with args %s ignored" %
(plugin_key, function_name, args))
return
device_params = self._invoke_inventory(plugin_key, function_name,
args)
device_ips = device_params[const.DEVICE_IP]
if not device_ips:
# Return in a list
return [self._invoke_plugin(plugin_key, function_name, args,
device_params)]
else:
# Return a list of return values from each device
output = []
for device_ip in device_ips:
new_device_params = deepcopy(device_params)
new_device_params[const.DEVICE_IP] = device_ip
output.append(self._invoke_plugin(plugin_key, function_name,
args, new_device_params))
return output
def _invoke_inventory(self, plugin_key, function_name, args):
"""Invoke only the inventory implementation"""
if not plugin_key in self._inventory.keys():
LOG.warn("No %s inventory loaded" % plugin_key)
LOG.warn("%s: %s with args %s ignored" %
(plugin_key, function_name, args))
return {const.DEVICE_IP: []}
else:
return getattr(self._inventory[plugin_key], function_name)(args)
def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
"""Invoke only the device plugin"""
func = getattr(self._plugins[plugin_key], function_name)
# If there are more args than needed, add them to kwargs
args_copy = deepcopy(args)
if (args.__len__() + 1) > inspect.getargspec(func).args.__len__():
kwargs.update(args_copy.pop())
return func(*args_copy, **kwargs)
def get_all_networks(self, args):
"""Not implemented for this model"""
pass
def create_network(self, args):
"""Support for the Quantum core API call"""
output = []
ucs_output = self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
self._func_name(), args)
output.extend(ucs_output or [])
output.extend(nexus_output or [])
return output
def delete_network(self, args):
"""Support for the Quantum core API call"""
output = []
ucs_output = self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
self._func_name(), args)
output.extend(ucs_output or [])
output.extend(nexus_output or [])
return output
def get_network_details(self, args):
"""Not implemented for this model"""
pass
def update_network(self, args):
"""Support for the Quantum core API call"""
output = []
ucs_output = self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
nexus_output = self._invoke_plugin_per_device(const.NEXUS_PLUGIN,
self._func_name(), args)
output.extend(ucs_output or [])
output.extend(nexus_output or [])
return output
def get_all_ports(self, args):
"""Not implemented for this model"""
pass
def create_port(self, args):
"""Support for the Quantum core API call"""
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
def delete_port(self, args):
"""Support for the Quantum core API call"""
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
def update_port(self, args):
"""Not implemented for this model"""
pass
def get_port_details(self, args):
"""Not implemented for this model"""
pass
def plug_interface(self, args):
"""Support for the Quantum core API call"""
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
def unplug_interface(self, args):
"""Support for the Quantum core API call"""
return self._invoke_plugin_per_device(const.UCS_PLUGIN,
self._func_name(), args)
def schedule_host(self, args):
"""Provides the hostname on which a dynamic vnic is reserved"""
LOG.debug("schedule_host() called\n")
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
args)
def associate_port(self, args):
"""
Get the portprofile name and the device name for the dynamic vnic
"""
LOG.debug("associate_port() called\n")
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
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):
"""Support for extension API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)

View File

@ -1,175 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
from copy import deepcopy
import inspect
import logging
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.l2network_model_base import L2NetworkModelBase
from quantum.plugins.cisco import l2network_plugin_configuration as conf
LOG = logging.getLogger(__name__)
class L2NetworkSingleBlade(L2NetworkModelBase):
"""
Implements the L2NetworkModelBase
This implementation works with a single UCS blade
"""
_plugins = {}
_inventory = {}
def __init__(self):
for key in conf.PLUGINS[const.PLUGINS].keys():
plugin_obj = conf.PLUGINS[const.PLUGINS][key]
self._plugins[key] = importutils.import_object(plugin_obj)
LOG.debug("Loaded device plugin %s\n" %
conf.PLUGINS[const.PLUGINS][key])
if key in conf.PLUGINS[const.INVENTORY].keys():
inventory_obj = conf.PLUGINS[const.INVENTORY][key]
self._inventory[key] = importutils.import_object(inventory_obj)
LOG.debug("Loaded device inventory %s\n" %
conf.PLUGINS[const.INVENTORY][key])
def _func_name(self, offset=0):
"""Get the name of the calling function"""
return inspect.stack()[1 + offset][3]
def _invoke_plugin_per_device(self, plugin_key, function_name, args):
"""Invoke only device plugin for all the devices in the system"""
if not plugin_key in self._plugins.keys():
LOG.info("No %s Plugin loaded" % plugin_key)
LOG.info("%s: %s with args %s ignored" %
(plugin_key, function_name, args))
return
device_params = self._invoke_inventory(plugin_key, function_name,
args)
device_ips = device_params[const.DEVICE_IP]
if not device_ips:
self._invoke_plugin(plugin_key, function_name, args,
device_params)
else:
for device_ip in device_ips:
new_device_params = deepcopy(device_params)
new_device_params[const.DEVICE_IP] = device_ip
self._invoke_plugin(plugin_key, function_name, args,
new_device_params)
def _invoke_inventory(self, plugin_key, function_name, args):
"""Invoke only the inventory implementation"""
if not plugin_key in self._inventory.keys():
LOG.warn("No %s inventory loaded" % plugin_key)
LOG.warn("%s: %s with args %s ignored" %
(plugin_key, function_name, args))
return {const.DEVICE_IP: []}
else:
return getattr(self._inventory[plugin_key], function_name)(args)
def _invoke_plugin(self, plugin_key, function_name, args, kwargs):
"""Invoke only the device plugin"""
# If the last param is a dict, add it to kwargs
if args and isinstance(args[-1], dict):
kwargs.update(args.pop())
return getattr(self._plugins[plugin_key],
function_name)(*args, **kwargs)
def get_all_networks(self, args):
"""Not implemented for this model"""
pass
def create_network(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def delete_network(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def get_network_details(self, args):
"""Not implemented for this model"""
pass
def update_network(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def get_all_ports(self, args):
"""Not implemented for this model"""
pass
def create_port(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def delete_port(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def update_port(self, args):
"""Not implemented for this model"""
pass
def get_port_details(self, args):
"""Not implemented for this model"""
pass
def plug_interface(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def unplug_interface(self, args):
"""Support for the Quantum core API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)
def schedule_host(self, args):
"""Provides the hostname on which a dynamic vnic is reserved"""
LOG.debug("schedule_host() called\n")
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
args)
def associate_port(self, args):
"""
Get the portprofile name and the device namei for the dynamic vnic
"""
LOG.debug("associate_port() called\n")
return self._invoke_inventory(const.UCS_PLUGIN, self._func_name(),
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):
"""Support for extension API call"""
self._invoke_plugin_per_device(const.UCS_PLUGIN, self._func_name(),
args)

View File

@ -1,148 +0,0 @@
# vim: tabstop=4 shiftwidth=4 softtabstop=4
#
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
#
# @author: Debojyoti Dutta, Cisco Systems, Inc.
# @author: Edgar Magana, Cisco Systems Inc.
#
"""
Implements a Nexus-OS NETCONF over SSHv2 API Client
"""
import logging
from ncclient import manager
from quantum.plugins.cisco.db import network_db_v2 as cdb
from quantum.plugins.cisco.nexus import cisco_nexus_snippets as snipp
LOG = logging.getLogger(__name__)
class CiscoNEXUSDriver():
"""
Nexus Driver Main Class
"""
def __init__(self):
pass
def nxos_connect(self, nexus_host, nexus_ssh_port, nexus_user,
nexus_password):
"""
Makes the SSH connection to the Nexus Switch
"""
man = manager.connect(host=nexus_host, port=nexus_ssh_port,
username=nexus_user, password=nexus_password)
return man
def create_xml_snippet(self, cutomized_config):
"""
Creates the Proper XML structure for the Nexus Switch Configuration
"""
conf_xml_snippet = snipp.EXEC_CONF_SNIPPET % (cutomized_config)
return conf_xml_snippet
def enable_vlan(self, mgr, vlanid, vlanname):
"""
Creates a VLAN on Nexus Switch given the VLAN ID and Name
"""
confstr = snipp.CMD_VLAN_CONF_SNIPPET % (vlanid, vlanname)
confstr = self.create_xml_snippet(confstr)
mgr.edit_config(target='running', config=confstr)
def disable_vlan(self, mgr, vlanid):
"""
Delete a VLAN on Nexus Switch given the VLAN ID
"""
confstr = snipp.CMD_NO_VLAN_CONF_SNIPPET % vlanid
confstr = self.create_xml_snippet(confstr)
mgr.edit_config(target='running', config=confstr)
def enable_port_trunk(self, mgr, interface):
"""
Enables trunk mode an interface on Nexus Switch
"""
confstr = snipp.CMD_PORT_TRUNK % (interface)
confstr = self.create_xml_snippet(confstr)
LOG.debug("NexusDriver: %s" % confstr)
mgr.edit_config(target='running', config=confstr)
def disable_switch_port(self, mgr, interface):
"""
Disables trunk mode an interface on Nexus Switch
"""
confstr = snipp.CMD_NO_SWITCHPORT % (interface)
confstr = self.create_xml_snippet(confstr)
LOG.debug("NexusDriver: %s" % confstr)
mgr.edit_config(target='running', config=confstr)
def enable_vlan_on_trunk_int(self, mgr, interface, vlanid):
"""
Enables trunk mode vlan access an interface on Nexus Switch given
VLANID
"""
confstr = snipp.CMD_VLAN_INT_SNIPPET % (interface, vlanid)
confstr = self.create_xml_snippet(confstr)
LOG.debug("NexusDriver: %s" % confstr)
mgr.edit_config(target='running', config=confstr)
def disable_vlan_on_trunk_int(self, mgr, interface, vlanid):
"""
Enables trunk mode vlan access an interface on Nexus Switch given
VLANID
"""
confstr = snipp.CMD_NO_VLAN_INT_SNIPPET % (interface, vlanid)
confstr = self.create_xml_snippet(confstr)
LOG.debug("NexusDriver: %s" % confstr)
mgr.edit_config(target='running', config=confstr)
def create_vlan(self, vlan_name, vlan_id, nexus_host, nexus_user,
nexus_password, nexus_ports, nexus_ssh_port):
"""
Creates a VLAN and Enable on trunk mode an interface on Nexus Switch
given the VLAN ID and Name and Interface Number
"""
with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
nexus_password) as man:
self.enable_vlan(man, vlan_id, vlan_name)
vlan_ids = self.build_vlans_cmd()
LOG.debug("NexusDriver VLAN IDs: %s" % vlan_ids)
for ports in nexus_ports:
self.enable_vlan_on_trunk_int(man, ports, vlan_ids)
def delete_vlan(self, vlan_id, nexus_host, nexus_user, nexus_password,
nexus_ports, nexus_ssh_port):
"""
Delete a VLAN and Disables trunk mode an interface on Nexus Switch
given the VLAN ID and Interface Number
"""
with self.nxos_connect(nexus_host, int(nexus_ssh_port), nexus_user,
nexus_password) as man:
self.disable_vlan(man, vlan_id)
for ports in nexus_ports:
self.disable_vlan_on_trunk_int(man, ports, vlan_id)
def build_vlans_cmd(self):
"""
Builds a string with all the VLANs on the same Switch
"""
assigned_vlan = cdb.get_all_vlanids_used()
vlans = ''
for vlanid in assigned_vlan:
vlans = str(vlanid["vlan_id"]) + ',' + vlans
if vlans == '':
vlans = 'none'
return vlans.strip(',')

View File

@ -1,198 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
# @author: Edgar Magana, Cisco Systems, Inc.
#
"""
PlugIn for Nexus OS driver
"""
import logging
from quantum.common import exceptions as exc
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
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.l2device_plugin_base import L2DevicePluginBase
from quantum.plugins.cisco.nexus import cisco_nexus_configuration as conf
LOG = logging.getLogger(__name__)
class NexusPlugin(L2DevicePluginBase):
"""
Nexus PLugIn Main Class
"""
_networks = {}
def __init__(self):
"""
Extracts the configuration parameters from the configuration file
"""
self._client = importutils.import_object(conf.NEXUS_DRIVER)
LOG.debug("Loaded driver %s\n" % conf.NEXUS_DRIVER)
self._nexus_ip = conf.NEXUS_IP_ADDRESS
self._nexus_username = cred.Store.getUsername(conf.NEXUS_IP_ADDRESS)
self._nexus_password = cred.Store.getPassword(conf.NEXUS_IP_ADDRESS)
self._nexus_first_port = conf.NEXUS_FIRST_PORT
self._nexus_second_port = conf.NEXUS_SECOND_PORT
self._nexus_ssh_port = conf.NEXUS_SSH_PORT
def get_all_networks(self, tenant_id):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
the specified tenant.
"""
LOG.debug("NexusPlugin:get_all_networks() called\n")
return self._networks.values()
def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id,
**kwargs):
"""
Create a VLAN in the switch, and configure the appropriate interfaces
for this VLAN
"""
LOG.debug("NexusPlugin:create_network() called\n")
self._client.create_vlan(
vlan_name, str(vlan_id), self._nexus_ip,
self._nexus_username, self._nexus_password,
self._nexus_first_port, self._nexus_second_port,
self._nexus_ssh_port)
nxos_db.add_nexusport_binding(self._nexus_first_port, str(vlan_id))
nxos_db.add_nexusport_binding(self._nexus_second_port, str(vlan_id))
new_net_dict = {const.NET_ID: net_id,
const.NET_NAME: net_name,
const.NET_PORTS: {},
const.NET_VLAN_NAME: vlan_name,
const.NET_VLAN_ID: vlan_id}
self._networks[net_id] = new_net_dict
return new_net_dict
def delete_network(self, tenant_id, net_id, **kwargs):
"""
Deletes a VLAN in the switch, and removes the VLAN configuration
from the relevant interfaces
"""
LOG.debug("NexusPlugin:delete_network() called\n")
vlan_id = self._get_vlan_id_for_network(tenant_id, net_id)
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)
net = self._get_network(tenant_id, net_id)
if net:
self._client.delete_vlan(
str(vlan_id), self._nexus_ip,
self._nexus_username, self._nexus_password,
self._nexus_first_port, self._nexus_second_port,
self._nexus_ssh_port)
return net
# Network not found
raise exc.NetworkNotFound(net_id=net_id)
def get_network_details(self, tenant_id, net_id, **kwargs):
"""
Returns the details of a particular network
"""
LOG.debug("NexusPlugin:get_network_details() called\n")
network = self._get_network(tenant_id, net_id)
return network
def update_network(self, tenant_id, net_id, **kwargs):
"""
Updates the properties of a particular
Virtual Network.
"""
LOG.debug("NexusPlugin:update_network() called\n")
network = self._get_network(tenant_id, net_id)
network[const.NET_NAME] = kwargs["name"]
return network
def get_all_ports(self, tenant_id, net_id, **kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:get_all_ports() called\n")
def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:create_port() called\n")
def delete_port(self, tenant_id, net_id, port_id, **kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:delete_port() called\n")
def update_port(self, tenant_id, net_id, port_id, port_state, **kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:update_port() called\n")
def get_port_details(self, tenant_id, net_id, port_id, **kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:get_port_details() called\n")
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id,
**kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:plug_interface() called\n")
def unplug_interface(self, tenant_id, net_id, port_id, **kwargs):
"""
This is probably not applicable to the Nexus plugin.
Delete if not required.
"""
LOG.debug("NexusPlugin:unplug_interface() called\n")
def _get_vlan_id_for_network(self, tenant_id, network_id):
"""
Obtain the VLAN ID given the Network ID
"""
net = self._get_network(tenant_id, network_id)
vlan_id = net[const.NET_VLAN_ID]
return vlan_id
def _get_network(self, tenant_id, network_id):
"""
Gets the NETWORK ID
"""
network = db.network_get(network_id)
if not network:
raise exc.NetworkNotFound(net_id=network_id)
vlan = cdb.get_vlan_binding(network_id)
return {const.NET_ID: network_id, const.NET_NAME: network.name,
const.NET_PORTS: network.ports,
const.NET_VLAN_NAME: vlan.vlan_name,
const.NET_VLAN_ID: vlan.vlan_id}

View File

@ -1,46 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
#
import logging
from quantum.plugins.cisco.common import cisco_constants as const
from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco.l2network_segmentation_base import (
L2NetworkSegmentationMgrBase,
)
LOG = logging.getLogger(__name__)
class L2NetworkVLANMgr(L2NetworkSegmentationMgrBase):
"""
VLAN Manager which gets VLAN ID from DB
"""
def __init__(self):
cdb.create_vlanids()
def reserve_segmentation_id(self, tenant_id, net_name, **kwargs):
"""Get an available VLAN ID"""
return cdb.reserve_vlanid()
def release_segmentation_id(self, tenant_id, net_id, **kwargs):
"""Release the ID"""
vlan_binding = cdb.get_vlan_binding(net_id)
return cdb.release_vlanid(vlan_binding[const.VLANID])

View File

@ -26,9 +26,9 @@ import unittest
from quantum.plugins.cisco.common import cisco_constants as const
import quantum.plugins.cisco.db.api as db
import quantum.plugins.cisco.db.l2network_db as l2network_db
import quantum.plugins.cisco.db.nexus_db as nexus_db
import quantum.plugins.cisco.db.nexus_db_v2 as nexus_db
import quantum.plugins.cisco.db.services_db as services_db
import quantum.plugins.cisco.db.ucs_db as ucs_db
import quantum.plugins.cisco.db.ucs_db_v2 as ucs_db
LOG.getLogger(const.LOGGER_COMPONENT_NAME)

File diff suppressed because it is too large Load Diff

View File

@ -1,360 +0,0 @@
# 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: Shubhangi Satras, Cisco Systems, Inc.
# @author: Peter Strunk, Cisco Systems, Inc.
# @author: Atul Gaikad, Cisco Systems, Inc.
# @author: Tyler Smith, Cisco Systems, Inc.
import logging
import unittest
from quantum.common import exceptions as exc
from quantum.openstack.common import importutils
from quantum.plugins.cisco.common import cisco_constants as const
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 import l2network_plugin_configuration as conf
from quantum.plugins.cisco.models import l2network_multi_blade
logging.basicConfig(level=logging.WARN)
LOG = logging.getLogger(__name__)
# Set some data to use in tests
tenant_id = "network_admin"
net_name = "TestNetwork1"
new_net_name = "NewTestNetwork1"
net_id = "44"
port_id = "p0005"
port_state = const.PORT_UP
interface_id = "vif-01"
vlan_id = "102"
def vlan_name(id):
return "q-%svlan" % id[0:10]
class TestMultiBlade(unittest.TestCase):
"""
Tests for the multi-blade model for the L2Network plugin
"""
_plugins = {}
_inventory = {}
def setUp(self):
"""Setup our tests"""
# Initialize cdb and credentials
db.configure_db({'sql_connection': 'sqlite:///:memory:'})
cdb.initialize()
creds.Store.initialize()
# Create a place a store net and port ids for the druation of the test
self.net_id = 0
self.port_id = 0
# Create the multiblade object
self._l2network_multiblade = (
l2network_multi_blade.L2NetworkMultiBlade())
self.plugin_key = (
"quantum.plugins.cisco.ucs.cisco_ucs_plugin.UCSVICPlugin")
# Get UCS inventory to make sure all UCSs are affected by tests
for key in conf.PLUGINS[const.PLUGINS].keys():
if key in conf.PLUGINS[const.INVENTORY].keys():
plugin_obj = conf.PLUGINS[const.INVENTORY][key]
self._inventory[key] = importutils.import_object(plugin_obj)
self.ucs_count = self._inventory['ucs_plugin']._inventory.__len__()
def tearDown(self):
"""Tear down our tests"""
try:
port = db.port_get(self.net_id, self.port_id)
self._l2network_multiblade.delete_port([tenant_id, self.net_id,
self.port_id])
except exc.NetworkNotFound:
# We won't always have a port to remove
pass
except exc.PortNotFound:
# We won't always have a port to remove
pass
try:
net = db.network_get(self.net_id)
self._l2network_multiblade.delete_network([tenant_id, self.net_id])
except exc.NetworkNotFound:
# We won't always have a network to remove
pass
db.clear_db()
def test_create_network(self):
"""Support for the Quantum core API call"""
LOG.debug("test_create_network - START")
# Create the network in the test DB, then with the model
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
networks = self._l2network_multiblade.create_network([
tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id,
])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
for network in networks:
self.assertEqual(network[const.NET_ID], self.net_id)
self.assertEqual(network[const.NET_NAME], net_name)
LOG.debug("test_create_network - END")
def test_delete_network(self):
"""Support for the Quantum core API call"""
LOG.debug("test_delete_network - START")
# Create the network in the test DB, then with the model
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
networks = self._l2network_multiblade.delete_network([tenant_id,
self.net_id])
cdb.remove_vlan_binding(self.net_id)
db.network_destroy(self.net_id)
for network in networks:
self.assertEqual(network[const.NET_ID], self.net_id)
self.assertEqual(network[const.NET_NAME], net_name)
LOG.debug("test_delete_network - END")
def test_delete_networkDNE(self):
"""Support for the Quantum core API call"""
LOG.debug("test_delete_networkDNE - START")
self.assertRaises(exc.NetworkNotFound,
self._l2network_multiblade.delete_network,
[tenant_id, net_id])
LOG.debug("test_delete_networkDNE - END")
def test_update_network(self):
"""Support for the Quantum core API call"""
LOG.debug("test_update_network - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
net_details = db.network_update(self.net_id, tenant_id,
name=new_net_name)
networks = self._l2network_multiblade.update_network([
tenant_id,
self.net_id,
{'name': new_net_name},
])
for network in networks:
self.assertEqual(network[const.NET_ID], self.net_id)
self.assertEqual(network[const.NET_NAME], new_net_name)
LOG.debug("test_update_network - END")
def test_update_networkDNE(self):
"""Support for the Quantum core API call"""
LOG.debug("test_update_networkDNE - START")
self.assertRaises(exc.NetworkNotFound,
self._l2network_multiblade.update_network,
[tenant_id, net_id, {'name': new_net_name}])
LOG.debug("test_update_networkDNE - END")
def test_get_all_networks(self):
"""Not implemented for this model"""
pass
def test_get_network_details(self):
"""Not implemented for this model"""
pass
def test_create_port(self):
"""Support for the Quantum core API call"""
LOG.debug("test_create_port - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
self.port_id = db.port_create(self.net_id, port_state)[const.UUID]
port = self._l2network_multiblade.create_port([tenant_id,
self.net_id,
port_state,
self.port_id])
self.assertEqual(self.port_id, port[0][const.PORTID])
LOG.debug("test_create_port - END")
def test_delete_port(self):
"""Support for the Quantum core API call"""
LOG.debug("test_delete_port - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
self.port_id = db.port_create(self.net_id, port_state)[const.UUID]
self._l2network_multiblade.create_port([tenant_id,
self.net_id,
port_state, self.port_id])
port = self._l2network_multiblade.delete_port([tenant_id,
self.net_id,
self.port_id])
self.assertEqual(self.port_id, port[0][const.PORTID])
# Recreating port so tear down doesn't cause an error
self.port_id = db.port_create(self.net_id, port_state)[const.UUID]
self._l2network_multiblade.create_port([tenant_id,
self.net_id,
port_state, self.port_id])
LOG.debug("test_delete_port - END")
def test_get_all_ports(self):
"""Not implemented for this model"""
pass
def test_update_port(self):
"""Not implemented for this model"""
pass
def test_update_portDNE(self):
"""Not implemented for this model"""
pass
def test_update_port_networkDNE(self):
"""Not implemented for this model"""
pass
def test_port_details(self):
"""Not implemented for this model"""
pass
def test_plug_interface(self):
"""Support for the Quantum core API call"""
LOG.debug("test_plug_interface - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
self.port_id = db.port_create(self.net_id, port_state)[const.UUID]
self._l2network_multiblade.create_port([tenant_id,
self.net_id,
port_state, self.port_id])
interface = self._l2network_multiblade.plug_interface(
[tenant_id, self.net_id, self.port_id, interface_id])
port = db.port_set_attachment(self.net_id, self.port_id, interface_id)
self.assertEqual(self.port_id, interface[0][const.PORTID])
self.assertEqual(port[const.INTERFACEID], interface_id)
LOG.debug("test_plug_interface - END")
def test_plug_interface_networkDNE(self):
"""Support for the Quantum core API call"""
LOG.debug("test_plug_interface_networkDNE - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
self.port_id = db.port_create(self.net_id, port_state)[const.UUID]
self._l2network_multiblade.create_port([tenant_id,
self.net_id,
port_state, self.port_id])
self.assertRaises(exc.NetworkNotFound,
self._l2network_multiblade.plug_interface,
[tenant_id, net_id, self.port_id, interface_id])
LOG.debug("test_plug_interface_networkDNE - END")
def test_plug_interface_portDNE(self):
"""Support for the Quantum core API call"""
LOG.debug("test_plug_interface_portDNE - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
self.assertRaises(exc.PortNotFound,
self._l2network_multiblade.plug_interface,
[tenant_id, self.net_id, port_id, interface_id])
LOG.debug("test_plug_interface_portDNE - START")
def test_unplug_interface(self):
"""Support for the Quantum core API call"""
LOG.debug("test_unplug_interface - START")
self.net_id = db.network_create(tenant_id, net_name)[const.UUID]
self._l2network_multiblade.create_network([tenant_id,
net_name,
self.net_id,
vlan_name(self.net_id),
vlan_id])
cdb.add_vlan_binding(vlan_id, vlan_name(self.net_id), self.net_id)
self.port_id = db.port_create(self.net_id, port_state)[const.UUID]
self._l2network_multiblade.create_port([tenant_id,
self.net_id,
port_state, self.port_id])
self._l2network_multiblade.plug_interface([tenant_id, self.net_id,
self.port_id, interface_id])
db.port_set_attachment(self.net_id, self.port_id, interface_id)
interface = self._l2network_multiblade.unplug_interface([tenant_id,
self.net_id,
self.port_id])
self.assertEqual(self.port_id, interface[0][const.PORTID])
LOG.debug("test_unplug_interface - END")

View File

@ -1,315 +0,0 @@
# 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: Shweta Padubidri, Peter Strunk, Cisco Systems, Inc.
import logging
import unittest
from quantum.common import exceptions as exc
from quantum.plugins.cisco.common import cisco_constants as const
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.nexus import cisco_nexus_plugin
LOG = logging.getLogger('quantum.tests.test_nexus')
class TestNexusPlugin(unittest.TestCase):
def setUp(self):
"""
Set up function
"""
self.tenant_id = "test_tenant_cisco1"
self.net_name = "test_network_cisco1"
self.net_id = 000007
self.vlan_name = "q-" + str(self.net_id) + "vlan"
self.vlan_id = 267
self.second_vlan_id = 265
self.port_id = "9"
db.configure_db({'sql_connection': 'sqlite:///:memory:'})
cdb.initialize()
creds.Store.initialize()
self._cisco_nexus_plugin = cisco_nexus_plugin.NexusPlugin()
def test_create_network(self, net_tenant_id=None, network_name=None,
net_vlan_name=None, net_vlan_id=None):
"""
Tests creation of new Virtual Network.
"""
LOG.debug("test_create_network - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
if network_name:
net_name = network_name
else:
net_name = self.net_name
if net_vlan_name:
vlan_name = net_vlan_name
else:
vlan_name = self.vlan_name
if net_vlan_id:
vlan_id = net_vlan_id
else:
vlan_id = self.vlan_id
network_created = self.create_network(tenant_id, net_name)
cdb.add_vlan_binding(vlan_id, vlan_name, network_created["net-id"])
new_net_dict = self._cisco_nexus_plugin.create_network(
tenant_id, net_name, network_created["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_VLAN_NAME], self.vlan_name)
self.assertEqual(new_net_dict[const.NET_VLAN_ID], self.vlan_id)
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_create_network - END")
def test_delete_network(self, net_tenant_id=None, network_name=None):
"""
Tests deletion of a Virtual Network.
"""
LOG.debug("test_delete_network - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
if network_name:
net_name = network_name
else:
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(
tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id)
deleted_net_dict = self._cisco_nexus_plugin.delete_network(
tenant_id, new_net_dict[const.NET_ID])
self.assertEqual(deleted_net_dict[const.NET_ID],
network_created["net-id"])
LOG.debug("test_delete_network - END")
def test_delete_network_DNE(self, net_tenant_id=None, net_id='0005'):
"""
Tests deletion of a Virtual Network when Network does not exist.
"""
LOG.debug("test_delete_network_DNE - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
self.assertRaises(exc.NetworkNotFound,
self._cisco_nexus_plugin.delete_network,
tenant_id, net_id)
LOG.debug("test_delete_network_DNE - END")
def test_get_network_details(self, net_tenant_id=None, network_name=None):
"""
Tests displays details of a Virtual Network .
"""
LOG.debug("test_get_network_details - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
if network_name:
net_name = network_name
else:
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(
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(
tenant_id, network_created["net-id"])
self.assertEqual(check_net_dict[const.NET_ID],
network_created["net-id"])
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_ID], self.vlan_id)
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_get_network_details - END")
def test_get_networkDNE(self, net_tenant_id=None, net_id='0005'):
"""
Tests display of a Virtual Network when Network does not exist.
"""
LOG.debug("test_get_network_details_network_does_not_exist - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
self.assertRaises(exc.NetworkNotFound,
self._cisco_nexus_plugin.get_network_details,
tenant_id, net_id)
LOG.debug("test_get_network_details_network_does_not_exist - END")
def test_update_network(self, new_name="new_network_name",
net_tenant_id=None, network_name=None):
"""
Tests update of a Virtual Network .
"""
LOG.debug("test_update_network - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
if network_name:
net_name = network_name
else:
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(
tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id)
rename_net_dict = self._cisco_nexus_plugin.update_network(
tenant_id, new_net_dict[const.NET_ID], name=new_name)
self.assertEqual(rename_net_dict[const.NET_NAME], new_name)
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_update_network - END")
def test_update_network_DNE(self, new_name="new_network_name",
net_tenant_id=None, network_id='0005'):
"""
Tests update of a Virtual Network when Network does not exist.
"""
LOG.debug("test_update_network_DNE - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
if network_id:
net_id = network_id
else:
net_id = self.net_id
self.assertRaises(exc.NetworkNotFound,
self._cisco_nexus_plugin.update_network,
tenant_id, net_id, name=new_name)
LOG.debug("test_update_network_DNE - END")
def test_list_all_networks(self, net_tenant_id=None):
"""
Tests listing of all the Virtual Networks .
"""
LOG.debug("test_list_all_networks - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
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(
tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id)
network_created2 = self.create_network(tenant_id, 'test_network2')
cdb.add_vlan_binding(self.second_vlan_id, 'second_vlan',
network_created2["net-id"])
new_net_dict2 = self._cisco_nexus_plugin.create_network(
tenant_id, "New_Network2", network_created2["net-id"],
"second_vlan", self.second_vlan_id)
list_net_dict = self._cisco_nexus_plugin.get_all_networks(tenant_id)
net_temp_list = [new_net_dict1, new_net_dict2]
self.assertTrue(net_temp_list[0] in list_net_dict)
self.assertTrue(net_temp_list[1] in list_net_dict)
self.tearDownNetwork(tenant_id, new_net_dict1[const.NET_ID])
self.tearDownNetwork(tenant_id, new_net_dict2[const.NET_ID])
LOG.debug("test_list_all_networks - END")
def test_get_vlan_id_for_network(self, net_tenant_id=None,
network_name=None):
"""
Tests retrieval of vlan id for a Virtual Networks .
"""
LOG.debug("test_get_vlan_id_for_network - START")
if net_tenant_id:
tenant_id = net_tenant_id
else:
tenant_id = self.tenant_id
if network_name:
net_name = network_name
else:
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(
tenant_id, self.net_name, network_created["net-id"],
self.vlan_name, self.vlan_id)
result_vlan_id = self._cisco_nexus_plugin._get_vlan_id_for_network(
tenant_id, network_created["net-id"])
self.assertEqual(result_vlan_id, self.vlan_id)
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
LOG.debug("test_get_vlan_id_for_network - END")
def create_network(self, tenant_id, net_name):
"""Create a network"""
net_dict = {}
try:
res = db.network_create(tenant_id, net_name)
LOG.debug("Created network: %s" % res.uuid)
net_dict["tenant-id"] = res.tenant_id
net_dict["net-id"] = str(res.uuid)
net_dict["net-name"] = res.name
return net_dict
except Exception, exc:
LOG.error("Failed to create network: %s" % str(exc))
def tearDownNetwork(self, tenant_id, network_dict_id):
"""
Clean up functions after the tests
"""
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

@ -1,198 +0,0 @@
# 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: Shubhangi Satras, Cisco Systems, Inc.
# @author: Tyler Smith, Cisco Systems, Inc.
import logging
import unittest
from quantum.common import exceptions as exc
from quantum.plugins.cisco.common import cisco_constants as const
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.l2network_plugin import L2Network
from quantum.plugins.cisco.ucs.cisco_ucs_inventory import UCSInventory
LOG = logging.getLogger(__name__)
# Set some data to use in tests
tenant = 'shubh'
net_name = 'TestNetwork1'
port_state = const.PORT_UP
interface_id = 'vif-01'
class TestUCSInventory(unittest.TestCase):
"""
Tests for the UCS Inventory. Each high-level operation should return
some information about which devices to perform the action on.
"""
def setUp(self):
"""Setup our tests"""
# Initialize cdb and credentials
db.configure_db({'sql_connection': 'sqlite:///:memory:'})
cdb.initialize()
creds.Store.initialize()
# Create the ucs inventory object
self._ucs_inventory = UCSInventory()
self.inventory = self._ucs_inventory._inventory
# Create a plugin instance to create networks/ports
self._l2network = L2Network()
def assertValidUCM(self, ip_address):
"""Asserts that the given ip is in the UCS inventory"""
if ip_address in self.inventory.keys():
assert(1)
return
assert(0)
def assertPortNotFound(self, cmd, args):
"""Asserts that the given command raises a PortNotFound exception"""
cmd = getattr(self._ucs_inventory, cmd)
self.assertRaises(exc.PortNotFound, cmd, args)
def _test_get_all_ucms(self, cmd):
"""Runs tests for commands that expect a list of all UCMS"""
LOG.debug("test_%s - START", cmd)
results = getattr(self._ucs_inventory, cmd)([])
self.assertEqual(results[const.DEVICE_IP], self.inventory.keys())
LOG.debug("test_%s - END", cmd)
def _test_with_port_creation(self, cmd, params=None):
"""Tests commands that requires a port to exist"""
LOG.debug("test_%s - START", cmd)
net = self._l2network.create_network(tenant, net_name)
port = self._l2network.create_port(tenant, net[const.NET_ID],
port_state, state=port_state)
args = [tenant, net[const.NET_ID], port[const.PORT_ID]]
if params is not None:
args.extend(params)
ip_address = getattr(self._ucs_inventory, cmd)(args)
ip_address = ip_address[const.DEVICE_IP][0]
self.assertValidUCM(ip_address)
# Clean up created network and port
try:
self._l2network.unplug_interface(
tenant, net[const.NET_ID], port[const.PORT_ID])
except:
pass
self._l2network.delete_port(tenant,
net[const.NET_ID], port[const.PORT_ID])
self._l2network.delete_network(tenant, net[const.NET_ID])
db.clear_db()
LOG.debug("test_%s - END", cmd)
def _test_port_not_found(self, cmd, params=None):
"""Tests commands that should raise a PortNotFound exception"""
# Figure out the correct name of this test
name = cmd
if name[-5:] == "_port":
name += "_not_found"
else:
name += "_port_not_found"
LOG.debug("test_%s - START", name)
args = [tenant, 1, 1]
if params is not None:
args.extend(params)
self.assertPortNotFound(cmd, args)
LOG.debug("test_%s - END", name)
def test_create_port(self):
"""Test that the UCS Inventory returns the correct devices to use"""
LOG.debug("test_create_port - START")
results = self._ucs_inventory.create_port([])
results = results[const.LEAST_RSVD_BLADE_DICT]
ip_address = results[const.LEAST_RSVD_BLADE_UCSM]
chassis = results[const.LEAST_RSVD_BLADE_CHASSIS]
blade = results[const.LEAST_RSVD_BLADE_ID]
if blade not in self.inventory[ip_address][chassis]:
self.assertEqual(0, 1)
self.assertEqual(1, 1)
LOG.debug("test_create_port - END")
def test_get_all_networks(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('get_all_networks')
def test_create_network(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('create_network')
def test_delete_network(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('delete_network')
def test_get_network_details(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('get_network_details')
def test_update_network(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('update_network')
def test_get_all_ports(self):
"""Test that the UCS Inventory returns the correct devices to use"""
self._test_get_all_ucms('get_all_ports')
def test_delete_port(self):
"""Test that the UCS Inventory returns a valid UCM"""
self._test_with_port_creation('delete_port')
def test_get_port_details(self):
"""Test that the UCS Inventory returns a valid UCM"""
self._test_with_port_creation('get_port_details')
def test_update_port(self):
"""Test that the UCS Inventory returns a valid UCM"""
self._test_with_port_creation('update_port', [port_state])
def test_plug_interface(self):
"""Test that the UCS Inventory returns a valid UCM"""
self._test_with_port_creation('plug_interface', [interface_id])
def test_unplug_interface(self):
"""Test that the UCS Inventory returns a valid UCM"""
self._test_with_port_creation('unplug_interface')
def test_update_port_not_found(self):
"""Test that the UCS Inventory raises a PortNotFound exception"""
self._test_port_not_found('update_port')
def test_get_port_details_port_not_found(self):
"""Test that the UCS Inventory raises a PortNotFound exception"""
self._test_port_not_found('get_port_details')
def test_plug_interface_port_not_found(self):
"""Test that the UCS Inventory raises a PortNotFound exception"""
self._test_port_not_found('plug_interface', [interface_id])
def test_unplug_interface_port_not_found(self):
"""Test that the UCS Inventory raises a PortNotFound exception"""
self._test_port_not_found('unplug_interface')

View File

@ -1,518 +0,0 @@
#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: Shubhangi Satras, Cisco Systems, Inc.
# Shweta Padubidri, Cisco Systems, Inc.
import logging
import unittest
from quantum.common import exceptions as exc
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_exceptions as c_exc
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf
from quantum.plugins.cisco.ucs import cisco_ucs_inventory as ucsinv
from quantum.plugins.cisco.ucs import cisco_ucs_plugin
LOG = logging.getLogger(__name__)
class UCSVICTestPlugin(unittest.TestCase):
"""
Unit Tests for the UCS Plugin functions
"""
def setUp(self):
self.tenant_id = "test_tenant_cisco12"
self.net_name = "test_network_cisco12"
self.net_id = 000011
self.vlan_name = conf.DEFAULT_VLAN_NAME
self.vlan_id = conf.DEFAULT_VLAN_ID
self.port_id = "4"
cdb.initialize()
cred.Store.initialize()
self._cisco_ucs_plugin = cisco_ucs_plugin.UCSVICPlugin()
self.device_ip = conf.UCSM_IP_ADDRESS
self._ucs_inventory = ucsinv.UCSInventory()
self._ucs_inventory._load_inventory()
self.chassis_id_list = (
self._ucs_inventory._inventory[self.device_ip].keys())
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):
"""
Tests creation of new Virtual Network.
"""
LOG.debug("UCSVICTestPlugin:_test_create_network() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID])
self.assertEqual(new_net_dict[const.NET_NAME],
new_network[const.NETWORKNAME])
self.tear_down_network(self.tenant_id, new_network[const.UUID])
def test_delete_network(self):
"""
Tests deletion of the network with the specified network identifier
belonging to the specified tenant.
"""
LOG.debug("UCSVICTestPlugin:test_delete_network() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_net_dict = self._cisco_ucs_plugin.delete_network(
self.tenant_id, new_network[const.UUID], device_ip=self.device_ip)
self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID])
def test_get_network_details(self):
"""
Tests the deletion the Virtual Network belonging to a the
spec
"""
LOG.debug("UCSVICTestPlugin:test_get_network_details() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_net_dict = self._cisco_ucs_plugin.get_network_details(
self.tenant_id, new_network[const.UUID],
device_ip=self.device_ip)
self.assertEqual(new_net_dict[const.NET_ID], new_network[const.UUID])
self.assertEqual(new_net_dict[const.NET_NAME],
new_network[const.NETWORKNAME])
self.tear_down_network(self.tenant_id, new_network[const.UUID])
def test_get_all_networks(self):
"""
Tests whether dictionary is returned containing all
<network_uuid, network_name> for
the specified tenant.
"""
LOG.debug("UCSVICTestPlugin:test_get_all_networks() called\n")
new_network1 = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network1[const.UUID])
new_net_dict1 = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network1[const.NETWORKNAME],
new_network1[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_network2 = db.network_create(self.tenant_id, "test_network2")
cdb.add_vlan_binding("6", "q-000006vlan", new_network2[const.UUID])
new_net_dict2 = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network2[const.NETWORKNAME],
new_network2[const.UUID], "q-000006vlan", "6",
device_ip=self.device_ip)
net_list = self._cisco_ucs_plugin.get_all_networks(
self.tenant_id, device_ip=self.device_ip)
net_id_list = [new_net_dict1, new_net_dict2]
self.assertTrue(net_list[0] in net_id_list)
self.assertTrue(net_list[1] in net_id_list)
self.tear_down_network(self.tenant_id, new_network1[const.UUID])
self.tear_down_network(self.tenant_id, new_network2[const.UUID])
def test_get_all_ports(self):
"""
Retrieves all port identifiers belonging to the
specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:get_all_ports() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_port1 = db.port_create(new_network[const.UUID], const.PORT_UP)
port_dict1 = self._cisco_ucs_plugin.create_port(
self.tenant_id, self.net_id, const.PORT_UP,
new_port1[const.UUID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
new_port2 = db.port_create(new_network[const.UUID], const.PORT_UP)
port_dict2 = self._cisco_ucs_plugin.create_port(
self.tenant_id, self.net_id, const.PORT_UP,
new_port2[const.UUID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
ports_on_net = self._cisco_ucs_plugin.get_all_ports(
self.tenant_id, new_net_dict[const.NET_ID],
device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
port_list = [port_dict1, port_dict2]
self.assertTrue(str(ports_on_net[1]) == str(port_list[1]) or
str(ports_on_net[1]) == str(port_list[0]))
self.assertTrue(str(ports_on_net[0]) == str(port_list[1]) or
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.tenant_id, new_net_dict[const.NET_ID],
port_dict1[const.PORTID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=blade_intf_details[
const.BLADE_INTF_DN],
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
self.tear_down_network_port(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict2[const.PORTID])
def test_create_port(self):
"""
Tests creation of a port on the specified Virtual Network.
"""
LOG.debug("UCSVICTestPlugin:_test_create_port() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_port = db.port_create(new_network[const.UUID], const.PORT_UP)
port_dict = self._cisco_ucs_plugin.create_port(
self.tenant_id, self.net_id, const.PORT_UP,
new_port[const.UUID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
self.assertEqual(port_dict[const.PORTID], new_port[const.UUID])
profile_name = (
self._cisco_ucs_plugin._get_profile_name(port_dict[const.PORTID]))
self.assertTrue(profile_name is not None)
self.tear_down_network_port(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID])
def test_delete_port(self):
"""
Tests Deletion of a port on a specified Virtual Network,
if the port contains a remote interface attachment,
the remote interface should first be un-plugged and
then the port can be deleted.
"""
LOG.debug("UCSVICTestPlugin:_test_delete_port() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_port = db.port_create(new_network[const.UUID], const.PORT_UP)
port_dict = self._cisco_ucs_plugin.create_port(
self.tenant_id, self.net_id, const.PORT_UP,
new_port[const.UUID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._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(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=blade_intf_details[
const.BLADE_INTF_DN],
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
self.assertEqual(port_bind[const.PORTID], new_port[const.UUID])
self.tear_down_network(self.tenant_id, new_net_dict[const.NET_ID])
def _test_get_port_details(self, port_state):
"""
Tests whether user is able to retrieve a remote interface
that is attached to this particular port when port state is Up.
"""
LOG.debug("UCSVICTestPlugin:_test_get_port_details() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_port = db.port_create(new_network[const.UUID], port_state)
port_dict = self._cisco_ucs_plugin.create_port(
self.tenant_id, self.net_id, port_state,
new_port[const.UUID], device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
port_detail = self._cisco_ucs_plugin.get_port_details(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], device_ip=self.device_ip)
self.assertEqual(str(port_dict), str(port_detail))
self.tear_down_network_port(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID])
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)
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)
def test_create_port_profile(self):
"""
Tests creation of port profile
"""
LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_port = db.port_create(new_network[const.UUID], const.PORT_UP)
self._cisco_ucs_plugin._set_ucsm(self.device_ip)
new_port_profile = self._cisco_ucs_plugin._create_port_profile(
self.tenant_id, new_network[const.UUID],
new_port[const.UUID], self.vlan_name,
self.vlan_id)
profile_name = (
self._cisco_ucs_plugin._get_profile_name(new_port[const.UUID]))
self.assertEqual(new_port_profile[const.PROFILE_NAME], profile_name)
self.assertEqual(new_port_profile[const.PROFILE_VLAN_NAME],
self.vlan_name)
self.assertEqual(new_port_profile[const.PROFILE_VLAN_ID], self.vlan_id)
self._cisco_ucs_plugin._delete_port_profile(new_port[const.UUID],
profile_name)
def test_delete_port_profile(self):
"""
Tests deletion of port profile
"""
LOG.debug("UCSVICTestPlugin:test_delete_port_profile() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_port = db.port_create(new_network[const.UUID], const.PORT_UP)
self._cisco_ucs_plugin._set_ucsm(self.device_ip)
self._cisco_ucs_plugin._create_port_profile(
self.tenant_id, new_network[const.UUID],
new_port[const.UUID], self.vlan_name,
self.vlan_id)
profile_name = (
self._cisco_ucs_plugin._get_profile_name(new_port[const.UUID]))
counter1 = self._cisco_ucs_plugin._port_profile_counter
self._cisco_ucs_plugin._delete_port_profile(new_port[const.UUID],
profile_name)
counter2 = self._cisco_ucs_plugin._port_profile_counter
self.assertEqual(counter1 - 1, counter2)
def test_plug_interface(self, remote_interface_id=None,
new_vlanid=10, new_vlan_name='new_vlan'):
"""
Attaches a remote interface to the specified port on the
specified Virtual Network.
"""
LOG.debug("UCSVICTestPlugin:_test_plug_interface() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_port = db.port_create(new_network[const.UUID], const.PORT_UP)
port_dict = self._cisco_ucs_plugin.create_port(
self.tenant_id, new_net_dict[const.NET_ID],
const.PORT_UP, new_port[const.UUID],
device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
cdb.update_vlan_binding(new_network[const.UUID],
str(new_vlanid), new_vlan_name)
port_bind = self._cisco_ucs_plugin.plug_interface(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], remote_interface_id,
device_ip=self.device_ip)
self.assertEqual(port_bind[const.VLANNAME], new_vlan_name)
self.assertEqual(port_bind[const.VLANID], new_vlanid)
self.tear_down_network_port_interface(
self.tenant_id, new_net_dict[const.NET_ID],
new_port[const.UUID])
def test_unplug_interface(self, remote_interface_id=None,
new_vlanid=10, new_vlan_name='new_vlan'):
"""
Tests whether remote interface detaches from the specified port on the
specified Virtual Network.
"""
LOG.debug("UCSVICTestPlugin:_test_unplug_interface() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
new_port = db.port_create(new_network[const.UUID], const.PORT_UP)
port_dict = self._cisco_ucs_plugin.create_port(
self.tenant_id, new_net_dict[const.NET_ID],
const.PORT_UP, new_port[const.UUID],
device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
cdb.update_vlan_binding(new_network[const.UUID],
str(new_vlanid), new_vlan_name)
self._cisco_ucs_plugin.plug_interface(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], remote_interface_id,
device_ip=self.device_ip)
port_bind = self._cisco_ucs_plugin.unplug_interface(
self.tenant_id, new_net_dict[const.NET_ID],
port_dict[const.PORTID], device_ip=self.device_ip)
self.assertEqual(port_bind[const.VLANNAME], self.vlan_name)
self.assertEqual(port_bind[const.VLANID], self.vlan_id)
self.tear_down_network_port_interface(
self.tenant_id, new_net_dict[const.NET_ID],
new_port[const.UUID])
def test_get_vlan_name_for_network(self):
"""
Tests retrieval of vlan name
"""
LOG.debug("UCSVICTestPlugin:test_get_vlan_name_for_network() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
vlan_bind_name = self._cisco_ucs_plugin._get_vlan_name_for_network(
self.tenant_id, new_network[const.UUID])
self.assertEqual(vlan_bind_name, self.vlan_name)
def test_get_vlan_id_for_network(self):
"""
Tests retrieval of vlan id
"""
LOG.debug("UCSVICTestPlugin:test_get_vlan_id_for_network() called\n")
new_network = db.network_create(self.tenant_id, self.net_name)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
vlan_bind_id = self._cisco_ucs_plugin._get_vlan_id_for_network(
self.tenant_id, new_network[const.UUID])
self.assertEqual(str(vlan_bind_id), self.vlan_id)
def test_show_network_not_found(self):
"""
Negative Test for show network details when network not found
"""
self.assertRaises(exc.NetworkNotFound,
self._cisco_ucs_plugin.get_network_details,
self.tenant_id, self.net_id,
device_ip=self.device_ip)
def test_delete_network_not_found(self):
"""
Negative Test for delete network when network not found
"""
self.assertRaises(exc.NetworkNotFound,
self._cisco_ucs_plugin.delete_network,
self.tenant_id, self.net_id,
device_ip=self.device_ip)
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)
cdb.add_vlan_binding(str(self.vlan_id), self.vlan_name,
new_network[const.UUID])
new_net_dict = self._cisco_ucs_plugin.create_network(
self.tenant_id, new_network[const.NETWORKNAME],
new_network[const.UUID], self.vlan_name, self.vlan_id,
device_ip=self.device_ip)
self.assertRaises(c_exc.PortVnicNotFound,
self._cisco_ucs_plugin.delete_port,
self.tenant_id, new_net_dict[const.NET_ID],
self.port_id, device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=None,
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
self.tear_down_network(self.tenant_id, new_net_dict[const.NET_ID])
def tearDown(self):
"""Clear the test environment"""
# Remove database contents
db.clear_db()
def tear_down_network(self, tenant_id, net_id):
self._cisco_ucs_plugin.delete_network(tenant_id, net_id,
device_ip=self.device_ip)
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(
tenant_id, net_id, port_id, device_ip=self.device_ip,
ucs_inventory=self._ucs_inventory,
chassis_id=self.chassis_id, blade_id=self.blade_id,
blade_intf_distinguished_name=blade_intf_details[
const.BLADE_INTF_DN],
least_rsvd_blade_dict=(
self._ucs_inventory._get_least_reserved_blade()))
self.tear_down_network(tenant_id, net_id)
def tear_down_network_port_interface(self, tenant_id, net_id, port_id):
self._cisco_ucs_plugin.unplug_interface(tenant_id, net_id, port_id,
device_ip=self.device_ip)
self.tear_down_network_port(tenant_id, net_id, port_id)

View File

@ -1,93 +0,0 @@
# 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 logging
import unittest
from quantum.common import exceptions as exc
from quantum.plugins.cisco.common import cisco_credentials as creds
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import l2network_db as cdb
from quantum.plugins.cisco import l2network_plugin_configuration as conf
from quantum.plugins.cisco.segmentation.l2network_vlan_mgr import (
L2NetworkVLANMgr,
)
logging.basicConfig(level=logging.WARN)
LOG = logging.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

@ -1,713 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
"""
The _inventory data strcuture contains a nested disctioary:
{"UCSM_IP: {"Chassis-ID": [Balde-ID, Blade-ID],
"Chassis-ID": [Blade-ID, Blade-ID, Blade-ID]]},
"UCSM_IP: {"Chassis-ID": [Balde-ID]}
}
"""
"""
_inventory_state data structure is organized as below:
{ucsm_ip:
{chassis_id:
{blade_id:
{'blade-data':
{blade-dn-1: {blade-intf-data},
blade-dn-2: {blade-intf-data}
}
}
}
}
}
'blade-data': Blade Data dictionary has the following keys:
===========================================================
const.BLADE_INTF_DATA: This is a dictionary, with the key as the
dn of the interface, and the value as the
Blade Interface Dictionary described next
const.BLADE_UNRESERVED_INTF_COUNT: Number of unreserved interfaces
on this blade
'blade-intf-data': Blade Interface dictionary has the following keys:
=====================================================================
const.BLADE_INTF_DN
const.BLADE_INTF_ORDER
const.BLADE_INTF_LINK_STATE
const.BLADE_INTF_OPER_STATE
const.BLADE_INTF_INST_TYPE
const.BLADE_INTF_RHEL_DEVICE_NAME
const.BLADE_INTF_RESERVATION
const.TENANTID
const.PORTID
const.PROFILE_ID
const.INSTANCE_ID
const.VIF_ID
"""
from copy import deepcopy
import logging
from quantum.common import exceptions as exc
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_exceptions as cexc
from quantum.plugins.cisco.db import api as db
from quantum.plugins.cisco.db import ucs_db as udb
from quantum.plugins.cisco.l2device_inventory_base import (
L2NetworkDeviceInventoryBase,
)
from quantum.plugins.cisco.ucs import (
cisco_ucs_inventory_configuration as conf,
)
from quantum.plugins.cisco.ucs import cisco_ucs_network_driver
LOG = logging.getLogger(__name__)
class UCSInventory(L2NetworkDeviceInventoryBase):
"""
Manages the state of all the UCS chasses, and blades in
the system
"""
_inventory = {}
_host_names = {}
_inventory_state = {}
def __init__(self):
self._client = cisco_ucs_network_driver.CiscoUCSMDriver()
self._load_inventory()
def _load_inventory(self):
"""Load the inventory from a config file"""
inventory = deepcopy(conf.INVENTORY)
LOG.info("Loaded UCS inventory: %s\n" % inventory)
LOG.info("Building UCS inventory state (this may take a while)...")
for ucsm in inventory.keys():
ucsm_ip = inventory[ucsm][const.IP_ADDRESS]
inventory[ucsm].pop(const.IP_ADDRESS)
chassis_dict = {}
for chassis in inventory[ucsm].keys():
chassis_id = inventory[ucsm][chassis][const.CHASSIS_ID]
inventory[ucsm][chassis].pop(const.CHASSIS_ID)
blade_list = []
for blade in inventory[ucsm][chassis].keys():
blade_id = (
inventory[ucsm][chassis][blade][const.BLADE_ID])
host_name = (
inventory[ucsm][chassis][blade][const.HOST_NAME])
host_key = ucsm_ip + "-" + chassis_id + "-" + blade_id
self._host_names[host_key] = host_name
blade_list.append(blade_id)
chassis_dict[chassis_id] = blade_list
self._inventory[ucsm_ip] = chassis_dict
self._build_inventory_state()
def _build_inventory_state(self):
"""Populate the state of all the blades"""
for ucsm_ip in self._inventory.keys():
self._inventory_state[ucsm_ip] = {ucsm_ip: {}}
ucsm_username = cred.Store.getUsername(ucsm_ip)
ucsm_password = cred.Store.getPassword(ucsm_ip)
chasses_state = {}
self._inventory_state[ucsm_ip] = chasses_state
ucsm = self._inventory[ucsm_ip]
for chassis_id in ucsm.keys():
blades_dict = {}
chasses_state[chassis_id] = blades_dict
for blade_id in ucsm[chassis_id]:
blade_data = self._get_initial_blade_state(chassis_id,
blade_id,
ucsm_ip,
ucsm_username,
ucsm_password)
blades_dict[blade_id] = blade_data
LOG.debug("UCS Inventory state is: %s\n" % self._inventory_state)
return True
def _get_host_name(self, ucsm_ip, chassis_id, blade_id):
"""Get the hostname based on the blade info"""
host_key = ucsm_ip + "-" + chassis_id + "-" + blade_id
return self._host_names[host_key]
def _get_initial_blade_state(self, chassis_id, blade_id, ucsm_ip,
ucsm_username, ucsm_password):
"""Get the initial blade state"""
blade_intf_data = self._client.get_blade_data(chassis_id, blade_id,
ucsm_ip, ucsm_username,
ucsm_password)
unreserved_counter = 0
for blade_intf in blade_intf_data.keys():
dist_name = blade_intf_data[blade_intf][const.BLADE_INTF_DN]
# We first make a pass through the state in UCSM
# If a particular interface is showing as being allocated in
# UCSM then it is definitely being used and so should be
# marked as reserved, else we temporarily mark it as unreserved
# based on the UCSM state, but may later change it if a port
# association is found in the DB
if not const.TENANTID in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.TENANTID] = None
if not const.PORTID in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.PORTID] = None
if not const.PROFILE_ID in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.PROFILE_ID] = None
if not const.INSTANCE_ID in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.INSTANCE_ID] = None
if not const.VIF_ID in blade_intf_data[blade_intf].keys():
blade_intf_data[blade_intf][const.VIF_ID] = None
if (blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNALLOCATED or
blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN) and (
blade_intf_data[blade_intf][const.BLADE_INTF_OPER_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN):
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_UNRESERVED)
unreserved_counter += 1
else:
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
port_binding = udb.get_portbinding_dn(dist_name)
if port_binding:
# We have found a port binding for this interface in the DB,
# so we have earlier marked this interface as unreserved, we
# need to change it, and also load the state from the DB for
# other associations
intf_data = blade_intf_data[blade_intf]
if ((intf_data[const.BLADE_INTF_RESERVATION] == const.
BLADE_INTF_UNRESERVED)):
unreserved_counter -= 1
intf_data[const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
intf_data[const.TENANTID] = port_binding[const.TENANTID]
intf_data[const.PORTID] = port_binding[const.PORTID]
intf_data[const.PROFILE_ID] = (
port_binding[const.PORTPROFILENAME])
intf_data[const.INSTANCE_ID] = port_binding[const.INSTANCE_ID]
intf_data[const.VIF_ID] = port_binding[const.VIF_ID]
host_name = self._get_host_name(ucsm_ip, chassis_id, blade_id)
blade_data = {const.BLADE_INTF_DATA: blade_intf_data,
const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter,
const.HOST_NAME: host_name}
return blade_data
def _get_blade_state(self, chassis_id, blade_id, ucsm_ip,
ucsm_username, ucsm_password):
"""Get the blade state"""
blade_intf_data = self._client.get_blade_data(chassis_id, blade_id,
ucsm_ip, ucsm_username,
ucsm_password)
unreserved_counter = 0
for blade_intf in blade_intf_data.keys():
if (blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNALLOCATED or
blade_intf_data[blade_intf][const.BLADE_INTF_LINK_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN) and (
blade_intf_data[blade_intf][const.BLADE_INTF_OPER_STATE] ==
const.BLADE_INTF_STATE_UNKNOWN):
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_UNRESERVED)
unreserved_counter += 1
else:
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
blade_data = {const.BLADE_INTF_DATA: blade_intf_data,
const.BLADE_UNRESERVED_INTF_COUNT: unreserved_counter}
return blade_data
def _get_all_ucsms(self):
"""Return a list of the IPs of all the UCSMs in the system"""
return {const.DEVICE_IP: self._inventory.keys()}
def _get_blade_for_port(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
tenant_id = args[0]
net_id = args[1]
port_id = args[2]
rsvd_info = self._get_rsvd_blade_intf_by_port(tenant_id, port_id)
if not rsvd_info:
raise exc.PortNotFound(net_id=net_id, port_id=port_id)
device_params = {const.DEVICE_IP: [rsvd_info[const.UCSM_IP]]}
return device_params
def _get_host_name_for_rsvd_intf(self, tenant_id, instance_id):
"""
Return the hostname of the blade with a reserved instance
for this tenant
"""
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
tmp = deepcopy(blade_intf_data[blade_intf])
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
intf_data[const.INSTANCE_ID] is None):
intf_data[const.INSTANCE_ID] = instance_id
host_name = self._get_host_name(ucsm_ip,
chassis_id,
blade_id)
port_binding = udb.get_portbinding_dn(blade_intf)
port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id,
instance_id=instance_id)
return host_name
LOG.warn("Could not find a reserved dynamic nic for tenant: %s" %
tenant_id)
return None
def _get_instance_port(self, tenant_id, instance_id, vif_id):
"""
Return the device name for a reserved interface
"""
found_blade_intf_data = None
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
intf_data[const.INSTANCE_ID] == instance_id):
found_blade_intf_data = blade_intf_data
LOG.debug(("Found blade %s associated with this"
" instance: %s") % (blade_id,
instance_id))
break
if found_blade_intf_data:
blade_intf_data = found_blade_intf_data
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
(not intf_data[const.VIF_ID])):
intf_data[const.VIF_ID] = vif_id
intf_data[const.INSTANCE_ID] = instance_id
port_binding = udb.get_portbinding_dn(blade_intf)
port_id = port_binding[const.PORTID]
udb.update_portbinding(port_id, instance_id=instance_id,
vif_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]
profile_name = port_binding[const.PORTPROFILENAME]
dynamicnic_details = {
const.DEVICENAME: device_name,
const.UCSPROFILE: profile_name,
}
LOG.debug(("Found reserved dynamic nic: %s"
"associated with port %s") %
(intf_data, port_id))
LOG.debug("Returning dynamic nic details: %s" %
dynamicnic_details)
return dynamicnic_details
LOG.warn("Could not find a reserved dynamic nic for tenant: %s" %
tenant_id)
return None
def _disassociate_vifid_from_port(self, tenant_id, instance_id, vif_id):
"""
Disassociate a VIF-ID from a port, this happens when a
VM is destroyed
"""
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
blade_intf_data[blade_intf][const.INSTANCE_ID]
== instance_id and
intf_data[const.VIF_ID][:const.UUID_LENGTH] ==
vif_id):
intf_data[const.VIF_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,
vif_id=None)
db.port_unset_attachment_by_id(port_id)
LOG.debug(
("Disassociated VIF-ID: %s "
"from port: %s"
"in UCS inventory state for blade: %s") %
(vif_id, port_id, intf_data))
device_params = {const.DEVICE_IP: [ucsm_ip],
const.PORTID: port_id}
return device_params
LOG.warn(("Disassociating VIF-ID in UCS inventory failed. "
"Could not find a reserved dynamic nic for tenant: %s") %
tenant_id)
return None
def _get_rsvd_blade_intf_by_port(self, tenant_id, port_id):
"""
Lookup a reserved blade interface based on tenant_id and port_id
and return the blade interface info
"""
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
for blade_intf in blade_intf_data.keys():
if ((not blade_intf_data[blade_intf][const.PORTID] or
not blade_intf_data[blade_intf][const.TENANTID])):
continue
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_RESERVED and
intf_data[const.TENANTID] == tenant_id and
intf_data[const.PORTID] == port_id):
interface_dn = intf_data[const.BLADE_INTF_DN]
blade_intf_info = {const.UCSM_IP: ucsm_ip,
const.CHASSIS_ID: chassis_id,
const.BLADE_ID: blade_id,
const.BLADE_INTF_DN:
interface_dn}
return blade_intf_info
LOG.warn("Could not find a reserved nic for tenant: %s port: %s" %
(tenant_id, port_id))
return None
def _get_least_reserved_blade(self, intf_count=1):
"""Return the blade with least number of dynamic nics reserved"""
unreserved_interface_count = 0
least_reserved_blade_ucsm = None
least_reserved_blade_chassis = None
least_reserved_blade_id = None
least_reserved_blade_data = None
for ucsm_ip in self._inventory_state.keys():
ucsm = self._inventory_state[ucsm_ip]
for chassis_id in ucsm.keys():
for blade_id in ucsm[chassis_id]:
blade_data = ucsm[chassis_id][blade_id]
if ((blade_data[const.BLADE_UNRESERVED_INTF_COUNT] >
unreserved_interface_count)):
unreserved_interface_count = (
blade_data[const.BLADE_UNRESERVED_INTF_COUNT])
least_reserved_blade_ucsm = ucsm_ip
least_reserved_blade_chassis = chassis_id
least_reserved_blade_id = blade_id
least_reserved_blade_data = blade_data
if unreserved_interface_count < intf_count:
LOG.warn(("Not enough dynamic nics available on a single host."
" Requested: %s, Maximum available: %s") %
(intf_count, unreserved_interface_count))
return False
least_reserved_blade_dict = {
const.LEAST_RSVD_BLADE_UCSM: least_reserved_blade_ucsm,
const.LEAST_RSVD_BLADE_CHASSIS: least_reserved_blade_chassis,
const.LEAST_RSVD_BLADE_ID: least_reserved_blade_id,
const.LEAST_RSVD_BLADE_DATA: least_reserved_blade_data,
}
LOG.debug("Found dynamic nic %s available for reservation",
least_reserved_blade_dict)
return least_reserved_blade_dict
def reload_inventory(self):
"""Reload the inventory from a conf file"""
self._load_inventory()
def reserve_blade_interface(self, ucsm_ip, chassis_id, blade_id,
blade_data_dict, tenant_id, port_id,
portprofile_name):
"""Reserve an interface on a blade"""
ucsm_username = cred.Store.getUsername(ucsm_ip)
ucsm_password = cred.Store.getPassword(ucsm_ip)
"""
We are first getting the updated UCSM-specific blade
interface state
"""
blade_data = self._get_blade_state(chassis_id, blade_id, ucsm_ip,
ucsm_username, ucsm_password)
blade_intf_data = blade_data[const.BLADE_INTF_DATA]
chassis_data = self._inventory_state[ucsm_ip][chassis_id]
old_blade_intf_data = chassis_data[blade_id][const.BLADE_INTF_DATA]
"""
We will now copy the older non-UCSM-specific blade
interface state
"""
for blade_intf in blade_intf_data.keys():
old_intf_data = old_blade_intf_data[blade_intf]
blade_intf_data[blade_intf][const.BLADE_INTF_RESERVATION] = (
old_intf_data[const.BLADE_INTF_RESERVATION])
blade_intf_data[blade_intf][const.TENANTID] = (
old_intf_data[const.TENANTID])
blade_intf_data[blade_intf][const.PORTID] = (
old_intf_data[const.PORTID])
blade_intf_data[blade_intf][const.PROFILE_ID] = (
old_intf_data[const.PROFILE_ID])
blade_intf_data[blade_intf][const.INSTANCE_ID] = (
old_intf_data[const.INSTANCE_ID])
blade_intf_data[blade_intf][const.VIF_ID] = (
old_intf_data[const.VIF_ID])
blade_data[const.BLADE_UNRESERVED_INTF_COUNT] = (
chassis_data[blade_id][const.BLADE_UNRESERVED_INTF_COUNT])
"""
Now we will reserve an interface if its available
"""
for blade_intf in blade_intf_data.keys():
intf_data = blade_intf_data[blade_intf]
if (intf_data[const.BLADE_INTF_RESERVATION] ==
const.BLADE_INTF_UNRESERVED):
intf_data[const.BLADE_INTF_RESERVATION] = (
const.BLADE_INTF_RESERVED)
intf_data[const.TENANTID] = tenant_id
intf_data[const.PORTID] = port_id
intf_data[const.INSTANCE_ID] = None
dev_eth_name = intf_data[const.BLADE_INTF_RHEL_DEVICE_NAME]
"""
We are replacing the older blade interface state with new
"""
chassis_data[blade_id][const.BLADE_INTF_DATA] = blade_intf_data
chassis_data[blade_id][const.BLADE_UNRESERVED_INTF_COUNT] -= 1
host_name = self._get_host_name(ucsm_ip, chassis_id, blade_id)
reserved_nic_dict = {
const.RESERVED_NIC_HOSTNAME: host_name,
const.RESERVED_NIC_NAME: dev_eth_name,
const.BLADE_INTF_DN: blade_intf,
}
port_binding = udb.add_portbinding(port_id, blade_intf, None,
None, None, None)
udb.update_portbinding(port_id,
tenant_id=intf_data[const.TENANTID])
LOG.debug("Reserved blade interface: %s\n" % reserved_nic_dict)
return reserved_nic_dict
LOG.warn("Dynamic nic %s could not be reserved for port-id: %s" %
(blade_data, port_id))
return False
def unreserve_blade_interface(self, ucsm_ip, chassis_id, blade_id,
interface_dn):
"""Unreserve a previously reserved interface on a blade"""
ucsm_username = cred.Store.getUsername(ucsm_ip)
ucsm_password = cred.Store.getPassword(ucsm_ip)
blade_data = self._inventory_state[ucsm_ip][chassis_id][blade_id]
blade_data[const.BLADE_UNRESERVED_INTF_COUNT] += 1
blade_intf = blade_data[const.BLADE_INTF_DATA][interface_dn]
blade_intf[const.BLADE_INTF_RESERVATION] = const.BLADE_INTF_UNRESERVED
blade_intf[const.TENANTID] = None
blade_intf[const.PORTID] = None
blade_intf[const.PROFILE_ID] = None
blade_intf[const.INSTANCE_ID] = None
blade_intf[const.VIF_ID] = None
LOG.debug("Unreserved blade interface %s\n" % interface_dn)
def add_blade(self, ucsm_ip, chassis_id, blade_id):
"""Add a blade to the inventory"""
# TODO (Sumit)
pass
def get_all_networks(self, args):
"""Return all UCSM IPs"""
LOG.debug("get_all_networks() called\n")
return self._get_all_ucsms()
def create_network(self, args):
"""Return all UCSM IPs"""
LOG.debug("create_network() called\n")
return self._get_all_ucsms()
def delete_network(self, args):
"""Return all UCSM IPs"""
LOG.debug("delete_network() called\n")
return self._get_all_ucsms()
def get_network_details(self, args):
"""Return all UCSM IPs"""
LOG.debug("get_network_details() called\n")
return self._get_all_ucsms()
def update_network(self, args):
"""Return all UCSM IPs"""
LOG.debug("update_network() called\n")
return self._get_all_ucsms()
def get_all_ports(self, args):
"""Return all UCSM IPs"""
LOG.debug("get_all_ports() called\n")
return self._get_all_ucsms()
def create_port(self, args):
"""
Return the a dict with information of the blade
on which a dynamic vnic is available
"""
LOG.debug("create_port() called\n")
least_reserved_blade_dict = self._get_least_reserved_blade()
if not least_reserved_blade_dict:
raise cexc.NoMoreNics()
ucsm_ip = least_reserved_blade_dict[const.LEAST_RSVD_BLADE_UCSM]
device_params = {
const.DEVICE_IP: [ucsm_ip],
const.UCS_INVENTORY: self,
const.LEAST_RSVD_BLADE_DICT: least_reserved_blade_dict,
}
return device_params
def delete_port(self, args):
"""
Return the a dict with information of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug("delete_port() called\n")
tenant_id = args[0]
net_id = args[1]
port_id = args[2]
rsvd_info = self._get_rsvd_blade_intf_by_port(tenant_id, port_id)
if not rsvd_info:
LOG.warn("UCSInventory: Port not found: net_id: %s, port_id: %s" %
(net_id, port_id))
return {const.DEVICE_IP: []}
device_params = {
const.DEVICE_IP: [rsvd_info[const.UCSM_IP]],
const.UCS_INVENTORY: self,
const.CHASSIS_ID: rsvd_info[const.CHASSIS_ID],
const.BLADE_ID: rsvd_info[const.BLADE_ID],
const.BLADE_INTF_DN: rsvd_info[const.BLADE_INTF_DN],
}
return device_params
def update_port(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug("update_port() called\n")
return self._get_blade_for_port(args)
def get_port_details(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug("get_port_details() called\n")
return self._get_blade_for_port(args)
def plug_interface(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug("plug_interface() called\n")
return self._get_blade_for_port(args)
def unplug_interface(self, args):
"""
Return the a dict with IP address of the blade
on which a dynamic vnic was reserved for this port
"""
LOG.debug("unplug_interface() called\n")
return self._get_blade_for_port(args)
def schedule_host(self, args):
"""Provides the hostname on which a dynamic vnic is reserved"""
LOG.debug("schedule_host() called\n")
instance_id = args[1]
tenant_id = args[2][const.PROJECT_ID]
host_name = self._get_host_name_for_rsvd_intf(tenant_id, instance_id)
host_list = {const.HOST_LIST: {const.HOST_1: host_name}}
LOG.debug("host_list is: %s" % host_list)
return host_list
def associate_port(self, args):
"""
Get the portprofile name and the device name for the dynamic vnic
"""
LOG.debug("associate_port() called\n")
instance_id = args[1]
tenant_id = args[2][const.PROJECT_ID]
vif_id = args[2][const.VIF_ID]
vif_info = self._get_instance_port(tenant_id, instance_id, vif_id)
vif_desc = {const.VIF_DESC: vif_info}
LOG.debug("vif_desc is: %s" % 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):
"""
Create multiple ports for a VM
"""
LOG.debug("create_ports() called\n")
tenant_id = args[0]
ports_num = args[2]
least_reserved_blade_dict = self._get_least_reserved_blade(ports_num)
if not least_reserved_blade_dict:
raise cexc.NoMoreNics()
ucsm_ip = least_reserved_blade_dict[const.LEAST_RSVD_BLADE_UCSM]
device_params = {
const.DEVICE_IP: [ucsm_ip],
const.UCS_INVENTORY: self,
const.LEAST_RSVD_BLADE_DICT:
least_reserved_blade_dict,
}
return device_params

View File

@ -1,337 +0,0 @@
# 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: Sumit Naiksatam, Cisco Systems, Inc.
#
import logging
from quantum.openstack.common import importutils
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_exceptions as cexc
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 l2network_db as cdb
from quantum.plugins.cisco.db import ucs_db as udb
from quantum.plugins.cisco.l2device_plugin_base import L2DevicePluginBase
from quantum.plugins.cisco.ucs import cisco_ucs_configuration as conf
LOG = logging.getLogger(__name__)
class UCSVICPlugin(L2DevicePluginBase):
"""UCS Device Plugin"""
def __init__(self):
self._driver = importutils.import_object(conf.UCSM_DRIVER)
LOG.debug("Loaded driver %s\n" % conf.UCSM_DRIVER)
# TODO (Sumit) Make the counter per UCSM
self._port_profile_counter = 0
def get_all_networks(self, tenant_id, **kwargs):
"""
Returns a dictionary containing all
<network_uuid, network_name> for
the specified tenant.
"""
LOG.debug("UCSVICPlugin:get_all_networks() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
networks_list = db.network_list(tenant_id)
new_networks_list = []
for network in networks_list:
new_network_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
[])
new_networks_list.append(new_network_dict)
return new_networks_list
def create_network(self, tenant_id, net_name, net_id, vlan_name, vlan_id,
**kwargs):
"""
Creates a new Virtual Network, and assigns it
a symbolic name.
"""
LOG.debug("UCSVICPlugin:create_network() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
self._driver.create_vlan(vlan_name, str(vlan_id), self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
network = db.network_get(net_id)
ports_on_net = []
new_network_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
ports_on_net)
return new_network_dict
def delete_network(self, tenant_id, net_id, **kwargs):
"""
Deletes the network with the specified network identifier
belonging to the specified tenant.
"""
LOG.debug("UCSVICPlugin:delete_network() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
net = db.network_get(net_id)
vlan_binding = cdb.get_vlan_binding(net[const.UUID])
vlan_name = vlan_binding[const.VLANNAME]
self._driver.delete_vlan(vlan_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
net_dict = cutil.make_net_dict(net[const.UUID],
net[const.NETWORKNAME],
[])
return net_dict
def get_network_details(self, tenant_id, net_id, **kwargs):
"""
Deletes the Virtual Network belonging to a the
spec
"""
LOG.debug("UCSVICPlugin:get_network_details() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
network = db.network_get(net_id)
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
for port in ports_list:
new_port = cutil.make_port_dict(port[const.UUID],
port[const.PORTSTATE],
port[const.NETWORKID],
port[const.INTERFACEID])
ports_on_net.append(new_port)
new_network = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
ports_on_net)
return new_network
def update_network(self, tenant_id, net_id, **kwargs):
"""
Updates the symbolic name belonging to a particular
Virtual Network.
"""
LOG.debug("UCSVICPlugin:update_network() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
network = db.network_get(net_id)
net_dict = cutil.make_net_dict(network[const.UUID],
network[const.NETWORKNAME],
[])
return net_dict
def get_all_ports(self, tenant_id, net_id, **kwargs):
"""
Retrieves all port identifiers belonging to the
specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:get_all_ports() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
network = db.network_get(net_id)
ports_list = network[const.NETWORKPORTS]
ports_on_net = []
for port in ports_list:
port_binding = udb.get_portbinding(port[const.UUID])
ports_on_net.append(port_binding)
return ports_on_net
def create_port(self, tenant_id, net_id, port_state, port_id, **kwargs):
"""
Creates a port on the specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:create_port() 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]
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)
return port_binding
def delete_port(self, tenant_id, net_id, port_id, **kwargs):
"""
Deletes a port on a specified Virtual Network,
if the port contains a remote interface attachment,
the remote interface should first be un-plugged and
then the port can be deleted.
"""
LOG.debug("UCSVICPlugin:delete_port() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
ucs_inventory = kwargs[const.UCS_INVENTORY]
chassis_id = kwargs[const.CHASSIS_ID]
blade_id = kwargs[const.BLADE_ID]
interface_dn = kwargs[const.BLADE_INTF_DN]
port_binding = udb.get_portbinding(port_id)
profile_name = port_binding[const.PORTPROFILENAME]
self._delete_port_profile(port_id, profile_name)
ucs_inventory.unreserve_blade_interface(self._ucsm_ip, chassis_id,
blade_id, interface_dn)
return udb.remove_portbinding(port_id)
def update_port(self, tenant_id, net_id, port_id, **kwargs):
"""
Updates the state of a port on the specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:update_port() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
pass
def get_port_details(self, tenant_id, net_id, port_id, **kwargs):
"""
This method allows the user to retrieve a remote interface
that is attached to this particular port.
"""
LOG.debug("UCSVICPlugin:get_port_details() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
port_binding = udb.get_portbinding(port_id)
return port_binding
def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id,
**kwargs):
"""
Attaches a remote interface to the specified port on the
specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:plug_interface() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
port_binding = udb.get_portbinding(port_id)
profile_name = port_binding[const.PORTPROFILENAME]
old_vlan_name = port_binding[const.VLANNAME]
new_vlan_name = self._get_vlan_name_for_network(tenant_id, net_id)
new_vlan_id = self._get_vlan_id_for_network(tenant_id, net_id)
self._driver.change_vlan_in_profile(profile_name, old_vlan_name,
new_vlan_name, self._ucsm_ip,
self._ucsm_username,
self._ucsm_password)
return udb.update_portbinding(port_id, vlan_name=new_vlan_name,
vlan_id=new_vlan_id)
def unplug_interface(self, tenant_id, net_id, port_id, **kwargs):
"""
Detaches a remote interface from the specified port on the
specified Virtual Network.
"""
LOG.debug("UCSVICPlugin:unplug_interface() called\n")
self._set_ucsm(kwargs[const.DEVICE_IP])
port_binding = udb.get_portbinding(port_id)
profile_name = port_binding[const.PORTPROFILENAME]
old_vlan_name = port_binding[const.VLANNAME]
new_vlan_name = conf.DEFAULT_VLAN_NAME
self._driver.change_vlan_in_profile(profile_name, old_vlan_name,
new_vlan_name, self._ucsm_ip,
self._ucsm_username,
self._ucsm_password)
return udb.update_portbinding(port_id, vlan_name=new_vlan_name,
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):
"""Returns the port profile name based on the port UUID"""
profile_name = conf.PROFILE_NAME_PREFIX + cutil.get16ByteUUID(port_id)
return profile_name
def _get_vlan_name_for_network(self, tenant_id, network_id):
"""Return the VLAN name as set by the L2 network plugin"""
vlan_binding = cdb.get_vlan_binding(network_id)
return vlan_binding[const.VLANNAME]
def _get_vlan_id_for_network(self, tenant_id, network_id):
"""Return the VLAN id as set by the L2 network plugin"""
vlan_binding = cdb.get_vlan_binding(network_id)
return vlan_binding[const.VLANID]
def _create_port_profile(self, tenant_id, net_id, port_id, vlan_name,
vlan_id):
"""Create port profile in UCSM"""
if self._port_profile_counter >= int(conf.MAX_UCSM_PORT_PROFILES):
raise cexc.UCSMPortProfileLimit(net_id=net_id, port_id=port_id)
profile_name = self._get_profile_name(port_id)
self._driver.create_profile(profile_name, vlan_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
self._port_profile_counter += 1
new_port_profile = {const.PROFILE_NAME: profile_name,
const.PROFILE_VLAN_NAME: vlan_name,
const.PROFILE_VLAN_ID: vlan_id}
return new_port_profile
def _delete_port_profile(self, port_id, profile_name):
"""Delete port profile in UCSM"""
self._driver.delete_profile(profile_name, self._ucsm_ip,
self._ucsm_username, self._ucsm_password)
self._port_profile_counter -= 1
def _set_ucsm(self, ucsm_ip):
"""Set the UCSM IP, username, and password"""
self._ucsm_ip = ucsm_ip
self._ucsm_username = cred.Store.getUsername(conf.UCSM_IP_ADDRESS)
self._ucsm_password = cred.Store.getPassword(conf.UCSM_IP_ADDRESS)