Example #1
0
    def handle(self, request, response):
        xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
        deserializers = {'application/xml': xml_deserializer,
                         'application/json': wsgi.JSONDeserializer()}
        xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
        serializers = {'application/xml': xml_serializer,
                       'application/json': wsgi.JSONDictSerializer()}
        format_types = {'xml': 'application/xml',
                        'json': 'application/json'}

        path = [part for part in request.path_url.split("/") if part]
        id = path[-1].split('.')[0]

        content_type = format_types.get(None,
                                        request.best_match_content_type())
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        body = None
        if request.body:
            body = deserializer.deserialize(request.body)['body']

        api_response = self._plugin.post_update_port(request.context,
                                                     id,
                                                     body)
        return serializer.serialize({"port": api_response})
Example #2
0
    def handle(self, request, response):
        xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
        deserializers = {
            'application/xml': xml_deserializer,
            'application/json': wsgi.JSONDeserializer()
        }
        xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
        serializers = {
            'application/xml': xml_serializer,
            'application/json': wsgi.JSONDictSerializer()
        }
        format_types = {'xml': 'application/xml', 'json': 'application/json'}

        path = [part for part in request.path_url.split("/") if part]
        id = path[-1].split('.')[0]

        content_type = format_types.get(None,
                                        request.best_match_content_type())
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        body = None
        if request.body:
            body = deserializer.deserialize(request.body)['body']

        api_response = self._plugin.post_update_port(request.context, id, body)
        return serializer.serialize({"port": api_response})
Example #3
0
    def test_non_root_one_item_dic_xml(self):
        data = {'test1': 1}
        # We have a key in this dict, and its value is an integer.
        # XML is:
        # <test1 quantum:type="int"
        #        xmlns="http://openstack.org/quantum/api/v2.0"
        #        xmlns:quantum="http://openstack.org/quantum/api/v2.0"
        #        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        # 1</test1>

        serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
        result = serializer.serialize(data)
        deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
        new_data = deserializer.deserialize(result)['body']
        self.assertEqual(data, new_data)
Example #4
0
 def test_empty_dic_xml(self):
     data = {}
     # Since it is an empty dict, we use quantum:type='dict' and
     # an empty XML element to represent it. In addition, we use an
     # virtual XML root _v_root to wrap the XML doc.
     # XML is:
     # <_v_root quantum:type="dict"
     #          xmlns="http://openstack.org/quantum/api/v2.0"
     #          xmlns:quantum="http://openstack.org/quantum/api/v2.0"
     #          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
     serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
     result = serializer.serialize(data)
     deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
     new_data = deserializer.deserialize(result)['body']
     self.assertEqual(data, new_data)
Example #5
0
 def test_None(self):
     data = None
     # Since it is None, we use xsi:nil='true'.
     # In addition, we use an
     # virtual XML root _v_root to wrap the XML doc.
     # XML is:
     # <_v_root xsi:nil="true"
     #          xmlns="http://openstack.org/quantum/api/v2.0"
     #          xmlns:quantum="http://openstack.org/quantum/api/v2.0"
     #          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" />
     serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
     result = serializer.serialize(data)
     deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
     new_data = deserializer.deserialize(result)['body']
     self.assertIsNone(new_data)
Example #6
0
    def test_non_root_two_items_dic_xml(self):
        data = {'test1': 1, 'test2': '2'}
        # We have no root element in this data, We will use a virtual
        # root element _v_root to wrap the doct.
        # The XML is:
        # <_v_root xmlns="http://openstack.org/quantum/api/v2.0"
        #          xmlns:quantum="http://openstack.org/quantum/api/v2.0"
        #          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
        #    <test1 quantum:type="int">1</test1><test2>2</test2>
        # </_v_root>

        serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
        result = serializer.serialize(data)
        deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
        new_data = deserializer.deserialize(result)['body']
        self.assertEqual(data, new_data)
Example #7
0
 def setUp(self):
     super(WebTestCase, self).setUp()
     json_deserializer = wsgi.JSONDeserializer()
     xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
     self._deserializers = {
         'application/json': json_deserializer,
         'application/xml': xml_deserializer,
     }
Example #8
0
 def setUp(self):
     super(WebTestCase, self).setUp()
     json_deserializer = wsgi.JSONDeserializer()
     xml_deserializer = wsgi.XMLDeserializer(
         attributes.get_attr_metadata())
     self._deserializers = {
         'application/json': json_deserializer,
         'application/xml': xml_deserializer,
     }
Example #9
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
    default_deserializers = {'application/xml': xml_deserializer,
                             'application/json': wsgi.JSONDeserializer()}
    xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
    default_serializers = {'application/xml': xml_serializer,
                           'application/json': wsgi.JSONDictSerializer()}
    format_types = {'xml': 'application/xml',
                    'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt,
                                        request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']

            method = getattr(controller, action)

            result = method(request=request, **args)
        except (exceptions.NeutronException,
                netaddr.AddrFormatError) as e:
            LOG.exception(_('%s failed'), action)
            e = translate(e, language)
            # following structure is expected by python-neutronclient
            err_data = {'type': e.__class__.__name__,
                        'message': e, 'detail': ''}
            body = serializer.serialize({'NeutronError': err_data})
            kwargs = {'body': body, 'content_type': content_type}
            for fault in faults:
                if isinstance(e, fault):
                    raise faults[fault](**kwargs)
            raise webob.exc.HTTPInternalServerError(**kwargs)
        except webob.exc.HTTPException as e:
            LOG.exception(_('%s failed'), action)
            translate(e, language)
            e.body = serializer.serialize({'NeutronError': e})
            e.content_type = content_type
            raise
        except NotImplementedError as e:
            e = translate(e, language)
            # NOTE(armando-migliaccio): from a client standpoint
            # it makes sense to receive these errors, because
            # extensions may or may not be implemented by
            # the underlying plugin. So if something goes south,
            # because a plugin does not implement a feature,
            # returning 500 is definitely confusing.
            body = serializer.serialize(
                {'NotImplementedError': e.message})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPNotImplemented(**kwargs)
        except Exception as e:
            # NOTE(jkoelker) Everything else is 500
            LOG.exception(_('%s failed'), action)
            # Do not expose details of 500 error to clients.
            msg = _('Request Failed: internal server error while '
                    'processing your request.')
            msg = translate(msg, language)
            body = serializer.serialize({'NeutronError': msg})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)

        status = action_status.get(action, 200)
        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request, status=status,
                              content_type=content_type,
                              body=body)
    return resource
Example #10
0
 def serialize(self, data):
     ctype = 'application/%s' % self.fmt
     result = wsgi.Serializer(attributes.get_attr_metadata()).serialize(
         data, ctype)
     return result
Example #11
0
        #    <int quantum:type="float">5.0</int>  # Float text
        #    <dict quantum:type="dict" />     # Empty Dict
        #    <name>net1</name>
        #    <admin_state_up quantum:type="bool">True</admin_state_up> # Bool
        #    <test xsi:nil="true" />          # None
        #    <tenant_id>test-tenant</tenant_id>
        #    # We must have a namespace defined in root for prefix:external
        #    <prefix:external quantum:type="bool">True</prefix:external>
        #    <tests>                          # List
        #       <test><test1>value1</test1></test>
        #       <test><test3 quantum:type="int">3</test3>
        #             <test2 quantum:type="int">2</test2>
        #       </test></tests>
        # </network>

        metadata = attributes.get_attr_metadata()
        ns = {'prefix': 'http://xxxx.yy.com'}
        metadata[constants.EXT_NS] = ns
        metadata['plurals'] = {'tests': 'test'}
        serializer = wsgi.XMLDictSerializer(metadata)
        result = serializer.serialize(NETWORK)
        deserializer = wsgi.XMLDeserializer(metadata)
        new_net = deserializer.deserialize(result)['body']
        self.assertEqual(NETWORK, new_net)

    def test_None(self):
        data = None
        # Since it is None, we use xsi:nil='true'.
        # In addition, we use an
        # virtual XML root _v_root to wrap the XML doc.
        # XML is:
Example #12
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
    default_deserializers = {
        'application/xml': xml_deserializer,
        'application/json': wsgi.JSONDeserializer()
    }
    xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
    default_serializers = {
        'application/xml': xml_serializer,
        'application/json': wsgi.JSONDictSerializer()
    }
    format_types = {'xml': 'application/xml', 'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}
    #neutron/api/v2/base.py 789 wsgi_resource.Resource(controller, FAULT_MAP)
    #FAULT_MAP :neutron/api/v2/base.py 38

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        # #brk(host="10.10.12.21", port=49175)
        # #add by xm-2015.7.8:G-cloud7.0区域权限控制,
        # #根据api请求中是否附件resource_type及是否resource_type=0/1来区分用户角色
        # #resource_type = request.params.get('resource_type', None)
        # resource_type = request.environ.get('HTTP_G_AUTH_RESOURCETYPE', None)
        # #resource_type = request.headers.environ.get('HTTP_G_AUTH_RESOURCETYPE', None)
        # LOG.debug(_('resource_type_xm: %(resource_type)s'), {'resource_type': resource_type})
        # if resource_type == '0':
        #     request.context.roles = list(set(request.context.roles) - set(['admin']))
        #     request.context.is_admin = False
        # elif resource_type == '1':
        #     request.context.roles = list(set(request.context.roles) | set(['admin']))
        #     request.context.is_admin = True
        # #end-2015.7.8

        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt, request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']
                #首先进入/usr/lib/python2.7/site-packages/webob/request.py(671)_body__get() 然后return 到/usr/lib/python2.7/site-packages/neutron/wsgi.py(599)deserialize()

            method = getattr(controller, action)
            #pdb.set_trace()
            result = method(request=request, **args)
        except (exceptions.NeutronException, netaddr.AddrFormatError) as e:
            #faults = {<class 'neutron.common.exceptions.NotAuthorized'>: <class 'webob.exc.HTTPForbidden'>,
            # <class 'neutron.common.exceptions.Conflict'>: <class 'webob.exc.HTTPConflict'>,
            # <class 'neutron.common.exceptions.NotFound'>: <class 'webob.exc.HTTPNotFound'>,
            # <class 'neutron.common.exceptions.ServiceUnavailable'>: <class 'webob.exc.HTTPServiceUnavailable'>,
            # <class 'netaddr.core.AddrFormatError'>: <class 'webob.exc.HTTPBadRequest'>,
            # <class 'neutron.common.exceptions.BadRequest'>: <class 'webob.exc.HTTPBadRequest'>,
            # <class 'neutron.common.exceptions.InUse'>: <class 'webob.exc.HTTPConflict'>}
            for fault in faults:
                if isinstance(e, fault):
                    mapped_exc = faults[fault]
                    break
            else:
                if e.code and e.code != 500:
                    mapped_exc = webob.exc.HTTPClientError
                else:
                    mapped_exc = webob.exc.HTTPInternalServerError
            if 400 <= mapped_exc.code < 500:
                LOG.info(_('%(action)s failed (client error): %(exc)s'), {
                    'action': action,
                    'exc': e
                })
            else:
                LOG.exception(_('%s failed'), action)
            e = translate(e, language)
            body = serializer.serialize(
                {'NeutronError': get_exception_data(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise mapped_exc(**kwargs)
        except webob.exc.HTTPException as e:
            type_, value, tb = sys.exc_info()
            LOG.exception(_('%s failed'), action)
            translate(e, language)
            value.body = serializer.serialize(
                {'NeutronError': get_exception_data(e)})
            value.content_type = content_type
            six.reraise(type_, value, tb)
        except NotImplementedError as e:
            e = translate(e, language)
            # NOTE(armando-migliaccio): from a client standpoint
            # it makes sense to receive these errors, because
            # extensions may or may not be implemented by
            # the underlying plugin. So if something goes south,
            # because a plugin does not implement a feature,
            # returning 500 is definitely confusing.
            body = serializer.serialize(
                {'NotImplementedError': get_exception_data(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPNotImplemented(**kwargs)
        except Exception:
            # NOTE(jkoelker) Everything else is 500
            LOG.exception(_('%s failed'), action)
            # Do not expose details of 500 error to clients.
            msg = _('Request Failed: internal server error while '
                    'processing your request.')
            msg = translate(msg, language)
            body = serializer.serialize({
                'NeutronError':
                get_exception_data(webob.exc.HTTPInternalServerError(msg))
            })
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)

        status = action_status.get(action, 200)
        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request,
                              status=status,
                              content_type=content_type,
                              body=body)

    return resource
Example #13
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
    default_deserializers = {
        'application/xml': xml_deserializer,
        'application/json': wsgi.JSONDeserializer()
    }
    xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
    default_serializers = {
        'application/xml': xml_serializer,
        'application/json': wsgi.JSONDictSerializer()
    }
    format_types = {'xml': 'application/xml', 'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt, request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']

            method = getattr(controller, action)

            result = method(request=request, **args)
        except (exceptions.NeutronException, netaddr.AddrFormatError) as e:
            LOG.exception(_('%s failed'), action)
            e = translate(e, language)
            # following structure is expected by python-neutronclient
            err_data = {
                'type': e.__class__.__name__,
                'message': e,
                'detail': ''
            }
            body = serializer.serialize({'NeutronError': err_data})
            kwargs = {'body': body, 'content_type': content_type}
            for fault in faults:
                if isinstance(e, fault):
                    raise faults[fault](**kwargs)
            raise webob.exc.HTTPInternalServerError(**kwargs)
        except webob.exc.HTTPException as e:
            LOG.exception(_('%s failed'), action)
            translate(e, language)
            e.body = serializer.serialize({'NeutronError': e})
            e.content_type = content_type
            raise
        except NotImplementedError as e:
            e = translate(e, language)
            # NOTE(armando-migliaccio): from a client standpoint
            # it makes sense to receive these errors, because
            # extensions may or may not be implemented by
            # the underlying plugin. So if something goes south,
            # because a plugin does not implement a feature,
            # returning 500 is definitely confusing.
            body = serializer.serialize({'NotImplementedError': e.message})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPNotImplemented(**kwargs)
        except Exception as e:
            # NOTE(jkoelker) Everything else is 500
            LOG.exception(_('%s failed'), action)
            # Do not expose details of 500 error to clients.
            msg = _('Request Failed: internal server error while '
                    'processing your request.')
            msg = translate(msg, language)
            body = serializer.serialize({'NeutronError': msg})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)

        status = action_status.get(action, 200)
        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request,
                              status=status,
                              content_type=content_type,
                              body=body)

    return resource
Example #14
0
 def serialize(self, data):
     ctype = 'application/%s' % self.fmt
     result = wsgi.Serializer(
         attributes.get_attr_metadata()).serialize(data, ctype)
     return result
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
    default_deserializers = {'application/xml': xml_deserializer,
                             'application/json': wsgi.JSONDeserializer()}
    xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
    default_serializers = {'application/xml': xml_serializer,
                           'application/json': wsgi.JSONDictSerializer()}
    format_types = {'xml': 'application/xml',
                    'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}
    #neutron/api/v2/base.py 789 wsgi_resource.Resource(controller, FAULT_MAP)
    #FAULT_MAP :neutron/api/v2/base.py 38

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        # #brk(host="10.10.12.21", port=49175)
        # #add by xm-2015.7.8:G-cloud7.0区域权限控制,
        # #根据api请求中是否附件resource_type及是否resource_type=0/1来区分用户角色
        # #resource_type = request.params.get('resource_type', None)
        # resource_type = request.environ.get('HTTP_G_AUTH_RESOURCETYPE', None)
        # #resource_type = request.headers.environ.get('HTTP_G_AUTH_RESOURCETYPE', None)
        # LOG.debug(_('resource_type_xm: %(resource_type)s'), {'resource_type': resource_type})
        # if resource_type == '0':
        #     request.context.roles = list(set(request.context.roles) - set(['admin']))
        #     request.context.is_admin = False
        # elif resource_type == '1':
        #     request.context.roles = list(set(request.context.roles) | set(['admin']))
        #     request.context.is_admin = True
        # #end-2015.7.8

        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt,
                                        request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']
                #首先进入/usr/lib/python2.7/site-packages/webob/request.py(671)_body__get() 然后return 到/usr/lib/python2.7/site-packages/neutron/wsgi.py(599)deserialize()

            method = getattr(controller, action)
            #pdb.set_trace()
            result = method(request=request, **args)
        except (exceptions.NeutronException,
                netaddr.AddrFormatError) as e:
            #faults = {<class 'neutron.common.exceptions.NotAuthorized'>: <class 'webob.exc.HTTPForbidden'>,
            # <class 'neutron.common.exceptions.Conflict'>: <class 'webob.exc.HTTPConflict'>,
            # <class 'neutron.common.exceptions.NotFound'>: <class 'webob.exc.HTTPNotFound'>,
            # <class 'neutron.common.exceptions.ServiceUnavailable'>: <class 'webob.exc.HTTPServiceUnavailable'>,
            # <class 'netaddr.core.AddrFormatError'>: <class 'webob.exc.HTTPBadRequest'>,
            # <class 'neutron.common.exceptions.BadRequest'>: <class 'webob.exc.HTTPBadRequest'>,
            # <class 'neutron.common.exceptions.InUse'>: <class 'webob.exc.HTTPConflict'>}
            for fault in faults:
                if isinstance(e, fault):
                    mapped_exc = faults[fault]
                    break
            else:
                if e.code and e.code != 500:
                    mapped_exc = webob.exc.HTTPClientError
                else:
                    mapped_exc = webob.exc.HTTPInternalServerError
            if 400 <= mapped_exc.code < 500:
                LOG.info(_('%(action)s failed (client error): %(exc)s'),
                         {'action': action, 'exc': e})
            else:
                LOG.exception(_('%s failed'), action)
            e = translate(e, language)
            body = serializer.serialize(
                {'NeutronError': get_exception_data(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise mapped_exc(**kwargs)
        except webob.exc.HTTPException as e:
            type_, value, tb = sys.exc_info()
            LOG.exception(_('%s failed'), action)
            translate(e, language)
            value.body = serializer.serialize(
                {'NeutronError': get_exception_data(e)})
            value.content_type = content_type
            six.reraise(type_, value, tb)
        except NotImplementedError as e:
            e = translate(e, language)
            # NOTE(armando-migliaccio): from a client standpoint
            # it makes sense to receive these errors, because
            # extensions may or may not be implemented by
            # the underlying plugin. So if something goes south,
            # because a plugin does not implement a feature,
            # returning 500 is definitely confusing.
            body = serializer.serialize(
                {'NotImplementedError': get_exception_data(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPNotImplemented(**kwargs)
        except Exception:
            # NOTE(jkoelker) Everything else is 500
            LOG.exception(_('%s failed'), action)
            # Do not expose details of 500 error to clients.
            msg = _('Request Failed: internal server error while '
                    'processing your request.')
            msg = translate(msg, language)
            body = serializer.serialize(
                {'NeutronError': get_exception_data(
                    webob.exc.HTTPInternalServerError(msg))})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)

        status = action_status.get(action, 200)
        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request, status=status,
                              content_type=content_type,
                              body=body)
    return resource
Example #16
0
def Resource(controller, faults=None, deserializers=None, serializers=None):
    """Represents an API entity resource and the associated serialization and
    deserialization logic
    """
    xml_deserializer = wsgi.XMLDeserializer(attributes.get_attr_metadata())
    default_deserializers = {'application/xml': xml_deserializer,
                             'application/json': wsgi.JSONDeserializer()}
    xml_serializer = wsgi.XMLDictSerializer(attributes.get_attr_metadata())
    default_serializers = {'application/xml': xml_serializer,
                           'application/json': wsgi.JSONDictSerializer()}
    format_types = {'xml': 'application/xml',
                    'json': 'application/json'}
    action_status = dict(create=201, delete=204)

    default_deserializers.update(deserializers or {})
    default_serializers.update(serializers or {})

    deserializers = default_deserializers
    serializers = default_serializers
    faults = faults or {}

    @webob.dec.wsgify(RequestClass=Request)
    def resource(request):
        if request.path in ['/v2.0/floatingips','/v2.0/tenants'] and 'uos_staff' in request.context.roles:
            uos_utils.uos_staff_act_as_admin(request)

        if request.path in ['/v2.0/uos_resources.json'] and \
                        'routers' in request.params.getall('uos_resources') and \
                        len(request.params.getall('uos_resources')) == 1 and \
                        'uos_staff' in request.context.roles:
            uos_utils.uos_staff_act_as_admin(request)

        route_args = request.environ.get('wsgiorg.routing_args')
        if route_args:
            args = route_args[1].copy()
        else:
            args = {}

        # NOTE(jkoelker) by now the controller is already found, remove
        #                it from the args if it is in the matchdict
        args.pop('controller', None)
        fmt = args.pop('format', None)
        action = args.pop('action', None)
        content_type = format_types.get(fmt,
                                        request.best_match_content_type())
        language = request.best_match_language()
        deserializer = deserializers.get(content_type)
        serializer = serializers.get(content_type)

        try:
            if request.body:
                args['body'] = deserializer.deserialize(request.body)['body']

            method = getattr(controller, action)

            result = method(request=request, **args)
        except (exceptions.NeutronException,
                netaddr.AddrFormatError) as e:
            for fault in faults:
                if isinstance(e, fault):
                    mapped_exc = faults[fault]
                    break
            else:
                mapped_exc = webob.exc.HTTPInternalServerError
            if 400 <= mapped_exc.code < 500:
                LOG.info(_('%(action)s failed (client error): %(exc)s'),
                         {'action': action, 'exc': e})
            else:
                LOG.exception(_('%s failed'), action)
            e = translate(e, language)
            body = serializer.serialize(
                {'NeutronError': get_exception_data(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise mapped_exc(**kwargs)
        except webob.exc.HTTPException as e:
            type_, value, tb = sys.exc_info()
            LOG.exception(_('%s failed'), action)
            translate(e, language)
            value.body = serializer.serialize(
                {'NeutronError': get_exception_data(e)})
            value.content_type = content_type
            six.reraise(type_, value, tb)
        except NotImplementedError as e:
            e = translate(e, language)
            # NOTE(armando-migliaccio): from a client standpoint
            # it makes sense to receive these errors, because
            # extensions may or may not be implemented by
            # the underlying plugin. So if something goes south,
            # because a plugin does not implement a feature,
            # returning 500 is definitely confusing.
            body = serializer.serialize(
                {'NotImplementedError': get_exception_data(e)})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPNotImplemented(**kwargs)
        except Exception:
            # NOTE(jkoelker) Everything else is 500
            LOG.exception(_('%s failed'), action)
            # Do not expose details of 500 error to clients.
            msg = _('Request Failed: internal server error while '
                    'processing your request.')
            msg = translate(msg, language)
            body = serializer.serialize(
                {'NeutronError': get_exception_data(
                    webob.exc.HTTPInternalServerError(msg))})
            kwargs = {'body': body, 'content_type': content_type}
            raise webob.exc.HTTPInternalServerError(**kwargs)
        status = action_status.get(action, 200)

        if type(result) == dict and  'file' in result.keys():
            content_disposition = "attachment; filename=%s" % result['name']
            content_type = "application/binary; charset=UTF-8"
            contents = result['contents'].decode('base64')
            return file_response(request,status,content_type, content_disposition, contents)

        body = serializer.serialize(result)
        # NOTE(jkoelker) Comply with RFC2616 section 9.7
        if status == 204:
            content_type = ''
            body = None

        return webob.Response(request=request, status=status,
                              content_type=content_type,
                              body=body)
    return resource