From: Ying Liu Date: Thu, 18 Aug 2011 22:36:09 +0000 (-0700) Subject: fix pylint issuses X-Git-Url: https://review.fuel-infra.org/gitweb?a=commitdiff_plain;h=effced8b6b1c721c16c236503d96d1098b7926c8;p=openstack-build%2Fneutron-build.git fix pylint issuses --- effced8b6b1c721c16c236503d96d1098b7926c8 diff --cc cisco_demo/demo_client.py index 74b4a6a7a,000000000..4f91abc93 mode 100755,000000..100755 --- a/cisco_demo/demo_client.py +++ b/cisco_demo/demo_client.py @@@ -1,385 -1,0 +1,386 @@@ + +import os +import sys + +import gettext + +#gettext.install('quantum', unicode=1) +possible_topdir = os.path.normpath(os.path.join(os.path.abspath(sys.argv[0]), + os.pardir, + os.pardir)) +if os.path.exists(os.path.join(possible_topdir, 'quantum', '__init__.py')): + sys.path.insert(0, possible_topdir) + +gettext.install('quantum', unicode=1) + +from test_scripts.miniclient import MiniClient +from test_client import ExtClient +from quantum.common.wsgi import Serializer + +HOST = '127.0.0.1' +PORT = 9696 +USE_SSL = False +TENANT_ID = 'ucs_user' + + +test_network_data = \ + {'network': {'net-name': 'cisco_test_network', + 'valn-id': 28}} +test_portprofile_data = \ + {'portprofile': {'portprofile_name': 'cisco_test_portprofile', + 'qos_name': 2, + 'qos_name': 'test-qos'}} +test_cred_data = \ + {'credential': {'credential_name': 'cred3', + 'user_name': 'newUser', + 'password': 'newPasswd' + }} +test_qos_data = \ + {'qos': {'qos_name': 'plantimum', + 'qos_desc': {'PPS': 50, 'TTL': 5}}} + + +#we put this assignment under portprofile resources +#therefore we need to create such a test data +test_port_assign_data = {'portprofile': {'network-id': '001', + 'port-id': '1'}} +test_attach_data = {'port': {'attachment-id': 'v01'}} + +test_act_data = {"get_available_host":123} + +test_instance_data={'novatenant':{'instance_id' : 1, + 'instance_desc' : {'key1' : '1', + 'key2' : '2' + }}} + +def test_get_host(format='json'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + body = Serializer().serialize(test_instance_data, content_type) + res = client.do_request(TENANT_ID, + 'PUT', "/novatenants/001/get_host." + format, body=body) + print "XML Response" + print_response(res) + print "COMPLETED" + print "----------------------------" + +def test_get_instance_port(format='json'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + body = Serializer().serialize(test_instance_data, content_type) + res = client.do_request(TENANT_ID, + 'PUT', "/novatenants/001/get_instance_port." + format, body=body) + print "XML Response" + print_response(res) + print "COMPLETED" + print "----------------------------" + +def test_action_ext(format='json'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + action_name = 'get_available_host' + action_params = dict(name='test') + body = Serializer().serialize(test_act_data, content_type) + + + res = client.do_request(TENANT_ID, 'POST', "/act_resources/1/action." + format, body=body) + content = print_response(res) + +def print_response(res): + content = res.read() + print "Status: %s" % res.status + print "Content: %s" % content + return content + + +def create_cisco_network(format='xml'): + + client = MiniClient(HOST, PORT, USE_SSL) + print "CREATE NETWORK -- FORMAT:%s" % format + print "----------------------------" + content_type = "application/" + format + body = Serializer().serialize(test_network_data, content_type) + res = client.do_request(TENANT_ID, + 'POST', "/networks." + format, body=body) + print "XML Response" + print_response(res) + print "COMPLETED" + print "----------------------------" + + +def create_cisco_portprofile(format='xml'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + print "List all Profile -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/portprofiles." + format) + content = print_response(res) + portprofile_data = Serializer().deserialize(content, content_type) + print portprofile_data - ++ ++ """ + print "List a specific Profile -- FORMAT:%s" % format + profile_id = portprofile_data['portprofiles'][0]['id'] + #profile_id='001' + print "profile_id " + profile_id + res = client.do_request(TENANT_ID, + 'GET', "/portprofiles/" + + profile_id + "." + format) + print_response(res) - ++ """ + print "CREATE Profile -- FORMAT:%s" % format + print "----------------------------" + content_type = "application/" + format + body = Serializer().serialize(test_portprofile_data, content_type) + print "***BODY is " + print body + res = client.do_request(TENANT_ID, 'POST', + "/portprofiles." + format, body=body) + print "XML Response" + print_response(res) + print "COMPLETED" + print "----------------------------" + +def test_credential (format='xml'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + print "----------------------------" + print "List all credentials -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/credentials." + format) + content = print_response(res) + credential_data = Serializer().deserialize(content, content_type) + print credential_data + + print "----------------------------" + print "CREATE Credential -- FORMAT:%s" % format + print "----------------------------" + content_type = "application/" + format + body = Serializer().serialize(test_cred_data, content_type) + print "***BODY is " + print body + res = client.do_request(TENANT_ID, 'POST', + "/credentials." + format, body=body) + print "XML Response" + print_response(res) + + print "----------------------------" + print "List all credentials -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/credentials." + format) + content = print_response(res) + credential_data = Serializer().deserialize(content, content_type) + print credential_data + print "----------------------------" + print "List a specific cred -- FORMAT:%s" % format + print "----------------------------" + cred_id = credential_data['credentials'][0]['id'] + #cred_id='001' + print "cred_id " + cred_id + res = client.do_request(TENANT_ID, + 'GET', "/credentials/" + + cred_id + "." + format) + print_response(res) + + print "----------------------------" + print "TEST DELETE Credential -- FORMAT:%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'DELETE', + "/credentials/" + cred_id + "." + format) + print_response(res) + + print "----------------------------" + print "List all credentials -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/credentials." + format) + content = print_response(res) + credential_data = Serializer().deserialize(content, content_type) + print credential_data + + print "COMPLETED" + print "----------------------------" + +def test_qos (format='xml'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + print "----------------------------" + print "List all qoss -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/qoss." + format) + content = print_response(res) + qos_data = Serializer().deserialize(content, content_type) + print qos_data + + print "----------------------------" + print "CREATE qos -- FORMAT:%s" % format + print "----------------------------" + content_type = "application/" + format + body = Serializer().serialize(test_qos_data, content_type) + print "***BODY is " + print body + res = client.do_request(TENANT_ID, 'POST', + "/qoss." + format, body=body) + print "XML Response" + print_response(res) + + print "----------------------------" + print "List all qoss -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/qoss." + format) + content = print_response(res) + qos_data = Serializer().deserialize(content, content_type) + print qos_data + print "----------------------------" + print "List a specific cred -- FORMAT:%s" % format + print "----------------------------" + qos_id = qos_data['qoss'][0]['id'] + #cred_id='001' + print "qos_id " + qos_id + res = client.do_request(TENANT_ID, + 'GET', "/qoss/" + + qos_id + "." + format) + print_response(res) + + print "----------------------------" + print "TEST DELETE qos -- FORMAT:%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'DELETE', + "/qoss/" + qos_id + "." + format) + print_response(res) + + print "----------------------------" + print "List all qoss -- FORMat%s" % format + print "----------------------------" + res = client.do_request(TENANT_ID, 'GET', "/qoss." + format) + content = print_response(res) + qos_data = Serializer().deserialize(content, content_type) + print qos_data + + print "COMPLETED" + print "----------------------------" + +def test_delete_network(format='xml'): + client = MiniClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + print "TEST DELETE NETWORK -- FORMAT:%s" % format + print "----------------------------" + print "--> Step 1 - List All Networks" + res = client.do_request(TENANT_ID, 'GET', "/networks." + format) + content = print_response(res) + network_data = Serializer().deserialize(content, content_type) + print network_data + net_id = network_data['networks'][0]['id'] + print "--> Step 2 - Delete network %s" % net_id + res = client.do_request(TENANT_ID, 'DELETE', + "/networks/" + net_id + "." + format) + print_response(res) + print "--> Step 3 - List All Networks (Again)" + res = client.do_request(TENANT_ID, 'GET', "/networks." + format) + print_response(res) + print "COMPLETED" + print "----------------------------" + + +def test_delete_portprofile(format='xml'): + client = ExtClient(HOST, PORT, USE_SSL) + content_type = "application/" + format + print "TEST DELETE PROFILE -- FORMAT:%s" % format + print "----------------------------" + print "--> Step 1 - List All Profiles" + res = client.do_request(TENANT_ID, 'GET', "/portprofiles." + format) + content = print_response(res) + portprofile_data = Serializer().deserialize(content, content_type) + print portprofile_data + profile_id = portprofile_data['portprofiles'][0]['id'] + print "--> Step 2 - Delete portprofile %s" % profile_id + res = client.do_request(TENANT_ID, 'DELETE', + "/portprofiles/" + profile_id + "." + format) + print_response(res) + print "--> Step 3 - List All Profiles (Again)" + res = client.do_request(TENANT_ID, 'GET', "/portprofiles." + format) + print_response(res) + print "COMPLETED" + print "----------------------------" + + +def test_create_port(format='xml'): + client = MiniClient(HOST, PORT, USE_SSL) + print "TEST CREATE PORT -- FORMAT:%s" % format + print "----------------------------" + print "--> Step 1 - List Ports for network 001" + res = client.do_request(TENANT_ID, 'GET', "/networks/001/ports." + format) + print_response(res) + print "--> Step 2 - Create Port for network 001" + res = client.do_request(TENANT_ID, 'POST', "/networks/001/ports." + format) + print_response(res) + print "--> Step 3 - List Ports for network 001 (again)" + res = client.do_request(TENANT_ID, 'GET', "/networks/001/ports." + format) + print_response(res) + print "COMPLETED" + print "----------------------------" + + +#assuming network 001 and ports 1 are created in the plug-in +def test_attach_resource(format='xml'): + client = MiniClient(HOST, PORT, USE_SSL) + print "TEST attach resources to port" + content_type = "application/" + format + body = Serializer().serialize(test_attach_data, content_type) + #attach virtual interface to the port + res = client.do_request(TENANT_ID, 'PUT', + "/networks/001/ports/1/attachment." + + format, body=body) + print_response(res) + #list existing interface of the port + res = client.do_request(TENANT_ID, 'GET', + "/networks/001/ports/1/attachment." + format) + print_response(res) + #de_attach virtual interface from the port + res = client.do_request(TENANT_ID, 'DELETE', + "/networks/001/ports/1/attachment." + format) + print_response(res) + #list existing interface of the port + res = client.do_request(TENANT_ID, 'GET', + "/networks/001/ports/1/attachment." + format) + print_response(res) + + +#assuming network 001, ports 1 and portprofile 002 are created in the plug-in +def test_assign_portprofile(format='xml'): + client = ExtClient(HOST, PORT, USE_SSL) + print "TEST attach resources to port" + content_type = "application/" + format + body = Serializer().serialize(test_port_assign_data, content_type) + print "body is " + body + res = client.do_request(TENANT_ID, 'PUT', + "/portprofiles/001/associate_portprofile." + + format, body=body) + print_response(res) + res = client.do_request(TENANT_ID, 'POST', + "/portprofiles/001/disassociate_portprofile." + + format, body=body) + + print_response(res) + + +def main(): + create_cisco_portprofile('json') - test_attach_resource('json') ++ #test_attach_resource('json') + + test_delete_portprofile('json') + test_credential('json') + test_qos('json') + ##test_action_ext('json') + test_get_host('json') + test_get_instance_port('json') + - #create_cisco_network('json') - #test_create_port('json') - #create_cisco_portprofile('json') - #test_assign_portprofile('json') ++ create_cisco_network('json') ++ test_create_port('json') ++ create_cisco_portprofile('json') ++ test_assign_portprofile('json') + pass + + +# Standard boilerplate to call the main() function. +if __name__ == '__main__': + main() diff --cc extensions/_credential_view.py index 062e8fa93,000000000..1c1cc3ac2 mode 100644,000000..100644 --- a/extensions/_credential_view.py +++ b/extensions/_credential_view.py @@@ -1,55 -1,0 +1,58 @@@ +""" +# 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. +# +""" ++ ++ +def get_view_builder(req): ++ """get view builder """ + base_url = req.application_url + return ViewBuilder(base_url) + + +class ViewBuilder(object): + """ + ViewBuilder for Credential, + derived from quantum.views.networks + """ + def __init__(self, base_url): + """ + :param base_url: url of the root wsgi application + """ + self.base_url = base_url + + def build(self, credential_data, is_detail=False): + """Generic method used to generate a credential entity.""" + print "credential-DATA:%s" % credential_data + if is_detail: + credential = self._build_detail(credential_data) + else: + credential = self._build_simple(credential_data) + return credential + + def _build_simple(self, credential_data): + """Return a simple model of a server.""" + return dict(credential=dict(id=credential_data['credential_id'])) + + def _build_detail(self, credential_data): + """Return a simple model of a server.""" + + return dict(credential=dict(id=credential_data['credential_id'], + name=credential_data['user_name'], + password=credential_data['password'])) diff --cc extensions/_exceptions.py index 99bc55da1,000000000..aeae4b647 mode 100644,000000..100644 --- a/extensions/_exceptions.py +++ b/extensions/_exceptions.py @@@ -1,162 -1,0 +1,181 @@@ +""" +# 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(f): ++def wrap_exception(afunc): ++ """Wrap Exception""" + def _wrap(*args, **kw): ++ """Internal Wrap Exception func""" + try: - return f(*args, **kw) - except Exception, e: - if not isinstance(e, Error): ++ 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(e)) ++ raise Error(str(exp)) + raise - _wrap.func_name = f.func_name ++ _wrap.func_name = afunc.func_name + return _wrap diff --cc extensions/_faults.py index 51866d5bc,000000000..cb44fd187 mode 100644,000000..100644 --- a/extensions/_faults.py +++ b/extensions/_faults.py @@@ -1,159 -1,0 +1,156 @@@ +""" +# 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 - import webob.exc + +from quantum.api import api_common as common +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 ctor.""" - #print ("*********TEST2") + # 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}} + # '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.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 + """ - #print ("*********TEST1") + 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 --cc extensions/_novatenant_view.py index bcfe1f476,000000000..6843361fb mode 100644,000000..100644 --- a/extensions/_novatenant_view.py +++ b/extensions/_novatenant_view.py @@@ -1,43 -1,0 +1,46 @@@ +""" +# 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. +# +""" ++ ++ +def get_view_builder(req): ++ """get view builder """ + base_url = req.application_url + return ViewBuilder(base_url) + + +class ViewBuilder(object): + """ + ViewBuilder for novatenant, + derived from quantum.views.networks + """ + def __init__(self, base_url): + """ + :param base_url: url of the root wsgi application + """ + self.base_url = base_url + + def build_host(self, host_data): + """Return host description.""" - return dict(host_desc=host_data['host_desc']) ++ return dict(host_list=host_data['host_list']) + + def build_vif(self, vif_data): + """Return VIF description.""" + return dict(vif_desc=vif_data['vif_desc']) diff --cc extensions/_pprofiles.py index da541274f,000000000..c3d814760 mode 100644,000000..100644 --- a/extensions/_pprofiles.py +++ b/extensions/_pprofiles.py @@@ -1,60 -1,0 +1,63 @@@ +""" +# 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. +# +""" ++ ++ +def get_view_builder(req): ++ """get view builder""" + base_url = req.application_url + return ViewBuilder(base_url) + + +class ViewBuilder(object): + """ + ViewBuilder for Portprofile, + derived from quantum.views.networks + """ + def __init__(self, base_url): + """ + :param base_url: url of the root wsgi application + """ + self.base_url = base_url + + def build(self, portprofile_data, is_detail=False): + """Generic method used to generate a portprofile entity.""" + print "portprofile_DATA:%s" % portprofile_data + if is_detail: + portprofile = self._build_detail(portprofile_data) + else: + portprofile = self._build_simple(portprofile_data) + return portprofile + + def _build_simple(self, portprofile_data): + """Return a simple model of a portprofile""" + return dict(portprofile=dict(id=portprofile_data['profile_id'])) + + def _build_detail(self, portprofile_data): + """Return a detailed info of a portprofile.""" + if (portprofile_data['assignment'] == None): + return dict(portprofile=dict(id=portprofile_data['profile_id'], + name=portprofile_data['profile_name'], + qos_name=portprofile_data['qos_name'])) + else: + return dict(portprofile=dict(id=portprofile_data['profile_id'], + name=portprofile_data['profile_name'], + qos_name=portprofile_data['qos_name'], + assignment=portprofile_data['assignment'])) diff --cc extensions/_qos_view.py index 63fc9f3a0,000000000..ca3f76caf mode 100644,000000..100644 --- a/extensions/_qos_view.py +++ b/extensions/_qos_view.py @@@ -1,55 -1,0 +1,56 @@@ +""" +# 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. +# +""" ++ ++ +def get_view_builder(req): ++ """get view builder""" + base_url = req.application_url + return ViewBuilder(base_url) + + +class ViewBuilder(object): + """ + ViewBuilder for QoS, + derived from quantum.views.networks + """ + def __init__(self, base_url): + """ + :param base_url: url of the root wsgi application + """ + self.base_url = base_url + + def build(self, qos_data, is_detail=False): + """Generic method used to generate a QoS entity.""" - print "qos_DATA:%s" % qos_data + if is_detail: + qos = self._build_detail(qos_data) + else: + qos = self._build_simple(qos_data) + return qos + + def _build_simple(self, qos_data): + """Return a simple model of a server.""" + return dict(qos=dict(id=qos_data['qos_id'])) + + def _build_detail(self, qos_data): + """Return a simple model of a server.""" - + return dict(qos=dict(id=qos_data['qos_id'], + name=qos_data['qos_name'], + description=qos_data['qos_desc'])) diff --cc extensions/credential.py index 782fddaad,000000000..1e6422216 mode 100644,000000..100644 --- a/extensions/credential.py +++ b/extensions/credential.py @@@ -1,160 -1,0 +1,171 @@@ +""" +# 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 + +from webob import exc +from extensions import _credential_view as credential_view +from extensions import _exceptions as exception +from extensions import _faults as faults + +from quantum.api import api_common as common - from quantum.common import wsgi +from quantum.common import extensions +from quantum.manager import QuantumManager + +LOG = logging.getLogger('quantum.api.credentials') + + +class Credential(object): - ++ """extension class Credential""" + def __init__(self): + pass - - def get_name(self): ++ ++ @classmethod ++ def get_name(cls): ++ """ Returns Ext Resource Name """ + return "Cisco Credential" + - def get_alias(self): ++ @classmethod ++ def get_alias(cls): ++ """ Returns Ext Resource Alias """ + return "Cisco Credential" + - def get_description(self): ++ @classmethod ++ def get_description(cls): ++ """ Returns Ext Resource Description """ + return "Credential include username and password" + - def get_namespace(self): - return "" ++ @classmethod ++ def get_namespace(cls): ++ """ Returns Ext Resource Namespace """ ++ return "http://docs.ciscocloud.com/api/ext/credential/v1.0" + - def get_updated(self): ++ @classmethod ++ def get_updated(cls): ++ """ Returns Ext Resource Name """ + return "2011-07-25T13:25:27-06:00" + - def get_resources(self): ++ @classmethod ++ def get_resources(cls): ++ """ 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)] + + +class CredentialController(common.QuantumController): + """ credential API controller + based on QuantumController """ + + _credential_ops_param_list = [{ + 'param-name': 'credential_name', + 'required': True}, { + 'param-name': 'user_name', + 'required': True}, { + 'param-name': 'password', + 'required': True}] + + _serialization_metadata = { + "application/xml": { + "attributes": { + "credential": ["id", "name"], + }, + }, + } + + def __init__(self, plugin): + self._resource_name = 'credential' - super(CredentialController, self).__init__(plugin) ++ self._plugin = plugin ++ #super(CredentialController, self).__init__(plugin) + + def index(self, request, tenant_id): + """ Returns a list of credential ids """ + #TODO: this should be for a given tenant!!! + return self._items(request, tenant_id, is_detail=False) + + def _items(self, request, tenant_id, is_detail): + """ Returns a list of credentials. """ + credentials = self._plugin.get_all_credentials(tenant_id) + builder = credential_view.get_view_builder(request) + result = [builder.build(credential, is_detail)['credential'] + for credential in credentials] + return dict(credentials=result) + ++ # pylint: disable-msg=E1101,W0613 + def show(self, request, tenant_id, id): + """ Returns credential details for the given credential id """ + try: + credential = self._plugin.get_credential_details( + tenant_id, id) + builder = credential_view.get_view_builder(request) + #build response with details + result = builder.build(credential, True) + return dict(credentials=result) - except exception.CredentialNotFound as e: - return faults.Fault(faults.CredentialNotFound(e)) - - #return faults.Fault(e) ++ except exception.CredentialNotFound as exp: ++ return faults.Fault(faults.CredentialNotFound(exp)) + + 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, + self._credential_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + credential = self._plugin.\ + create_credential(tenant_id, + req_params['credential_name'], + req_params['user_name'], + req_params['password']) + builder = credential_view.get_view_builder(request) + result = builder.build(credential) + return dict(credentials=result) + + def update(self, request, tenant_id, id): + """ Updates the name for the credential with the given id """ + try: + req_params = \ + self._parse_request_params(request, + self._credential_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + try: + credential = self._plugin.\ + rename_credential(tenant_id, + id, req_params['credential_name']) + + builder = credential_view.get_view_builder(request) + result = builder.build(credential, True) + return dict(credentials=result) - except exception.CredentialNotFound as e: - return faults.Fault(faults.CredentialNotFound(e)) ++ except exception.CredentialNotFound as exp: ++ return faults.Fault(faults.CredentialNotFound(exp)) + + def delete(self, request, tenant_id, id): + """ Destroys the credential with the given id """ + try: + self._plugin.delete_credential(tenant_id, id) + return exc.HTTPAccepted() - except exception.CredentialNotFound as e: - return faults.Fault(faults.CredentialNotFound(e)) ++ except exception.CredentialNotFound as exp: ++ return faults.Fault(faults.CredentialNotFound(exp)) + diff --cc extensions/novatenant.py index 9d37fe2ca,000000000..eddab4c17 mode 100644,000000..100644 --- a/extensions/novatenant.py +++ b/extensions/novatenant.py @@@ -1,164 -1,0 +1,175 @@@ +""" +# 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. +# +""" +from webob import exc + +from extensions import _novatenant_view as novatenant_view +from extensions import _exceptions as exception +from extensions import _faults as faults + +from quantum.api import api_common as common - from quantum.common import wsgi +from quantum.common import extensions +from quantum.manager import QuantumManager + + +class Novatenant(object): - ++ """extension class Novatenant""" + def __init__(self): + pass + - def get_name(self): ++ @classmethod ++ def get_name(cls): ++ """ Returns Ext Resource Name """ + return "Cisco Nova Tenant" - - def get_alias(self): ++ ++ @classmethod ++ def get_alias(cls): ++ """ Returns Ext Resource Name """ + return "Cisco Nova Tenant" - - def get_description(self): ++ ++ @classmethod ++ def get_description(cls): ++ """ Returns Ext Resource Name """ + return "novatenant resource is used by nova side to invoke quantum api" - - def get_namespace(self): - return "" - - def get_updated(self): ++ ++ @classmethod ++ def get_namespace(cls): ++ """ Returns Ext Resource Name """ ++ return "http://docs.ciscocloud.com/api/ext/novatenant/v1.0" ++ ++ @classmethod ++ def get_updated(cls): ++ """ Returns Ext Resource Name """ + return "2011-08-09T13:25:27-06:00" - - def get_resources(self): ++ ++ @classmethod ++ def get_resources(cls): ++ """ Returns Ext Resource Name """ + parent_resource = dict(member_name="tenant", + collection_name="extensions/csco/tenants") + member_actions = {'get_host': "PUT", + 'get_instance_port': "PUT"} + controller = NovatenantsController(QuantumManager.get_plugin()) + return [extensions.ResourceExtension('novatenants', controller, + parent=parent_resource, + member_actions=member_actions)] + + +class NovatenantsController(common.QuantumController): + """ Novatenant API controller + based on QuantumController """ + + _Novatenant_ops_param_list = [{ + 'param-name': 'novatenant_name', + 'required': True}] + + _get_host_ops_param_list = [{ + 'param-name': 'instance_id', + 'required': True}, { + 'param-name': 'instance_desc', + 'required': True}] + + _serialization_metadata = { + "application/xml": { + "attributes": { + "novatenant": ["id", "name"], + }, + }, + } + + def __init__(self, plugin): + self._resource_name = 'novatenant' - super(NovatenantsController, self).__init__(plugin) ++ 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" + ++ # 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 + def get_host(self, request, tenant_id, id): + content_type = request.best_match_content_type() + print "Content type:%s" % content_type + + try: + req_params = \ + self._parse_request_params(request, + self._get_host_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + instance_id = req_params['instance_id'] + + instance_desc = req_params['instance_desc'] + try: + host = self._plugin.get_host(tenant_id, instance_id, instance_desc) + builder = novatenant_view.get_view_builder(request) + result = builder.build_host(host) + return result + #return exc.HTTPAccepted() - except exception.NovatenantNotFound as e: - return faults.Fault(faults.NovatenantNotFound(e)) - except exception.PortNotFound as e: - return faults.Fault(faults.PortNotFound(e)) ++ except exception.NovatenantNotFound as exp: ++ return faults.Fault(faults.NovatenantNotFound(exp)) ++ except exception.PortNotFound as exp: ++ return faults.Fault(faults.PortNotFound(exp)) + - #added for Cisco extension + def get_instance_port(self, request, tenant_id, id): + content_type = request.best_match_content_type() + print "Content type:%s" % content_type + + try: + req_params = \ + self._parse_request_params(request, + self._get_host_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + instance_id = req_params['instance_id'] + + instance_desc = req_params['instance_desc'] + try: + vif = self._plugin. \ + get_instance_port(tenant_id, instance_id, instance_desc) + builder = novatenant_view.get_view_builder(request) + result = builder.build_vif(vif) + return result + - return exc.HTTPAccepted() - except exception.NovatenantNotFound as e: - return faults.Fault(faults.NovatenantNotFound(e)) - except exception.PortNotFound as e: - return faults.Fault(faults.PortNotFound(e)) ++ except exception.NovatenantNotFound as exp: ++ return faults.Fault(faults.NovatenantNotFound(exp)) ++ except exception.PortNotFound as exp: ++ return faults.Fault(faults.PortNotFound(exp)) diff --cc extensions/portprofile.py index fce20facd,000000000..8186f6903 mode 100644,000000..100644 --- a/extensions/portprofile.py +++ b/extensions/portprofile.py @@@ -1,220 -1,0 +1,223 @@@ +""" +# 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. +# +""" + +from webob import exc + +from extensions import _pprofiles as pprofiles_view +from extensions import _exceptions as exception +from extensions import _faults as faults + +from quantum.api import api_common as common - from quantum.common import wsgi +from quantum.common import extensions +from quantum.manager import QuantumManager + + +class Portprofile(object): - ++ """extension class Portprofile""" + def __init__(self): + pass - - def get_name(self): ++ ++ @classmethod ++ def get_name(cls): + """ Returns Ext Resource Name """ + return "Cisco Port Profile" - - def get_alias(self): ++ ++ @classmethod ++ def get_alias(cls): + """ Returns Ext Resource alias """ + return "Cisco Port Profile" - - def get_description(self): ++ ++ @classmethod ++ def get_description(cls): + """ Returns Ext Resource Description """ + return "Portprofile include QoS information" - - def get_namespace(self): ++ ++ @classmethod ++ def get_namespace(cls): + """ Returns Ext Resource Namespace """ - return "" - - def get_updated(self): ++ return "http://docs.ciscocloud.com/api/ext/portprofile/v1.0" ++ ++ @classmethod ++ def get_updated(cls): + """ Returns Ext Resource Updateed time """ + return "2011-07-23T13:25:27-06:00" - - def get_resources(self): ++ ++ @classmethod ++ def get_resources(cls): + """ Returns all defined resources """ + parent_resource = dict(member_name="tenant", + collection_name="extensions/csco/tenants") + member_actions = {'associate_portprofile': "PUT", + 'disassociate_portprofile': "POST"} + controller = PortprofilesController(QuantumManager.get_plugin()) + return [extensions.ResourceExtension('portprofiles', controller, + parent=parent_resource, + member_actions=member_actions)] + - ++ +class PortprofilesController(common.QuantumController): + """ portprofile API controller + based on QuantumController """ ++ ++ def __init__(self, plugin): ++ self._resource_name = 'portprofile' ++ self._plugin = plugin ++ #super(PortprofilesController, self).__init__(plugin) + - _portprofile_ops_param_list = [{ ++ self._portprofile_ops_param_list = [{ + 'param-name': 'portprofile_name', + 'required': True}, { + 'param-name': 'qos_name', + 'required': True}, { + 'param-name': 'assignment', + 'required': False}] + - _assignprofile_ops_param_list = [{ ++ self._assignprofile_ops_param_list = [{ + 'param-name': 'network-id', + 'required': True}, { + 'param-name': 'port-id', + 'required': True}] + - _serialization_metadata = { ++ self._serialization_metadata = { + "application/xml": { + "attributes": { + "portprofile": ["id", "name"], + }, + }, + } - - def __init__(self, plugin): - self._resource_name = 'portprofile' - self._plugin = plugin - super(PortprofilesController, self).__init__(plugin) - ++ + def index(self, request, tenant_id): + """ Returns a list of portprofile ids """ - #TODO: this should be for a given tenant!!! + return self._items(request, tenant_id, is_detail=False) + + def _items(self, request, tenant_id, is_detail): + """ Returns a list of portprofiles. """ + portprofiles = self._plugin.get_all_portprofiles(tenant_id) + builder = pprofiles_view.get_view_builder(request) + result = [builder.build(portprofile, is_detail)['portprofile'] + for portprofile in portprofiles] + return dict(portprofiles=result) + ++ # pylint: disable-msg=E1101 + def show(self, request, tenant_id, id): + """ Returns portprofile details for the given portprofile id """ + try: + portprofile = self._plugin.get_portprofile_details( + tenant_id, id) + builder = pprofiles_view.get_view_builder(request) + #build response with details + result = builder.build(portprofile, True) + return dict(portprofiles=result) - except exception.PortprofileNotFound as e: - return faults.Fault(faults.PortprofileNotFound(e)) - #return faults.Fault(e) ++ 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 """ + #look for portprofile name in request + try: + req_params = \ + self._parse_request_params(request, + self._portprofile_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + portprofile = self._plugin.\ + create_portprofile(tenant_id, + req_params['portprofile_name'], + req_params['qos_name']) + builder = pprofiles_view.get_view_builder(request) + result = builder.build(portprofile) + return dict(portprofiles=result) + + def update(self, request, tenant_id, id): + """ Updates the name for the portprofile with the given id """ + try: + req_params = \ + self._parse_request_params(request, + self._portprofile_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + try: + portprofile = self._plugin.\ + rename_portprofile(tenant_id, + id, req_params['portprofile_name']) + + builder = pprofiles_view.get_view_builder(request) + result = builder.build(portprofile, True) + return dict(portprofiles=result) - except exception.PortprofileNotFound as e: - return faults.Fault(faults.PortprofileNotFound(e)) ++ except exception.PortprofileNotFound as exp: ++ return faults.Fault(faults.PortprofileNotFound(exp)) + + def delete(self, request, tenant_id, id): + """ Destroys the portprofile with the given id """ + try: + self._plugin.delete_portprofile(tenant_id, id) + return exc.HTTPAccepted() - except exception.PortprofileNotFound as e: - return faults.Fault(faults.PortprofileNotFound(e)) ++ except exception.PortprofileNotFound as exp: ++ return faults.Fault(faults.PortprofileNotFound(exp)) + - #added for cisco's extension + def associate_portprofile(self, request, tenant_id, id): + """ associate a portprofile to the port """ + content_type = request.best_match_content_type() + print "Content type:%s" % content_type + + try: + req_params = \ + self._parse_request_params(request, + self._assignprofile_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ 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, + net_id, port_id, + id) + return exc.HTTPAccepted() - except exception.PortprofileNotFound as e: - return faults.Fault(faults.PortprofileNotFound(e)) - except exception.PortNotFound as e: - return faults.Fault(faults.PortNotFound(e)) ++ except exception.PortprofileNotFound as exp: ++ return faults.Fault(faults.PortprofileNotFound(exp)) ++ except exception.PortNotFound as exp: ++ return faults.Fault(faults.PortNotFound(exp)) + - #added for Cisco extension + def disassociate_portprofile(self, request, tenant_id, id): + """ Disassociate a portprofile from a port """ + content_type = request.best_match_content_type() + print "Content type:%s" % content_type + + try: + req_params = \ + self._parse_request_params(request, + self._assignprofile_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ 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. \ + disassociate_portprofile(tenant_id, + net_id, port_id, id) + return exc.HTTPAccepted() - except exception.PortprofileNotFound as e: - return faults.Fault(faults.PortprofileNotFound(e)) - except exception.PortNotFound as e: - return faults.Fault(faults.PortNotFound(e)) ++ except exception.PortprofileNotFound as exp: ++ return faults.Fault(faults.PortprofileNotFound(exp)) ++ except exception.PortNotFound as exp: ++ return faults.Fault(faults.PortNotFound(exp)) diff --cc extensions/qos.py index 777883d8c,000000000..a11f41af7 mode 100644,000000..100644 --- a/extensions/qos.py +++ b/extensions/qos.py @@@ -1,155 -1,0 +1,165 @@@ +""" +# 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 + +from webob import exc +from extensions import _qos_view as qos_view +from extensions import _exceptions as exception +from extensions import _faults as faults + +from quantum.api import api_common as common - from quantum.common import wsgi +from quantum.common import extensions +from quantum.manager import QuantumManager + +LOG = logging.getLogger('quantum.api.qoss') + + +class Qos(object): - ++ """Qos extension file""" + def __init__(self): + pass - - def get_name(self): ++ ++ @classmethod ++ def get_name(cls): ++ """ Returns Ext Resource Name """ + return "Cisco qos" + - def get_alias(self): ++ @classmethod ++ def get_alias(cls): ++ """ Returns Ext Resource Alias """ + return "Cisco qos" + - def get_description(self): ++ @classmethod ++ def get_description(cls): ++ """ Returns Ext Resource Description """ + return "qos include username and password" + - def get_namespace(self): - return "" - - def get_updated(self): ++ @classmethod ++ def get_namespace(cls): ++ """ Returns Ext Resource Namespace """ ++ return "http://docs.ciscocloud.com/api/ext/qos/v1.0" ++ ++ @classmethod ++ def get_updated(cls): ++ """ Returns Ext Resource update """ + return "2011-07-25T13:25:27-06:00" + - def get_resources(self): ++ @classmethod ++ def get_resources(cls): ++ """ Returns Ext Resources """ + parent_resource = dict(member_name="tenant", + collection_name="extensions/csco/tenants") + + controller = QosController(QuantumManager.get_plugin()) + return [extensions.ResourceExtension('qoss', controller, + parent=parent_resource)] + + +class QosController(common.QuantumController): + """ qos API controller + based on QuantumController """ + + _qos_ops_param_list = [{ + 'param-name': 'qos_name', + 'required': True}, { + 'param-name': 'qos_desc', + 'required': True}] + _serialization_metadata = { + "application/xml": { + "attributes": { + "qos": ["id", "name"], + }, + }, + } + + def __init__(self, plugin): + self._resource_name = 'qos' - super(QosController, self).__init__(plugin) ++ self._plugin = plugin ++ #super(QosController, self).__init__(plugin) + + def index(self, request, tenant_id): + """ Returns a list of qos ids """ - #TODO: this should be for a given tenant!!! + return self._items(request, tenant_id, is_detail=False) + + def _items(self, request, tenant_id, is_detail): + """ Returns a list of qoss. """ + qoss = self._plugin.get_all_qoss(tenant_id) + builder = qos_view.get_view_builder(request) + result = [builder.build(qos, is_detail)['qos'] + for qos in qoss] + return dict(qoss=result) + ++ # pylint: disable-msg=E1101 + def show(self, request, tenant_id, id): + """ Returns qos details for the given qos id """ + try: + qos = self._plugin.get_qos_details( + tenant_id, id) + builder = qos_view.get_view_builder(request) + #build response with details + result = builder.build(qos, True) + return dict(qoss=result) - except exception.QosNotFound as e: - return faults.Fault(faults.QosNotFound(e)) - - #return faults.Fault(e) ++ except exception.QosNotFound as exp: ++ return faults.Fault(faults.QosNotFound(exp)) + + def create(self, request, tenant_id): + """ Creates a new qos for a given tenant """ + #look for qos name in request + try: + req_params = \ + self._parse_request_params(request, + self._qos_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + qos = self._plugin.\ + create_qos(tenant_id, + req_params['qos_name'], + req_params['qos_desc']) + builder = qos_view.get_view_builder(request) + result = builder.build(qos) + return dict(qoss=result) + + def update(self, request, tenant_id, id): + """ Updates the name for the qos with the given id """ + try: + req_params = \ + self._parse_request_params(request, + self._qos_ops_param_list) - except exc.HTTPError as e: - return faults.Fault(e) ++ except exc.HTTPError as exp: ++ return faults.Fault(exp) + try: + qos = self._plugin.\ + rename_qos(tenant_id, + id, req_params['qos_name']) + + builder = qos_view.get_view_builder(request) + result = builder.build(qos, True) + return dict(qoss=result) - except exception.QosNotFound as e: - return faults.Fault(faults.QosNotFound(e)) ++ except exception.QosNotFound as exp: ++ return faults.Fault(faults.QosNotFound(exp)) + + def delete(self, request, tenant_id, id): + """ Destroys the qos with the given id """ + try: + self._plugin.delete_qos(tenant_id, id) + return exc.HTTPAccepted() - except exception.QosNotFound as e: - return faults.Fault(faults.QosNotFound(e)) ++ except exception.QosNotFound as exp: ++ return faults.Fault(faults.QosNotFound(exp)) diff --cc quantum/plugins/cisco/CiscoPlugin.py index bed81abf7,000000000..9300f34a2 mode 100644,000000..100644 --- a/quantum/plugins/cisco/CiscoPlugin.py +++ b/quantum/plugins/cisco/CiscoPlugin.py @@@ -1,562 -1,0 +1,562 @@@ +from quantum.common import exceptions as exc +from extensions import _exceptions as extexc + + +class CiscoPaloPlugin2(object): + """ + This plugin has internal data structure + derived from quantum fakeplugin + """ + + #static data for networks and ports + _port_dict_1 = { + 1: {'port-id': 1, + 'port-state': 'DOWN', + 'attachment': None, + 'portprofile': None}, + 2: {'port-id': 2, + 'port-state': 'UP', + 'attachment': None, + 'portprofile': None}} + _port_dict_2 = { + 1: {'port-id': 1, + 'port-state': 'UP', + 'attachment': 'SomeFormOfVIFID', + 'portprofile': '001'}, + 2: {'port-id': 2, + 'port-state': 'DOWN', + 'attachment': None, + 'portprofile': '001'}} + _networks = {'001': + { + 'net-id': '001', + 'net-name': 'pippotest', + 'net-ports': _port_dict_1}, + '002': + { + 'net-id': '002', + 'net-name': 'cicciotest', + 'net-ports': _port_dict_2}} + _portprofiles = {'001': + { + 'profile_id': '001', + 'profile_name': 'pprofiletest', + 'assignment': ['1', '2'], + 'qos_name': '001'}, + '002': + { + 'profile_id': '002', + 'profile_name': 'cicciotest', + 'qos_name': '002', + 'assignment': None}} + + _credentials = {'001': + { + 'credential_id': '001', + 'credential_name': 'cred1', + 'user_name': 'ying', + 'password': 'yingTest'}, + '002': + { + 'credential_id': '002', + 'credential_name': 'cred2', + 'user_name': 'admin', + 'password': 'adminTest'}} + _qoss = {'001': + { + 'qos_id': '001', + 'qos_name': 'silver', + 'qos_desc': {'pps':170, 'TTL':20}}, + '002': + { + 'qos_id': '002', + 'qos_name': 'gold', + 'qos_desc': {'pps':340, 'TTL':10}}} + - _host = {'host_desc': { ++ _host = {'host_list': { + "host_key1": "host_value1", + "host_key2": "host_value2"}} + _vif = {'vif_desc': { + "vif_key1": "vif_value1", + "vif_key2": "vif_value2"} + } + + + supported_extension_aliases = ["Cisco Credential", "Cisco Port Profile", "Cisco qos", "Cisco Nova Tenant"] + + + """ + def supports_extension(self, extension): + #return extension.get_alias() == "Cisco Port Profile" + return extension.get_alias() == "Cisco Credential" + """ + def __init__(self): + CiscoPaloPlugin2._net_counter = \ + len(CiscoPaloPlugin2._networks) + + CiscoPaloPlugin2._profile_counter = \ + len(CiscoPaloPlugin2._portprofiles) + + CiscoPaloPlugin2._credential_counter = \ + len(CiscoPaloPlugin2._credentials) + + CiscoPaloPlugin2._qos_counter = \ + len(CiscoPaloPlugin2._qoss) + def _get_network(self, tenant_id, network_id): + + network = CiscoPaloPlugin2._networks.get(network_id) + if not network: + raise exc.NetworkNotFound(net_id=network_id) + return network + + + + def _get_credential(self, tenant_id, credential_id): + credential = CiscoPaloPlugin2._credentials.get(credential_id) + if not credential: + raise extexc.CredentialNotFound(credential_id=credential_id) + return credential + + def _get_qos(self, tenant_id, qos_id): + qos = CiscoPaloPlugin2._qoss.get(qos_id) + if not qos: + raise extexc.QosNotFound(qos_id=qos_id) + return qos + + def _get_port(self, tenant_id, network_id, port_id): + net = self._get_network(tenant_id, network_id) + port = net['net-ports'].get(int(port_id)) + if not port: + raise exc.PortNotFound(net_id=network_id, port_id=port_id) + return port + + def _validate_port_state(self, port_state): + if port_state.upper() not in ('UP', 'DOWN'): + raise exc.StateInvalid(port_state=port_state) + return True + + def _validate_attachment(self, tenant_id, network_id, port_id, + remote_interface_id): + network = self._get_network(tenant_id, network_id) + for port in network['net-ports'].values(): + if port['attachment'] == remote_interface_id: + raise exc.AlreadyAttached(net_id=network_id, + port_id=port_id, + att_id=port['attachment'], + att_port_id=port['port-id']) + + def get_all_networks(self, tenant_id): + """ + Returns a dictionary containing all + for + the specified tenant. + """ + print("get_all_networks() called\n") + return CiscoPaloPlugin2._networks.values() + + def get_network_details(self, tenant_id, net_id): + """ + retrieved a list of all the remote vifs that + are attached to the network + """ + print("get_network_details() called\n") + return self._get_network(tenant_id, net_id) + + def create_network(self, tenant_id, net_name): + """ + Creates a new Virtual Network, and assigns it + a symbolic name. + """ + print("create_network() called\n") + CiscoPaloPlugin2._net_counter += 1 + new_net_id = ("0" * (3 - len(str(CiscoPaloPlugin2._net_counter)))) + \ + str(CiscoPaloPlugin2._net_counter) + print new_net_id + new_net_dict = {'net-id': new_net_id, + 'net-name': net_name, + 'net-ports': {}} + CiscoPaloPlugin2._networks[new_net_id] = new_net_dict + # return network_id of the created network + return new_net_dict + + def delete_network(self, tenant_id, net_id): + """ + Deletes the network with the specified network identifier + belonging to the specified tenant. + """ + print("delete_network() called\n") + net = CiscoPaloPlugin2._networks.get(net_id) + # Verify that no attachments are plugged into the network + if net: + if net['net-ports']: + for port in net['net-ports'].values(): + if port['attachment']: + raise exc.NetworkInUse(net_id=net_id) + CiscoPaloPlugin2._networks.pop(net_id) + return net + # Network not found + raise exc.NetworkNotFound(net_id=net_id) + + def rename_network(self, tenant_id, net_id, new_name): + """ + Updates the symbolic name belonging to a particular + Virtual Network. + """ + print("rename_network() called\n") + net = self._get_network(tenant_id, net_id) + net['net-name'] = new_name + return net + + def _get_portprofile(self, tenant_id, portprofile_id): + portprofile = CiscoPaloPlugin2._portprofiles.get(portprofile_id) + if not portprofile: + raise extexc.PortprofileNotFound(portprofile_id=portprofile_id) + return portprofile + + def get_all_portprofiles(self, tenant_id): + """ + Returns a dictionary containing all + for + the specified tenant. + """ + print("get_all_portprofiles() called\n") + return CiscoPaloPlugin2._portprofiles.values() + + def get_portprofile_details(self, tenant_id, profile_id): + """ + retrieved a list of all the remote vifs that + are attached to the portprofile + """ + print("get_portprofile_details() called\n") + return self._get_portprofile(tenant_id, profile_id) + + def create_portprofile(self, tenant_id, profile_name, vlan_id): + """ + Creates a new Virtual portprofile, and assigns it + a symbolic name. + """ + print("create_portprofile() called\n") + CiscoPaloPlugin2._profile_counter += 1 + new_profile_id = ("0" * \ + (3 - \ + len(str(CiscoPaloPlugin2._profile_counter)))) + \ + str(CiscoPaloPlugin2._profile_counter) + print new_profile_id + new_profile_dict = {'profile_id': new_profile_id, + 'profile_name': profile_name, + 'qos_name': vlan_id, + 'assignment': None} + CiscoPaloPlugin2._portprofiles[new_profile_id] = new_profile_dict + # return portprofile_id of the created portprofile + return new_profile_dict + + def delete_portprofile(self, tenant_id, profile_id): + """ + Deletes the portprofile with the specified portprofile identifier + belonging to the specified tenant. + """ + print("delete_portprofile() called\n") + profile = CiscoPaloPlugin2._portprofiles.get(profile_id) + # Verify that no attachments are plugged into the portprofile + if profile: + CiscoPaloPlugin2._portprofiles.pop(profile_id) + return profile + # portprofile not found + raise extexc.PortprofileNotFound(profile_id=profile_id) + + def rename_portprofile(self, tenant_id, profile_id, new_name): + """ + Updates the symbolic name belonging to a particular + Virtual portprofile. + """ + print("rename_portprofile() called\n") + profile = self._get_portprofile(tenant_id, profile_id) + profile['profile_name'] = new_name + return profile + + + + def associate_portprofile(self, tenant_id, net_id, port_id, pprofile_id): + """ + Assign portprofile to the specified port on the + specified Virtual Network. + """ + print("assign_portprofile() called\n") + print("net_id " + net_id) + # Validate attachment + #self._validate_attachment(tenant_id, net_id, port_id, + # remote_interface_id) + #TODO: modify the exception + port = self._get_port(tenant_id, net_id, port_id) + if (not port['portprofile'] == None): + raise exc.PortInUse(net_id=net_id, port_id=port_id, + att_id=port['portprofile']) + port['portprofile'] = pprofile_id + + def disassociate_portprofile(self, tenant_id, net_id, port_id, portprofile_id): + """ + De-assign a portprofile from the specified port on the + specified Virtual Network. + """ + print("deassign_portprofile() called\n") + #print("*******net_id is "+net_id) + port = self._get_port(tenant_id, net_id, port_id) + + port['portprofile'] = None + #TODO: + #modify assignment[portprofile_id] to remove this port + + #TODO: add new data structure to + #hold all the assignment for a specific portprofile + def get_portprofile_assignment(self, tenant_id, net_id, port_id): + print("get portprofile assignment called\n") + port = self._get_port(tenant_id, net_id, port_id) + ppid = port['portprofile'] + if (ppid == None): + print("***no portprofile attached") + return "no portprofile attached" + else: + print("***attached portprofile id is " + ppid) + return ("attached portprofile " + ppid) + + + def get_all_credentials(self, tenant_id): + """ + Returns a dictionary containing all + for + the specified tenant. + """ + print("get_all_credentials() called\n") + return CiscoPaloPlugin2._credentials.values() + + def get_credential_details(self, tenant_id, credential_id): + """ + retrieved a list of all the remote vifs that + are attached to the credential + """ + print("get_credential_details() called\n") + return self._get_credential(tenant_id, credential_id) + + def create_credential(self, tenant_id, credential_name, user_name, password): + """ + Creates a new Virtual credential, and assigns it + a symbolic name. + """ + print("create_credential() called\n") + CiscoPaloPlugin2._credential_counter += 1 + new_credential_id = ("0" * \ + (3 - \ + len(str(CiscoPaloPlugin2._credential_counter)))) + \ + str(CiscoPaloPlugin2._credential_counter) + print new_credential_id + new_credential_dict = {'credential_id': new_credential_id, + 'credential_name': credential_name, + 'user_name': user_name, + 'password': password} + CiscoPaloPlugin2._credentials[new_credential_id] = new_credential_dict + # return credential_id of the created credential + return new_credential_dict + + def delete_credential(self, tenant_id, credential_id): + """ + Deletes the credential with the specified credential identifier + belonging to the specified tenant. + """ + print("delete_credential() called\n") + credential = CiscoPaloPlugin2._credentials.get(credential_id) + + if credential: + CiscoPaloPlugin2._credentials.pop(credential_id) + return credential + # credential not found + raise extexc.CredentialNotFound(credential_id=credential_id) + + def rename_credential(self, tenant_id, credential_id, new_name): + """ + Updates the symbolic name belonging to a particular + Virtual credential. + """ + print("rename_credential() called\n") + credential = self._get_credential(tenant_id, credential_id) + credential['credential_name'] = new_name + return credential + + + def get_all_qoss(self, tenant_id): + """ + Returns a dictionary containing all + for + the specified tenant. + """ + print("get_all_qoss() called\n") + return CiscoPaloPlugin2._qoss.values() + + def get_qos_details(self, tenant_id, qos_id): + """ + retrieved a list of all the remote vifs that + are attached to the qos + """ + print("get_qos_details() called\n") + return self._get_qos(tenant_id, qos_id) + + def create_qos(self, tenant_id, qos_name, qos_desc): + """ + Creates a new Virtual qos, and assigns it + a symbolic name. + """ + print("create_qos() called\n") + CiscoPaloPlugin2._qos_counter += 1 + new_qos_id = ("0" * \ + (3 - \ + len(str(CiscoPaloPlugin2._qos_counter)))) + \ + str(CiscoPaloPlugin2._qos_counter) + print new_qos_id + new_qos_dict = {'qos_id': new_qos_id, + 'qos_name': qos_name, + 'qos_desc': qos_desc} + + print("************************") + print("test dictionary data") + print(qos_desc['TTL']) + print("************************") + + CiscoPaloPlugin2._qoss[new_qos_id] = new_qos_dict + # return qos_id of the created qos + return new_qos_dict + + def delete_qos(self, tenant_id, qos_id): + """ + Deletes the qos with the specified qos identifier + belonging to the specified tenant. + """ + print("delete_qos() called\n") + qos = CiscoPaloPlugin2._qoss.get(qos_id) + # Verify that no attachments are plugged into the qos + if qos: + CiscoPaloPlugin2._qoss.pop(qos_id) + return qos + # qos not found + raise extexc.QosNotFound(qos_id=qos_id) + + def rename_qos(self, tenant_id, qos_id, new_name): + """ + Updates the symbolic name belonging to a particular + Virtual qos. + """ + print("rename_qos() called\n") + qos = self._get_qos(tenant_id, qos_id) + qos['qos_name'] = new_name + return qos + + + + + def get_all_ports(self, tenant_id, net_id): + """ + Retrieves all port identifiers belonging to the + specified Virtual Network. + """ + print("get_all_ports() called\n") + network = self._get_network(tenant_id, net_id) + ports_on_net = network['net-ports'].values() + return ports_on_net + + def get_port_details(self, tenant_id, net_id, port_id): + """ + This method allows the user to retrieve a remote interface + that is attached to this particular port. + """ + print("get_port_details() called\n") + return self._get_port(tenant_id, net_id, port_id) + + def create_port(self, tenant_id, net_id, port_state=None): + """ + Creates a port on the specified Virtual Network. + """ + print("create_port() called\n") + net = self._get_network(tenant_id, net_id) + # check port state + # TODO(salvatore-orlando): Validate port state in API? + self._validate_port_state(port_state) + ports = net['net-ports'] + new_port_id = max(ports.keys()) + 1 + new_port_dict = {'port-id': new_port_id, + 'port-state': port_state, + 'attachment': None, + 'portprofile': None} + ports[new_port_id] = new_port_dict + return new_port_dict + + def update_port(self, tenant_id, net_id, port_id, port_state): + """ + Updates the state of a port on the specified Virtual Network. + """ + print("create_port() called\n") + port = self._get_port(tenant_id, net_id, port_id) + self._validate_port_state(port_state) + port['port-state'] = port_state + return port + + def delete_port(self, tenant_id, net_id, port_id): + """ + Deletes a port on a specified Virtual Network, + if the port contains a remote interface attachment, + the remote interface is first un-plugged and then the port + is deleted. + """ + print("delete_port() called\n") + net = self._get_network(tenant_id, net_id) + port = self._get_port(tenant_id, net_id, port_id) + if port['attachment']: + raise exc.PortInUse(net_id=net_id, port_id=port_id, + att_id=port['attachment']) + try: + net['net-ports'].pop(int(port_id)) + except KeyError: + raise exc.PortNotFound(net_id=net_id, port_id=port_id) + + def get_interface_details(self, tenant_id, net_id, port_id): + print("get interface detail called\n") + port = self._get_port(tenant_id, net_id, port_id) + vid = port['attachment'] + if (vid == None): + print("***no interface is attached") + return "no interface attached" + else: + print("***interface id is " + vid) + return ("attached interface " + vid) + + def plug_interface(self, tenant_id, net_id, port_id, remote_interface_id): + """ + Attaches a remote interface to the specified port on the + specified Virtual Network. + """ + print("plug_interface() called\n") + # Validate attachment + self._validate_attachment(tenant_id, net_id, port_id, + remote_interface_id) + port = self._get_port(tenant_id, net_id, port_id) + if port['attachment']: + raise exc.PortInUse(net_id=net_id, port_id=port_id, + att_id=port['attachment']) + port['attachment'] = remote_interface_id + + def unplug_interface(self, tenant_id, net_id, port_id): + """ + Detaches a remote interface from the specified port on the + specified Virtual Network. + """ + print("unplug_interface() called\n") + port = self._get_port(tenant_id, net_id, port_id) + # TODO(salvatore-orlando): + # Should unplug on port without attachment raise an Error? + port['attachment'] = None + + def get_host(self, tenant_id, instance_id, instance_desc): + print("associate an instance to a port....") + print("get key2: " + instance_desc['key2']) + return CiscoPaloPlugin2._host + def get_instance_port(self, tenant_id, instance_id, instance_desc): + print("get instance associated port....") + print("get key1: " + instance_desc['key1']) + return CiscoPaloPlugin2._vif diff --cc tests/unit/test_extensions.py index 5ad2a193e,5ad2a193e..14435e914 --- a/tests/unit/test_extensions.py +++ b/tests/unit/test_extensions.py @@@ -69,14 -69,14 +69,13 @@@ class ResourceExtensionTest(unittest.Te res_ext = extensions.ResourceExtension('tweedles', self.ResourceExtensionController()) test_app = setup_extensions_test_app(SimpleExtensionManager(res_ext)) -- index_response = test_app.get("/tweedles") self.assertEqual(200, index_response.status_int) self.assertEqual("resource index", index_response.body) -- ++ show_response = test_app.get("/tweedles/25266") self.assertEqual({'data': {'id': "25266"}}, show_response.json) -- ++ def test_resource_extension_with_custom_member_action(self): controller = self.ResourceExtensionController() member = {'custom_member_action': "GET"}