Merge ~lloydwaltersj/maas:missing-response into maas:master

Proposed by Jack Lloyd-Walters
Status: Merged
Approved by: Jack Lloyd-Walters
Approved revision: 54c3fcc4efc1ea4d29f205f379f2b86752ec93d6
Merge reported by: MAAS Lander
Merged at revision: not available
Proposed branch: ~lloydwaltersj/maas:missing-response
Merge into: maas:master
Diff against target: 153 lines (+59/-8)
3 files modified
src/maasserver/api/doc_oapi.py (+42/-6)
src/maasserver/api/machines.py (+15/-0)
src/maasserver/management/commands/tests/test_generate_oapi.py (+2/-2)
Reviewer Review Type Date Requested Status
MAAS Lander Approve
Adam Collard (community) Approve
Review via email: mp+428924@code.launchpad.net

Commit message

Generate responses for API operations.

Description of the change

OAS3 requires all operations present some responses, but some of our API operations do not have any defined.

To post a comment you must log in.
Revision history for this message
Adam Collard (adam-collard) wrote :

Merge conflicts

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/391/consoleText
COMMIT: e56068f4d787c750905801cd810002bdb5ab9ff4

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/393/consoleText
COMMIT: 0e830a1cb0d1a7b637989c105f362e23a4b6cd9f

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/394/consoleText
COMMIT: 372c110118966ff2981eb988d4d157bcd6cc7f58

review: Needs Fixing
Revision history for this message
Jack Lloyd-Walters (lloydwaltersj) wrote :

jenkins: !test

Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/395/consoleText
COMMIT: 372c110118966ff2981eb988d4d157bcd6cc7f58

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 7c9ee43b86e273e5afb69d7a2ef393c45046240b

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 7c628c8d3c411717abc060aa6d132d70809fe3df

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: f17159fcb1e073fbb494540e1bc1d474dce50334

review: Approve
Revision history for this message
Adam Collard (adam-collard) wrote :

Let's clean this up with the @deprecated work but get it landed for now

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/464/consoleText
COMMIT: b7abfa15244a4b7bc584eb6a8cd2c8a28ca96050

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: e9f2306ed4468566f6e56ecebbf9275efe186801

review: Approve
Revision history for this message
Adam Collard (adam-collard) :
Revision history for this message
Jack Lloyd-Walters (lloydwaltersj) :
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/473/consoleText
COMMIT: 42977b1868fab13ba490ae0f35424c47134d11c5

review: Needs Fixing
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: b8594841bc15b78be23b6b429d8ef8e744662172

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

UNIT TESTS
-b missing-response lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: SUCCESS
COMMIT: 54c3fcc4efc1ea4d29f205f379f2b86752ec93d6

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/src/maasserver/api/doc_oapi.py b/src/maasserver/api/doc_oapi.py
2index 25922cd..c0d0212 100644
3--- a/src/maasserver/api/doc_oapi.py
4+++ b/src/maasserver/api/doc_oapi.py
5@@ -7,7 +7,7 @@ This definition follows the rules and limitations of the ReST documentation.
6 (see doc.py and doc_handler.py).
7 """
8
9-from inspect import getdoc
10+from inspect import getdoc, signature
11 import json
12 import re
13 from textwrap import dedent
14@@ -144,7 +144,9 @@ def _prettify(doc):
15 return re.sub("(?<![.\n])[\n]+", " ", dedent(doc)).strip()
16
17
18-def _render_oapi_oper_item(http_method, op, doc, uri_params, function):
19+def _render_oapi_oper_item(
20+ http_method, op, doc, uri_params, function, resources
21+):
22 oper_id = op or support.OperationsResource.crudmap.get(http_method)
23 oper_obj = {
24 "operationId": f"{doc.name}_{oper_id}",
25@@ -154,14 +156,16 @@ def _render_oapi_oper_item(http_method, op, doc, uri_params, function):
26 "responses": {},
27 }
28 oper_docstring = _oapi_item_from_docstring(
29- function, http_method, uri_params
30+ function, http_method, uri_params, doc, resources
31 )
32 # Only overwrite the values that are non-blank
33 oper_obj.update({k: v for k, v in oper_docstring.items() if v})
34 return oper_obj
35
36
37-def _oapi_item_from_docstring(function, http_method, uri_params):
38+def _oapi_item_from_docstring(
39+ function, http_method, uri_params, doc, resources
40+):
41 def _type_to_string(schema):
42 match schema:
43 case "Boolean":
44@@ -187,6 +191,9 @@ def _oapi_item_from_docstring(function, http_method, uri_params):
45 paired.extend([status, content])
46 else:
47 content = response
48+ # edge case where a response is not given in the docstring
49+ if paired == [] and content:
50+ paired.extend([content, content])
51 paired = iter(paired)
52 return zip(paired, paired)
53
54@@ -202,6 +209,8 @@ def _oapi_item_from_docstring(function, http_method, uri_params):
55 ap_dict = ap.get_dict()
56 oper_obj["summary"] = ap_dict["description_title"].strip()
57 oper_obj["description"] = _prettify(ap_dict["description"])
58+ if "deprecated" in oper_obj["description"].lower():
59+ oper_obj["deprecated"] = True
60 for param in ap_dict["params"]:
61 description = _prettify(param["description_stripped"])
62 name = param["name"].strip("}{")
63@@ -268,11 +277,38 @@ def _oapi_item_from_docstring(function, http_method, uri_params):
64
65 status_code = status["name"]
66 if not status_code.isdigit():
67- status_code = _prettify(status["description_stripped"])
68+ status_code = (
69+ "200" if "success" in status_code.lower() else "404"
70+ )
71 oper_obj.setdefault("responses", {}).update(
72 {status_code: response},
73 )
74
75+ # populate deprecated functions properties using their replacement
76+ if (
77+ replacement_method := getattr(function, "deprecated", function)
78+ ) is not function:
79+ oper_obj["deprecated"] = True
80+ oper_obj["responses"] = _oapi_item_from_docstring(
81+ replacement_method, http_method, uri_params, doc, resources
82+ )["responses"]
83+
84+ # if a response is still empty, query the function
85+ if not oper_obj.get("responses"):
86+ # fetch a response by calling the function
87+ status, msg = "200", ""
88+ try:
89+ msg = function(*[""] * len(signature(function).parameters))
90+ except Exception as e:
91+ status = "404"
92+ msg = str(e)
93+ oper_obj["responses"] = {
94+ status: {
95+ "content": {"text/plain": {"schema": {"type": "string"}}},
96+ "description": msg,
97+ }
98+ }
99+
100 if body.get("properties"):
101 oper_obj.update(
102 {
103@@ -317,6 +353,6 @@ def _render_oapi_paths():
104 _new_path_item(params),
105 )
106 path_item[http_method.lower()] = _render_oapi_oper_item(
107- http_method, op, doc, params, function
108+ http_method, op, doc, params, function, resources
109 )
110 return paths
111diff --git a/src/maasserver/api/machines.py b/src/maasserver/api/machines.py
112index b6e92c6..93175c4 100644
113--- a/src/maasserver/api/machines.py
114+++ b/src/maasserver/api/machines.py
115@@ -669,6 +669,21 @@ class MachineHandler(NodeHandler, WorkloadAnnotationsMixin, PowerMixin):
116
117 @operation(idempotent=True)
118 def get_token(self, request, system_id):
119+ """@description-title Get a machine token
120+
121+ @param (string) "{system_id}" [required=true] The machines' system_id.
122+
123+ @success (http-status-code) "200" 200
124+ @success (json) "success-json" A JSON object containing information
125+ about the machine token.
126+ @success-example "success-json" [exkey=machines-placeholder]
127+ placeholder text
128+
129+ @error (http-status-code) "404" 404
130+ @error (content) "not-found" The requested machine is not found.
131+ @error-example "not-found"
132+ No Machine matches the given query.
133+ """
134 node = self.model.objects.get_node_or_404(
135 system_id=system_id,
136 user=request.user,
137diff --git a/src/maasserver/management/commands/tests/test_generate_oapi.py b/src/maasserver/management/commands/tests/test_generate_oapi.py
138index 2c49814..1431de1 100644
139--- a/src/maasserver/management/commands/tests/test_generate_oapi.py
140+++ b/src/maasserver/management/commands/tests/test_generate_oapi.py
141@@ -10,10 +10,10 @@ from django.core.management import call_command
142 import yaml
143
144 from maasserver.api.doc_oapi import get_api_endpoint
145-from maastesting.testcase import MAASTestCase
146+from maasserver.testing.testcase import MAASServerTestCase
147
148
149-class TestOAPIDoc(MAASTestCase):
150+class TestOAPIDoc(MAASServerTestCase):
151 def test_generate_spec(self):
152 spec = get_api_endpoint()
153 spec["externalDocs"]["url"] = "https://maas.io/docs"

Subscribers

People subscribed via source and target branches