Skip to content

Commit ddc3a81

Browse files
authored
Fix the section name in wait_for_oidc_server function (#3415)
* Fix the section name in the wait_for_oidc_server function - Fix leftover openid-connect -> openid - Add test coverage for wait_for_oidc_server - Add test coverage for the remaining parts of shell.py
1 parent 10d5704 commit ddc3a81

File tree

6 files changed

+95
-26
lines changed

6 files changed

+95
-26
lines changed

lib/pbench/cli/server/shell.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,16 @@ def run_gunicorn(server_config: PbenchServerConfig, logger: Logger) -> int:
110110
except OpenIDClient.NotConfigured as exc:
111111
logger.warning("OpenID Connect client not configured, {}", exc)
112112
notifier.notify("STOPPING=1")
113+
notifier.notify("STATUS=OPENID broker not configured")
114+
return 1
115+
except (
116+
OpenIDClient.ServerConnectionError,
117+
OpenIDClient.ServerConnectionTimedOut,
118+
) as exc:
119+
logger.warning("OpenID Connect client not reachable, {}", exc)
120+
notifier.notify("STOPPING=1")
113121
notifier.notify("STATUS=OPENID broker not responding")
122+
return 1
114123
else:
115124
logger.info("Pbench server using OIDC server {}", oidc_server)
116125

lib/pbench/server/api/resources/endpoint_configure.py

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
from configparser import NoOptionError, NoSectionError
21
from http import HTTPStatus
32
import re
43
from typing import Any, Dict
@@ -50,7 +49,7 @@ def get(self):
5049
Return server configuration information required by web clients
5150
including the Pbench dashboard UI. This includes:
5251
53-
openid-connect: A JSON object containing the OpenID Connect parameters
52+
openid: A JSON object containing the OpenID Connect parameters
5453
required for the web client to use OIDC authentication.
5554
identification: The Pbench server name and version
5655
uri: A dict of server API templates, where each template defines a
@@ -150,18 +149,15 @@ def get(self):
150149
"uri": templates,
151150
}
152151

153-
try:
154-
client = self.server_config.get("openid", "client")
155-
realm = self.server_config.get("openid", "realm")
156-
server = self.server_config.get("openid", "server_url")
157-
except (NoOptionError, NoSectionError):
158-
pass
159-
else:
160-
endpoints["openid"] = {
161-
"client": client,
162-
"realm": realm,
163-
"server": server,
164-
}
152+
client = self.server_config.get("openid", "client")
153+
realm = self.server_config.get("openid", "realm")
154+
server = self.server_config.get("openid", "server_url")
155+
156+
endpoints["openid"] = {
157+
"client": client,
158+
"realm": realm,
159+
"server": server,
160+
}
165161

166162
try:
167163
response = jsonify(endpoints)

lib/pbench/server/auth/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def wait_for_oidc_server(
208208
times out.
209209
"""
210210
try:
211-
oidc_server = server_config.get("openid-connect", "server_url")
211+
oidc_server = server_config.get("openid", "server_url")
212212
except (NoOptionError, NoSectionError) as exc:
213213
raise OpenIDClient.NotConfigured() from exc
214214

lib/pbench/test/unit/server/auth/test_auth.py

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
import pytest
99
import requests
1010
from requests.structures import CaseInsensitiveDict
11+
import responses
1112

1213
from pbench.server import JSON
1314
import pbench.server.auth
@@ -289,6 +290,64 @@ def get(self, path: str, **kwargs) -> MockResponse:
289290
class TestOpenIDClient:
290291
"""Verify the OpenIDClient class."""
291292

293+
@responses.activate
294+
def test_wait_for_oidc_server_fail(self, make_logger):
295+
"""Verify .wait_for_oidc_server() failure mode"""
296+
# Start with an empty configuration, no openid section
297+
config = configparser.ConfigParser()
298+
with pytest.raises(OpenIDClient.NotConfigured):
299+
OpenIDClient.wait_for_oidc_server(config, make_logger)
300+
# Missing "server_url"
301+
section = {}
302+
config["openid"] = section
303+
with pytest.raises(OpenIDClient.NotConfigured):
304+
OpenIDClient.wait_for_oidc_server(config, make_logger)
305+
306+
section = {"server_url": "https://example.com"}
307+
config["openid"] = section
308+
309+
# Keycloak health returning response but status is not UP
310+
responses.add(
311+
responses.GET,
312+
"https://example.com/health",
313+
body='{"status": "DOWN","checks": []}',
314+
content_type="application/json",
315+
)
316+
317+
with pytest.raises(OpenIDClient.ServerConnectionTimedOut):
318+
OpenIDClient.wait_for_oidc_server(config, make_logger)
319+
320+
# Keycloak health returning network exception and no content
321+
responses.add(
322+
responses.GET,
323+
"https://example.com/health",
324+
body=Exception("some network exception"),
325+
)
326+
327+
with pytest.raises(OpenIDClient.ServerConnectionError):
328+
OpenIDClient.wait_for_oidc_server(config, make_logger)
329+
330+
@responses.activate
331+
def test_wait_for_oidc_server_succ(self, make_logger):
332+
"""Verify .wait_for_oidc_server() success mode"""
333+
334+
config = configparser.ConfigParser()
335+
section = {"server_url": "https://example.com"}
336+
config["openid"] = section
337+
338+
# Keycloak health returning response with status UP
339+
responses.add(
340+
responses.GET,
341+
"https://example.com/health",
342+
body='{"status": "UP","checks": []}',
343+
content_type="application/json",
344+
)
345+
346+
assert (
347+
OpenIDClient.wait_for_oidc_server(config, make_logger)
348+
== "https://example.com"
349+
)
350+
292351
def test_construct_oidc_client_fail(self):
293352
"""Verfiy .construct_oidc_client() failure mode"""
294353

lib/pbench/test/unit/server/test_shell_cli.py

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -71,10 +71,7 @@ def test_find_the_unicorn(monkeypatch, make_logger):
7171

7272
@staticmethod
7373
@pytest.mark.parametrize("user_site", [False, True])
74-
@pytest.mark.parametrize("oidc_conf", [False, True])
75-
def test_main(
76-
monkeypatch, make_logger, mock_get_server_config, user_site, oidc_conf
77-
):
74+
def test_main(monkeypatch, make_logger, mock_get_server_config, user_site):
7875
called = []
7976

8077
def find_the_unicorn(logger: logging.Logger):
@@ -89,10 +86,8 @@ def init_indexing(*args, **kwargs):
8986
def wait_for_oidc_server(
9087
server_config: PbenchServerConfig, logger: logging.Logger
9188
) -> str:
92-
if oidc_conf:
93-
return "https://oidc.example.com"
94-
else:
95-
raise OpenIDClient.NotConfigured()
89+
called.append("wait_for_oidc_server")
90+
return "https://oidc.example.com"
9691

9792
commands = []
9893

@@ -117,6 +112,7 @@ def run(args, cwd: Optional[str] = None) -> subprocess.CompletedProcess:
117112
expected_called += [
118113
"wait_for_uri(sqlite:///:memory:,120)",
119114
"wait_for_uri(http://elasticsearch.example.com:7080,120)",
115+
"wait_for_oidc_server",
120116
"init_indexing",
121117
]
122118
assert called == expected_called
@@ -211,8 +207,17 @@ def init_db(*args, **kwargs) -> int:
211207
assert ret_val == 1
212208

213209
@staticmethod
210+
@pytest.mark.parametrize(
211+
"exc",
212+
[
213+
Exception("oidc exception"),
214+
OpenIDClient.NotConfigured,
215+
OpenIDClient.ServerConnectionTimedOut,
216+
OpenIDClient.ServerConnectionError,
217+
],
218+
)
214219
def test_main_wait_for_oidc_server_exc(
215-
monkeypatch, make_logger, mock_get_server_config
220+
monkeypatch, make_logger, mock_get_server_config, exc
216221
):
217222
def immediate_success(*args, **kwargs):
218223
pass
@@ -223,7 +228,7 @@ def wait_for_oidc_server(
223228
server_config: PbenchServerConfig, logger: logging.Logger
224229
) -> str:
225230
called[0] = True
226-
raise Exception("oidc exception")
231+
raise exc
227232

228233
monkeypatch.setattr(shell.site, "ENABLE_USER_SITE", False)
229234
monkeypatch.setattr(shell, "wait_for_uri", immediate_success)

server/pbenchinacan/load_keycloak.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ KEYCLOAK_REDIRECT_URI=${KEYCLOAK_REDIRECT_URI:-"http://localhost:8080/*"}
2222
ADMIN_USERNAME=${ADMIN_USERNAME:-"admin"}
2323
ADMIN_PASSWORD=${ADMIN_PASSWORD:-"admin"}
2424
# These values must match the options "realm" and "client in the
25-
# "openid-connect" section of the pbench server configuration file.
25+
# "openid" section of the pbench server configuration file.
2626
REALM=${KEYCLOAK_REALM:-"pbench-server"}
2727
CLIENT=${KEYCLOAK_CLIENT:-"pbench-client"}
2828

0 commit comments

Comments
 (0)