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
diff --git a/src/maasserver/api/doc_oapi.py b/src/maasserver/api/doc_oapi.py
index 25922cd..c0d0212 100644
--- a/src/maasserver/api/doc_oapi.py
+++ b/src/maasserver/api/doc_oapi.py
@@ -7,7 +7,7 @@ This definition follows the rules and limitations of the ReST documentation.
7(see doc.py and doc_handler.py).7(see doc.py and doc_handler.py).
8"""8"""
99
10from inspect import getdoc10from inspect import getdoc, signature
11import json11import json
12import re12import re
13from textwrap import dedent13from textwrap import dedent
@@ -144,7 +144,9 @@ def _prettify(doc):
144 return re.sub("(?<![.\n])[\n]+", " ", dedent(doc)).strip()144 return re.sub("(?<![.\n])[\n]+", " ", dedent(doc)).strip()
145145
146146
147def _render_oapi_oper_item(http_method, op, doc, uri_params, function):147def _render_oapi_oper_item(
148 http_method, op, doc, uri_params, function, resources
149):
148 oper_id = op or support.OperationsResource.crudmap.get(http_method)150 oper_id = op or support.OperationsResource.crudmap.get(http_method)
149 oper_obj = {151 oper_obj = {
150 "operationId": f"{doc.name}_{oper_id}",152 "operationId": f"{doc.name}_{oper_id}",
@@ -154,14 +156,16 @@ def _render_oapi_oper_item(http_method, op, doc, uri_params, function):
154 "responses": {},156 "responses": {},
155 }157 }
156 oper_docstring = _oapi_item_from_docstring(158 oper_docstring = _oapi_item_from_docstring(
157 function, http_method, uri_params159 function, http_method, uri_params, doc, resources
158 )160 )
159 # Only overwrite the values that are non-blank161 # Only overwrite the values that are non-blank
160 oper_obj.update({k: v for k, v in oper_docstring.items() if v})162 oper_obj.update({k: v for k, v in oper_docstring.items() if v})
161 return oper_obj163 return oper_obj
162164
163165
164def _oapi_item_from_docstring(function, http_method, uri_params):166def _oapi_item_from_docstring(
167 function, http_method, uri_params, doc, resources
168):
165 def _type_to_string(schema):169 def _type_to_string(schema):
166 match schema:170 match schema:
167 case "Boolean":171 case "Boolean":
@@ -187,6 +191,9 @@ def _oapi_item_from_docstring(function, http_method, uri_params):
187 paired.extend([status, content])191 paired.extend([status, content])
188 else:192 else:
189 content = response193 content = response
194 # edge case where a response is not given in the docstring
195 if paired == [] and content:
196 paired.extend([content, content])
190 paired = iter(paired)197 paired = iter(paired)
191 return zip(paired, paired)198 return zip(paired, paired)
192199
@@ -202,6 +209,8 @@ def _oapi_item_from_docstring(function, http_method, uri_params):
202 ap_dict = ap.get_dict()209 ap_dict = ap.get_dict()
203 oper_obj["summary"] = ap_dict["description_title"].strip()210 oper_obj["summary"] = ap_dict["description_title"].strip()
204 oper_obj["description"] = _prettify(ap_dict["description"])211 oper_obj["description"] = _prettify(ap_dict["description"])
212 if "deprecated" in oper_obj["description"].lower():
213 oper_obj["deprecated"] = True
205 for param in ap_dict["params"]:214 for param in ap_dict["params"]:
206 description = _prettify(param["description_stripped"])215 description = _prettify(param["description_stripped"])
207 name = param["name"].strip("}{")216 name = param["name"].strip("}{")
@@ -268,11 +277,38 @@ def _oapi_item_from_docstring(function, http_method, uri_params):
268277
269 status_code = status["name"]278 status_code = status["name"]
270 if not status_code.isdigit():279 if not status_code.isdigit():
271 status_code = _prettify(status["description_stripped"])280 status_code = (
281 "200" if "success" in status_code.lower() else "404"
282 )
272 oper_obj.setdefault("responses", {}).update(283 oper_obj.setdefault("responses", {}).update(
273 {status_code: response},284 {status_code: response},
274 )285 )
275286
287 # populate deprecated functions properties using their replacement
288 if (
289 replacement_method := getattr(function, "deprecated", function)
290 ) is not function:
291 oper_obj["deprecated"] = True
292 oper_obj["responses"] = _oapi_item_from_docstring(
293 replacement_method, http_method, uri_params, doc, resources
294 )["responses"]
295
296 # if a response is still empty, query the function
297 if not oper_obj.get("responses"):
298 # fetch a response by calling the function
299 status, msg = "200", ""
300 try:
301 msg = function(*[""] * len(signature(function).parameters))
302 except Exception as e:
303 status = "404"
304 msg = str(e)
305 oper_obj["responses"] = {
306 status: {
307 "content": {"text/plain": {"schema": {"type": "string"}}},
308 "description": msg,
309 }
310 }
311
276 if body.get("properties"):312 if body.get("properties"):
277 oper_obj.update(313 oper_obj.update(
278 {314 {
@@ -317,6 +353,6 @@ def _render_oapi_paths():
317 _new_path_item(params),353 _new_path_item(params),
318 )354 )
319 path_item[http_method.lower()] = _render_oapi_oper_item(355 path_item[http_method.lower()] = _render_oapi_oper_item(
320 http_method, op, doc, params, function356 http_method, op, doc, params, function, resources
321 )357 )
322 return paths358 return paths
diff --git a/src/maasserver/api/machines.py b/src/maasserver/api/machines.py
index b6e92c6..93175c4 100644
--- a/src/maasserver/api/machines.py
+++ b/src/maasserver/api/machines.py
@@ -669,6 +669,21 @@ class MachineHandler(NodeHandler, WorkloadAnnotationsMixin, PowerMixin):
669669
670 @operation(idempotent=True)670 @operation(idempotent=True)
671 def get_token(self, request, system_id):671 def get_token(self, request, system_id):
672 """@description-title Get a machine token
673
674 @param (string) "{system_id}" [required=true] The machines' system_id.
675
676 @success (http-status-code) "200" 200
677 @success (json) "success-json" A JSON object containing information
678 about the machine token.
679 @success-example "success-json" [exkey=machines-placeholder]
680 placeholder text
681
682 @error (http-status-code) "404" 404
683 @error (content) "not-found" The requested machine is not found.
684 @error-example "not-found"
685 No Machine matches the given query.
686 """
672 node = self.model.objects.get_node_or_404(687 node = self.model.objects.get_node_or_404(
673 system_id=system_id,688 system_id=system_id,
674 user=request.user,689 user=request.user,
diff --git a/src/maasserver/management/commands/tests/test_generate_oapi.py b/src/maasserver/management/commands/tests/test_generate_oapi.py
index 2c49814..1431de1 100644
--- a/src/maasserver/management/commands/tests/test_generate_oapi.py
+++ b/src/maasserver/management/commands/tests/test_generate_oapi.py
@@ -10,10 +10,10 @@ from django.core.management import call_command
10import yaml10import yaml
1111
12from maasserver.api.doc_oapi import get_api_endpoint12from maasserver.api.doc_oapi import get_api_endpoint
13from maastesting.testcase import MAASTestCase13from maasserver.testing.testcase import MAASServerTestCase
1414
1515
16class TestOAPIDoc(MAASTestCase):16class TestOAPIDoc(MAASServerTestCase):
17 def test_generate_spec(self):17 def test_generate_spec(self):
18 spec = get_api_endpoint()18 spec = get_api_endpoint()
19 spec["externalDocs"]["url"] = "https://maas.io/docs"19 spec["externalDocs"]["url"] = "https://maas.io/docs"

Subscribers

People subscribed via source and target branches