Example #1
0
def describe(request):
    """Render a description of the whole MAAS API.

    :param request: A "related" HTTP request. This is used to derive the URL
        where the client expects to see the MAAS API.
    :return: An `HttpResponse` containing a JSON description of the whole MAAS
        API. Links to the API will use the same scheme and hostname that the
        client used in `request`.
    """
    description = describe_api()
    # Add hash so that client can check if things are up to date.
    description["hash"] = get_api_description_hash()
    # Make all URIs absolute. Clients - and the command-line client in
    # particular - expect that all handler URIs are absolute, not just paths.
    # The handler URIs returned by describe_resource() are relative paths.
    absolute = partial(build_absolute_uri, request)
    for resource in description["resources"]:
        for handler_type in "anon", "auth":
            handler = resource[handler_type]
            if handler is not None:
                handler["uri"] = absolute(handler["path"])
    # Return as a JSON document.
    return HttpResponse(
        json.dumps(description),
        content_type="application/json")
Example #2
0
    def test_describe_api_returns_description_document(self):
        is_list = IsInstance(list)
        is_tuple = IsInstance(tuple)
        is_text = MatchesAny(IsInstance((str, bytes)), Is(None))
        is_bool = IsInstance(bool)

        is_operation = MatchesAny(Is(None), is_text)

        is_http_method = MatchesAny(
            Equals("GET"), Equals("POST"), Equals("PUT"), Equals("DELETE")
        )

        is_action = MatchesDict(
            {
                "doc": is_text,
                "method": is_http_method,
                "name": is_text,
                "op": is_operation,
                "restful": is_bool,
            }
        )

        is_handler = MatchesDict(
            {
                "actions": MatchesAll(is_list, AllMatch(is_action)),
                "doc": is_text,
                "name": is_text,
                "params": is_tuple,
                "path": is_text,
            }
        )

        is_resource = MatchesDict(
            {
                "anon": MatchesAny(Is(None), is_handler),
                "auth": MatchesAny(Is(None), is_handler),
                "name": is_text,
            }
        )

        is_resource_list = MatchesAll(is_list, AllMatch(is_resource))
        is_legacy_handler_list = MatchesAll(is_list, AllMatch(is_handler))

        self.assertThat(
            describe_api(),
            MatchesDict(
                {
                    "doc": Equals("MAAS API"),
                    "resources": is_resource_list,
                    "handlers": is_legacy_handler_list,
                }
            ),
        )