]> review.fuel-infra Code Review - openstack-build/neutron-build.git/commitdiff
fix pylint issuses
authorYing Liu <yinliu2@cisco.com>
Thu, 18 Aug 2011 22:36:09 +0000 (15:36 -0700)
committerYing Liu <yinliu2@cisco.com>
Thu, 18 Aug 2011 22:36:09 +0000 (15:36 -0700)
13 files changed:
1  2 
cisco_demo/demo_client.py
extensions/_credential_view.py
extensions/_exceptions.py
extensions/_faults.py
extensions/_novatenant_view.py
extensions/_pprofiles.py
extensions/_qos_view.py
extensions/credential.py
extensions/novatenant.py
extensions/portprofile.py
extensions/qos.py
quantum/plugins/cisco/CiscoPlugin.py
tests/unit/test_extensions.py

index 74b4a6a7a0b435b6689cd7742059ce5d5b466023,0000000000000000000000000000000000000000..4f91abc93e7e552a16aea29cc1cd46cb2030330d
mode 100755,000000..100755
--- /dev/null
@@@ -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)
-     test_attach_resource('json') 
++    """
 +    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') 
-     #create_cisco_network('json')
-     #test_create_port('json')
-     #create_cisco_portprofile('json')
-     #test_assign_portprofile('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')
 +    pass
 +    
 +
 +# Standard boilerplate to call the main() function.
 +if __name__ == '__main__':
 +    main()
index 062e8fa934d911425d0651c5a9dfc323f052428b,0000000000000000000000000000000000000000..1c1cc3ac2cca6d9efbfebc790a46cfdd1bdcaf83
mode 100644,000000..100644
--- /dev/null
@@@ -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']))
index 99bc55da11bae35ecde5300ecd11049cdfab1994,0000000000000000000000000000000000000000..aeae4b647ec3b00878b964cdb7517044f569b998
mode 100644,000000..100644
--- /dev/null
@@@ -1,162 -1,0 +1,181 @@@
- def wrap_exception(f):
 +"""
 +# 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
 +
 +
-             return f(*args, **kw)
-         except Exception, e:
-             if not isinstance(e, Error):
++def wrap_exception(afunc):
++    """Wrap Exception"""
 +    def _wrap(*args, **kw):
++        """Internal Wrap Exception func"""
 +        try:
-                 raise Error(str(e))
++            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))
-     _wrap.func_name = f.func_name
++                raise Error(str(exp))
 +            raise
++    _wrap.func_name = afunc.func_name
 +    return _wrap
index 51866d5bc9fa66f579aacc49feaebf179e546332,0000000000000000000000000000000000000000..cb44fd1873ce6f690548ec306df97a582b424872
mode 100644,000000..100644
--- /dev/null
@@@ -1,159 -1,0 +1,156 @@@
- import webob.exc
 +"""
 +# 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
-         #print ("*********TEST2")
 +
 +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 ("*********TEST1")
 +        # 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
 +    """
 +    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.')
index bcfe1f476b7ac77c54edc5c5f5eb4f6831c98ece,0000000000000000000000000000000000000000..6843361fb212d0ef1b1157217d9719dcacc053da
mode 100644,000000..100644
--- /dev/null
@@@ -1,43 -1,0 +1,46 @@@
-         return dict(host_desc=host_data['host_desc'])
 +"""
 +# 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_list=host_data['host_list'])
 +    
 +    def build_vif(self, vif_data):
 +        """Return VIF description."""
 +        return dict(vif_desc=vif_data['vif_desc'])   
index da541274f9fe7dfa14305474c8f72004e2376dde,0000000000000000000000000000000000000000..c3d8147603715978980b91337ff330a79879dfc0
mode 100644,000000..100644
--- /dev/null
@@@ -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']))
index 63fc9f3a07904a5d554b96319ba5b0a730ef6177,0000000000000000000000000000000000000000..ca3f76caf1e54ad7a0be435bdd22915ba84bcc82
mode 100644,000000..100644
--- /dev/null
@@@ -1,55 -1,0 +1,56 @@@
-         print "qos_DATA:%s" % qos_data
 +"""
 +# 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."""
-         
 +        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']))
index 782fddaaddc019a8ead1bbebd6284657caf0fda3,0000000000000000000000000000000000000000..1e64222166fe063b139ffa339e1b506c17ab3465
mode 100644,000000..100644
--- /dev/null
@@@ -1,160 -1,0 +1,171 @@@
- from quantum.common import wsgi
 +"""
 +# 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 extensions
 +from quantum.manager import QuantumManager
 +
 +LOG = logging.getLogger('quantum.api.credentials')
 +
 +
 +class Credential(object):
-     def get_name(self):
++    """extension class Credential"""
 +    def __init__(self):
 +        pass
-     def get_alias(self):
++    
++    @classmethod
++    def get_name(cls):
++        """ Returns Ext Resource Name """
 +        return "Cisco Credential"
 +
-     def get_description(self):
++    @classmethod
++    def get_alias(cls):
++        """ Returns Ext Resource Alias """
 +        return "Cisco Credential"
 +
-     def get_namespace(self):
-         return ""
++    @classmethod
++    def get_description(cls):
++        """ Returns Ext Resource Description """
 +        return "Credential include username and password"
 +
-     def get_updated(self):
++    @classmethod
++    def get_namespace(cls):
++        """ Returns Ext Resource Namespace """
++        return "http://docs.ciscocloud.com/api/ext/credential/v1.0"
 +
-     def get_resources(self):
++    @classmethod
++    def get_updated(cls):
++        """ Returns Ext Resource Name """
 +        return "2011-07-25T13:25:27-06:00"
 +
-         super(CredentialController, self).__init__(plugin)
++    @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'
-         except exception.CredentialNotFound as e:
-             return faults.Fault(faults.CredentialNotFound(e))
-                                 
-             #return faults.Fault(e)
++        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 exc.HTTPError as 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 exception.CredentialNotFound as e:
-             return faults.Fault(faults.CredentialNotFound(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 exp:
++            return faults.Fault(faults.CredentialNotFound(exp))
 +        
index 9d37fe2ca459738997cea0f97d76820d1368d3ea,0000000000000000000000000000000000000000..eddab4c17f5ff797c8713b6ee12803e4287086bc
mode 100644,000000..100644
--- /dev/null
@@@ -1,164 -1,0 +1,175 @@@
- from quantum.common import wsgi
 +"""
 +# 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 extensions
 +from quantum.manager import QuantumManager
 +
 +
 +class Novatenant(object):
-     def get_name(self):
++    """extension class Novatenant"""
 +    def __init__(self):
 +        pass
 +
-     def get_alias(self):
++    @classmethod
++    def get_name(cls):
++        """ Returns Ext Resource Name """   
 +        return "Cisco Nova Tenant"
-     def get_description(self):
++    
++    @classmethod
++    def get_alias(cls):
++        """ Returns Ext Resource Name """
 +        return "Cisco Nova Tenant"
-     def get_namespace(self):
-         return ""
-     def get_updated(self):
++    
++    @classmethod
++    def get_description(cls):
++        """ Returns Ext Resource Name """
 +        return "novatenant resource is used by nova side to invoke quantum api"
-     def get_resources(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"
-         super(NovatenantsController, self).__init__(plugin)
++    
++    @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'
-         except exc.HTTPError as e:
-             return faults.Fault(e)
++        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 exception.NovatenantNotFound as e:
-             return faults.Fault(faults.NovatenantNotFound(e))
-         except exception.PortNotFound as e:
-             return faults.Fault(faults.PortNotFound(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()
-      #added for Cisco extension
++        except exception.NovatenantNotFound as exp:
++            return faults.Fault(faults.NovatenantNotFound(exp))
++        except exception.PortNotFound as exp:
++            return faults.Fault(faults.PortNotFound(exp))
 +        
-         except exc.HTTPError as e:
-             return faults.Fault(e)
 +    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)
-             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 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
 +            
++        except exception.NovatenantNotFound as exp:
++            return faults.Fault(faults.NovatenantNotFound(exp))
++        except exception.PortNotFound as exp:
++            return faults.Fault(faults.PortNotFound(exp))
index fce20facd0d75d2767c8ca7e7f9f2157b6973c21,0000000000000000000000000000000000000000..8186f6903db1f6f6597d4cff838b208d0f004462
mode 100644,000000..100644
--- /dev/null
@@@ -1,220 -1,0 +1,223 @@@
- from quantum.common import wsgi
 +"""
 +# 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 extensions
 +from quantum.manager import QuantumManager
 +
 +
 +class Portprofile(object):
-     def get_name(self):
++    """extension class Portprofile"""
 +    def __init__(self):
 +        pass
-     def get_alias(self):
++    
++    @classmethod
++    def get_name(cls):
 +        """ Returns Ext Resource Name """
 +        return "Cisco Port Profile"
-     def get_description(self):
++    
++    @classmethod
++    def get_alias(cls):
 +        """ Returns Ext Resource alias """
 +        return "Cisco Port Profile"
-     def get_namespace(self):
++    
++    @classmethod
++    def get_description(cls):
 +        """ Returns Ext Resource Description """
 +        return "Portprofile include QoS information"
-         return ""
-     def get_updated(self):
++    
++    @classmethod
++    def get_namespace(cls):
 +        """ Returns Ext Resource Namespace """
-     def get_resources(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"
-     
++    
++    @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)]
 +    
-     _portprofile_ops_param_list = [{
++     
 +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)
 +        
-     _assignprofile_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}]
 +    
-     _serialization_metadata = {
++        self._assignprofile_ops_param_list = [{
 +        'param-name': 'network-id',
 +        'required': True}, {
 +        'param-name': 'port-id',
 +        'required': True}]
 +    
-     
-     def __init__(self, plugin):
-         self._resource_name = 'portprofile'
-         self._plugin = plugin
-         super(PortprofilesController, self).__init__(plugin)
-              
++        self._serialization_metadata = {
 +        "application/xml": {
 +            "attributes": {
 +                "portprofile": ["id", "name"],
 +            },
 +        },
 +    }
-         #TODO: this should be for a given tenant!!!
++      
 +    def index(self, request, tenant_id):
 +        """ Returns a list of portprofile ids """
-         except exception.PortprofileNotFound as e:
-             return faults.Fault(faults.PortprofileNotFound(e))
-             #return faults.Fault(e)
 +        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 exc.HTTPError as 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 exception.PortprofileNotFound as e:
-             return faults.Fault(faults.PortprofileNotFound(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()
-     #added for cisco's extension
++        except exception.PortprofileNotFound as exp:
++            return faults.Fault(faults.PortprofileNotFound(exp))
 +         
-         except exc.HTTPError as e:
-             return faults.Fault(e)
 +    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 exception.PortprofileNotFound as e:
-             return faults.Fault(faults.PortprofileNotFound(e))
-         except exception.PortNotFound as e:
-             return faults.Fault(faults.PortNotFound(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()
-      #added for Cisco extension
++        except exception.PortprofileNotFound as exp:
++            return faults.Fault(faults.PortprofileNotFound(exp))
++        except exception.PortNotFound as exp:
++            return faults.Fault(faults.PortNotFound(exp))
 +        
-         except exc.HTTPError as e:
-             return faults.Fault(e)
 +    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 exception.PortprofileNotFound as e:
-             return faults.Fault(faults.PortprofileNotFound(e))
-         except exception.PortNotFound as e:
-             return faults.Fault(faults.PortNotFound(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 exp:
++            return faults.Fault(faults.PortprofileNotFound(exp))
++        except exception.PortNotFound as exp:
++            return faults.Fault(faults.PortNotFound(exp))
index 777883d8cf1002d8df3ace5b66c69ed5df3a76ed,0000000000000000000000000000000000000000..a11f41af7797733279398811fc94b6d765e1da10
mode 100644,000000..100644
--- /dev/null
@@@ -1,155 -1,0 +1,165 @@@
- from quantum.common import wsgi
 +"""
 +# 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 extensions
 +from quantum.manager import QuantumManager
 +
 +LOG = logging.getLogger('quantum.api.qoss')
 +
 +
 +class Qos(object):
-     def get_name(self):
++    """Qos extension file"""
 +    def __init__(self):
 +        pass
-     def get_alias(self):
++    
++    @classmethod
++    def get_name(cls):
++        """ Returns Ext Resource Name """
 +        return "Cisco qos"
 +
-     def get_description(self):
++    @classmethod
++    def get_alias(cls):
++        """ Returns Ext Resource Alias """
 +        return "Cisco qos"
 +
-     def get_namespace(self):
-         return ""
-     def get_updated(self):
++    @classmethod
++    def get_description(cls):
++        """ Returns Ext Resource Description """
 +        return "qos include username and password"
 +
-     def get_resources(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"
 +
-         super(QosController, self).__init__(plugin)
++    @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'
-         #TODO: this should be for a given tenant!!!
++        self._plugin = plugin
++        #super(QosController, self).__init__(plugin)
 +             
 +    def index(self, request, tenant_id):
 +        """ Returns a list of qos ids """
-         except exception.QosNotFound as e:
-             return faults.Fault(faults.QosNotFound(e))
-                                 
-             #return faults.Fault(e)
 +        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 exc.HTTPError as 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 exception.QosNotFound as e:
-             return faults.Fault(faults.QosNotFound(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 exp:
++            return faults.Fault(faults.QosNotFound(exp))
index bed81abf7ee5699640917dc6c83a855d02544385,0000000000000000000000000000000000000000..9300f34a2d474f2e55298ae5320affbc8cdaef82
mode 100644,000000..100644
--- /dev/null
@@@ -1,562 -1,0 +1,562 @@@
-     _host = {'host_desc': {
 +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_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
 +        <network_uuid, network_name> 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
 +        <portprofile_uuid, portprofile_name> 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
 +        <credential_id, credential_name> 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
 +        <qos_id, qos_name> 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
index 5ad2a193e664467997e1baf3d0b8bf6862e6e007,5ad2a193e664467997e1baf3d0b8bf6862e6e007..14435e914105ecbefadfc4a1d9ab4ddb142897c3
@@@ -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"}