diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8344ca34da..200780819c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -44,11 +44,10 @@ jobs: OPENSVC_CI_EXTRA_TIME_OSVCD_STARTUP: 25 run: sudo $(which pytest) ${{ matrix.PYTEST_EXTRA_ARGS }} -m "ci" - - name: Run codecov - if: ${{ success() }} + - name: Run coverage report + if: ${{ success() && matrix.PYTEST_EXTRA_ARGS == '--cov' }} run: | - pip install codecov - codecov + coverage report ci-pylint: runs-on: ubuntu-latest diff --git a/opensvc/core/node/nodedict.py b/opensvc/core/node/nodedict.py index d034118302..f74cb036f8 100644 --- a/opensvc/core/node/nodedict.py +++ b/opensvc/core/node/nodedict.py @@ -695,6 +695,13 @@ "example": "https://keycloak.opensvc.com/auth/realms/clusters/.well-known/openid-configuration", "text": "The url serving the well-known configuration of an openid provider. If set, the h2 listener will try to validate the Bearer token provided in the requests. If valid the user name is fetched from the 'preferred_username' claim (fallback on 'name'), and the user grants are fetched from the 'grant' claim. Grant can be a list, in which case a proper grant value is formatted via concatenation of the list elements." }, + { + "section": "listener", + "keyword": "ui", + "convert": "boolean", + "default": True, + "text": "Serve the ui webapp to browsers getting the api / path.", + }, { "section": "syslog", "keyword": "facility", diff --git a/opensvc/daemon/handlers/api/get.py b/opensvc/daemon/handlers/api/get.py index c66f7f7f2c..a497166634 100644 --- a/opensvc/daemon/handlers/api/get.py +++ b/opensvc/daemon/handlers/api/get.py @@ -9,7 +9,10 @@ class Handler(daemon.handler.BaseHandler): (None, "get_api"), ) prototype = [] - access = {} + access = { + "roles": ["guest"], + "namespaces": "ANY", + } def action(self, nodename, thr=None, **kwargs): sigs = [] diff --git a/opensvc/daemon/handlers/keywords/get.py b/opensvc/daemon/handlers/keywords/get.py index 18ce434338..07fe7abdd3 100644 --- a/opensvc/daemon/handlers/keywords/get.py +++ b/opensvc/daemon/handlers/keywords/get.py @@ -20,7 +20,10 @@ class Handler(daemon.handler.BaseHandler): "desc": "The object kind or 'node'.", }, ] - access = {} + access = { + "roles": ["guest"], + "namespaces": "ANY", + } def action(self, nodename, thr=None, **kwargs): options = self.parse_options(kwargs) diff --git a/opensvc/daemon/listener.py b/opensvc/daemon/listener.py index 26cea03694..5a6607952b 100644 --- a/opensvc/daemon/listener.py +++ b/opensvc/daemon/listener.py @@ -1258,7 +1258,7 @@ def h2_router(self, stream_id): sending_progress = "sending %s /%s result" % (method, path) if path == "favicon.ico": self.parent.stats.sessions.alive[self.sid].progress = sending_progress - return 200, "image/x-icon", ICON + return self.favicon() elif path in ("", "index.html"): self.parent.stats.sessions.alive[self.sid].progress = sending_progress return self.index() @@ -2116,6 +2116,16 @@ def load_file(self, path): # App # ########################################################################## + + @staticmethod + def ui(): + return shared.NODE.oget("listener", "ui") + + def favicon(self): + if not self.ui(): + return 403, "", "" + return 200, "image/x-icon", ICON + def serve_file(self, rpath, content_type): try: return 200, content_type, self.load_file(rpath) @@ -2123,10 +2133,14 @@ def serve_file(self, rpath, content_type): return 404, content_type, "The webapp is not installed." def index(self): + if not self.ui(): + return 403, "", "" #data = self.load_file("index.js") #self.h2_push_promise(stream_id, "/index.js", data, "application/javascript") return self.serve_file("index.html", "text/html") def index_js(self): + if not self.ui(): + return 403, "", "" return self.serve_file("index.js", "application/javascript")