From ea6c9343a9d91b8235b1e0b9108ec07c46c8d05b Mon Sep 17 00:00:00 2001 From: Ying Liu Date: Thu, 25 Aug 2011 12:30:20 -0700 Subject: [PATCH] move faults/exceptions to l2network package, remove unecessary faults definitions change the portprofile action api's method fix imports order and other comments issues --- extensions/_credential_view.py | 6 +- extensions/_exceptions.py | 160 ------------------ extensions/_faults.py | 153 ----------------- extensions/_novatenant_view.py | 5 +- extensions/_pprofiles.py | 2 +- extensions/_qos_view.py | 4 +- extensions/credential.py | 14 +- extensions/novatenant.py | 33 +--- extensions/portprofile.py | 9 +- extensions/qos.py | 7 +- .../cisco/tests/unit/test_cisco_extension.py | 16 +- 11 files changed, 34 insertions(+), 375 deletions(-) delete mode 100644 extensions/_exceptions.py delete mode 100644 extensions/_faults.py diff --git a/extensions/_credential_view.py b/extensions/_credential_view.py index 453cd8b24..3c8ce49a4 100644 --- a/extensions/_credential_view.py +++ b/extensions/_credential_view.py @@ -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'])) \ No newline at end of file + password=credential_data['password'])) diff --git a/extensions/_exceptions.py b/extensions/_exceptions.py deleted file mode 100644 index 2310d44e6..000000000 --- a/extensions/_exceptions.py +++ /dev/null @@ -1,160 +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 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 diff --git a/extensions/_faults.py b/extensions/_faults.py deleted file mode 100644 index 5b9c233ec..000000000 --- a/extensions/_faults.py +++ /dev/null @@ -1,153 +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 webob.dec - -from quantum.common import wsgi - - -class Fault(webob.exc.HTTPException): - """Error codes for API faults""" - - _fault_names = { - 400: "malformedRequest", - 401: "unauthorized", - 420: "networkNotFound", - 421: "PortprofileInUse", - 430: "portNotFound", - 431: "requestedStateInvalid", - 432: "portInUse", - 440: "alreadyAttached", - 450: "PortprofileNotFound", - 451: "CredentialNotFound", - 452: "QoSNotFound", - 453: "NovatenantNotFound", - 470: "serviceUnavailable", - 471: "pluginFault"} - - def __init__(self, exception): - """Create a Fault for the given webob.exc.exception.""" - self.wrapped_exc = exception - - @webob.dec.wsgify(RequestClass=wsgi.Request) - def __call__(self, req): - """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}} - # 'code' is an attribute on the fault tag itself - content_type = req.best_match_content_type() - self.wrapped_exc.body = wsgi.Serializer().\ - serialize(fault_data, content_type) - self.wrapped_exc.content_type = content_type - return self.wrapped_exc - - -class PortprofileNotFound(webob.exc.HTTPClientError): - """ - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the Portprofile specified - in the HTTP request - - code: 450, title: Portprofile not Found - """ - code = 450 - title = 'Portprofile Not Found' - explanation = ('Unable to find a Portprofile with' - + ' the specified identifier.') - - -class PortNotFound(webob.exc.HTTPClientError): - """ - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the port specified - in the HTTP request for a given network - - code: 430, title: Port not Found - """ - 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` - - This indicates that the server did not find the Credential specified - in the HTTP request - - code: 460, title: Credential not Found - """ - code = 451 - title = 'Credential Not Found' - explanation = ('Unable to find a Credential with' - + ' the specified identifier.') - - -class QosNotFound(webob.exc.HTTPClientError): - """ - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the QoS specified - in the HTTP request - - code: 480, title: QoS not Found - """ - code = 452 - title = 'QoS Not Found' - explanation = ('Unable to find a QoS with' - + ' the specified identifier.') - - -class NovatenantNotFound(webob.exc.HTTPClientError): - """ - subclass of :class:`~HTTPClientError` - - This indicates that the server did not find the Novatenant specified - in the HTTP request - - code: 480, title: Nova tenant not Found - """ - code = 453 - title = 'Nova tenant Not Found' - explanation = ('Unable to find a Novatenant with' - + ' the specified identifier.') - - -class RequestedStateInvalid(webob.exc.HTTPClientError): - """ - subclass of :class:`~HTTPClientError` - - This indicates that the server could not update the port state to - to the request value - - code: 431, title: Requested State Invalid - """ - code = 431 - title = 'Requested State Invalid' - explanation = ('Unable to update port state with specified value.') diff --git a/extensions/_novatenant_view.py b/extensions/_novatenant_view.py index 6843361fb..a25654916 100644 --- a/extensions/_novatenant_view.py +++ b/extensions/_novatenant_view.py @@ -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]) diff --git a/extensions/_pprofiles.py b/extensions/_pprofiles.py index ba94c472b..cf851bae0 100644 --- a/extensions/_pprofiles.py +++ b/extensions/_pprofiles.py @@ -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): diff --git a/extensions/_qos_view.py b/extensions/_qos_view.py index ca3f76caf..3ad0d30c3 100644 --- a/extensions/_qos_view.py +++ b/extensions/_qos_view.py @@ -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'])) diff --git a/extensions/credential.py b/extensions/credential.py index 0b6928481..31c49bdd0 100644 --- a/extensions/credential.py +++ b/extensions/credential.py @@ -21,13 +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 _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') @@ -36,7 +36,7 @@ class Credential(object): """extension class Credential""" def __init__(self): pass - + @classmethod def get_name(cls): """ Returns Ext Resource Name """ @@ -67,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)] @@ -84,7 +83,7 @@ class CredentialController(common.QuantumController): 'required': True}, { 'param-name': 'password', 'required': True}] - + _serialization_metadata = { "application/xml": { "attributes": { @@ -96,7 +95,7 @@ class CredentialController(common.QuantumController): def __init__(self, plugin): self._resource_name = 'credential' self._plugin = plugin - + def index(self, request, tenant_id): """ Returns a list of credential ids """ return self._items(request, tenant_id, is_detail=False) @@ -165,4 +164,3 @@ class CredentialController(common.QuantumController): return exc.HTTPAccepted() except exception.CredentialNotFound as exp: return faults.Fault(faults.CredentialNotFound(exp)) - diff --git a/extensions/novatenant.py b/extensions/novatenant.py index c4ab55db0..84453ccfb 100644 --- a/extensions/novatenant.py +++ b/extensions/novatenant.py @@ -21,12 +21,11 @@ from webob import exc from extensions import _novatenant_view as novatenant_view -from quantum.common import exceptions as qexception -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): @@ -97,33 +96,9 @@ class NovatenantsController(common.QuantumController): def __init__(self, plugin): self._resource_name = 'novatenant' self._plugin = 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" - - # pylint: disable-msg=E1101,W0613 - def show(self, request, tenant_id, id): - """ Returns novatenant details for the given novatenant id """ - return "novatenant is a dummy resource" - - def create(self, request, tenant_id): - """ Creates a new novatenant for a given tenant """ - return "novatenant is a dummy resource" - - def update(self, request, tenant_id, id): - """ Updates the name for the novatenant with the given id """ - return "novatenant is a dummy resource" - - def delete(self, request, tenant_id, id): - """ Destroys the Novatenant with the given id """ - return "novatenant is a dummy resource" - + #added for cisco's extension + # pylint: disable-msg=E1101,W0613 def get_host(self, request, tenant_id, id): content_type = request.best_match_content_type() print "Content type:%s" % content_type diff --git a/extensions/portprofile.py b/extensions/portprofile.py index c20eea3ac..4dd9c7b41 100644 --- a/extensions/portprofile.py +++ b/extensions/portprofile.py @@ -22,13 +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 _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): @@ -67,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, diff --git a/extensions/qos.py b/extensions/qos.py index bcff6de8a..6e8cb7233 100644 --- a/extensions/qos.py +++ b/extensions/qos.py @@ -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') diff --git a/quantum/plugins/cisco/tests/unit/test_cisco_extension.py b/quantum/plugins/cisco/tests/unit/test_cisco_extension.py index a6bbe3c64..e1f2391bf 100644 --- a/quantum/plugins/cisco/tests/unit/test_cisco_extension.py +++ b/quantum/plugins/cisco/tests/unit/test_cisco_extension.py @@ -68,7 +68,7 @@ class PortprofileExtensionTest(unittest.TestCase): 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, @@ -206,7 +206,7 @@ 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") @@ -410,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) @@ -433,7 +433,7 @@ class PortprofileExtensionTest(unittest.TestCase): """ Tear down associate profile""" - self.test_app.post(dissociate_profile_path, req_body, + self.test_app.put(dissociate_profile_path, req_body, content_type=self.contenttype) self.tear_down_profile(delete_profile_path) @@ -475,8 +475,8 @@ class NovatenantExtensionTest(unittest.TestCase): req_body = json.dumps(self.test_instance_data) host_path = self.novatenants_path + "001/get_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_get_host - END") @@ -487,8 +487,8 @@ class NovatenantExtensionTest(unittest.TestCase): LOG.debug("test_get_hostBADRequest - START") host_path = self.novatenants_path + "001/get_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_get_hostBADRequest - END") -- 2.45.2