Syncing with Cisco extensions branch.
This commit is contained in:
commit
0ab88c27a5
@ -47,12 +47,12 @@ class ViewBuilder(object):
|
||||
return credential
|
||||
|
||||
def _build_simple(self, credential_data):
|
||||
"""Return a simple model of a server."""
|
||||
"""Return a simple description of credential."""
|
||||
return dict(credential=dict(id=credential_data['credential_id']))
|
||||
|
||||
def _build_detail(self, credential_data):
|
||||
"""Return a simple model of a server."""
|
||||
"""Return a detailed description of credential."""
|
||||
|
||||
return dict(credential=dict(id=credential_data['credential_id'],
|
||||
name=credential_data['user_name'],
|
||||
password=credential_data['password']))
|
||||
password=credential_data['password']))
|
||||
|
@ -1,181 +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: Ying Liu, Cisco Systems, Inc.
|
||||
#
|
||||
"""
|
||||
import logging
|
||||
|
||||
|
||||
# pylint: disable-msg=E0602
|
||||
class ExtensionException(Exception):
|
||||
"""Quantum Cisco api Exception
|
||||
|
||||
Taken from nova.exception.NovaException
|
||||
To correctly use this class, inherit from it and define
|
||||
a 'message' property. That message will get printf'd
|
||||
with the keyword arguments provided to the constructor.
|
||||
|
||||
"""
|
||||
message = _("An unknown exception occurred.")
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
try:
|
||||
self._error_string = self.message % kwargs
|
||||
|
||||
except Exception:
|
||||
# at least get the core message out if something happened
|
||||
self._error_string = self.message
|
||||
|
||||
def __str__(self):
|
||||
"""Error Msg"""
|
||||
return self._error_string
|
||||
|
||||
|
||||
class ProcessExecutionError(IOError):
|
||||
"""Process Exe Error"""
|
||||
def __init__(self, stdout=None, stderr=None, exit_code=None, cmd=None,
|
||||
description=None):
|
||||
if description is None:
|
||||
description = "Unexpected error while running command."
|
||||
if exit_code is None:
|
||||
exit_code = '-'
|
||||
message = "%s\nCommand: %s\nExit code: %s\nStdout: %r\nStderr: %r" % (
|
||||
description, cmd, exit_code, stdout, stderr)
|
||||
IOError.__init__(self, message)
|
||||
|
||||
|
||||
class Error(Exception):
|
||||
"""Error Class"""
|
||||
def __init__(self, message=None):
|
||||
super(Error, self).__init__(message)
|
||||
|
||||
|
||||
class ApiError(Error):
|
||||
"""Api Error"""
|
||||
def __init__(self, message='Unknown', code='Unknown'):
|
||||
self.message = message
|
||||
self.code = code
|
||||
super(ApiError, self).__init__('%s: %s' % (code, message))
|
||||
|
||||
|
||||
class NotFound(ExtensionException):
|
||||
"""Error Msg"""
|
||||
pass
|
||||
|
||||
|
||||
class ClassNotFound(NotFound):
|
||||
"""Extension Error Msg"""
|
||||
message = _("Class %(class_name)s could not be found")
|
||||
|
||||
|
||||
class PortprofileNotFound(NotFound):
|
||||
"""Extension Error Msg"""
|
||||
message = _("Portprofile %(_id)s could not be found")
|
||||
|
||||
|
||||
class NovatenantNotFound(NotFound):
|
||||
"""Extension Error Msg"""
|
||||
message = _("Novatenant %(_id)s could not be found")
|
||||
|
||||
|
||||
class PortNotFound(NotFound):
|
||||
"""Extension Error"""
|
||||
message = _("Port %(port_id)s could not be found " \
|
||||
"on Network %(net_id)s")
|
||||
|
||||
|
||||
class CredentialNotFound(NotFound):
|
||||
"""Extension Error"""
|
||||
message = _("Credential %(_id)s could not be found")
|
||||
|
||||
|
||||
class QosNotFound(NotFound):
|
||||
"""Extension Error"""
|
||||
message = _("QoS %(_id)s could not be found")
|
||||
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class PortprofileInUse(ExtensionException):
|
||||
message = _("Unable to complete operation on Portprofile %(net_id)s. " \
|
||||
"There is one or more attachments plugged into its ports.")
|
||||
|
||||
|
||||
class PortInUse(ExtensionException):
|
||||
message = _("Unable to complete operation on port %(port_id)s " \
|
||||
"for Portprofile %(net_id)s. The attachment '%(att_id)s" \
|
||||
"is plugged into the logical port.")
|
||||
|
||||
class AlreadyAttached(ExtensionException):
|
||||
message = _("Unable to plug the attachment %(att_id)s into port " \
|
||||
"%(port_id)s for Portprofile %(net_id)s. The attachment is " \
|
||||
"already plugged into port %(att_port_id)s")
|
||||
|
||||
"""
|
||||
|
||||
|
||||
class Duplicate(Error):
|
||||
"""Duplication Error"""
|
||||
pass
|
||||
|
||||
|
||||
class NotAuthorized(Error):
|
||||
"Not Auth Error"
|
||||
pass
|
||||
|
||||
|
||||
class NotEmpty(Error):
|
||||
"""Not Empty Error"""
|
||||
pass
|
||||
|
||||
|
||||
class Invalid(Error):
|
||||
"""Invalid Error"""
|
||||
pass
|
||||
|
||||
|
||||
class InvalidContentType(Invalid):
|
||||
message = _("Invalid content type %(content_type)s.")
|
||||
|
||||
|
||||
class BadInputError(Exception):
|
||||
"""Error resulting from a client sending bad input to a server"""
|
||||
pass
|
||||
|
||||
|
||||
class MissingArgumentError(Error):
|
||||
"""Miss arg error"""
|
||||
pass
|
||||
|
||||
|
||||
def wrap_exception(afunc):
|
||||
"""Wrap Exception"""
|
||||
def _wrap(*args, **kw):
|
||||
"""Internal Wrap Exception func"""
|
||||
try:
|
||||
return afunc(*args, **kw)
|
||||
except Exception, exp:
|
||||
if not isinstance(exp, Error):
|
||||
#exc_type, exc_value, exc_traceback = sys.exc_info()
|
||||
logging.exception('Uncaught exception')
|
||||
#logging.error(traceback.extract_stack(exc_traceback))
|
||||
raise Error(str(exp))
|
||||
raise
|
||||
_wrap.func_name = afunc.func_name
|
||||
return _wrap
|
@ -18,6 +18,7 @@
|
||||
# @author: Ying Liu, Cisco Systems, Inc.
|
||||
#
|
||||
"""
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
|
||||
|
||||
def get_view_builder(req):
|
||||
@ -39,8 +40,8 @@ class ViewBuilder(object):
|
||||
|
||||
def build_host(self, host_data):
|
||||
"""Return host description."""
|
||||
return dict(host_list=host_data['host_list'])
|
||||
return dict(host_list=host_data[const.HOST_LIST])
|
||||
|
||||
def build_vif(self, vif_data):
|
||||
"""Return VIF description."""
|
||||
return dict(vif_desc=vif_data['vif_desc'])
|
||||
return dict(vif_desc=vif_data[const.VIF_DESC])
|
||||
|
@ -47,7 +47,7 @@ class ViewBuilder(object):
|
||||
return portprofile
|
||||
|
||||
def _build_simple(self, portprofile_data):
|
||||
"""Return a simple model of a portprofile"""
|
||||
"""Return a simple description of a portprofile"""
|
||||
return dict(portprofile=dict(id=portprofile_data['profile_id']))
|
||||
|
||||
def _build_detail(self, portprofile_data):
|
||||
|
@ -46,11 +46,11 @@ class ViewBuilder(object):
|
||||
return qos
|
||||
|
||||
def _build_simple(self, qos_data):
|
||||
"""Return a simple model of a server."""
|
||||
"""Return a simple description of qos."""
|
||||
return dict(qos=dict(id=qos_data['qos_id']))
|
||||
|
||||
def _build_detail(self, qos_data):
|
||||
"""Return a simple model of a server."""
|
||||
"""Return a detailed description of qos."""
|
||||
return dict(qos=dict(id=qos_data['qos_id'],
|
||||
name=qos_data['qos_name'],
|
||||
description=qos_data['qos_desc']))
|
||||
|
@ -21,14 +21,13 @@
|
||||
import logging
|
||||
|
||||
from webob import exc
|
||||
from extensions import _credential_view as credential_view
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as exception
|
||||
#from extensions import _exceptions as exception
|
||||
from extensions import _faults as faults
|
||||
|
||||
from extensions import _credential_view as credential_view
|
||||
from quantum.api import api_common as common
|
||||
from quantum.common import extensions
|
||||
from quantum.manager import QuantumManager
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as exception
|
||||
from quantum.plugins.cisco.common import cisco_faults as faults
|
||||
|
||||
LOG = logging.getLogger('quantum.api.credentials')
|
||||
|
||||
@ -37,7 +36,7 @@ class Credential(object):
|
||||
"""extension class Credential"""
|
||||
def __init__(self):
|
||||
pass
|
||||
|
||||
|
||||
@classmethod
|
||||
def get_name(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
@ -60,7 +59,7 @@ class Credential(object):
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
""" Returns Ext Resource Update Time """
|
||||
return "2011-07-25T13:25:27-06:00"
|
||||
|
||||
@classmethod
|
||||
@ -68,7 +67,6 @@ class Credential(object):
|
||||
""" Returns Ext Resources """
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
|
||||
controller = CredentialController(QuantumManager.get_plugin())
|
||||
return [extensions.ResourceExtension('credentials', controller,
|
||||
parent=parent_resource)]
|
||||
@ -85,7 +83,7 @@ class CredentialController(common.QuantumController):
|
||||
'required': True}, {
|
||||
'param-name': 'password',
|
||||
'required': True}]
|
||||
|
||||
|
||||
_serialization_metadata = {
|
||||
"application/xml": {
|
||||
"attributes": {
|
||||
@ -97,8 +95,7 @@ class CredentialController(common.QuantumController):
|
||||
def __init__(self, plugin):
|
||||
self._resource_name = 'credential'
|
||||
self._plugin = plugin
|
||||
#super(CredentialController, self).__init__(plugin)
|
||||
|
||||
|
||||
def index(self, request, tenant_id):
|
||||
""" Returns a list of credential ids """
|
||||
return self._items(request, tenant_id, is_detail=False)
|
||||
@ -126,7 +123,6 @@ class CredentialController(common.QuantumController):
|
||||
|
||||
def create(self, request, tenant_id):
|
||||
""" Creates a new credential for a given tenant """
|
||||
#look for credential name in request
|
||||
try:
|
||||
req_params = \
|
||||
self._parse_request_params(request,
|
||||
@ -168,4 +164,3 @@ class CredentialController(common.QuantumController):
|
||||
return exc.HTTPAccepted()
|
||||
except exception.CredentialNotFound as exp:
|
||||
return faults.Fault(faults.CredentialNotFound(exp))
|
||||
|
@ -21,13 +21,11 @@
|
||||
from webob import exc
|
||||
|
||||
from extensions import _novatenant_view as novatenant_view
|
||||
from quantum.common import exceptions as qexception
|
||||
#from extensions import _exceptions as exception
|
||||
from extensions import _faults as faults
|
||||
|
||||
from quantum.api import api_common as common
|
||||
from quantum.common import exceptions as qexception
|
||||
from quantum.common import extensions
|
||||
from quantum.manager import QuantumManager
|
||||
from quantum.plugins.cisco.common import cisco_faults as faults
|
||||
|
||||
|
||||
class Novatenant(object):
|
||||
@ -42,27 +40,27 @@ class Novatenant(object):
|
||||
|
||||
@classmethod
|
||||
def get_alias(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
""" Returns Ext Resource alias"""
|
||||
return "Cisco Nova Tenant"
|
||||
|
||||
@classmethod
|
||||
def get_description(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
""" Returns Ext Resource Description """
|
||||
return "novatenant resource is used by nova side to invoke quantum api"
|
||||
|
||||
@classmethod
|
||||
def get_namespace(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
""" Returns Ext Resource Namespace """
|
||||
return "http://docs.ciscocloud.com/api/ext/novatenant/v1.0"
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
""" Returns Ext Resource Updated Time """
|
||||
return "2011-08-09T13:25:27-06:00"
|
||||
|
||||
@classmethod
|
||||
def get_resources(cls):
|
||||
""" Returns Ext Resource Name """
|
||||
""" Returns Ext Resource """
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
member_actions = {'schedule_host': "PUT",
|
||||
@ -98,16 +96,8 @@ class NovatenantsController(common.QuantumController):
|
||||
def __init__(self, plugin):
|
||||
self._resource_name = 'novatenant'
|
||||
self._plugin = plugin
|
||||
#super(NovatenantsController, self).__init__(plugin)
|
||||
|
||||
def index(self, request, tenant_id):
|
||||
""" Returns a list of novatenant ids """
|
||||
return "novatenant is a dummy resource"
|
||||
|
||||
def _items(self, request, tenant_id, is_detail):
|
||||
""" Returns a list of novatenants. """
|
||||
return "novatenant is a dummy resource"
|
||||
|
||||
|
||||
#added for cisco's extension
|
||||
# pylint: disable-msg=E1101,W0613
|
||||
def show(self, request, tenant_id, id):
|
||||
""" Returns novatenant details for the given novatenant id """
|
||||
@ -144,7 +134,6 @@ class NovatenantsController(common.QuantumController):
|
||||
builder = novatenant_view.get_view_builder(request)
|
||||
result = builder.build_host(host)
|
||||
return result
|
||||
#return exc.HTTPAccepted()
|
||||
except qexception.PortNotFound as exp:
|
||||
return faults.Fault(faults.PortNotFound(exp))
|
||||
|
||||
|
@ -22,14 +22,12 @@
|
||||
from webob import exc
|
||||
|
||||
from extensions import _pprofiles as pprofiles_view
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as exception
|
||||
from quantum.common import exceptions as qexception
|
||||
#from extensions import _exceptions as exception
|
||||
from extensions import _faults as faults
|
||||
|
||||
from quantum.api import api_common as common
|
||||
from quantum.common import exceptions as qexception
|
||||
from quantum.common import extensions
|
||||
from quantum.manager import QuantumManager
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as exception
|
||||
from quantum.plugins.cisco.common import cisco_faults as faults
|
||||
|
||||
|
||||
class Portprofile(object):
|
||||
@ -59,7 +57,7 @@ class Portprofile(object):
|
||||
|
||||
@classmethod
|
||||
def get_updated(cls):
|
||||
""" Returns Ext Resource Updateed time """
|
||||
""" Returns Ext Resource Updated time """
|
||||
return "2011-07-23T13:25:27-06:00"
|
||||
|
||||
@classmethod
|
||||
@ -68,7 +66,7 @@ class Portprofile(object):
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
member_actions = {'associate_portprofile': "PUT",
|
||||
'disassociate_portprofile': "POST"}
|
||||
'disassociate_portprofile': "PUT"}
|
||||
controller = PortprofilesController(QuantumManager.get_plugin())
|
||||
return [extensions.ResourceExtension('portprofiles', controller,
|
||||
parent=parent_resource,
|
||||
@ -82,7 +80,6 @@ class PortprofilesController(common.QuantumController):
|
||||
def __init__(self, plugin):
|
||||
self._resource_name = 'portprofile'
|
||||
self._plugin = plugin
|
||||
#super(PortprofilesController, self).__init__(plugin)
|
||||
|
||||
self._portprofile_ops_param_list = [{
|
||||
'param-name': 'portprofile_name',
|
||||
@ -130,7 +127,6 @@ class PortprofilesController(common.QuantumController):
|
||||
return dict(portprofiles=result)
|
||||
except exception.PortProfileNotFound as exp:
|
||||
return faults.Fault(faults.PortprofileNotFound(exp))
|
||||
#return faults.Fault(exp)
|
||||
|
||||
def create(self, request, tenant_id):
|
||||
""" Creates a new portprofile for a given tenant """
|
||||
@ -188,7 +184,6 @@ class PortprofilesController(common.QuantumController):
|
||||
except exc.HTTPError as exp:
|
||||
return faults.Fault(exp)
|
||||
net_id = req_params['network-id'].strip()
|
||||
#print "*****net id "+net_id
|
||||
port_id = req_params['port-id'].strip()
|
||||
try:
|
||||
self._plugin.associate_portprofile(tenant_id,
|
||||
@ -212,7 +207,6 @@ class PortprofilesController(common.QuantumController):
|
||||
except exc.HTTPError as exp:
|
||||
return faults.Fault(exp)
|
||||
net_id = req_params['network-id'].strip()
|
||||
#print "*****net id "+net_id
|
||||
port_id = req_params['port-id'].strip()
|
||||
try:
|
||||
self._plugin. \
|
||||
|
@ -22,13 +22,12 @@ import logging
|
||||
|
||||
from webob import exc
|
||||
from extensions import _qos_view as qos_view
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as exception
|
||||
from extensions import _exceptions as exte
|
||||
from extensions import _faults as faults
|
||||
|
||||
from quantum.api import api_common as common
|
||||
from quantum.common import extensions
|
||||
from quantum.manager import QuantumManager
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as exception
|
||||
from quantum.plugins.cisco.common import cisco_faults as faults
|
||||
|
||||
|
||||
LOG = logging.getLogger('quantum.api.qoss')
|
||||
|
||||
@ -94,7 +93,6 @@ class QosController(common.QuantumController):
|
||||
def __init__(self, plugin):
|
||||
self._resource_name = 'qos'
|
||||
self._plugin = plugin
|
||||
#super(QosController, self).__init__(plugin)
|
||||
|
||||
def index(self, request, tenant_id):
|
||||
""" Returns a list of qos ids """
|
||||
|
@ -240,7 +240,7 @@ def api_plug_iface(client, *args):
|
||||
res = client.attach_resource(nid, pid, data)
|
||||
except Exception, e:
|
||||
LOG.error("Failed to plug iface \"%s\" to port \"%s\": %s" % (vid,
|
||||
pid, output))
|
||||
pid, e))
|
||||
return
|
||||
LOG.debug(res)
|
||||
print "Plugged interface \"%s\" to port:%s on network:%s" % (vid, pid, nid)
|
||||
@ -386,6 +386,6 @@ if __name__ == "__main__":
|
||||
commands[cmd]["api_func"](client, *args)
|
||||
else:
|
||||
quantum = QuantumManager()
|
||||
manager = quantum.get_manager()
|
||||
manager = quantum.get_plugin()
|
||||
commands[cmd]["func"](manager, *args)
|
||||
sys.exit(0)
|
||||
|
@ -20,16 +20,32 @@ import httplib
|
||||
import socket
|
||||
import urllib
|
||||
from quantum.common.wsgi import Serializer
|
||||
from quantum.common import exceptions
|
||||
|
||||
EXCEPTIONS = {
|
||||
400: exceptions.BadInputError,
|
||||
401: exceptions.NotAuthorized,
|
||||
420: exceptions.NetworkNotFound,
|
||||
421: exceptions.NetworkInUse,
|
||||
422: exceptions.NetworkNameExists,
|
||||
430: exceptions.PortNotFound,
|
||||
431: exceptions.StateInvalid,
|
||||
432: exceptions.PortInUse,
|
||||
440: exceptions.AlreadyAttached,
|
||||
441: exceptions.AttachmentNotReady,
|
||||
}
|
||||
|
||||
|
||||
class api_call(object):
|
||||
class ApiCall(object):
|
||||
"""A Decorator to add support for format and tenant overriding"""
|
||||
def __init__(self, f):
|
||||
self.f = f
|
||||
def __init__(self, function):
|
||||
self.function = function
|
||||
|
||||
def __get__(self, instance, owner):
|
||||
def with_params(*args, **kwargs):
|
||||
# Temporarily set format and tenant for this request
|
||||
"""
|
||||
Temporarily sets the format and tenant for this request
|
||||
"""
|
||||
(format, tenant) = (instance.format, instance.tenant)
|
||||
|
||||
if 'format' in kwargs:
|
||||
@ -37,7 +53,7 @@ class api_call(object):
|
||||
if 'tenant' in kwargs:
|
||||
instance.tenant = kwargs['tenant']
|
||||
|
||||
ret = self.f(instance, *args)
|
||||
ret = self.function(instance, *args)
|
||||
(instance.format, instance.tenant) = (format, tenant)
|
||||
return ret
|
||||
return with_params
|
||||
@ -47,9 +63,7 @@ class Client(object):
|
||||
|
||||
"""A base client class - derived from Glance.BaseClient"""
|
||||
|
||||
action_prefix = '/v0.1/tenants/{tenant_id}'
|
||||
|
||||
"""Action query strings"""
|
||||
# Action query strings
|
||||
networks_path = "/networks"
|
||||
network_path = "/networks/%s"
|
||||
ports_path = "/networks/%s/ports"
|
||||
@ -58,7 +72,7 @@ class Client(object):
|
||||
|
||||
def __init__(self, host="127.0.0.1", port=9696, use_ssl=False, tenant=None,
|
||||
format="xml", testingStub=None, key_file=None, cert_file=None,
|
||||
logger=None):
|
||||
logger=None, action_prefix="/v0.1/tenants/{tenant_id}"):
|
||||
"""
|
||||
Creates a new client to some service.
|
||||
|
||||
@ -81,6 +95,7 @@ class Client(object):
|
||||
self.key_file = key_file
|
||||
self.cert_file = cert_file
|
||||
self.logger = logger
|
||||
self.action_prefix = action_prefix
|
||||
|
||||
def get_connection_type(self):
|
||||
"""
|
||||
@ -114,7 +129,7 @@ class Client(object):
|
||||
|
||||
# Add format and tenant_id
|
||||
action += ".%s" % self.format
|
||||
action = Client.action_prefix + action
|
||||
action = self.action_prefix + action
|
||||
action = action.replace('{tenant_id}', self.tenant)
|
||||
|
||||
if type(params) is dict:
|
||||
@ -133,9 +148,9 @@ class Client(object):
|
||||
certs = dict((x, certs[x]) for x in certs if certs[x] != None)
|
||||
|
||||
if self.use_ssl and len(certs):
|
||||
c = connection_type(self.host, self.port, **certs)
|
||||
conn = connection_type(self.host, self.port, **certs)
|
||||
else:
|
||||
c = connection_type(self.host, self.port)
|
||||
conn = connection_type(self.host, self.port)
|
||||
|
||||
if self.logger:
|
||||
self.logger.debug("Quantum Client Request:\n" \
|
||||
@ -143,8 +158,8 @@ class Client(object):
|
||||
if body:
|
||||
self.logger.debug(body)
|
||||
|
||||
c.request(method, action, body, headers)
|
||||
res = c.getresponse()
|
||||
conn.request(method, action, body, headers)
|
||||
res = conn.getresponse()
|
||||
status_code = self.get_status_code(res)
|
||||
data = res.read()
|
||||
|
||||
@ -158,6 +173,8 @@ class Client(object):
|
||||
httplib.NO_CONTENT):
|
||||
return self.deserialize(data, status_code)
|
||||
else:
|
||||
if res.status in EXCEPTIONS:
|
||||
raise EXCEPTIONS[res.status]()
|
||||
raise Exception("Server returned error: %s" % res.read())
|
||||
|
||||
except (socket.error, IOError), e:
|
||||
@ -175,6 +192,10 @@ class Client(object):
|
||||
return response.status
|
||||
|
||||
def serialize(self, data):
|
||||
"""
|
||||
Serializes a dictionary with a single key (which can contain any
|
||||
structure) into either xml or json
|
||||
"""
|
||||
if data is None:
|
||||
return None
|
||||
elif type(data) is dict:
|
||||
@ -184,65 +205,72 @@ class Client(object):
|
||||
% type(data))
|
||||
|
||||
def deserialize(self, data, status_code):
|
||||
"""
|
||||
Deserializes a an xml or json string into a dictionary
|
||||
"""
|
||||
if status_code == 202:
|
||||
return data
|
||||
return Serializer().deserialize(data, self.content_type())
|
||||
|
||||
def content_type(self, format=None):
|
||||
"""
|
||||
Returns the mime-type for either 'xml' or 'json'. Defaults to the
|
||||
currently set format
|
||||
"""
|
||||
if not format:
|
||||
format = self.format
|
||||
return "application/%s" % (format)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def list_networks(self):
|
||||
"""
|
||||
Fetches a list of all networks for a tenant
|
||||
"""
|
||||
return self.do_request("GET", self.networks_path)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def show_network_details(self, network):
|
||||
"""
|
||||
Fetches the details of a certain network
|
||||
"""
|
||||
return self.do_request("GET", self.network_path % (network))
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def create_network(self, body=None):
|
||||
"""
|
||||
Creates a new network
|
||||
"""
|
||||
return self.do_request("POST", self.networks_path, body=body)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def update_network(self, network, body=None):
|
||||
"""
|
||||
Updates a network
|
||||
"""
|
||||
return self.do_request("PUT", self.network_path % (network), body=body)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def delete_network(self, network):
|
||||
"""
|
||||
Deletes the specified network
|
||||
"""
|
||||
return self.do_request("DELETE", self.network_path % (network))
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def list_ports(self, network):
|
||||
"""
|
||||
Fetches a list of ports on a given network
|
||||
"""
|
||||
return self.do_request("GET", self.ports_path % (network))
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def show_port_details(self, network, port):
|
||||
"""
|
||||
Fetches the details of a certain port
|
||||
"""
|
||||
return self.do_request("GET", self.port_path % (network, port))
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def create_port(self, network, body=None):
|
||||
"""
|
||||
Creates a new port on a given network
|
||||
@ -250,14 +278,14 @@ class Client(object):
|
||||
body = self.serialize(body)
|
||||
return self.do_request("POST", self.ports_path % (network), body=body)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def delete_port(self, network, port):
|
||||
"""
|
||||
Deletes the specified port from a network
|
||||
"""
|
||||
return self.do_request("DELETE", self.port_path % (network, port))
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def set_port_state(self, network, port, body=None):
|
||||
"""
|
||||
Sets the state of the specified port
|
||||
@ -265,14 +293,14 @@ class Client(object):
|
||||
return self.do_request("PUT",
|
||||
self.port_path % (network, port), body=body)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def show_port_attachment(self, network, port):
|
||||
"""
|
||||
Fetches the attachment-id associated with the specified port
|
||||
"""
|
||||
return self.do_request("GET", self.attachment_path % (network, port))
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def attach_resource(self, network, port, body=None):
|
||||
"""
|
||||
Sets the attachment-id of the specified port
|
||||
@ -280,7 +308,7 @@ class Client(object):
|
||||
return self.do_request("PUT",
|
||||
self.attachment_path % (network, port), body=body)
|
||||
|
||||
@api_call
|
||||
@ApiCall
|
||||
def detach_resource(self, network, port):
|
||||
"""
|
||||
Removes the attachment-id of the specified port
|
||||
|
@ -111,6 +111,10 @@ class AlreadyAttached(QuantumException):
|
||||
"already plugged into port %(att_port_id)s")
|
||||
|
||||
|
||||
class AttachmentNotReady(QuantumException):
|
||||
message = _("The attachment %(att_id)s is not ready")
|
||||
|
||||
|
||||
class NetworkNameExists(QuantumException):
|
||||
message = _("Unable to set network name to %(net_name). " \
|
||||
"Network with id %(net_id) already has this name for " \
|
||||
|
@ -226,9 +226,22 @@ class ExtensionMiddleware(wsgi.Middleware):
|
||||
for resource in self.ext_mgr.get_resources():
|
||||
LOG.debug(_('Extended resource: %s'),
|
||||
resource.collection)
|
||||
for action, method in resource.collection_actions.iteritems():
|
||||
path_prefix = ""
|
||||
parent = resource.parent
|
||||
conditions = dict(method=[method])
|
||||
path = "/%s/%s" % (resource.collection, action)
|
||||
if parent:
|
||||
path_prefix = "/%s/{%s_id}" % (parent["collection_name"],
|
||||
parent["member_name"])
|
||||
with mapper.submapper(controller=resource.controller,
|
||||
action=action,
|
||||
path_prefix=path_prefix,
|
||||
conditions=conditions) as submap:
|
||||
submap.connect(path)
|
||||
submap.connect("%s.:(format)" % path)
|
||||
mapper.resource(resource.collection, resource.collection,
|
||||
controller=resource.controller,
|
||||
collection=resource.collection_actions,
|
||||
member=resource.member_actions,
|
||||
parent_resource=resource.parent)
|
||||
|
||||
|
@ -134,7 +134,8 @@ nexus_ip_address=10.0.0.1
|
||||
# Use shortened interface syntax, e.g. "1/10" not "Ethernet1/10".
|
||||
nexus_first_port=1/10
|
||||
nexus_second_port=1/11
|
||||
#Port number where the SSH will be running at Nexus Switch, e.g.: 22 (Default)
|
||||
#Port number where SSH will be running on the Nexus switch. Typically this is 22
|
||||
#unless you've configured your switch otherwise.
|
||||
nexus_ssh_port=22
|
||||
|
||||
[DRIVER]
|
||||
@ -153,8 +154,15 @@ name=quantum.plugins.cisco.nexus.cisco_nexus_network_driver.CiscoNEXUSDriver
|
||||
|
||||
mysql -u<mysqlusername> -p<mysqlpassword> -e "create database quantum_l2network"
|
||||
|
||||
5b. Enter the quantum_l2netowrk database configuration info in the
|
||||
5b. Enter the quantum_l2network database configuration info in the
|
||||
quantum/plugins/cisco/conf/db_conn.ini file.
|
||||
|
||||
5c. If there is a change in the plugin configuration, service would need
|
||||
to be restarted after dropping and re-creating the database using
|
||||
the following commands -
|
||||
|
||||
mysql -u<mysqlusername> -p<mysqlpassword> -e "drop database quantum_l2network"
|
||||
mysql -u<mysqlusername> -p<mysqlpassword> -e "create database quantum_l2network"
|
||||
|
||||
6. Verify that you have the correct credentials for each IP address listed
|
||||
in quantum/plugins/cisco/conf/credentials.ini. Example:
|
||||
@ -229,7 +237,8 @@ result the quantum/plugins/cisco/run_tests.py script.
|
||||
Set the environment variable PLUGIN_DIR to the location of the plugin
|
||||
directory. This is manadatory if the run_tests.sh script is used.
|
||||
|
||||
export PLUGIN_DIR=quantum/plugins/cisco
|
||||
In bash : export PLUGIN_DIR=quantum/plugins/cisco
|
||||
tcsh/csh : setenv PLUGIN_DIR quantum/plugins/cisco
|
||||
./run_tests.sh quantum.plugins.cisco.tests.unit.test_l2networkApi
|
||||
|
||||
or
|
||||
@ -240,7 +249,8 @@ result the quantum/plugins/cisco/run_tests.py script.
|
||||
2. Specific Plugin unit test (needs environment setup as indicated in the
|
||||
pre-requisites):
|
||||
|
||||
export PLUGIN_DIR=quantum/plugins/cisco
|
||||
In bash : export PLUGIN_DIR=quantum/plugins/cisco
|
||||
tcsh/csh : setenv PLUGIN_DIR quantum/plugins/cisco
|
||||
./run_tests.sh quantum.plugins.cisco.tests.unit.<name_of_the file>
|
||||
|
||||
or
|
||||
@ -254,7 +264,9 @@ result the quantum/plugins/cisco/run_tests.py script.
|
||||
|
||||
3. All unit tests (needs environment setup as indicated in the pre-requisites):
|
||||
|
||||
export PLUGIN_DIR=quantum/plugins/cisco
|
||||
In bash : export PLUGIN_DIR=quantum/plugins/cisco
|
||||
tcsh/csh : setenv PLUGIN_DIR quantum/plugins/cisco
|
||||
|
||||
./run_tests.sh quantum.plugins.cisco.tests.unit
|
||||
|
||||
or
|
||||
@ -266,6 +278,13 @@ result the quantum/plugins/cisco/run_tests.py script.
|
||||
change later.
|
||||
Location quantum/plugins/cisco/tests/unit/test_cisco_extension.py
|
||||
|
||||
The script can be executed by :
|
||||
./run_tests.sh quantum.plugins.cisco.tests.unit.test_cisco_extension
|
||||
|
||||
or
|
||||
|
||||
python run_tests.py quantum.plugins.cisco.tests.unit.test_cisco_extension
|
||||
|
||||
Bingo bango bongo! That's it! Thanks for taking the leap into Quantum.
|
||||
|
||||
...Oh, boy!
|
||||
|
@ -22,8 +22,8 @@
|
||||
import logging as LOG
|
||||
import os
|
||||
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
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
|
||||
|
||||
|
@ -1,4 +1,3 @@
|
||||
"""
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
#
|
||||
# Copyright 2011 Cisco Systems, Inc. All rights reserved.
|
||||
@ -17,7 +16,7 @@
|
||||
#
|
||||
# @author: Sumit Naiksatam, Cisco Systems, Inc.
|
||||
# @author: Rohit Agarwalla, Cisco Systems, Inc.
|
||||
"""
|
||||
|
||||
"""
|
||||
Exceptions used by the Cisco plugin
|
||||
"""
|
||||
@ -86,18 +85,18 @@ class VlanIDNotFound(exceptions.QuantumException):
|
||||
|
||||
|
||||
class VlanIDNotAvailable(exceptions.QuantumException):
|
||||
"""VLAN ID is reserved"""
|
||||
message = _("No available Vlan ID found")
|
||||
"""No VLAN ID available"""
|
||||
message = _("No Vlan ID available")
|
||||
|
||||
|
||||
class QosNotFound(exceptions.QuantumException):
|
||||
"""QoS ID could not be found"""
|
||||
"""QoS level with this ID cannot be found"""
|
||||
message = _("QoS level %(qos_id)s could not be found " \
|
||||
"for tenant %(tenant_id)s")
|
||||
|
||||
|
||||
class QoSLevelInvalidDelete(exceptions.QuantumException):
|
||||
"""QoS ID could not be deleted"""
|
||||
"""QoS is associated with a port profile, hence cannot be deleted"""
|
||||
message = _("QoS level %(qos_id)s could not be deleted " \
|
||||
"for tenant %(tenant_id)s since association exists")
|
||||
|
||||
@ -109,7 +108,7 @@ class QosNameAlreadyExists(exceptions.QuantumException):
|
||||
|
||||
|
||||
class CredentialNotFound(exceptions.QuantumException):
|
||||
"""Credential ID could not be found"""
|
||||
"""Credential with this ID cannot be found"""
|
||||
message = _("Credential %(credential_id)s could not be found " \
|
||||
"for tenant %(tenant_id)s")
|
||||
|
||||
|
@ -20,7 +20,6 @@
|
||||
"""
|
||||
import webob.dec
|
||||
|
||||
from quantum.api import api_common as common
|
||||
from quantum.common import wsgi
|
||||
|
||||
|
||||
@ -30,12 +29,7 @@ class Fault(webob.exc.HTTPException):
|
||||
_fault_names = {
|
||||
400: "malformedRequest",
|
||||
401: "unauthorized",
|
||||
420: "networkNotFound",
|
||||
421: "PortprofileInUse",
|
||||
430: "portNotFound",
|
||||
431: "requestedStateInvalid",
|
||||
432: "portInUse",
|
||||
440: "alreadyAttached",
|
||||
450: "PortprofileNotFound",
|
||||
451: "CredentialNotFound",
|
||||
452: "QoSNotFound",
|
||||
@ -49,21 +43,19 @@ class Fault(webob.exc.HTTPException):
|
||||
|
||||
@webob.dec.wsgify(RequestClass=wsgi.Request)
|
||||
def __call__(self, req):
|
||||
"""Generate a WSGI response based on the exception passed to ctor."""
|
||||
"""Generate a WSGI response based on the
|
||||
exception passed to constructor."""
|
||||
# Replace the body with fault details.
|
||||
code = self.wrapped_exc.status_int
|
||||
fault_name = self._fault_names.get(code, "quantumServiceFault")
|
||||
fault_data = {
|
||||
fault_name: {
|
||||
'code': code,
|
||||
'message': self.wrapped_exc.explanation,
|
||||
'detail': self.wrapped_exc.detail}}
|
||||
'message': self.wrapped_exc.explanation}}
|
||||
# 'code' is an attribute on the fault tag itself
|
||||
metadata = {'application/xml': {'attributes': {fault_name: 'code'}}}
|
||||
default_xmlns = common.XML_NS_V10
|
||||
serializer = wsgi.Serializer(metadata, default_xmlns)
|
||||
content_type = req.best_match_content_type()
|
||||
#self.wrapped_exc.body = serializer.serialize(fault_data, content_type)
|
||||
self.wrapped_exc.body = wsgi.Serializer().\
|
||||
serialize(fault_data, content_type)
|
||||
self.wrapped_exc.content_type = content_type
|
||||
return self.wrapped_exc
|
||||
|
||||
@ -79,7 +71,7 @@ class PortprofileNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
code = 450
|
||||
title = 'Portprofile Not Found'
|
||||
explanation = ('Unable to find a Portprofile with'
|
||||
explanation = ('Unable to find a Portprofile with'
|
||||
+ ' the specified identifier.')
|
||||
|
||||
|
||||
@ -95,8 +87,8 @@ class PortNotFound(webob.exc.HTTPClientError):
|
||||
code = 430
|
||||
title = 'Port not Found'
|
||||
explanation = ('Unable to find a port with the specified identifier.')
|
||||
|
||||
|
||||
|
||||
|
||||
class CredentialNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
subclass of :class:`~HTTPClientError`
|
||||
@ -108,10 +100,10 @@ class CredentialNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
code = 451
|
||||
title = 'Credential Not Found'
|
||||
explanation = ('Unable to find a Credential with'
|
||||
explanation = ('Unable to find a Credential with'
|
||||
+ ' the specified identifier.')
|
||||
|
||||
|
||||
|
||||
|
||||
class QosNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
subclass of :class:`~HTTPClientError`
|
||||
@ -123,10 +115,10 @@ class QosNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
code = 452
|
||||
title = 'QoS Not Found'
|
||||
explanation = ('Unable to find a QoS with'
|
||||
explanation = ('Unable to find a QoS with'
|
||||
+ ' the specified identifier.')
|
||||
|
||||
|
||||
|
||||
|
||||
class NovatenantNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
subclass of :class:`~HTTPClientError`
|
||||
@ -138,7 +130,7 @@ class NovatenantNotFound(webob.exc.HTTPClientError):
|
||||
"""
|
||||
code = 453
|
||||
title = 'Nova tenant Not Found'
|
||||
explanation = ('Unable to find a Novatenant with'
|
||||
explanation = ('Unable to find a Novatenant with'
|
||||
+ ' the specified identifier.')
|
||||
|
||||
|
@ -12,7 +12,7 @@ bind_host = 0.0.0.0
|
||||
bind_port = 9696
|
||||
|
||||
# Path to the extensions
|
||||
api_extensions_path = ../extensions
|
||||
api_extensions_path = ../../../../extensions
|
||||
|
||||
[pipeline:extensions_app_with_filter]
|
||||
pipeline = extensions extensions_test_app
|
||||
@ -21,4 +21,4 @@ pipeline = extensions extensions_test_app
|
||||
paste.filter_factory = quantum.common.extensions:plugin_aware_extension_middleware_factory
|
||||
|
||||
[app:extensions_test_app]
|
||||
paste.app_factory = tests.unit.test_cisco_extension:app_factory
|
||||
paste.app_factory = quantum.plugins.cisco.tests.unit.test_cisco_extension:app_factory
|
||||
|
@ -20,8 +20,8 @@ from sqlalchemy.orm import exc
|
||||
from quantum.common import exceptions as q_exc
|
||||
from quantum.plugins.cisco import l2network_plugin_configuration as conf
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
|
||||
from quantum.plugins.cisco.db import l2network_models
|
||||
|
||||
import l2network_models
|
||||
import logging as LOG
|
||||
import quantum.plugins.cisco.db.api as db
|
||||
import quantum.plugins.cisco.db.nexus_db as ndb
|
||||
@ -117,17 +117,16 @@ def reserve_vlanid():
|
||||
LOG.debug("reserve_vlanid() called")
|
||||
session = db.get_session()
|
||||
try:
|
||||
vlanids = session.query(l2network_models.VlanID).\
|
||||
rvlan = session.query(l2network_models.VlanID).\
|
||||
filter_by(vlan_used=False).\
|
||||
all()
|
||||
rvlan = vlanids[0]
|
||||
first()
|
||||
rvlanid = session.query(l2network_models.VlanID).\
|
||||
filter_by(vlan_id=rvlan["vlan_id"]).\
|
||||
one()
|
||||
rvlanid["vlan_used"] = True
|
||||
session.merge(rvlanid)
|
||||
session.flush()
|
||||
return vlanids[0]["vlan_id"]
|
||||
return rvlan["vlan_id"]
|
||||
except exc.NoResultFound:
|
||||
raise c_exc.VlanIDNotAvailable()
|
||||
|
||||
|
@ -185,6 +185,6 @@ class Credential(BASE, L2NetworkBase):
|
||||
self.password = password
|
||||
|
||||
def __repr__(self):
|
||||
return "<Credentials(%s,%s,%s,%s)>" % \
|
||||
return "<Credentials(%s,%s,%s,%s,%s)>" % \
|
||||
(self.credential_id, self.tenant_id, self.credential_name,
|
||||
self.user_name, self.password)
|
||||
|
@ -20,9 +20,9 @@ import logging as LOG
|
||||
from sqlalchemy.orm import exc
|
||||
|
||||
import quantum.plugins.cisco.db.api as db
|
||||
import nexus_models
|
||||
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as c_exc
|
||||
from quantum.plugins.cisco.db import nexus_models
|
||||
|
||||
|
||||
def get_all_nexusport_bindings():
|
||||
|
@ -27,8 +27,6 @@ class NexusPortBinding(BASE, L2NetworkBase):
|
||||
|
||||
id = Column(Integer, primary_key=True, autoincrement=True)
|
||||
port_id = Column(String(255))
|
||||
#vlan_id = Column(Integer, ForeignKey("vlan_bindings.vlan_id"), \
|
||||
# nullable=False)
|
||||
vlan_id = Column(Integer, nullable=False)
|
||||
|
||||
def __init__(self, port_id, vlan_id):
|
||||
|
@ -26,10 +26,11 @@ import platform
|
||||
from quantum.common import exceptions as exc
|
||||
from quantum.common import utils
|
||||
from quantum.quantum_plugin_base import QuantumPluginBase
|
||||
|
||||
from quantum.plugins.cisco import l2network_plugin_configuration as conf
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as cexc
|
||||
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
|
||||
@ -441,7 +442,7 @@ class L2Network(QuantumPluginBase):
|
||||
return credential
|
||||
|
||||
def rename_credential(self, tenant_id, credential_id, new_name):
|
||||
"""Do nothing for this resource"""
|
||||
"""Rename the particular credential resource"""
|
||||
LOG.debug("rename_credential() called\n")
|
||||
try:
|
||||
credential = cdb.get_credential(tenant_id, credential_id)
|
||||
|
@ -29,6 +29,9 @@ CONF_PARSER_OBJ = confp.\
|
||||
CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
|
||||
"/" + CONF_FILE)
|
||||
|
||||
"""
|
||||
Reading the conf for the l2network_plugin
|
||||
"""
|
||||
SECTION_CONF = CONF_PARSER_OBJ['VLANS']
|
||||
VLAN_NAME_PREFIX = SECTION_CONF['vlan_name_prefix']
|
||||
VLAN_START = SECTION_CONF['vlan_start']
|
||||
@ -55,6 +58,9 @@ CONF_PARSER_OBJ = confp.\
|
||||
CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
|
||||
"/" + CONF_FILE)
|
||||
|
||||
"""
|
||||
Reading the config for the device plugins
|
||||
"""
|
||||
PLUGINS = CONF_PARSER_OBJ.walk(CONF_PARSER_OBJ.dummy)
|
||||
|
||||
CONF_FILE = "conf/db_conn.ini"
|
||||
@ -63,6 +69,9 @@ CONF_PARSER_OBJ = confp.\
|
||||
CiscoConfigParser(os.path.dirname(os.path.realpath(__file__)) + \
|
||||
"/" + CONF_FILE)
|
||||
|
||||
"""
|
||||
Reading DB config for the Quantum DB
|
||||
"""
|
||||
SECTION_CONF = CONF_PARSER_OBJ['DATABASE']
|
||||
DB_NAME = SECTION_CONF['name']
|
||||
DB_USER = SECTION_CONF['user']
|
||||
|
@ -49,12 +49,19 @@ class CiscoNEXUSDriver():
|
||||
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 = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
|
||||
confstr = self.create_xml_snippet(confstr)
|
||||
mgr.edit_config(target='running', config=confstr)
|
||||
|
||||
def disable_vlan(self, mgr, vlanid):
|
||||
@ -62,7 +69,7 @@ class CiscoNEXUSDriver():
|
||||
Delete a VLAN on Nexus Switch given the VLAN ID
|
||||
"""
|
||||
confstr = snipp.CMD_NO_VLAN_CONF_SNIPPET % vlanid
|
||||
confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
|
||||
confstr = self.create_xml_snippet(confstr)
|
||||
mgr.edit_config(target='running', config=confstr)
|
||||
|
||||
def enable_port_trunk(self, mgr, interface):
|
||||
@ -70,7 +77,7 @@ class CiscoNEXUSDriver():
|
||||
Enables trunk mode an interface on Nexus Switch
|
||||
"""
|
||||
confstr = snipp.CMD_PORT_TRUNK % (interface)
|
||||
confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
|
||||
confstr = self.create_xml_snippet(confstr)
|
||||
LOG.debug("NexusDriver: %s" % confstr)
|
||||
mgr.edit_config(target='running', config=confstr)
|
||||
|
||||
@ -79,7 +86,7 @@ class CiscoNEXUSDriver():
|
||||
Disables trunk mode an interface on Nexus Switch
|
||||
"""
|
||||
confstr = snipp.CMD_NO_SWITCHPORT % (interface)
|
||||
confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
|
||||
confstr = self.create_xml_snippet(confstr)
|
||||
LOG.debug("NexusDriver: %s" % confstr)
|
||||
mgr.edit_config(target='running', config=confstr)
|
||||
|
||||
@ -89,7 +96,7 @@ class CiscoNEXUSDriver():
|
||||
VLANID
|
||||
"""
|
||||
confstr = snipp.CMD_VLAN_INT_SNIPPET % (interface, vlanid)
|
||||
confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
|
||||
confstr = self.create_xml_snippet(confstr)
|
||||
LOG.debug("NexusDriver: %s" % confstr)
|
||||
mgr.edit_config(target='running', config=confstr)
|
||||
|
||||
@ -99,7 +106,7 @@ class CiscoNEXUSDriver():
|
||||
VLANID
|
||||
"""
|
||||
confstr = snipp.CMD_NO_VLAN_INT_SNIPPET % (interface, vlanid)
|
||||
confstr = snipp.EXEC_CONF_PREFIX + confstr + snipp.EXEC_CONF_POSTFIX
|
||||
confstr = self.create_xml_snippet(confstr)
|
||||
LOG.debug("NexusDriver: %s" % confstr)
|
||||
mgr.edit_config(target='running', config=confstr)
|
||||
|
||||
|
@ -29,14 +29,10 @@ LOG.getLogger(const.LOGGER_COMPONENT_NAME)
|
||||
|
||||
|
||||
# The following are standard strings, messages used to communicate with Nexus,
|
||||
EXEC_CONF_PREFIX = """
|
||||
EXEC_CONF_SNIPPET = """
|
||||
<config xmlns:xc="urn:ietf:params:xml:ns:netconf:base:1.0">
|
||||
<configure xmlns="http://www.cisco.com/nxos:1.0:vlan_mgr_cli">
|
||||
<__XML__MODE__exec_configure>
|
||||
"""
|
||||
|
||||
|
||||
EXEC_CONF_POSTFIX = """
|
||||
<__XML__MODE__exec_configure>%s
|
||||
</__XML__MODE__exec_configure>
|
||||
</configure>
|
||||
</config>
|
||||
@ -156,4 +152,5 @@ FILTER_SHOW_VLAN_BRIEF_SNIPPET = """
|
||||
<vlan>
|
||||
<brief/>
|
||||
</vlan>
|
||||
</show> """
|
||||
</show>
|
||||
"""
|
||||
|
0
quantum/plugins/cisco/nova/__init__.py
Normal file
0
quantum/plugins/cisco/nova/__init__.py
Normal file
96
quantum/plugins/cisco/nova/quantum_aware_scheduler.py
Normal file
96
quantum/plugins/cisco/nova/quantum_aware_scheduler.py
Normal file
@ -0,0 +1,96 @@
|
||||
# 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 nova import exception as excp
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova.scheduler import driver
|
||||
from quantum.client import Client
|
||||
from quantum.common.wsgi import Serializer
|
||||
|
||||
LOG = logging.getLogger('quantum.plugins.cisco.nova.quantum_aware_scheduler')
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('quantum_host', "127.0.0.1",
|
||||
'IP address of the quantum network service.')
|
||||
flags.DEFINE_integer('quantum_port', 9696,
|
||||
'Listening port for Quantum network service')
|
||||
|
||||
HOST = FLAGS.quantum_host
|
||||
PORT = FLAGS.quantum_port
|
||||
USE_SSL = False
|
||||
ACTION_PREFIX_EXT = '/v0.1'
|
||||
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
|
||||
'/extensions/csco/tenants/{tenant_id}'
|
||||
TENANT_ID = 'nova'
|
||||
CSCO_EXT_NAME = 'Cisco Nova Tenant'
|
||||
|
||||
|
||||
class QuantumScheduler(driver.Scheduler):
|
||||
"""
|
||||
Quantum network service dependent scheduler
|
||||
Obtains the hostname from Quantum using an extension API
|
||||
"""
|
||||
def __init__(self):
|
||||
# We have to send a dummy tenant name here since the client
|
||||
# needs some tenant name, but the tenant name will not be used
|
||||
# since the extensions URL does not require it
|
||||
client = Client(HOST, PORT, USE_SSL, format='json',
|
||||
action_prefix=ACTION_PREFIX_EXT, tenant="dummy")
|
||||
request_url = "/extensions"
|
||||
data = client.do_request('GET', request_url)
|
||||
LOG.debug("Obtained supported extensions from Quantum: %s" % data)
|
||||
for ext in data['extensions']:
|
||||
name = ext['name']
|
||||
if name == CSCO_EXT_NAME:
|
||||
LOG.debug("Quantum plugin supports required \"%s\" extension"
|
||||
"for the scheduler." % name)
|
||||
return
|
||||
LOG.error("Quantum plugin does not support required \"%s\" extension"
|
||||
" for the scheduler. Scheduler will quit." % CSCO_EXT_NAME)
|
||||
raise excp.ServiceUnavailable()
|
||||
|
||||
def schedule(self, context, topic, *args, **kwargs):
|
||||
"""Gets the host name from the Quantum service"""
|
||||
instance_id = kwargs['instance_id']
|
||||
user_id = \
|
||||
kwargs['request_spec']['instance_properties']['user_id']
|
||||
project_id = \
|
||||
kwargs['request_spec']['instance_properties']['project_id']
|
||||
|
||||
instance_data_dict = \
|
||||
{'novatenant': \
|
||||
{'instance_id': instance_id,
|
||||
'instance_desc': \
|
||||
{'user_id': user_id,
|
||||
'project_id': project_id}}}
|
||||
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
|
||||
action_prefix=ACTION_PREFIX_CSCO)
|
||||
request_url = "/novatenants/" + project_id + "/get_host"
|
||||
data = client.do_request('PUT', request_url, body=instance_data_dict)
|
||||
|
||||
hostname = data["host_list"]["host_1"]
|
||||
if not hostname:
|
||||
raise driver.NoValidHost(_("Scheduler was unable to locate a host"
|
||||
" for this request. Is the appropriate"
|
||||
" service running?"))
|
||||
|
||||
LOG.debug(_("Quantum service returned host: %s") % hostname)
|
||||
return hostname
|
112
quantum/plugins/cisco/nova/vifdirect.py
Normal file
112
quantum/plugins/cisco/nova/vifdirect.py
Normal file
@ -0,0 +1,112 @@
|
||||
# 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.
|
||||
#
|
||||
|
||||
"""VIF drivers for interface type direct."""
|
||||
|
||||
from nova import exception as excp
|
||||
from nova import flags
|
||||
from nova import log as logging
|
||||
from nova.network import linux_net
|
||||
from nova.virt.libvirt import netutils
|
||||
from nova import utils
|
||||
from nova.virt.vif import VIFDriver
|
||||
from quantum.client import Client
|
||||
from quantum.common.wsgi import Serializer
|
||||
|
||||
LOG = logging.getLogger('quantum.plugins.cisco.nova.vifdirect')
|
||||
|
||||
FLAGS = flags.FLAGS
|
||||
flags.DEFINE_string('quantum_host', "127.0.0.1",
|
||||
'IP address of the quantum network service.')
|
||||
flags.DEFINE_integer('quantum_port', 9696,
|
||||
'Listening port for Quantum network service')
|
||||
|
||||
HOST = FLAGS.quantum_host
|
||||
PORT = FLAGS.quantum_port
|
||||
USE_SSL = False
|
||||
TENANT_ID = 'nova'
|
||||
ACTION_PREFIX_EXT = '/v0.1'
|
||||
ACTION_PREFIX_CSCO = ACTION_PREFIX_EXT + \
|
||||
'/extensions/csco/tenants/{tenant_id}'
|
||||
TENANT_ID = 'nova'
|
||||
CSCO_EXT_NAME = 'Cisco Nova Tenant'
|
||||
|
||||
|
||||
class Libvirt802dot1QbhDriver(VIFDriver):
|
||||
"""VIF driver for Linux bridge."""
|
||||
def __init__(self):
|
||||
# We have to send a dummy tenant name here since the client
|
||||
# needs some tenant name, but the tenant name will not be used
|
||||
# since the extensions URL does not require it
|
||||
client = Client(HOST, PORT, USE_SSL, format='json',
|
||||
action_prefix=ACTION_PREFIX_EXT, tenant="dummy")
|
||||
request_url = "/extensions"
|
||||
data = client.do_request('GET', request_url)
|
||||
LOG.debug("Obtained supported extensions from Quantum: %s" % data)
|
||||
for ext in data['extensions']:
|
||||
name = ext['name']
|
||||
if name == CSCO_EXT_NAME:
|
||||
LOG.debug("Quantum plugin supports required \"%s\" extension"
|
||||
"for the VIF driver." % name)
|
||||
return
|
||||
LOG.error("Quantum plugin does not support required \"%s\" extension"
|
||||
" for the VIF driver. nova-compute will quit." \
|
||||
% CSCO_EXT_NAME)
|
||||
raise excp.ServiceUnavailable()
|
||||
|
||||
def _get_configurations(self, instance, network, mapping):
|
||||
"""Gets the device name and the profile name from Quantum"""
|
||||
|
||||
instance_id = instance['id']
|
||||
user_id = instance['user_id']
|
||||
project_id = instance['project_id']
|
||||
vif_id = mapping['vif_uuid']
|
||||
|
||||
instance_data_dict = \
|
||||
{'novatenant': \
|
||||
{'instance_id': instance_id,
|
||||
'instance_desc': \
|
||||
{'user_id': user_id,
|
||||
'project_id': project_id,
|
||||
'vif_id': vif_id}}}
|
||||
|
||||
client = Client(HOST, PORT, USE_SSL, format='json', tenant=TENANT_ID,
|
||||
action_prefix=ACTION_PREFIX_CSCO)
|
||||
request_url = "/novatenants/" + project_id + "/get_instance_port"
|
||||
data = client.do_request('PUT', request_url, body=instance_data_dict)
|
||||
|
||||
device = data['vif_desc']['device']
|
||||
portprofile = data['vif_desc']['portprofile']
|
||||
LOG.debug(_("Quantum provided the device: %s") % device)
|
||||
LOG.debug(_("Quantum provided the portprofile: %s") % portprofile)
|
||||
mac_id = mapping['mac'].replace(':', '')
|
||||
|
||||
result = {
|
||||
'id': mac_id,
|
||||
'mac_address': mapping['mac'],
|
||||
'device_name': device,
|
||||
'profile_name': portprofile,
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
def plug(self, instance, network, mapping):
|
||||
return self._get_configurations(instance, network, mapping)
|
||||
|
||||
def unplug(self, instance, network, mapping):
|
||||
pass
|
@ -17,12 +17,12 @@
|
||||
# @authors: Shweta Padubidri, Cisco Systems, Inc.
|
||||
# Peter Strunk , Cisco Systems, Inc.
|
||||
# Shubhangi Satras , Cisco Systems, Inc.
|
||||
import json
|
||||
import os.path
|
||||
import routes
|
||||
import unittest
|
||||
import logging
|
||||
import webob
|
||||
import json
|
||||
import os.path
|
||||
import routes
|
||||
from webtest import TestApp
|
||||
from extensions import credential
|
||||
from extensions import portprofile
|
||||
@ -41,9 +41,9 @@ from quantum.manager import QuantumManager
|
||||
from quantum.plugins.cisco import l2network_plugin
|
||||
|
||||
TEST_CONF_FILE = os.path.join(os.path.dirname(__file__), os.pardir,
|
||||
os.pardir, 'etc', 'quantum.conf.ciscoext')
|
||||
EXTENSIONS_PATH = os.path.join(os.path.dirname(__file__), os.pardir,
|
||||
os.pardir, "extensions")
|
||||
os.pardir, 'conf', 'quantum.conf.ciscoext')
|
||||
EXTENSIONS_PATH = os.path.join(os.path.dirname(__file__), os.pardir, os.pardir,
|
||||
os.pardir, os.pardir, os.pardir, "extensions")
|
||||
|
||||
LOG = logging.getLogger('quantum.plugins.cisco.tests.test_cisco_extensions')
|
||||
|
||||
@ -62,10 +62,13 @@ class ExtensionsTestApp(wsgi.Router):
|
||||
class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
""" Set up function """
|
||||
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
member_actions = {'associate_portprofile': "PUT",
|
||||
'disassociate_portprofile': "POST"}
|
||||
'disassociate_portprofile': "PUT"}
|
||||
controller = portprofile.PortprofilesController(
|
||||
QuantumManager.get_plugin())
|
||||
res_ext = extensions.ResourceExtension('portprofiles', controller,
|
||||
@ -89,6 +92,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_list_portprofile(self):
|
||||
|
||||
""" Test List Portprofile"""
|
||||
|
||||
LOG.debug("test_list_portprofile - START")
|
||||
req_body1 = json.dumps(self.test_port_profile)
|
||||
create_response1 = self.test_app.post(
|
||||
@ -121,6 +126,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_create_portprofile(self):
|
||||
|
||||
""" Test create Portprofile"""
|
||||
|
||||
LOG.debug("test_create_portprofile - START")
|
||||
req_body = json.dumps(self.test_port_profile)
|
||||
index_response = self.test_app.post(self.profile_path, req_body,
|
||||
@ -138,6 +145,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_create_portprofileBADRequest(self):
|
||||
|
||||
""" Test create Portprofile Bad Request"""
|
||||
|
||||
LOG.debug("test_create_portprofileBADRequest - START")
|
||||
index_response = self.test_app.post(self.profile_path, 'BAD_REQUEST',
|
||||
content_type=self.contenttype,
|
||||
@ -147,6 +156,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_show_portprofile(self):
|
||||
|
||||
""" Test show Portprofile """
|
||||
|
||||
LOG.debug("test_show_portprofile - START")
|
||||
req_body = json.dumps(self.test_port_profile)
|
||||
index_response = self.test_app.post(self.profile_path, req_body,
|
||||
@ -165,6 +176,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_show_portprofileDNE(self, portprofile_id='100'):
|
||||
|
||||
""" Test show Portprofile does not exist"""
|
||||
|
||||
LOG.debug("test_show_portprofileDNE - START")
|
||||
show_path_temp = self.portprofile_path + portprofile_id
|
||||
show_port_path = str(show_path_temp)
|
||||
@ -174,6 +187,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_update_portprofile(self):
|
||||
|
||||
""" Test update Portprofile"""
|
||||
|
||||
LOG.debug("test_update_portprofile - START")
|
||||
req_body = json.dumps(self.test_port_profile)
|
||||
index_response = self.test_app.post(
|
||||
@ -191,12 +206,14 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
rename_response = self.test_app.put(rename_path, rename_req_body)
|
||||
self.assertEqual(200, rename_response.status_int)
|
||||
|
||||
# Clean Up - Delete the Port Profile
|
||||
# Clean Up - Delete the Port Profile
|
||||
self.tear_down_profile(rename_path)
|
||||
LOG.debug("test_update_portprofile - END")
|
||||
|
||||
def test_update_portprofileBADRequest(self):
|
||||
|
||||
""" Test update Portprofile Bad Request"""
|
||||
|
||||
LOG.debug("test_update_portprofileBADRequest - START")
|
||||
req_body = json.dumps(self.test_port_profile)
|
||||
index_response = self.test_app.post(
|
||||
@ -217,6 +234,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_update_portprofileDNE(self, portprofile_id='100'):
|
||||
|
||||
""" Test update Portprofile does not exist"""
|
||||
|
||||
LOG.debug("test_update_portprofileiDNE - START")
|
||||
rename_port_profile = {'portprofile':
|
||||
{'portprofile_name': 'cisco_rename_portprofile',
|
||||
@ -231,6 +250,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_delete_portprofile(self):
|
||||
|
||||
""" Test delete Portprofile"""
|
||||
|
||||
LOG.debug("test_delete_portprofile - START")
|
||||
req_body = json.dumps(self.test_port_profile)
|
||||
index_response = self.test_app.post(
|
||||
@ -248,6 +269,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_delete_portprofileDNE(self, portprofile_id='100'):
|
||||
|
||||
""" Test delete Portprofile does not exist"""
|
||||
|
||||
LOG.debug("test_delete_portprofileDNE - START")
|
||||
delete_path_temp = self.portprofile_path + portprofile_id
|
||||
delete_path = str(delete_path_temp)
|
||||
@ -257,6 +280,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def create_request(self, path, body, content_type, method='GET'):
|
||||
|
||||
""" Test create request"""
|
||||
|
||||
LOG.debug("test_create_request - START")
|
||||
req = webob.Request.blank(path)
|
||||
req.method = method
|
||||
@ -268,6 +293,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def _create_network(self, name=None):
|
||||
|
||||
""" Test create network"""
|
||||
|
||||
LOG.debug("Creating network - START")
|
||||
if name:
|
||||
net_name = name
|
||||
@ -286,6 +313,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def _create_port(self, network_id, port_state):
|
||||
|
||||
""" Test create port"""
|
||||
|
||||
LOG.debug("Creating port for network %s - START", network_id)
|
||||
port_path = "/tenants/tt/networks/%s/ports" % network_id
|
||||
port_req_data = {'port': {'port-state': '%s' % port_state}}
|
||||
@ -301,6 +330,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_associate_portprofile(self):
|
||||
|
||||
""" Test associate portprofile"""
|
||||
|
||||
LOG.debug("test_associate_portprofile - START")
|
||||
net_id = self._create_network()
|
||||
port_id = self._create_port(net_id, "ACTIVE")
|
||||
@ -336,6 +367,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_associate_portprofileDNE(self, portprofile_id='100'):
|
||||
|
||||
""" Test associate portprofile does not exist"""
|
||||
|
||||
LOG.debug("test_associate_portprofileDNE - START")
|
||||
test_port_assign_data = {'portprofile': {'network-id': '001',
|
||||
'port-id': '1'}}
|
||||
@ -350,6 +383,8 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_disassociate_portprofile(self):
|
||||
|
||||
""" Test disassociate portprofile"""
|
||||
|
||||
LOG.debug("test_disassociate_portprofile - START")
|
||||
net_id = self._create_network()
|
||||
port_id = self._create_port(net_id, "ACTIVE")
|
||||
@ -375,7 +410,7 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
"/disassociate_portprofile"
|
||||
|
||||
disassociate_path = str(disassociate_path_temp)
|
||||
disassociate_response = self.test_app.post(
|
||||
disassociate_response = self.test_app.put(
|
||||
disassociate_path, req_assign_body,
|
||||
content_type=self.contenttype)
|
||||
self.assertEqual(202, disassociate_response.status_int)
|
||||
@ -388,21 +423,33 @@ class PortprofileExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_disassociate_portprofile - END")
|
||||
|
||||
def tear_down_profile(self, delete_profile_path):
|
||||
|
||||
""" Tear down profile"""
|
||||
|
||||
self.test_app.delete(delete_profile_path)
|
||||
|
||||
def tear_down_associate_profile(self, delete_profile_path,
|
||||
dissociate_profile_path, req_body):
|
||||
self.test_app.post(dissociate_profile_path, req_body,
|
||||
|
||||
""" Tear down associate profile"""
|
||||
|
||||
self.test_app.put(dissociate_profile_path, req_body,
|
||||
content_type=self.contenttype)
|
||||
self.tear_down_profile(delete_profile_path)
|
||||
|
||||
def tearDown(self):
|
||||
|
||||
""" Tear down """
|
||||
|
||||
db.clear_db()
|
||||
|
||||
|
||||
class NovatenantExtensionTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
""" Set up function"""
|
||||
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
member_actions = {'schedule_host': "PUT",
|
||||
@ -416,44 +463,49 @@ class NovatenantExtensionTest(unittest.TestCase):
|
||||
SimpleExtensionManager(res_ext))
|
||||
self.contenttype = 'application/json'
|
||||
self.novatenants_path = '/extensions/csco/tenants/tt/novatenants/'
|
||||
self.test_instance_data = {'novatenant': {'instance_id': 1,
|
||||
self.test_associate_data = {'novatenant': {'instance_id': 1,
|
||||
'instance_desc': {'key1': '1',
|
||||
'key2': '2'}}}
|
||||
|
||||
def test_schedule_host(self):
|
||||
""" Test get host"""
|
||||
LOG.debug("test_schedule_host - START")
|
||||
req_body = json.dumps(self.test_instance_data)
|
||||
req_body = json.dumps(self.test_associate_data)
|
||||
host_path = self.novatenants_path + "001/schedule_host"
|
||||
host_response = self.test_app.put(
|
||||
host_path, req_body,
|
||||
content_type=self.contenttype)
|
||||
host_path, req_body,
|
||||
content_type=self.contenttype)
|
||||
self.assertEqual(200, host_response.status_int)
|
||||
LOG.debug("test_schedule_host - END")
|
||||
|
||||
def test_schedule_hostBADRequest(self):
|
||||
""" Test get host bad request"""
|
||||
LOG.debug("test_schedule_hostBADRequest - START")
|
||||
host_path = self.novatenants_path + "001/schedule_host"
|
||||
host_response = self.test_app.put(
|
||||
host_path, 'BAD_REQUEST',
|
||||
content_type=self.contenttype, status='*')
|
||||
host_path, 'BAD_REQUEST',
|
||||
content_type=self.contenttype, status='*')
|
||||
self.assertEqual(400, host_response.status_int)
|
||||
LOG.debug("test_schedule_hostBADRequest - END")
|
||||
|
||||
def test_instance_port(self):
|
||||
LOG.debug("test_instance_port - START")
|
||||
req_body = json.dumps(self.test_instance_data)
|
||||
instance_port_path = self.novatenants_path + "001/associate_port"
|
||||
instance_port_response = self.test_app.put(
|
||||
instance_port_path, req_body,
|
||||
def test_associate_port(self):
|
||||
""" Test get associate port """
|
||||
LOG.debug("test_associate_port - START")
|
||||
req_body = json.dumps(self.test_associate_data)
|
||||
associate_port_path = self.novatenants_path + "001/associate_port"
|
||||
associate_port_response = self.test_app.put(
|
||||
associate_port_path, req_body,
|
||||
content_type=self.contenttype)
|
||||
self.assertEqual(200, instance_port_response.status_int)
|
||||
LOG.debug("test_instance_port - END")
|
||||
self.assertEqual(200, associate_port_response.status_int)
|
||||
LOG.debug("test_associate_port - END")
|
||||
|
||||
|
||||
class QosExtensionTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
""" Set up function """
|
||||
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
controller = qos.QosController(QuantumManager.get_plugin())
|
||||
@ -470,6 +522,8 @@ class QosExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_create_qos(self):
|
||||
|
||||
""" Test create qos """
|
||||
|
||||
LOG.debug("test_create_qos - START")
|
||||
req_body = json.dumps(self.test_qos_data)
|
||||
index_response = self.test_app.post(self.qos_path,
|
||||
@ -488,6 +542,8 @@ class QosExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_create_qosBADRequest(self):
|
||||
|
||||
""" Test create qos bad request """
|
||||
|
||||
LOG.debug("test_create_qosBADRequest - START")
|
||||
index_response = self.test_app.post(self.qos_path,
|
||||
'BAD_REQUEST',
|
||||
@ -497,6 +553,9 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_create_qosBADRequest - END")
|
||||
|
||||
def test_list_qoss(self):
|
||||
|
||||
""" Test list qoss """
|
||||
|
||||
LOG.debug("test_list_qoss - START")
|
||||
req_body1 = json.dumps(self.test_qos_data)
|
||||
create_resp1 = self.test_app.post(self.qos_path, req_body1,
|
||||
@ -524,6 +583,9 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_list_qoss - END")
|
||||
|
||||
def test_show_qos(self):
|
||||
|
||||
""" Test show qos """
|
||||
|
||||
LOG.debug("test_show_qos - START")
|
||||
req_body = json.dumps(self.test_qos_data)
|
||||
index_response = self.test_app.post(self.qos_path, req_body,
|
||||
@ -541,6 +603,9 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_show_qos - END")
|
||||
|
||||
def test_show_qosDNE(self, qos_id='100'):
|
||||
|
||||
""" Test show qos does not exist"""
|
||||
|
||||
LOG.debug("test_show_qosDNE - START")
|
||||
show_path_temp = self.qos_second_path + qos_id
|
||||
show_qos_path = str(show_path_temp)
|
||||
@ -550,6 +615,8 @@ class QosExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_update_qos(self):
|
||||
|
||||
""" Test update qos """
|
||||
|
||||
LOG.debug("test_update_qos - START")
|
||||
req_body = json.dumps(self.test_qos_data)
|
||||
index_response = self.test_app.post(self.qos_path, req_body,
|
||||
@ -567,6 +634,9 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_update_qos - END")
|
||||
|
||||
def test_update_qosDNE(self, qos_id='100'):
|
||||
|
||||
""" Test update qos does not exist """
|
||||
|
||||
LOG.debug("test_update_qosDNE - START")
|
||||
rename_req_body = json.dumps({'qos': {'qos_name': 'cisco_rename_qos',
|
||||
'qos_desc': {'PPS': 50, 'TTL': 5}}})
|
||||
@ -578,6 +648,9 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_update_qosDNE - END")
|
||||
|
||||
def test_update_qosBADRequest(self):
|
||||
|
||||
""" Test update qos bad request """
|
||||
|
||||
LOG.debug("test_update_qosBADRequest - START")
|
||||
req_body = json.dumps(self.test_qos_data)
|
||||
index_response = self.test_app.post(self.qos_path, req_body,
|
||||
@ -597,6 +670,8 @@ class QosExtensionTest(unittest.TestCase):
|
||||
|
||||
def test_delete_qos(self):
|
||||
|
||||
""" Test delte qos """
|
||||
|
||||
LOG.debug("test_delete_qos - START")
|
||||
req_body = json.dumps({'qos': {'qos_name': 'cisco_test_qos',
|
||||
'qos_desc': {'PPS': 50, 'TTL': 5}}})
|
||||
@ -612,6 +687,9 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_delete_qos - END")
|
||||
|
||||
def test_delete_qosDNE(self, qos_id='100'):
|
||||
|
||||
""" Test delte qos does not exist"""
|
||||
|
||||
LOG.debug("test_delete_qosDNE - START")
|
||||
delete_path_temp = self.qos_second_path + qos_id
|
||||
delete_path = str(delete_path_temp)
|
||||
@ -620,12 +698,18 @@ class QosExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_delete_qosDNE - END")
|
||||
|
||||
def tearDownQos(self, delete_profile_path):
|
||||
|
||||
""" Tear Down Qos """
|
||||
|
||||
self.test_app.delete(delete_profile_path)
|
||||
|
||||
|
||||
class CredentialExtensionTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
|
||||
""" Set up function """
|
||||
|
||||
parent_resource = dict(member_name="tenant",
|
||||
collection_name="extensions/csco/tenants")
|
||||
controller = credential.CredentialController(
|
||||
@ -643,6 +727,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
'password': 'newPasswd1'}}
|
||||
|
||||
def test_list_credentials(self):
|
||||
|
||||
""" Test list credentials """
|
||||
|
||||
#Create Credential before listing
|
||||
LOG.debug("test_list_credentials - START")
|
||||
req_body1 = json.dumps(self.test_credential_data)
|
||||
@ -675,6 +762,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_list_credentials - END")
|
||||
|
||||
def test_create_credential(self):
|
||||
|
||||
""" Test create credential """
|
||||
|
||||
LOG.debug("test_create_credential - START")
|
||||
req_body = json.dumps(self.test_credential_data)
|
||||
index_response = self.test_app.post(
|
||||
@ -691,6 +781,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_create_credential - END")
|
||||
|
||||
def test_create_credentialBADRequest(self):
|
||||
|
||||
""" Test create credential bad request """
|
||||
|
||||
LOG.debug("test_create_credentialBADRequest - START")
|
||||
index_response = self.test_app.post(
|
||||
self.credential_path, 'BAD_REQUEST',
|
||||
@ -699,6 +792,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_create_credentialBADRequest - END")
|
||||
|
||||
def test_show_credential(self):
|
||||
|
||||
""" Test show credential """
|
||||
|
||||
LOG.debug("test_show_credential - START")
|
||||
req_body = json.dumps(self.test_credential_data)
|
||||
index_response = self.test_app.post(
|
||||
@ -714,6 +810,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_show_credential - END")
|
||||
|
||||
def test_show_credentialDNE(self, credential_id='100'):
|
||||
|
||||
""" Test show credential does not exist """
|
||||
|
||||
LOG.debug("test_show_credentialDNE - START")
|
||||
show_path_temp = self.cred_second_path + credential_id
|
||||
show_cred_path = str(show_path_temp)
|
||||
@ -722,6 +821,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_show_credentialDNE - END")
|
||||
|
||||
def test_update_credential(self):
|
||||
|
||||
""" Test update credential """
|
||||
|
||||
LOG.debug("test_update_credential - START")
|
||||
req_body = json.dumps(self.test_credential_data)
|
||||
|
||||
@ -744,6 +846,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_update_credential - END")
|
||||
|
||||
def test_update_credBADReq(self):
|
||||
|
||||
""" Test update credential bad request """
|
||||
|
||||
LOG.debug("test_update_credBADReq - START")
|
||||
req_body = json.dumps(self.test_credential_data)
|
||||
index_response = self.test_app.post(
|
||||
@ -760,6 +865,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_update_credBADReq - END")
|
||||
|
||||
def test_update_credentialDNE(self, credential_id='100'):
|
||||
|
||||
""" Test update credential does not exist"""
|
||||
|
||||
LOG.debug("test_update_credentialDNE - START")
|
||||
rename_req_body = json.dumps({'credential':
|
||||
{'credential_name': 'cred3',
|
||||
@ -773,6 +881,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_update_credentialDNE - END")
|
||||
|
||||
def test_delete_credential(self):
|
||||
|
||||
""" Test delete credential """
|
||||
|
||||
LOG.debug("test_delete_credential - START")
|
||||
req_body = json.dumps(self.test_credential_data)
|
||||
index_response = self.test_app.post(
|
||||
@ -788,6 +899,9 @@ class CredentialExtensionTest(unittest.TestCase):
|
||||
LOG.debug("test_delete_credential - END")
|
||||
|
||||
def test_delete_credentialDNE(self, credential_id='100'):
|
||||
|
||||
""" Test delete credential does not exist """
|
||||
|
||||
LOG.debug("test_delete_credentialDNE - START")
|
||||
delete_path_temp = self.cred_second_path + credential_id
|
||||
delete_path = str(delete_path_temp)
|
||||
|
@ -19,13 +19,11 @@
|
||||
|
||||
import logging
|
||||
import unittest
|
||||
#import time
|
||||
from quantum.common import exceptions as exc
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as cexc
|
||||
from quantum.plugins.cisco import l2network_plugin
|
||||
from quantum.plugins.cisco import l2network_plugin_configuration as conf
|
||||
#from quantum.plugins.cisco.common import cisco_utils as utils
|
||||
from quantum.plugins.cisco.db import api as db
|
||||
from quantum.plugins.cisco.db import l2network_db as cdb
|
||||
|
||||
@ -72,7 +70,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
tenant_id, new_net_dict[const.NET_ID])
|
||||
self.assertRaises(exc.NetworkNotFound, db.network_get,
|
||||
new_net_dict[const.NET_ID])
|
||||
#self.assertEqual(net, None)
|
||||
self.assertEqual(
|
||||
new_net_dict[const.NET_ID], delete_net_dict[const.NET_ID])
|
||||
LOG.debug("test_delete_network - END")
|
||||
@ -303,11 +300,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
port_dict[const.PORT_ID])
|
||||
self.assertRaises(exc.PortNotFound, db.port_get,
|
||||
new_net_dict[const.NET_ID], port_dict[const.PORT_ID])
|
||||
#self.assertEqual(port, None)
|
||||
# self.assertEqual(delete_port_dict[const.PORT_STATE], port_state)
|
||||
# self.assertEqual(delete_port_dict[const.NET_ID], new_net_dict[NET_ID])
|
||||
# self.assertEqual(delete_port_dict[const.PORT_ID],
|
||||
# new_net_dict[PORT_ID])
|
||||
self.tearDownNetwork(tenant_id, new_net_dict[const.NET_ID])
|
||||
self.assertEqual(delete_port_dict[const.PORT_ID],
|
||||
port_dict[const.PORT_ID])
|
||||
@ -470,10 +462,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
port_dict[const.PORT_ID], remote_interface)
|
||||
port = db.port_get(new_net_dict[const.NET_ID],
|
||||
port_dict[const.PORT_ID])
|
||||
# self.assertEqual(
|
||||
# self._l2network_plugin._networks[new_net_dict[const.NET_ID]]
|
||||
# [const.NET_PORTS][port_dict[const.PORT_ID]]
|
||||
# [const.ATTACHMENT], remote_interface)
|
||||
self.assertEqual(port[const.INTERFACEID], remote_interface)
|
||||
self.tearDownNetworkPortInterface(
|
||||
tenant_id, new_net_dict[const.NET_ID],
|
||||
@ -553,9 +541,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
port_dict[const.PORT_ID])
|
||||
port = db.port_get(new_net_dict[const.NET_ID],
|
||||
port_dict[const.PORT_ID])
|
||||
# self.assertEqual(self._l2network_plugin._networks
|
||||
# [new_net_dict[const.NET_ID]][const.NET_PORTS]
|
||||
# [port_dict[const.PORT_ID]][const.ATTACHMENT], None)
|
||||
self.assertEqual(port[const.INTERFACEID], None)
|
||||
self.tearDownNetworkPort(tenant_id, new_net_dict[const.NET_ID],
|
||||
port_dict[const.PORT_ID])
|
||||
@ -616,12 +601,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
port_profile = cdb.get_portprofile(tenant_id, port_profile_id)
|
||||
self.assertEqual(port_profile[const.PPNAME], profile_name)
|
||||
self.assertEqual(port_profile[const.PPQOS], qos)
|
||||
# self.assertEqual(
|
||||
# self._l2network_plugin._portprofiles[port_profile_id]['vlan-id'],
|
||||
# vlan_id)
|
||||
#self.assertEqual(
|
||||
# self._l2network_plugin._portprofiles[port_profile_id]
|
||||
# ['profile-name'], profile_name)
|
||||
self.tearDownPortProfile(tenant_id, port_profile_id)
|
||||
LOG.debug("test_create_portprofile - tenant id: %s - END",
|
||||
net_tenant_id)
|
||||
@ -641,10 +620,7 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
tenant_id, self.profile_name, self.qos)
|
||||
port_profile_id = port_profile_dict['profile_id']
|
||||
self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)
|
||||
# port_profile = cdb.get_portprofile(tenant_id, port_profile_id)
|
||||
self.assertRaises(Exception, cdb.get_portprofile, port_profile_id)
|
||||
# self.assertEqual(port_profile, {})
|
||||
# self.assertEqual(self._l2network_plugin._portprofiles, {})
|
||||
LOG.debug("test_delete_portprofile - tenant id: %s - END",
|
||||
net_tenant_id)
|
||||
|
||||
@ -714,14 +690,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
new_pplist.append(new_pp)
|
||||
self.assertTrue(new_pplist[0] in port_profile_list)
|
||||
self.assertTrue(new_pplist[1] in port_profile_list)
|
||||
# self.assertEqual(self._l2network_plugin._portprofiles
|
||||
# [port_profile_id1]['vlan-id'], self.vlan_id)
|
||||
# self.assertEqual(self._l2network_plugin._portprofiles
|
||||
# [port_profile_id1]['profile-name'], self.profile_name)
|
||||
# self.assertEqual(self._l2network_plugin._portprofiles
|
||||
# [port_profile_id2]['vlan-id'], vlan_id2)
|
||||
# self.assertEqual(self._l2network_plugin._portprofiles
|
||||
# [port_profile_id2]['profile-name'], profile_name2)
|
||||
self.tearDownPortProfile(tenant_id, port_profile_id1)
|
||||
self.tearDownPortProfile(tenant_id, port_profile_id2)
|
||||
|
||||
@ -816,9 +784,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
port_profile_associate = cdb.get_pp_binding(tenant_id, port_profile_id)
|
||||
self.assertEqual(port_profile_associate[const.PORTID],
|
||||
port_dict[const.PORT_ID])
|
||||
#self.assertEqual(
|
||||
# self._l2network_plugin._portprofiles[port_profile_id]
|
||||
# [const.PROFILE_ASSOCIATIONS][0], port_id)
|
||||
self.tearDownAssociatePortProfile(
|
||||
tenant_id, new_net_dict[const.NET_ID],
|
||||
port_dict[const.PORT_ID], port_profile_id)
|
||||
@ -863,8 +828,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
port_dict[const.PORT_ID], port_profile_id)
|
||||
port_profile_associate = cdb.get_pp_binding(tenant_id, port_profile_id)
|
||||
self.assertEqual(port_profile_associate, [])
|
||||
# self.assertEqual(self._l2network_plugin._portprofiles
|
||||
# [port_profile_id][const.PROFILE_ASSOCIATIONS], [])
|
||||
self.tearDownPortProfile(tenant_id, port_profile_id)
|
||||
self.tearDownNetworkPort(
|
||||
tenant_id, new_net_dict[const.NET_ID],
|
||||
@ -883,7 +846,6 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
tenant_id, net_id, port_id, profile_id)
|
||||
LOG.debug("test_disassociate_portprofileDNE - END")
|
||||
|
||||
# def test_disassociate_portprofile_Unassociated
|
||||
def test_get_vlan_name(self, net_tenant_id=None, vlan_id="NewVlan",
|
||||
vlan_prefix=conf.VLAN_NAME_PREFIX):
|
||||
"""
|
||||
@ -923,22 +885,17 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
LOG.debug("test_validate_port_state - END")
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up function
|
||||
"""
|
||||
self.tenant_id = "test_tenant"
|
||||
self.network_name = "test_network"
|
||||
self.profile_name = "test_tenant_port_profile"
|
||||
# self.vlan_id = "test_tenant_vlanid300"
|
||||
self.qos = "test_qos"
|
||||
self.port_state = const.PORT_UP
|
||||
self.net_id = '00005'
|
||||
self.port_id = 'p0005'
|
||||
self.remote_interface = 'new_interface'
|
||||
#sql_query = "drop database quantum_l2network"
|
||||
#sql_query_2 = "create database quantum_l2network"
|
||||
#self._utils = utils.DBUtils()
|
||||
#self._utils.execute_db_query(sql_query)
|
||||
#time.sleep(10)
|
||||
#self._utils.execute_db_query(sql_query_2)
|
||||
#time.sleep(10)
|
||||
self._l2network_plugin = l2network_plugin.L2Network()
|
||||
|
||||
"""
|
||||
@ -950,29 +907,50 @@ class CoreAPITestFunc(unittest.TestCase):
|
||||
db.clear_db()
|
||||
|
||||
def tearDownNetwork(self, tenant_id, network_dict_id):
|
||||
"""
|
||||
Tear down the Network
|
||||
"""
|
||||
self._l2network_plugin.delete_network(tenant_id, network_dict_id)
|
||||
|
||||
def tearDownPortOnly(self, tenant_id, network_dict_id, port_id):
|
||||
"""
|
||||
Tear doen the port
|
||||
"""
|
||||
self._l2network_plugin.delete_port(tenant_id, network_dict_id, port_id)
|
||||
|
||||
def tearDownNetworkPort(self, tenant_id, network_dict_id, port_id):
|
||||
"""
|
||||
Tear down Network Port
|
||||
"""
|
||||
self._l2network_plugin.delete_port(tenant_id, network_dict_id, port_id)
|
||||
self.tearDownNetwork(tenant_id, network_dict_id)
|
||||
|
||||
def tearDownNetworkPortInterface(self, tenant_id, network_dict_id,
|
||||
port_id):
|
||||
"""
|
||||
Tear down Network Port Interface
|
||||
"""
|
||||
self._l2network_plugin.unplug_interface(tenant_id,
|
||||
network_dict_id, port_id)
|
||||
self.tearDownNetworkPort(tenant_id, network_dict_id, port_id)
|
||||
|
||||
def tearDownPortProfile(self, tenant_id, port_profile_id):
|
||||
"""
|
||||
Tear down Port Profile
|
||||
"""
|
||||
self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)
|
||||
|
||||
def tearDownPortProfileBinding(self, tenant_id, port_profile_id):
|
||||
"""
|
||||
Tear down port profile binding
|
||||
"""
|
||||
self._l2network_plugin.delete_portprofile(tenant_id, port_profile_id)
|
||||
|
||||
def tearDownAssociatePortProfile(self, tenant_id, net_id, port_id,
|
||||
port_profile_id):
|
||||
"""
|
||||
Tear down associate port profile
|
||||
"""
|
||||
self._l2network_plugin.disassociate_portprofile(
|
||||
tenant_id, net_id, port_id, port_profile_id)
|
||||
self.tearDownPortProfile(tenant_id, port_profile_id)
|
||||
|
@ -28,6 +28,9 @@ 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"
|
||||
@ -281,18 +284,3 @@ class TestNexusPlugin(unittest.TestCase):
|
||||
Clean up functions after the tests
|
||||
"""
|
||||
self._cisco_nexus_plugin.delete_network(tenant_id, network_dict_id)
|
||||
|
||||
# def test_create_network(self):
|
||||
# _test_create_network(self._cisco_nexus_plugin)
|
||||
|
||||
# def test_delete_network(self):
|
||||
# _test_delete_network(self._cisco_nexus_plugin)
|
||||
|
||||
# def test_rename_network(self):
|
||||
# _test_rename_network(self._cisco_nexus_plugin)
|
||||
|
||||
# def test_show_network(self):
|
||||
# _test_get_network_details(self._cisco_nexus_plugin)
|
||||
|
||||
# def test_list_networks(self):
|
||||
# _test_list_all_networks(self._cisco_nexus_plugin)
|
||||
|
@ -73,6 +73,7 @@ ASSOCIATE_PROFILE_OUTPUT = "<configConfMos cookie=\"cookie_placeholder\" "\
|
||||
class TestUCSDriver(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
""" Set up function"""
|
||||
self.ucsm_driver = cisco_ucs_network_driver.CiscoUCSMDriver()
|
||||
self.vlan_name = 'New Vlan'
|
||||
self.vlan_id = '200'
|
||||
@ -136,8 +137,6 @@ class TestUCSDriver(unittest.TestCase):
|
||||
"""
|
||||
|
||||
LOG.debug("test_create_profile_post_data - START")
|
||||
#profile_details = self.ucsm_driver._create_profile_post_data(
|
||||
# self.profile_name, self.vlan_name)
|
||||
self.ucsm_driver._create_profile_post_data(
|
||||
self.profile_name, self.vlan_name)
|
||||
profile_delete_details = self.ucsm_driver._delete_profile_post_data(
|
||||
|
@ -29,6 +29,9 @@ LOG.getLogger("cisco_plugin")
|
||||
class UCSVICTestPlugin(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
"""
|
||||
Set up function.
|
||||
"""
|
||||
|
||||
self.tenant_id = "test_tenant_cisco12"
|
||||
self.net_name = "test_network_cisco12"
|
||||
@ -141,6 +144,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetwork(self.tenant_id, self.net_id)
|
||||
|
||||
def test_rename_network(self):
|
||||
"""
|
||||
Tests rename network.
|
||||
"""
|
||||
self._test_rename_network("new_test_network1")
|
||||
|
||||
def _test_create_port(self, port_state):
|
||||
@ -166,6 +172,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)
|
||||
|
||||
def test_create_port(self):
|
||||
"""
|
||||
Tests create port.
|
||||
"""
|
||||
self._test_create_port(const.PORT_UP)
|
||||
|
||||
def _test_delete_port(self, port_state):
|
||||
@ -188,6 +197,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetwork(self.tenant_id, self.net_id)
|
||||
|
||||
def test_delete_port(self):
|
||||
"""
|
||||
Tests delete port.
|
||||
"""
|
||||
self._test_delete_port(const.PORT_UP)
|
||||
|
||||
def _test_update_port(self, port_state):
|
||||
@ -207,9 +219,15 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)
|
||||
|
||||
def test_update_port_state_up(self):
|
||||
"""
|
||||
Tests update port state up
|
||||
"""
|
||||
self._test_update_port(const.PORT_UP)
|
||||
|
||||
def test_update_port_state_down(self):
|
||||
"""
|
||||
Tests update port state down
|
||||
"""
|
||||
self._test_update_port(const.PORT_DOWN)
|
||||
|
||||
def _test_get_port_details_state_up(self, port_state):
|
||||
@ -266,12 +284,21 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)
|
||||
|
||||
def test_get_port_details_state_up(self):
|
||||
"""
|
||||
Tests get port details state up
|
||||
"""
|
||||
self._test_get_port_details_state_up(const.PORT_UP)
|
||||
|
||||
def test_show_port_state_down(self):
|
||||
"""
|
||||
Tests show port state down
|
||||
"""
|
||||
self._test_show_port_state_down(const.PORT_DOWN)
|
||||
|
||||
def test_create_port_profile(self):
|
||||
"""
|
||||
Tests create port profile
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:test_create_port_profile() called\n")
|
||||
new_port_profile = self._cisco_ucs_plugin._create_port_profile(
|
||||
self.tenant_id, self.net_id, self.port_id,
|
||||
@ -284,6 +311,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self._cisco_ucs_plugin._delete_port_profile(self.port_id, profile_name)
|
||||
|
||||
def test_delete_port_profile(self):
|
||||
"""
|
||||
Tests delete port profile
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:test_delete_port_profile() called\n")
|
||||
self._cisco_ucs_plugin._create_port_profile(
|
||||
self.tenant_id, self.net_id, self.port_id, self.vlan_name,
|
||||
@ -313,7 +343,6 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tenant_id, self.net_id, self.port_id)
|
||||
self.assertEqual(port[const.ATTACHMENT], remote_interface_id)
|
||||
port_profile = port[const.PORT_PROFILE]
|
||||
#profile_name = port_profile[const.PROFILE_NAME]
|
||||
new_vlan_name = self._cisco_ucs_plugin._get_vlan_name_for_network(
|
||||
self.tenant_id, self.net_id)
|
||||
new_vlan_id = self._cisco_ucs_plugin._get_vlan_id_for_network(
|
||||
@ -323,7 +352,10 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetworkPortInterface(self.tenant_id, self.net_id,
|
||||
self.port_id)
|
||||
|
||||
def test_plug_interface(self):
|
||||
def test_plug_interface(self):
|
||||
"""
|
||||
Tests test plug interface
|
||||
"""
|
||||
self._test_plug_interface("4")
|
||||
|
||||
def _test_unplug_interface(self, remote_interface_id):
|
||||
@ -346,17 +378,22 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tenant_id, self.net_id, self.port_id)
|
||||
self.assertEqual(port[const.ATTACHMENT], None)
|
||||
port_profile = port[const.PORT_PROFILE]
|
||||
#profile_name = port_profile[const.PROFILE_NAME]
|
||||
self.assertEqual(port_profile[const.PROFILE_VLAN_NAME],
|
||||
conf.DEFAULT_VLAN_NAME)
|
||||
self.assertEqual(port_profile[const.PROFILE_VLAN_ID],
|
||||
conf.DEFAULT_VLAN_ID)
|
||||
self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)
|
||||
|
||||
def test_unplug_interface(self):
|
||||
def test_unplug_interface(self):
|
||||
"""
|
||||
Tests unplug interface
|
||||
"""
|
||||
self._test_unplug_interface("4")
|
||||
|
||||
def test_get_vlan_name_for_network(self):
|
||||
"""
|
||||
Tests get vlan name for network
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:test_get_vlan_name_for_network() called\n")
|
||||
net = self._cisco_ucs_plugin.create_network(
|
||||
self.tenant_id, self.net_name, self.net_id,
|
||||
@ -365,6 +402,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetwork(self.tenant_id, self.net_id)
|
||||
|
||||
def test_get_vlan_id_for_network(self):
|
||||
"""
|
||||
Tests get vlan id for network
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:test_get_vlan_id_for_network() called\n")
|
||||
net = self._cisco_ucs_plugin.create_network(
|
||||
self.tenant_id, self.net_name, self.net_id, self.vlan_name,
|
||||
@ -373,6 +413,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetwork(self.tenant_id, self.net_id)
|
||||
|
||||
def test_get_network(self):
|
||||
"""
|
||||
Tests get network
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:test_get_network() called\n")
|
||||
net = self._cisco_ucs_plugin.create_network(
|
||||
self.tenant_id, self.net_name, self.net_id, self.vlan_name,
|
||||
@ -381,6 +424,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetwork(self.tenant_id, self.net_id)
|
||||
|
||||
def test_get_port(self):
|
||||
"""
|
||||
Tests get port
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:test_get_port() called\n")
|
||||
self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
|
||||
self.net_id, self.vlan_name,
|
||||
@ -392,19 +438,31 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetworkPort(self.tenant_id, self.net_id, self.port_id)
|
||||
|
||||
def test_get_network_NetworkNotFound(self):
|
||||
"""
|
||||
Tests get network not found
|
||||
"""
|
||||
self.assertRaises(exc.NetworkNotFound,
|
||||
self._cisco_ucs_plugin._get_network,
|
||||
self.tenant_id, self.net_id)
|
||||
|
||||
def test_delete_network_NetworkNotFound(self):
|
||||
"""
|
||||
Tests delete network not found
|
||||
"""
|
||||
self.assertRaises(exc.NetworkNotFound,
|
||||
self._cisco_ucs_plugin.delete_network,
|
||||
self.tenant_id, self.net_id)
|
||||
|
||||
def test_delete_port_PortInUse(self):
|
||||
"""
|
||||
Tests delete port in use
|
||||
"""
|
||||
self._test_delete_port_PortInUse("4")
|
||||
|
||||
def _test_delete_port_PortInUse(self, remote_interface_id):
|
||||
"""
|
||||
Tests delete port in use
|
||||
"""
|
||||
self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
|
||||
self.net_id, self.vlan_name,
|
||||
self.vlan_id)
|
||||
@ -419,6 +477,9 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.port_id)
|
||||
|
||||
def test_delete_port_PortNotFound(self):
|
||||
"""
|
||||
Tests delete port not found
|
||||
"""
|
||||
self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
|
||||
self.net_id, self.vlan_name,
|
||||
self.vlan_id)
|
||||
@ -427,10 +488,16 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.tearDownNetwork(self.tenant_id, self.net_id)
|
||||
|
||||
def test_plug_interface_PortInUse(self):
|
||||
"""
|
||||
Tests plug interface port in use
|
||||
"""
|
||||
self._test_plug_interface_PortInUse("6", "5")
|
||||
|
||||
def _test_plug_interface_PortInUse(self, remote_interface_id1,
|
||||
remote_interface_id2):
|
||||
"""
|
||||
Tests plug interface port in use
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:_test_plug_interface_PortInUse() called\n")
|
||||
self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
|
||||
self.net_id, self.vlan_name,
|
||||
@ -447,10 +514,16 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.port_id)
|
||||
|
||||
def test_attachment_exists(self):
|
||||
"""
|
||||
Tests attachment exists
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:testValidateAttachmentAlreadyAttached")
|
||||
self._test_attachment_exists("4")
|
||||
|
||||
def _test_attachment_exists(self, remote_interface_id):
|
||||
"""
|
||||
Tests attachment exists
|
||||
"""
|
||||
LOG.debug("UCSVICTestPlugin:_test_validate_attachmentAlreadyAttached")
|
||||
self._cisco_ucs_plugin.create_network(self.tenant_id, self.net_name,
|
||||
self.net_id, self.vlan_name,
|
||||
@ -467,14 +540,23 @@ class UCSVICTestPlugin(unittest.TestCase):
|
||||
self.port_id)
|
||||
|
||||
def tearDownNetwork(self, tenant_id, net_id):
|
||||
"""
|
||||
Tear down network
|
||||
"""
|
||||
self._cisco_ucs_plugin.delete_network(tenant_id, net_id)
|
||||
|
||||
def tearDownNetworkPort(self, tenant_id, net_id, port_id):
|
||||
"""
|
||||
Tear down network port
|
||||
"""
|
||||
self._cisco_ucs_plugin.delete_port(tenant_id, net_id,
|
||||
port_id)
|
||||
self.tearDownNetwork(tenant_id, net_id)
|
||||
|
||||
def tearDownNetworkPortInterface(self, tenant_id, net_id, port_id):
|
||||
"""
|
||||
Tear down network port interface
|
||||
"""
|
||||
self._cisco_ucs_plugin.unplug_interface(tenant_id, net_id,
|
||||
port_id)
|
||||
self.tearDownNetworkPort(tenant_id, net_id, port_id)
|
||||
|
@ -27,8 +27,8 @@ import httplib
|
||||
import logging as LOG
|
||||
from xml.etree import ElementTree as et
|
||||
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as cexc
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
from quantum.plugins.cisco.ucs import cisco_getvif as gvif
|
||||
|
||||
|
||||
|
@ -23,9 +23,9 @@ import logging as LOG
|
||||
|
||||
from quantum.common import exceptions as exc
|
||||
from quantum.common import utils
|
||||
from quantum.plugins.cisco.common import cisco_exceptions as cexc
|
||||
from quantum.plugins.cisco.common import cisco_constants as const
|
||||
from quantum.plugins.cisco.common import cisco_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
|
||||
|
@ -22,7 +22,6 @@ import logging as LOG
|
||||
from optparse import OptionParser
|
||||
import os
|
||||
import sys
|
||||
import unittest
|
||||
|
||||
from quantum.common import exceptions as q_exc
|
||||
from quantum.quantum_plugin_base import QuantumPluginBase
|
||||
@ -200,41 +199,3 @@ class OVSQuantumPlugin(QuantumPluginBase):
|
||||
def get_interface_details(self, tenant_id, net_id, port_id):
|
||||
res = db.port_get(port_id, net_id)
|
||||
return res.interface_id
|
||||
|
||||
|
||||
class VlanMapTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.vmap = VlanMap()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def testAddVlan(self):
|
||||
vlan_id = self.vmap.acquire("foobar")
|
||||
self.assertTrue(vlan_id == 2)
|
||||
|
||||
def testReleaseVlan(self):
|
||||
vlan_id = self.vmap.acquire("foobar")
|
||||
self.vmap.release("foobar")
|
||||
self.assertTrue(self.vmap.get(vlan_id) == None)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
usagestr = "Usage: %prog [OPTIONS] <command> [args]"
|
||||
parser = OptionParser(usage=usagestr)
|
||||
parser.add_option("-v", "--verbose", dest="verbose",
|
||||
action="store_true", default=False, help="turn on verbose logging")
|
||||
|
||||
options, args = parser.parse_args()
|
||||
|
||||
if options.verbose:
|
||||
LOG.basicConfig(level=LOG.DEBUG)
|
||||
else:
|
||||
LOG.basicConfig(level=LOG.WARN)
|
||||
|
||||
# Make sqlalchemy quieter
|
||||
LOG.getLogger('sqlalchemy.engine').setLevel(LOG.WARN)
|
||||
# Run the tests
|
||||
suite = unittest.TestLoader().loadTestsFromTestCase(VlanMapTest)
|
||||
unittest.TextTestRunner(verbosity=2).run(suite)
|
||||
|
89
quantum/plugins/openvswitch/run_tests.py
Normal file
89
quantum/plugins/openvswitch/run_tests.py
Normal file
@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
|
||||
# Copyright 2010 OpenStack, LLC
|
||||
# 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.
|
||||
|
||||
|
||||
"""Unittest runner for quantum OVS plugin
|
||||
|
||||
This file should be run from the top dir in the quantum directory
|
||||
|
||||
To run all test::
|
||||
python quantum/plugins/openvswitch/run_tests.py
|
||||
|
||||
To run all unit tests::
|
||||
python quantum/plugins/openvswitch/run_tests.py unit
|
||||
|
||||
To run all functional tests::
|
||||
python quantum/plugins/openvswitch/run_tests.py functional
|
||||
|
||||
To run a single unit test::
|
||||
python quantum/plugins/openvswitch/run_tests.py \
|
||||
unit.test_stores:TestSwiftBackend.test_get
|
||||
|
||||
To run a single functional test::
|
||||
python quantum/plugins/openvswitch/run_tests.py \
|
||||
functional.test_service:TestController.test_create
|
||||
|
||||
To run a single unit test module::
|
||||
python quantum/plugins/openvswitch/run_tests.py unit.test_stores
|
||||
|
||||
To run a single functional test module::
|
||||
python quantum/plugins/openvswitch/run_tests.py functional.test_stores
|
||||
"""
|
||||
|
||||
import gettext
|
||||
import logging
|
||||
import os
|
||||
import unittest
|
||||
import sys
|
||||
|
||||
from nose import config
|
||||
|
||||
sys.path.append(os.getcwd())
|
||||
|
||||
from quantum.common.test_lib import run_tests, test_config
|
||||
from quantum.plugins.openvswitch.tests.test_vlan_map import VlanMapTest
|
||||
|
||||
if __name__ == '__main__':
|
||||
exit_status = False
|
||||
|
||||
# if a single test case was specified,
|
||||
# we should only invoked the tests once
|
||||
invoke_once = len(sys.argv) > 1
|
||||
|
||||
cwd = os.getcwd()
|
||||
|
||||
working_dir = os.path.abspath("tests")
|
||||
c = config.Config(stream=sys.stdout,
|
||||
env=os.environ,
|
||||
verbosity=3,
|
||||
workingDir=working_dir)
|
||||
exit_status = run_tests(c)
|
||||
|
||||
if invoke_once:
|
||||
sys.exit(0)
|
||||
|
||||
os.chdir(cwd)
|
||||
|
||||
working_dir = os.path.abspath("quantum/plugins/openvswitch/tests")
|
||||
c = config.Config(stream=sys.stdout,
|
||||
env=os.environ,
|
||||
verbosity=3,
|
||||
workingDir=working_dir)
|
||||
exit_status = exit_status or run_tests(c)
|
||||
|
||||
sys.exit(exit_status)
|
0
quantum/plugins/openvswitch/tests/__init__.py
Normal file
0
quantum/plugins/openvswitch/tests/__init__.py
Normal file
36
quantum/plugins/openvswitch/tests/test_vlan_map.py
Normal file
36
quantum/plugins/openvswitch/tests/test_vlan_map.py
Normal file
@ -0,0 +1,36 @@
|
||||
# vim: tabstop=4 shiftwidth=4 softtabstop=4
|
||||
# Copyright 2011 Nicira Networks, 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.
|
||||
|
||||
import unittest
|
||||
from quantum.plugins.openvswitch.ovs_quantum_plugin import VlanMap
|
||||
|
||||
|
||||
class VlanMapTest(unittest.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
self.vmap = VlanMap()
|
||||
|
||||
def tearDown(self):
|
||||
pass
|
||||
|
||||
def testAddVlan(self):
|
||||
vlan_id = self.vmap.acquire("foobar")
|
||||
self.assertTrue(vlan_id == 2)
|
||||
|
||||
def testReleaseVlan(self):
|
||||
vlan_id = self.vmap.acquire("foobar")
|
||||
self.vmap.release("foobar")
|
||||
self.assertTrue(self.vmap.get(vlan_id) == None)
|
34
setup.py
Normal file
34
setup.py
Normal file
@ -0,0 +1,34 @@
|
||||
import os
|
||||
import sys
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
def read(fname):
|
||||
return open(os.path.join(os.path.dirname(__file__), fname)).read()
|
||||
|
||||
requirements = ['httplib2','eventlet','routes','webob']
|
||||
|
||||
setup(
|
||||
name = "Quantum",
|
||||
version = "0.1",
|
||||
description = "Layer 2 network as a service for Openstack",
|
||||
long_description = read('README'),
|
||||
url = 'http://launchpad.net/quantum',
|
||||
license = 'Apache',
|
||||
author = 'Netstack',
|
||||
author_email = 'netstack@launchpad.net',
|
||||
packages = find_packages(exclude=['tests']),
|
||||
classifiers = [
|
||||
'Development Status :: 4 - Beta',
|
||||
'Environment :: Console',
|
||||
'Intended Audience :: Developers',
|
||||
'Intended Audience :: Information Technology',
|
||||
'License :: OSI Approved :: BSD License',
|
||||
'Operating System :: OS Independent',
|
||||
'Programming Language :: Python',
|
||||
],
|
||||
namespace_packages = ["quantum"],
|
||||
install_requires = requirements,
|
||||
|
||||
tests_require = ["nose"],
|
||||
test_suite = "nose.collector",
|
||||
)
|
@ -62,7 +62,7 @@ class ResourceExtensionTest(unittest.TestCase):
|
||||
def custom_member_action(self, request, id):
|
||||
return {'member_action': 'value'}
|
||||
|
||||
def custom_collection_action(self, request):
|
||||
def custom_collection_action(self, request, **kwargs):
|
||||
return {'collection': 'value'}
|
||||
|
||||
def test_resource_can_be_added_as_extension(self):
|
||||
@ -87,7 +87,7 @@ class ResourceExtensionTest(unittest.TestCase):
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['member_action'], "value")
|
||||
|
||||
def test_resource_extension_with_custom_collection_action(self):
|
||||
def test_resource_extension_for_get_custom_collection_action(self):
|
||||
controller = self.ResourceExtensionController()
|
||||
collections = {'custom_collection_action': "GET"}
|
||||
res_ext = extensions.ResourceExtension('tweedles', controller,
|
||||
@ -98,6 +98,69 @@ class ResourceExtensionTest(unittest.TestCase):
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['collection'], "value")
|
||||
|
||||
def test_resource_extension_for_put_custom_collection_action(self):
|
||||
controller = self.ResourceExtensionController()
|
||||
collections = {'custom_collection_action': "PUT"}
|
||||
res_ext = extensions.ResourceExtension('tweedles', controller,
|
||||
collection_actions=collections)
|
||||
test_app = setup_extensions_test_app(SimpleExtensionManager(res_ext))
|
||||
|
||||
response = test_app.put("/tweedles/custom_collection_action")
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['collection'], 'value')
|
||||
|
||||
def test_resource_extension_for_post_custom_collection_action(self):
|
||||
controller = self.ResourceExtensionController()
|
||||
collections = {'custom_collection_action': "POST"}
|
||||
res_ext = extensions.ResourceExtension('tweedles', controller,
|
||||
collection_actions=collections)
|
||||
test_app = setup_extensions_test_app(SimpleExtensionManager(res_ext))
|
||||
|
||||
response = test_app.post("/tweedles/custom_collection_action")
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['collection'], 'value')
|
||||
|
||||
def test_resource_extension_for_delete_custom_collection_action(self):
|
||||
controller = self.ResourceExtensionController()
|
||||
collections = {'custom_collection_action': "DELETE"}
|
||||
res_ext = extensions.ResourceExtension('tweedles', controller,
|
||||
collection_actions=collections)
|
||||
test_app = setup_extensions_test_app(SimpleExtensionManager(res_ext))
|
||||
|
||||
response = test_app.delete("/tweedles/custom_collection_action")
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['collection'], 'value')
|
||||
|
||||
def test_resource_ext_for_formatted_req_on_custom_collection_action(self):
|
||||
controller = self.ResourceExtensionController()
|
||||
collections = {'custom_collection_action': "GET"}
|
||||
res_ext = extensions.ResourceExtension('tweedles', controller,
|
||||
collection_actions=collections)
|
||||
test_app = setup_extensions_test_app(SimpleExtensionManager(res_ext))
|
||||
|
||||
response = test_app.get("/tweedles/custom_collection_action.json")
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['collection'], "value")
|
||||
|
||||
def test_resource_ext_for_nested_resource_custom_collection_action(self):
|
||||
controller = self.ResourceExtensionController()
|
||||
collections = {'custom_collection_action': "GET"}
|
||||
parent = dict(collection_name='beetles', member_name='beetle')
|
||||
res_ext = extensions.ResourceExtension('tweedles', controller,
|
||||
collection_actions=collections,
|
||||
parent=parent)
|
||||
test_app = setup_extensions_test_app(SimpleExtensionManager(res_ext))
|
||||
|
||||
response = test_app.get("/beetles/beetle_id"
|
||||
"/tweedles/custom_collection_action")
|
||||
|
||||
self.assertEqual(200, response.status_int)
|
||||
self.assertEqual(json.loads(response.body)['collection'], "value")
|
||||
|
||||
def test_returns_404_for_non_existant_extension(self):
|
||||
test_app = setup_extensions_test_app(SimpleExtensionManager(None))
|
||||
|
||||
|
@ -15,106 +15,45 @@
|
||||
# under the License.
|
||||
# @author: Dan Wendlandt, Nicira Networks, Inc.
|
||||
|
||||
import httplib
|
||||
import logging as LOG
|
||||
import json
|
||||
import socket
|
||||
import sys
|
||||
import urllib
|
||||
|
||||
from quantum.manager import QuantumManager
|
||||
from optparse import OptionParser
|
||||
from quantum.common.wsgi import Serializer
|
||||
from quantum.cli import MiniClient
|
||||
import sys
|
||||
|
||||
from quantum.client import Client
|
||||
from quantum.manager import QuantumManager
|
||||
|
||||
FORMAT = "json"
|
||||
CONTENT_TYPE = "application/" + FORMAT
|
||||
|
||||
|
||||
def delete_all_nets(client, tenant_id):
|
||||
res = client.do_request(tenant_id, 'GET', "/networks." + FORMAT)
|
||||
resdict = json.loads(res.read())
|
||||
LOG.debug(resdict)
|
||||
for n in resdict["networks"]:
|
||||
def delete_all_nets(client):
|
||||
res = client.list_networks()
|
||||
for n in res["networks"]:
|
||||
nid = n["id"]
|
||||
|
||||
res = client.do_request(tenant_id, 'GET',
|
||||
"/networks/%s/ports.%s" % (nid, FORMAT))
|
||||
output = res.read()
|
||||
if res.status != 200:
|
||||
LOG.error("Failed to list ports: %s" % output)
|
||||
continue
|
||||
rd = json.loads(output)
|
||||
LOG.debug(rd)
|
||||
for port in rd["ports"]:
|
||||
pid = port["id"]
|
||||
|
||||
data = {'port': {'attachment-id': ''}}
|
||||
body = Serializer().serialize(data, CONTENT_TYPE)
|
||||
res = client.do_request(tenant_id, 'DELETE',
|
||||
"/networks/%s/ports/%s/attachment.%s" % \
|
||||
(nid, pid, FORMAT), body=body)
|
||||
output = res.read()
|
||||
LOG.debug(output)
|
||||
if res.status != 202:
|
||||
LOG.error("Failed to unplug iface from port \"%s\": %s" % (vid,
|
||||
pid, output))
|
||||
continue
|
||||
LOG.info("Unplugged interface from port:%s on network:%s" % (pid,
|
||||
nid))
|
||||
|
||||
res = client.do_request(tenant_id, 'DELETE',
|
||||
"/networks/%s/ports/%s.%s" % (nid, pid, FORMAT))
|
||||
output = res.read()
|
||||
if res.status != 202:
|
||||
LOG.error("Failed to delete port: %s" % output)
|
||||
continue
|
||||
pres = client.list_ports(nid)
|
||||
for port in pres["ports"]:
|
||||
pid = port['id']
|
||||
client.detach_resource(nid, pid)
|
||||
client.delete_port(nid, pid)
|
||||
print "Deleted Virtual Port:%s " \
|
||||
"on Virtual Network:%s" % (pid, nid)
|
||||
|
||||
res = client.do_request(tenant_id, 'DELETE',
|
||||
"/networks/" + nid + "." + FORMAT)
|
||||
status = res.status
|
||||
if status != 202:
|
||||
Log.error("Failed to delete network: %s" % nid)
|
||||
output = res.read()
|
||||
print output
|
||||
else:
|
||||
print "Deleted Virtual Network with ID:%s" % nid
|
||||
client.delete_network(nid)
|
||||
print "Deleted Virtual Network with ID:%s" % nid
|
||||
|
||||
|
||||
def create_net_with_attachments(net_name, iface_ids):
|
||||
def create_net_with_attachments(client, net_name, iface_ids):
|
||||
data = {'network': {'net-name': '%s' % net_name}}
|
||||
body = Serializer().serialize(data, CONTENT_TYPE)
|
||||
res = client.do_request(tenant_id, 'POST',
|
||||
"/networks." + FORMAT, body=body)
|
||||
rd = json.loads(res.read())
|
||||
LOG.debug(rd)
|
||||
nid = rd["networks"]["network"]["id"]
|
||||
res = client.create_network(data)
|
||||
nid = res["networks"]["network"]["id"]
|
||||
print "Created a new Virtual Network %s with ID:%s" % (net_name, nid)
|
||||
|
||||
for iface_id in iface_ids:
|
||||
res = client.do_request(tenant_id, 'POST',
|
||||
"/networks/%s/ports.%s" % (nid, FORMAT))
|
||||
output = res.read()
|
||||
if res.status != 200:
|
||||
LOG.error("Failed to create port: %s" % output)
|
||||
continue
|
||||
rd = json.loads(output)
|
||||
new_port_id = rd["ports"]["port"]["id"]
|
||||
res = client.create_port(nid)
|
||||
new_port_id = res["ports"]["port"]["id"]
|
||||
print "Created Virtual Port:%s " \
|
||||
"on Virtual Network:%s" % (new_port_id, nid)
|
||||
data = {'port': {'attachment-id': '%s' % iface_id}}
|
||||
body = Serializer().serialize(data, CONTENT_TYPE)
|
||||
res = client.do_request(tenant_id, 'PUT',
|
||||
"/networks/%s/ports/%s/attachment.%s" %\
|
||||
(nid, new_port_id, FORMAT), body=body)
|
||||
output = res.read()
|
||||
LOG.debug(output)
|
||||
if res.status != 202:
|
||||
LOG.error("Failed to plug iface \"%s\" to port \"%s\": %s" % \
|
||||
(iface_id, new_port_id, output))
|
||||
continue
|
||||
client.attach_resource(nid, new_port_id, data)
|
||||
print "Plugged interface \"%s\" to port:%s on network:%s" % \
|
||||
(iface_id, new_port_id, nid)
|
||||
|
||||
@ -149,7 +88,6 @@ if __name__ == "__main__":
|
||||
|
||||
if len(args) < 1:
|
||||
parser.print_help()
|
||||
help()
|
||||
sys.exit(1)
|
||||
|
||||
nets = {}
|
||||
@ -163,12 +101,13 @@ if __name__ == "__main__":
|
||||
|
||||
print "nets: %s" % str(nets)
|
||||
|
||||
client = MiniClient(options.host, options.port, options.ssl)
|
||||
client = Client(options.host, options.port, options.ssl,
|
||||
format='json', tenant=tenant_id)
|
||||
|
||||
if options.delete:
|
||||
delete_all_nets(client, tenant_id)
|
||||
delete_all_nets(client)
|
||||
|
||||
for net_name, iface_ids in nets.items():
|
||||
create_net_with_attachments(net_name, iface_ids)
|
||||
create_net_with_attachments(client, net_name, iface_ids)
|
||||
|
||||
sys.exit(0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user