Пример #1
0
    def __init__(self, schema, base_path=None, default_policy=None):
        schema = 'python://' + schema.strip('/')
        try:
            parser = ResolvingParser(schema, backend='openapi-spec-validator')
        except (FileNotFoundError, IsADirectoryError):
            raise NotFoundError('OpenAPI Schema not found')
        self._spec = parser.specification
        self._paths = self._spec.get('paths', [])
        self._policy = {}
        if base_path:
            self._spec['basePath'] = base_path.rstrip('/')

        self._request_body = {}
        self._response_body = {}
        self._request_params = {}
        self._operation_ids = {}
        self._routes = []
        self._schemas = []

        for path in self._paths:
            route = self.base_path + '/' + path.strip('/')
            for method in self._paths[path]:
                op_id = self._paths[path][method].get('operationId')
                params = self._paths[path][method].get('parameters', [])
                resps = self._paths[path][method].get('responses', [])

                if op_id:
                    if op_id not in self._operation_ids:
                        self._operation_ids[op_id] = []
                        self._request_params[op_id] = {}
                        self._request_body[op_id] = None
                        self._response_body[op_id] = {}

                    for param in params:
                        if param.get('in', '') == 'query':
                            p_name = param.get('name')
                            if p_name:
                                self._request_params[op_id][p_name] = param
                        elif param.get('in', '') == 'body':
                            self._request_body[op_id] = param

                    for resp in resps:
                        self._response_body[op_id][resp] = resps[resp]

                    _route = (
                        method,
                        route,
                        op_id,
                        default_policy,
                    )

                    self._routes.append(_route)

                    if op_id not in self._operation_ids:
                        self._operation_ids[op_id] = []

                    self._operation_ids[op_id].append(route)
Пример #2
0
    def get_zone_slot(self, zone):
        """Get zone slot.

        Args:
            zone (str): Exisiting Zone name.
        """
        try:
            return self._zone_index[zone]
        except KeyError:
            raise NotFoundError("Zone not found '%s'" % zone) from None
Пример #3
0
    def delete_node(self, node_id):
        """Delete node.

        Args:
            node_id (str): Unique Node Identifier.
        """
        try:
            zone, slot = self._node_index[node_id]
        except KeyError:
            raise NotFoundError('Node not found') from None

        del self._node_index[node_id]
        self._nodes[slot] = None
        self._zones[zone][1].remove(slot)
Пример #4
0
    def update_node(self, node_id, zone=None, weight=None, **kwargs):
        """Update node.

        Args:
            node_id (str): Unique Node Identifier.
            zone (str): Exisiting zone name.
            weight (float/int): Weight for element.
            **kwargs: Arbitrary options for nodes.

        Returns:
            dict: Node with property value pairs.
        """
        node = self.get_node(node_id, raw=True)
        if node:
            if weight:
                weight = parse_weight(weight)
                node['weight'] = weight

            if zone:
                zone = parse_zone(zone)
                new_zone_slot = self.get_zone_slot(zone)
                if new_zone_slot != node['zone']:
                    zone = self.get_zone_slot(zone)
                    slot = self._take_empty_node_slot()
                    old_zone_slot, old_node_slot = self._node_index[node_id]
                    self._zones[old_zone_slot][1][old_node_slot] = None
                    node['zone'] = new_zone_slot
                    node['node_slot'] = slot
                    self._node_index[node_id] = (
                        zone,
                        slot,
                    )
                    self._nodes[slot] = node

            for kwarg in kwargs:
                node[kwarg] = kwargs[kwarg]

            return node

        else:
            raise NotFoundError("Update node not found '%s'" % node_id)
Пример #5
0
    def proc(self, method, route):
        try:
            with Timer() as elapsed:
                # Request Object.
                request = g.current_request = Request(method, route)

                # Response Object.
                response = Response()

                # Set Response object for request.
                request.response = response

                # Debug output
                if g.app.debug is True:
                    log.info('Request %s' % request.route +
                             ' Method %s\n' % request.method)

                # Process the middleware 'pre' method before routing it
                for middleware in register._middleware_pre:
                    middleware(request, response)

                # Route Object.
                resource, method, r_kwargs, target, tag, cache = router.find(
                    request.method, request.route)

                # Route Kwargs in requests.
                request.route_kwargs = r_kwargs

                # Set route tag in requests.
                request.tag = tag

                # If route tagged validate with policy
                if tag is not None:
                    if not request.policy.validate(tag):
                        raise AccessDeniedError("Access Denied by" +
                                                " policy '%s'" % tag)

                # Execute Routed View.
                try:
                    # Process the middleware 'resource' after routing it
                    for middleware in register._middleware_resource:
                        middleware(request, response)
                    # Run View method.
                    if resource is not None:
                        view = resource(request, response, **r_kwargs)
                        if view is not None:
                            response.write(view)
                    else:
                        raise NotFoundError("Route not found" +
                                            " Method '%s'" % request.method +
                                            " Route '%s'" % request.route)
                finally:
                    # Process the middleware 'post' at the end
                    for middleware in register._middleware_post:
                        middleware(request, response)
        except KeyboardInterrupt:
            response.write('CTRL-C / KeyboardInterrupt')
        except Exception as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            # Return response object.
        finally:
            # Completed Request
            log.info('Completed CMD', timer=elapsed())
Пример #6
0
    def __call__(self, *args, **kwargs):
        """Application Request Interface.

        A clean request and response object is provided to the interface that
        is unique this to this thread.

        It passes any args and kwargs to the interface.

        Response object is returned.
        """
        try:
            with Timer() as elapsed:
                # Request Object.
                request = g.current_request = Request(*args, **kwargs)
                request.env['SCRIPT_NAME'] = g.app.config.get(
                    'application',
                    'script',
                    fallback=request.env['SCRIPT_NAME'])

                script_name = request.get_header('X-Script-Name')
                if script_name:
                    request.env['SCRIPT_NAME'] = script_name

                # Response Object.
                response = Response(*args, **kwargs)

                # Set Response object for request.
                request.response = response

                # Debug output
                if g.app.debug is True:
                    log.info('Request %s' % request.route +
                             ' Method %s\n' % request.method)

                # Process the middleware 'pre' method before routing it
                for middleware in register._middleware_pre:
                    middleware(request, response)

                # Route Object.
                resource, method, r_kwargs, target, tag, cache = router.find(
                    request.method, request.route)

                # Route Kwargs in requests.
                request.route_kwargs = r_kwargs

                # Set route tag in requests.
                request.tag = tag

                # If route tagged validate with policy
                if tag is not None:
                    if not request.policy.validate(tag,
                                                   access_denied_raise=True):
                        raise AccessDeniedError("Access Denied by" +
                                                " policy '%s'" % tag)

                # Execute Routed View.
                try:
                    # Process the middleware 'resource' after routing it
                    for middleware in register._middleware_resource:
                        middleware(request, response)
                    # Run View method.
                    if resource is not None:
                        view = resource(request, response, **r_kwargs)
                        if view is not None:
                            response.body(view)
                    else:
                        raise NotFoundError("Route not found" +
                                            " Method '%s'" % request.method +
                                            " Route '%s'" % request.route)
                finally:
                    # Process the middleware 'post' at the end
                    self.post_middleware(request, response, False)

            # Cache GET Response.
            # Only cache for GET responses!
            if cache > 0 and request.method == 'GET':
                # Get session_id if any for Caching
                session_id = request.cookies.get(request.host)

                # NOTE(cfrademan): Instruct to use cache but revalidate on,
                # stale cache entry. Expire remote cache in same duration
                # as internal cache.
                if session_id:
                    response.set_header(
                        "cache-control",
                        "must-revalidate, private, max-age=" + str(cache))
                else:
                    response.set_header(
                        "cache-control",
                        "must-revalidate, max-age=" + str(cache))

                # Set Vary Header
                # NOTE(cfrademan): Client should uniquely cache
                # based these request headers.
                response.set_header(
                    'Vary', 'Cookie, Accept-Encoding' + ', Content-Type')

                # Set Etag
                # NOTE(cfrademan): Needed Encoding for Different Etag.
                if isinstance(response._stream, bytes):
                    encoding = request.get_header('Accept-Encoding')
                    response.etag.set(etagger(response._stream, encoding))

                # If Etag matches do not return full body use
                # external/user-agent cache.
                if (len(request.if_none_match) > 0
                        and request.if_none_match in response.etag):
                    # Etag matches do not return full body.
                    response.not_modified()

                # NOTE(cfrademan): Use last_modified as last resort for
                # external/user-agent cache.
                elif (request.if_modified_since and response.last_modified
                      and request.if_modified_since <= response.last_modified):
                    # Last-Modified matches do not return full body.
                    response.not_modified()
            else:
                response.set_header("cache-control",
                                    "no-store, no-cache, max-age=0")

            # Return response object.
            return response()

        except HTTPError as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            self.post_middleware(request, response, True)
            # Return response object.
            return response()
        except Error as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            self.post_middleware(request, response, True)
            # Return response object.
            return response()
        except Exception as exception:
            trace = str(traceback.format_exc())
            self.handle_error(request, response, exception, trace)
            self.post_middleware(request, response, True)
            # Return response object.
            return response()
        finally:
            # Completed Request
            log.info('Completed Request', timer=elapsed())
Пример #7
0
 def __getitem__(self, name):
     try:
         return self.named_objects[name]
     except KeyError:
         raise NotFoundError("Entry Point '%s' not found" % name) from None