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:
parent
f8c8f53b37
commit
a37f35841c
@ -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.
|
@ -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()
|
@ -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)
|
@ -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()
|
@ -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)
|
@ -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 []
|
@ -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)
|
@ -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
|
@ -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]
|
@ -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)
|
@ -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)
|
@ -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(',')
|
@ -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}
|
@ -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])
|
@ -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
@ -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")
|
@ -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()
|
@ -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')
|
@ -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)
|
@ -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")
|
@ -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
|
@ -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)
|
Loading…
Reference in New Issue
Block a user