Merge ~lloydwaltersj/maas:oapi-html-docs into maas:master

Proposed by Jack Lloyd-Walters
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)
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

To post a comment you must log in.
Revision history for this message
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://maas-ci.internal:8080/job/maas-tester/260/consoleText
COMMIT: 4a035f2be920bbf379dd4b853d1dc12661b3642d

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 oapi-html-docs lp:~lloydwaltersj/maas/+git/maas into -b master lp:~maas-committers/maas

STATUS: FAILED
LOG: http://maas-ci.internal:8080/job/maas-tester/261/consoleText
COMMIT: 4a035f2be920bbf379dd4b853d1dc12661b3642d

review: Needs Fixing
~lloydwaltersj/maas:oapi-html-docs updated
aa518d8... by Jack Lloyd-Walters

move JS dependencies out of maas

Revision history for this message
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://maas-ci.internal:8080/job/maas-tester/262/consoleText
COMMIT: aa518d85234b54d71ab852e958465a0b08d9f449

review: Needs Fixing
~lloydwaltersj/maas:oapi-html-docs updated
47f294d... by Jack Lloyd-Walters

run linting

Revision history for this message
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://maas-ci.internal:8080/job/maas-tester/263/consoleText
COMMIT: 47f294dd342164c1ea3782ab2c8e3bc9c5afa703

review: Needs Fixing
~lloydwaltersj/maas:oapi-html-docs updated
5c19028... by Jack Lloyd-Walters

testing jenkins

Revision history for this message
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://maas-ci.internal:8080/job/maas-tester/265/consoleText
COMMIT: 5c19028f007e13054e22ce8ffa1b5795ad47265b

review: Needs Fixing
~lloydwaltersj/maas:oapi-html-docs updated
ede1fc1... by Jack Lloyd-Walters

fix test

Revision history for this message
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: ede1fc119d3f9a71fa48238bbc599176b999e075

review: Approve
Revision history for this message
Alberto Donato (ack) wrote :

LGTM, one minor comment inline

review: Approve
~lloydwaltersj/maas:oapi-html-docs updated
cca21cb... by Jack Lloyd-Walters

change to comment

Revision history for this message
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: cca21cb74427cddb474abf5df90ee96b88d2a16d

review: Approve

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 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 from maasserver.api.doc import find_api_resources, generate_doc
7 from maasserver.djangosettings import settings
8 from maasserver.models.config import Config
9+from maasserver.models.controllerinfo import get_maas_version
10 from maasserver.utils import build_absolute_uri
11
12
13+def openapi_docs_context(request):
14+ """Return the aadditional context needed for the oapi doc template to function"""
15+ colourmap = {
16+ "bark": "#585841",
17+ "blue": "#0060bf",
18+ "magenta": "#974097",
19+ "olive": "#3d5f11",
20+ "prussian green": "#225d5c",
21+ "purple": "#7764d8",
22+ "red": "#a71b33",
23+ "sage": "#4e5f51",
24+ "viridian": "#025a3d",
25+ }
26+ local_server = _get_maas_servers()[0]
27+ context = {
28+ "openapi_url": local_server["url"] + "openapi.yaml",
29+ "maas_colour": colourmap.get(
30+ Config.objects.get_config("theme").lower(), "#262626"
31+ ),
32+ "maas_name": local_server["description"].removesuffix(" API"),
33+ "maas_version": get_maas_version(),
34+ }
35+ return context
36+
37+
38 def landing_page(request):
39 """Render a landing page with pointers for the MAAS API.
40
41@@ -71,7 +97,7 @@ def get_api_landing_page():
42 "title": "the API definition",
43 },
44 {
45- "path": "/MAAS/docs/api.html",
46+ "path": "/MAAS/api/docs/",
47 "rel": "service-doc",
48 "type": "text/html",
49 "title": "the API documentation",
50diff --git a/src/maasserver/api/tests/test_oapi.py b/src/maasserver/api/tests/test_oapi.py
51index 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
56 import yaml
57
58-from maasserver.api.doc_oapi import _render_oapi_paths, endpoint, landing_page
59+from maasserver.api.doc_oapi import (
60+ _render_oapi_paths,
61+ endpoint,
62+ landing_page,
63+ openapi_docs_context,
64+)
65 from maasserver.models.config import Config
66 from maasserver.testing.factory import factory
67 from maasserver.testing.testcase import MAASServerTestCase
68@@ -53,6 +58,18 @@ class TestApiEndpoint(MAASServerTestCase):
69 self.assertEqual(maasserver["description"], f"{maas_name} API")
70
71
72+class TestOAPIDocs(MAASServerTestCase):
73+ def test_docs_point_to_api(self):
74+ request = factory.make_fake_request()
75+ page = landing_page(request)
76+ content = json.loads(page.content)
77+ oapi_res = content["resources"][1]
78+ context = openapi_docs_context(request)
79+ self.assertEqual(
80+ context["openapi_url"], f"http://localhost:5240{oapi_res['path']}"
81+ )
82+
83+
84 class TestOAPISpec(MAASServerTestCase):
85 def setUp(self):
86 self.oapi_types = ["boolean", "integer", "number", "object", "string"]
87@@ -103,6 +120,5 @@ class TestOAPISpec(MAASServerTestCase):
88 yield (k, v)
89
90 for k, v in _get_all_key_values(_render_oapi_paths()):
91- print(k, v)
92 if k == "type":
93 self.assertIn(v, self.oapi_types)
94diff --git a/src/maasserver/templates/openapi.html b/src/maasserver/templates/openapi.html
95new file mode 100644
96index 0000000..5381de5
97--- /dev/null
98+++ b/src/maasserver/templates/openapi.html
99@@ -0,0 +1,67 @@
100+{# HTML for static distribution bundle build #}
101+<!DOCTYPE html>
102+<html lang="en">
103+ <head>
104+ <meta charset="UTF-8">
105+ <title>MAAS API</title>
106+ <link href="/MAAS/r/static/css/main.05850fff.css" rel="stylesheet">
107+ <link rel="stylesheet" href="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui.css" />
108+ <style>
109+ html * {
110+ font-family: ubuntu !important;
111+ font-weight: 300 !important;
112+ line-height: 1.5rem;
113+ }
114+ h3 {
115+ min-width: 100%;
116+ }
117+ p {
118+ margin: 0 !important;
119+ max-width: 100% !important;
120+ }
121+ </style>
122+ </head>
123+
124+ <body>
125+ <header class="p-navigation is-dark" style="background-color: {{ maas_colour }};">
126+ <div class="p-navigation__row">
127+ <div class="p-navigation__banner">
128+ <div class="p-navigation__tagged-logo">
129+ <a aria-label="Homepage" class="p-navigation__link" href="/MAAS/r/dashboard">
130+ <div class="p-navigation__logo-tag">
131+ <svg class="p-navigation__logo-icon" fill="#fff" viewBox="0 0 165.5 174.3" xmlns="http://www.w3.org/2000/svg">
132+ <ellipse cx="15.57" cy="111.46" rx="13.44" ry="13.3"></ellipse>
133+ <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+ <ellipse cx="15.62" cy="63.98" rx="13.44" ry="13.3"></ellipse>
135+ <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+ <ellipse cx="16.79" cy="16.5" rx="13.44" ry="13.3"></ellipse>
137+ <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+ <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+ </svg>
140+ </div>
141+ <span class="p-navigation__logo-title">Canonical MAAS</span>
142+ </a>
143+ </div>
144+ </div>
145+ <div style="margin: auto; margin-right:0;">
146+ <a aria-label="Homepage" class="p-navigation__link" href="/MAAS/api/">
147+ <div class="p-navigation__logo-title">{{ maas_name }} MAAS: {{ maas_version }}</div>
148+ </a>
149+ </div>
150+ </header>
151+ <div id="swagger-ui" style="max-width: 90rem; margin: auto;"></div>
152+ <script src="https://unpkg.com/swagger-ui-dist@4.5.0/swagger-ui-bundle.js" crossorigin></script>
153+ <script>
154+ window.onload = function() {
155+ window.ui = SwaggerUIBundle({
156+ url: "{{ openapi_url }}",
157+ dom_id: '#swagger-ui',
158+ deepLinking: true,
159+ presets: [
160+ SwaggerUIBundle.presets.apis,
161+ ],
162+ });
163+ };
164+ </script>
165+ </body>
166+</html>
167\ No newline at end of file
168diff --git a/src/maasserver/urls.py b/src/maasserver/urls.py
169index 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 from django.views.generic import TemplateView
174
175 from maasserver import urls_api
176-from maasserver.api.doc_oapi import landing_page
177+from maasserver.api.doc_oapi import landing_page, openapi_docs_context
178 from maasserver.bootresources import (
179 simplestreams_file_handler,
180 simplestreams_stream_handler,
181@@ -78,6 +78,13 @@ urlpatterns += [re_path(r"^accounts/logout/$", logout, name="logout")]
182 # API URLs. If old API requested, provide error message directing to new API.
183 urlpatterns += [
184 re_path(r"^api/$", landing_page),
185+ re_path(
186+ r"^api/docs/",
187+ lambda request: TemplateView.as_view(
188+ template_name="openapi.html",
189+ extra_context=openapi_docs_context(request),
190+ ),
191+ ),
192 re_path(r"^api/2\.0/", include(urls_api)),
193 re_path(
194 r"^api/version/",

Subscribers

People subscribed via source and target branches