Merge ~lloydwaltersj/maas:oapi-html-docs into maas:master
- Git
- lp:~lloydwaltersj/maas
- oapi-html-docs
- Merge into master
Status: | Merged |
---|---|
Approved by: | Jack Lloyd-Walters |
Approved revision: | cca21cb74427cddb474abf5df90ee96b88d2a16d |
Merge reported by: | MAAS Lander |
Merged at revision: | not available |
Proposed branch: | ~lloydwaltersj/maas:oapi-html-docs |
Merge into: | maas:master |
Diff against target: |
194 lines (+120/-4) 4 files modified
src/maasserver/api/doc_oapi.py (+27/-1) src/maasserver/api/tests/test_oapi.py (+18/-2) src/maasserver/templates/openapi.html (+67/-0) src/maasserver/urls.py (+8/-1) |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
MAAS Lander | Approve | ||
Alberto Donato (community) | Approve | ||
Review via email: mp+427769@code.launchpad.net |
Commit message
Generate html docs from oapi spec
Description of the change
Jack Lloyd-Walters (lloydwaltersj) wrote : | # |
jenkins: !test
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED
LOG: http://
COMMIT: 4a035f2be920bbf
- aa518d8... by Jack Lloyd-Walters
-
move JS dependencies out of maas
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED
LOG: http://
COMMIT: aa518d85234b54d
- 47f294d... by Jack Lloyd-Walters
-
run linting
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED
LOG: http://
COMMIT: 47f294dd342164c
- 5c19028... by Jack Lloyd-Walters
-
testing jenkins
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED
LOG: http://
COMMIT: 5c19028f007e130
- ede1fc1... by Jack Lloyd-Walters
-
fix test
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: SUCCESS
COMMIT: ede1fc119d3f9a7
Alberto Donato (ack) wrote : | # |
LGTM, one minor comment inline
- cca21cb... by Jack Lloyd-Walters
-
change to comment
MAAS Lander (maas-lander) wrote : | # |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: SUCCESS
COMMIT: cca21cb74427cdd
Preview Diff
1 | diff --git a/src/maasserver/api/doc_oapi.py b/src/maasserver/api/doc_oapi.py | |||
2 | index 9e7c55f..36793e2 100644 | |||
3 | --- a/src/maasserver/api/doc_oapi.py | |||
4 | +++ b/src/maasserver/api/doc_oapi.py | |||
5 | @@ -19,9 +19,35 @@ from maasserver.api.annotations import APIDocstringParser | |||
6 | 19 | from maasserver.api.doc import find_api_resources, generate_doc | 19 | from maasserver.api.doc import find_api_resources, generate_doc |
7 | 20 | from maasserver.djangosettings import settings | 20 | from maasserver.djangosettings import settings |
8 | 21 | from maasserver.models.config import Config | 21 | from maasserver.models.config import Config |
9 | 22 | from maasserver.models.controllerinfo import get_maas_version | ||
10 | 22 | from maasserver.utils import build_absolute_uri | 23 | from maasserver.utils import build_absolute_uri |
11 | 23 | 24 | ||
12 | 24 | 25 | ||
13 | 26 | def openapi_docs_context(request): | ||
14 | 27 | """Return the aadditional context needed for the oapi doc template to function""" | ||
15 | 28 | colourmap = { | ||
16 | 29 | "bark": "#585841", | ||
17 | 30 | "blue": "#0060bf", | ||
18 | 31 | "magenta": "#974097", | ||
19 | 32 | "olive": "#3d5f11", | ||
20 | 33 | "prussian green": "#225d5c", | ||
21 | 34 | "purple": "#7764d8", | ||
22 | 35 | "red": "#a71b33", | ||
23 | 36 | "sage": "#4e5f51", | ||
24 | 37 | "viridian": "#025a3d", | ||
25 | 38 | } | ||
26 | 39 | local_server = _get_maas_servers()[0] | ||
27 | 40 | context = { | ||
28 | 41 | "openapi_url": local_server["url"] + "openapi.yaml", | ||
29 | 42 | "maas_colour": colourmap.get( | ||
30 | 43 | Config.objects.get_config("theme").lower(), "#262626" | ||
31 | 44 | ), | ||
32 | 45 | "maas_name": local_server["description"].removesuffix(" API"), | ||
33 | 46 | "maas_version": get_maas_version(), | ||
34 | 47 | } | ||
35 | 48 | return context | ||
36 | 49 | |||
37 | 50 | |||
38 | 25 | def landing_page(request): | 51 | def landing_page(request): |
39 | 26 | """Render a landing page with pointers for the MAAS API. | 52 | """Render a landing page with pointers for the MAAS API. |
40 | 27 | 53 | ||
41 | @@ -71,7 +97,7 @@ def get_api_landing_page(): | |||
42 | 71 | "title": "the API definition", | 97 | "title": "the API definition", |
43 | 72 | }, | 98 | }, |
44 | 73 | { | 99 | { |
46 | 74 | "path": "/MAAS/docs/api.html", | 100 | "path": "/MAAS/api/docs/", |
47 | 75 | "rel": "service-doc", | 101 | "rel": "service-doc", |
48 | 76 | "type": "text/html", | 102 | "type": "text/html", |
49 | 77 | "title": "the API documentation", | 103 | "title": "the API documentation", |
50 | diff --git a/src/maasserver/api/tests/test_oapi.py b/src/maasserver/api/tests/test_oapi.py | |||
51 | index 8ea0e79..641726d 100644 | |||
52 | --- a/src/maasserver/api/tests/test_oapi.py | |||
53 | +++ b/src/maasserver/api/tests/test_oapi.py | |||
54 | @@ -5,7 +5,12 @@ import json | |||
55 | 5 | 5 | ||
56 | 6 | import yaml | 6 | import yaml |
57 | 7 | 7 | ||
59 | 8 | from maasserver.api.doc_oapi import _render_oapi_paths, endpoint, landing_page | 8 | from maasserver.api.doc_oapi import ( |
60 | 9 | _render_oapi_paths, | ||
61 | 10 | endpoint, | ||
62 | 11 | landing_page, | ||
63 | 12 | openapi_docs_context, | ||
64 | 13 | ) | ||
65 | 9 | from maasserver.models.config import Config | 14 | from maasserver.models.config import Config |
66 | 10 | from maasserver.testing.factory import factory | 15 | from maasserver.testing.factory import factory |
67 | 11 | from maasserver.testing.testcase import MAASServerTestCase | 16 | from maasserver.testing.testcase import MAASServerTestCase |
68 | @@ -53,6 +58,18 @@ class TestApiEndpoint(MAASServerTestCase): | |||
69 | 53 | self.assertEqual(maasserver["description"], f"{maas_name} API") | 58 | self.assertEqual(maasserver["description"], f"{maas_name} API") |
70 | 54 | 59 | ||
71 | 55 | 60 | ||
72 | 61 | class TestOAPIDocs(MAASServerTestCase): | ||
73 | 62 | def test_docs_point_to_api(self): | ||
74 | 63 | request = factory.make_fake_request() | ||
75 | 64 | page = landing_page(request) | ||
76 | 65 | content = json.loads(page.content) | ||
77 | 66 | oapi_res = content["resources"][1] | ||
78 | 67 | context = openapi_docs_context(request) | ||
79 | 68 | self.assertEqual( | ||
80 | 69 | context["openapi_url"], f"http://localhost:5240{oapi_res['path']}" | ||
81 | 70 | ) | ||
82 | 71 | |||
83 | 72 | |||
84 | 56 | class TestOAPISpec(MAASServerTestCase): | 73 | class TestOAPISpec(MAASServerTestCase): |
85 | 57 | def setUp(self): | 74 | def setUp(self): |
86 | 58 | self.oapi_types = ["boolean", "integer", "number", "object", "string"] | 75 | self.oapi_types = ["boolean", "integer", "number", "object", "string"] |
87 | @@ -103,6 +120,5 @@ class TestOAPISpec(MAASServerTestCase): | |||
88 | 103 | yield (k, v) | 120 | yield (k, v) |
89 | 104 | 121 | ||
90 | 105 | for k, v in _get_all_key_values(_render_oapi_paths()): | 122 | for k, v in _get_all_key_values(_render_oapi_paths()): |
91 | 106 | print(k, v) | ||
92 | 107 | if k == "type": | 123 | if k == "type": |
93 | 108 | self.assertIn(v, self.oapi_types) | 124 | self.assertIn(v, self.oapi_types) |
94 | diff --git a/src/maasserver/templates/openapi.html b/src/maasserver/templates/openapi.html | |||
95 | 109 | new file mode 100644 | 125 | new file mode 100644 |
96 | index 0000000..5381de5 | |||
97 | --- /dev/null | |||
98 | +++ b/src/maasserver/templates/openapi.html | |||
99 | @@ -0,0 +1,67 @@ | |||
100 | 1 | {# HTML for static distribution bundle build #} | ||
101 | 2 | <!DOCTYPE html> | ||
102 | 3 | <html lang="en"> | ||
103 | 4 | <head> | ||
104 | 5 | <meta charset="UTF-8"> | ||
105 | 6 | <title>MAAS API</title> | ||
106 | 7 | <link href="/MAAS/r/static/css/main.05850fff.css" rel="stylesheet"> | ||
107 | 8 | <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css" /> | ||
108 | 9 | <style> | ||
109 | 10 | html * { | ||
110 | 11 | font-family: ubuntu !important; | ||
111 | 12 | font-weight: 300 !important; | ||
112 | 13 | line-height: 1.5rem; | ||
113 | 14 | } | ||
114 | 15 | h3 { | ||
115 | 16 | min-width: 100%; | ||
116 | 17 | } | ||
117 | 18 | p { | ||
118 | 19 | margin: 0 !important; | ||
119 | 20 | max-width: 100% !important; | ||
120 | 21 | } | ||
121 | 22 | </style> | ||
122 | 23 | </head> | ||
123 | 24 | |||
124 | 25 | <body> | ||
125 | 26 | <header class="p-navigation is-dark" style="background-color: {{ maas_colour }};"> | ||
126 | 27 | <div class="p-navigation__row"> | ||
127 | 28 | <div class="p-navigation__banner"> | ||
128 | 29 | <div class="p-navigation__tagged-logo"> | ||
129 | 30 | <a aria-label="Homepage" class="p-navigation__link" href="/MAAS/r/dashboard"> | ||
130 | 31 | <div class="p-navigation__logo-tag"> | ||
131 | 32 | <svg class="p-navigation__logo-icon" fill="#fff" viewBox="0 0 165.5 174.3" xmlns="http://www.w3.org/2000/svg"> | ||
132 | 33 | <ellipse cx="15.57" cy="111.46" rx="13.44" ry="13.3"></ellipse> | ||
133 | 34 | <path d="M156.94 101.45H31.88a18.91 18.91 0 0 1 .27 19.55c-.09.16-.2.31-.29.46h125.08a6 6 0 0 0 6.06-5.96v-8.06a6 6 0 0 0-6-6Z"></path> | ||
134 | 35 | <ellipse cx="15.62" cy="63.98" rx="13.44" ry="13.3"></ellipse> | ||
135 | 36 | <path d="M156.94 53.77H31.79a18.94 18.94 0 0 1 .42 19.75l-.16.24h124.89a6 6 0 0 0 6.06-5.94v-8.06a6 6 0 0 0-6-6Z"></path> | ||
136 | 37 | <ellipse cx="16.79" cy="16.5" rx="13.44" ry="13.3"></ellipse> | ||
137 | 38 | <path d="M156.94 6.5H33.1a19.15 19.15 0 0 1 2.21 5.11A18.82 18.82 0 0 1 33.42 26l-.29.46h123.81a6 6 0 0 0 6.06-5.9V12.5a6 6 0 0 0-6-6Z"></path><ellipse cx="15.57" cy="158.94" rx="13.44" ry="13.3"></ellipse> | ||
138 | 39 | <path d="M156.94 149H31.88a18.88 18.88 0 0 1 .27 19.5c-.09.16-.19.31-.29.46h125.08A6 6 0 0 0 163 163v-8.06a6 6 0 0 0-6-6Z"></path> | ||
139 | 40 | </svg> | ||
140 | 41 | </div> | ||
141 | 42 | <span class="p-navigation__logo-title">Canonical MAAS</span> | ||
142 | 43 | </a> | ||
143 | 44 | </div> | ||
144 | 45 | </div> | ||
145 | 46 | <div style="margin: auto; margin-right:0;"> | ||
146 | 47 | <a aria-label="Homepage" class="p-navigation__link" href="/MAAS/api/"> | ||
147 | 48 | <div class="p-navigation__logo-title">{{ maas_name }} MAAS: {{ maas_version }}</div> | ||
148 | 49 | </a> | ||
149 | 50 | </div> | ||
150 | 51 | </header> | ||
151 | 52 | <div id="swagger-ui" style="max-width: 90rem; margin: auto;"></div> | ||
152 | 53 | <script src="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js" crossorigin></script> | ||
153 | 54 | <script> | ||
154 | 55 | window.onload = function() { | ||
155 | 56 | window.ui = SwaggerUIBundle({ | ||
156 | 57 | url: "{{ openapi_url }}", | ||
157 | 58 | dom_id: '#swagger-ui', | ||
158 | 59 | deepLinking: true, | ||
159 | 60 | presets: [ | ||
160 | 61 | SwaggerUIBundle.presets.apis, | ||
161 | 62 | ], | ||
162 | 63 | }); | ||
163 | 64 | }; | ||
164 | 65 | </script> | ||
165 | 66 | </body> | ||
166 | 67 | </html> | ||
167 | 0 | \ No newline at end of file | 68 | \ No newline at end of file |
168 | diff --git a/src/maasserver/urls.py b/src/maasserver/urls.py | |||
169 | index c2cba09..63ef2ec 100644 | |||
170 | --- a/src/maasserver/urls.py | |||
171 | +++ b/src/maasserver/urls.py | |||
172 | @@ -9,7 +9,7 @@ from django.urls import include, re_path | |||
173 | 9 | from django.views.generic import TemplateView | 9 | from django.views.generic import TemplateView |
174 | 10 | 10 | ||
175 | 11 | from maasserver import urls_api | 11 | from maasserver import urls_api |
177 | 12 | from maasserver.api.doc_oapi import landing_page | 12 | from maasserver.api.doc_oapi import landing_page, openapi_docs_context |
178 | 13 | from maasserver.bootresources import ( | 13 | from maasserver.bootresources import ( |
179 | 14 | simplestreams_file_handler, | 14 | simplestreams_file_handler, |
180 | 15 | simplestreams_stream_handler, | 15 | simplestreams_stream_handler, |
181 | @@ -78,6 +78,13 @@ urlpatterns += [re_path(r"^accounts/logout/$", logout, name="logout")] | |||
182 | 78 | # API URLs. If old API requested, provide error message directing to new API. | 78 | # API URLs. If old API requested, provide error message directing to new API. |
183 | 79 | urlpatterns += [ | 79 | urlpatterns += [ |
184 | 80 | re_path(r"^api/$", landing_page), | 80 | re_path(r"^api/$", landing_page), |
185 | 81 | re_path( | ||
186 | 82 | r"^api/docs/", | ||
187 | 83 | lambda request: TemplateView.as_view( | ||
188 | 84 | template_name="openapi.html", | ||
189 | 85 | extra_context=openapi_docs_context(request), | ||
190 | 86 | ), | ||
191 | 87 | ), | ||
192 | 81 | re_path(r"^api/2\.0/", include(urls_api)), | 88 | re_path(r"^api/2\.0/", include(urls_api)), |
193 | 82 | re_path( | 89 | re_path( |
194 | 83 | r"^api/version/", | 90 | r"^api/version/", |
UNIT TESTS
-b oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas
STATUS: FAILED maas-ci. internal: 8080/job/ maas-tester/ 260/consoleText 379dd4b853d1dc1 2661b3642d
LOG: http://
COMMIT: 4a035f2be920bbf