Skip to content

Commit

Permalink
Remove HTTP access to the canned Pbench Server (#3451)
Browse files Browse the repository at this point in the history
Access now requires HTTPS.

Updates the Server documentation examples, the default Agent configuration,
the run-server-func-tests script, the unit tests and unit test infrastructure,
the canned Nginx proxy configuration, and the Keycloak redirect
configuration and the Keycloak access adapter.

PBENCH-1176
  • Loading branch information
webbnh authored Jun 23, 2023
1 parent 68d543d commit fa225e2
Show file tree
Hide file tree
Showing 17 changed files with 82 additions and 52 deletions.
2 changes: 1 addition & 1 deletion agent/config/pbench-agent-default.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ssh_opts = -o BatchMode=yes -o StrictHostKeyChecking=no
# REST API entrypoint
api_version = 1
rest_endpoint = api/v%(api_version)s
server_rest_url = http://%(pbench_web_server)s/%(rest_endpoint)s
server_rest_url = https://%(pbench_web_server)s/%(rest_endpoint)s

[pbench/tools]
light-tool-set = vmstat
Expand Down
14 changes: 7 additions & 7 deletions docs/Server/API/V1/contents.md
Original file line number Diff line number Diff line change
Expand Up @@ -77,12 +77,12 @@ Pbench returns a JSON object with two list fields:
{
"name": "dir1",
"type": "dir",
"uri": "http://hostname/api/v1/datasets/<id>/contents/dir1"
"uri": "https://hostname/api/v1/datasets/<id>/contents/dir1"
},
{
"name": "dir2",
"type": "dir",
"uri": "http://hostname/api/v1/datasets/<id>/contents/dir2"
"uri": "https://hostname/api/v1/datasets/<id>/contents/dir2"
},
...
],
Expand All @@ -93,15 +93,15 @@ Pbench returns a JSON object with two list fields:
"size": 24,
"mode": "0o644",
"type": "reg",
"uri": "http://hostname/api/v1/datasets/<id>/inventory/file.txt"
"uri": "https://hostname/api/v1/datasets/<id>/inventory/file.txt"
},
{
"name": "data.lis",
"mtime": "2022-05-18T16:02:06",
"size": 18,
"mode": "0o644",
"type": "reg",
"uri": "http://hostname/api/v1/datasets/<id>/inventory/data.lis"
"uri": "https://hostname/api/v1/datasets/<id>/inventory/data.lis"
},
...
]
Expand All @@ -126,12 +126,12 @@ The `type` codes are:
{
"name": "reference-result",
"type": "sym",
"uri": "http://hostname/api/v1/datasets/<id>/contents/linkresult"
"uri": "https://hostname/api/v1/datasets/<id>/contents/linkresult"
},
{
"name": "directory",
"type": "dir",
"uri": "http://hostname/api/v1/datasets/<id>/contents/directory"
"uri": "https://hostname/api/v1/datasets/<id>/contents/directory"
}
```

Expand Down Expand Up @@ -159,6 +159,6 @@ URI returning the linked file's byte stream.
"size": 18,
"mode": "0o644",
"type": "reg",
"uri": "http://hostname/api/v1/datasets/<id>/inventory/<path>"
"uri": "https://hostname/api/v1/datasets/<id>/inventory/<path>"
}
```
40 changes: 20 additions & 20 deletions docs/Server/API/V1/endpoints.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ URI template and parameters for the API.
##### `template`

The API's URI template pattern, with URI parameters in the form `{<name>}`, as in
`http://host:port/api/v1/datasets/{dataset}/metadata`.
`https://host:port/api/v1/datasets/{dataset}/metadata`.

##### `params`

Expand Down Expand Up @@ -104,7 +104,7 @@ let uri = uriTemplate(
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}"
},
"datasets_contents": {
"params": {
Expand All @@ -115,19 +115,19 @@ let uri = uriTemplate(
"type": "path"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}/contents/{target}"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}/contents/{target}"
},
"datasets_daterange": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/datasets/daterange"
"template": "https://10.1.1.1:8443/api/v1/datasets/daterange"
},
"datasets_detail": {
"params": {
"dataset": {
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}/detail"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}/detail"
},
"datasets_inventory": {
"params": {
Expand All @@ -138,27 +138,27 @@ let uri = uriTemplate(
"type": "path"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}/inventory/{target}"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}/inventory/{target}"
},
"datasets_list": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/datasets"
"template": "https://10.1.1.1:8443/api/v1/datasets"
},
"datasets_mappings": {
"params": {
"dataset_view": {
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/mappings/{dataset_view}"
"template": "https://10.1.1.1:8443/api/v1/datasets/mappings/{dataset_view}"
},
"datasets_metadata": {
"params": {
"dataset": {
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}/metadata"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}/metadata"
},
"datasets_namespace": {
"params": {
Expand All @@ -169,11 +169,11 @@ let uri = uriTemplate(
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}/namespace/{dataset_view}"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}/namespace/{dataset_view}"
},
"datasets_search": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/datasets/search"
"template": "https://10.1.1.1:8443/api/v1/datasets/search"
},
"datasets_values": {
"params": {
Expand All @@ -184,51 +184,51 @@ let uri = uriTemplate(
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/datasets/{dataset}/values/{dataset_view}"
"template": "https://10.1.1.1:8443/api/v1/datasets/{dataset}/values/{dataset_view}"
},
"endpoints": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/endpoints"
"template": "https://10.1.1.1:8443/api/v1/endpoints"
},
"login": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/login"
"template": "https://10.1.1.1:8443/api/v1/login"
},
"logout": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/logout"
"template": "https://10.1.1.1:8443/api/v1/logout"
},
"register": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/register"
"template": "https://10.1.1.1:8443/api/v1/register"
},
"server_audit": {
"params": {},
"template": "http://10.1.1.1:8080/api/v1/server/audit"
"template": "https://10.1.1.1:8443/api/v1/server/audit"
},
"server_settings": {
"params": {
"key": {
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/server/settings/{key}"
"template": "https://10.1.1.1:8443/api/v1/server/settings/{key}"
},
"upload": {
"params": {
"filename": {
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/upload/{filename}"
"template": "https://10.1.1.1:8443/api/v1/upload/{filename}"
},
"user": {
"params": {
"target_username": {
"type": "string"
}
},
"template": "http://10.1.1.1:8080/api/v1/user/{target_username}"
"template": "https://10.1.1.1:8443/api/v1/user/{target_username}"
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions docs/Server/API/V1/list.md
Original file line number Diff line number Diff line change
Expand Up @@ -264,12 +264,12 @@ display purposes and must not be assumed to be unique or definitive.
JSON object in this field.

For example, the query
`GET http://host/api/v1/datasets/list?metadata=user.dashboard.favorite&limit=3`
`GET https://host/api/v1/datasets/list?metadata=user.dashboard.favorite&limit=3`
might return:

```json
{
"next_url": "http://pbench.example.com/api/v1/datasets?limit=3&metadata=user.dashboard.favorite&offset=3",
"next_url": "https://pbench.example.com/api/v1/datasets?limit=3&metadata=user.dashboard.favorite&offset=3",
"results": [
{
"metadata": {
Expand Down
13 changes: 12 additions & 1 deletion jenkins/run-server-func-tests
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,20 @@ export PB_SERVER_IMAGE_TAG=${PB_SERVER_IMAGE_TAG:-"$(cat jenkins/branch.name)"}
export PB_POD_NAME=${PB_POD_NAME:-"pbench-in-a-can_${PB_SERVER_IMAGE_TAG}"}
export PB_SERVER_CONTAINER_NAME=${PB_SERVER_CONTAINER_NAME:-"${PB_POD_NAME}-pbenchserver"}

SERVER_URL="http://localhost:8080"
# Note: the value of PB_HOST_IP will be used to generate the TLS certificate
# and so it (not `localhost`) must also be used to access the Pbench Server;
# otherwise, the TLS validation will fail due to a host mismatch.
if [[ -z "${PB_HOST_IP}" ]]; then
host_ip_list=$(hostname -I)
PB_HOST_IP=${host_ip_list%% *}
export PB_HOST_IP
fi
SERVER_URL="https://${PB_HOST_IP}:8443"
SERVER_API_ENDPOINTS="${SERVER_URL}/api/v1/endpoints"

# Have Curl use the Pbench CA certificate to validate the TLS/SSL connection
export CURL_CA_BUNDLE="${PWD}/server/pbenchinacan/etc/pki/tls/certs/pbench_CA.crt"

cleanup_flag=0
keep_flag=0
exit_status=0
Expand Down
7 changes: 6 additions & 1 deletion lib/pbench/client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from enum import Enum
import os
from pathlib import Path
from typing import Iterator, Optional
from urllib import parse
Expand Down Expand Up @@ -57,7 +58,7 @@ class API(Enum):


class PbenchServerClient:
DEFAULT_SCHEME = "http"
DEFAULT_SCHEME = "https"
DEFAULT_PAGE_SIZE = 100

def __init__(self, host: str):
Expand Down Expand Up @@ -316,6 +317,10 @@ def connect(self, headers: Optional[dict[str, str]] = None) -> None:
"""
url = parse.urljoin(self.url, "api/v1/endpoints")
self.session = requests.Session()

# Use the same CA as Curl to do TLS verification;
# if it's not defined then disable TLS verification.
self.session.verify = os.environ.get("CURL_CA_BUNDLE", False)
if headers:
self.session.headers.update(headers)
response = self.session.get(url)
Expand Down
2 changes: 1 addition & 1 deletion lib/pbench/server/api/resources/endpoint_configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ def get(self):
API to get or modify metadata is:
{
"template": "http://host/api/v1/datasets/{dataset}/metadata",
"template": "https://host/api/v1/datasets/{dataset}/metadata",
"params": {"dataset": {"type": "string"}}
}
Expand Down
1 change: 1 addition & 0 deletions lib/pbench/server/auth/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,7 @@ def wait_for_oidc_server(
)
adapter = HTTPAdapter(max_retries=retry)
session.mount("http://", adapter)
session.mount("https://", adapter)

# We will also need to retry the connection if the health status is not UP.
connected = False
Expand Down
8 changes: 4 additions & 4 deletions lib/pbench/test/unit/agent/task/test_results_move.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,11 +51,11 @@ class TestResultsMove:
TOKN_TEXT = "what is a token but 139 characters of gibberish"
ACCESS_TEXT = "private"
RELAY_TEXT = "http://relay.example.com"
SRVR_TEXT = "http://pbench.test.example.com"
SRVR_TEXT = "https://pbench.test.example.com"
META_SWITCH = "--metadata"
META_TEXT_FOO = "pbench.sat:FOO"
META_TEXT_TEST = "pbench.test:TEST"
URL = "http://pbench.example.com/api/v1"
URL = "https://pbench.example.com/api/v1"
ENDPOINT = "/login"

@staticmethod
Expand Down Expand Up @@ -203,7 +203,7 @@ def test_results_move(monkeypatch, caplog, setup):

responses.add(
responses.PUT,
f"http://pbench.example.com/api/v1/upload/{name}.tar.xz",
f"{TestResultsMove.URL}/upload/{name}.tar.xz",
status=200,
)

Expand Down Expand Up @@ -292,7 +292,7 @@ def test_results_move_server(monkeypatch, caplog, setup):

responses.add(
responses.PUT,
f"{TestResultsMove.SRVR_TEXT}/api/v1/upload/{script}_{config}_{date}.tar.xz",
f"{TestResultsMove.SRVR_TEXT}/api/v1/upload/{name}.tar.xz",
status=200,
)

Expand Down
4 changes: 2 additions & 2 deletions lib/pbench/test/unit/agent/task/test_results_push.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ class TestResultsPush:
RELAY_SWITCH = "--relay"
SRVR_SWITCH = "--server"
RELAY_TEXT = "http://relay.example.com"
SRVR_TEXT = "http://pbench.test.example.com"
URL = "http://pbench.example.com/api/v1"
SRVR_TEXT = "https://pbench.test.example.com"
URL = "https://pbench.example.com/api/v1"

@staticmethod
def server_mock(
Expand Down
4 changes: 2 additions & 2 deletions lib/pbench/test/unit/client/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,15 @@ def connect():
"api": {},
"uri": {},
"openid": {
"server": "http://oidc_server",
"server": "https://oidc_server",
"realm": "pbench-server",
"client": "pbench-client",
},
},
)
responses.add(
responses.POST,
"http://oidc_server/realms/master/protocol/openid-connect/token",
"https://oidc_server/realms/master/protocol/openid-connect/token",
json={
"access_token": "admin_token",
},
Expand Down
4 changes: 2 additions & 2 deletions lib/pbench/test/unit/client/test_connect.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ class TestConnect:
def test_construct_host(self):
pbench = PbenchServerClient("10.1.100.2")
assert pbench.host == "10.1.100.2"
assert pbench.scheme == "http"
assert pbench.scheme == "https"
assert pbench.session is None
assert pbench.endpoints is None

Expand All @@ -22,7 +22,7 @@ def test_construct_url(self):
def test_connect(self):
pbench = PbenchServerClient("10.1.100.2")
url = f"{pbench.url}/api/v1/endpoints"
openid_dict = {"server": "http://oidc_server", "client": "pbench_client"}
openid_dict = {"server": "https://oidc_server", "client": "pbench_client"}

with responses.RequestsMock() as rsp:
rsp.add(
Expand Down
3 changes: 2 additions & 1 deletion lib/pbench/test/unit/server/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
secret-key = my_precious
[openid]
server_url = http://openid.example.com
server_url = https://openid.example.com
[logging]
logger_type = null
Expand Down Expand Up @@ -189,6 +189,7 @@ def client(monkeypatch, server_config, add_auth_connection_mock):
the db_session fixture instead, which adds DB cleanup after the test.
"""
app = create_app(server_config)
app.config["PREFERRED_URL_SCHEME"] = "https"

app_client = app.test_client()
app_client.logger = app.logger
Expand Down
2 changes: 1 addition & 1 deletion lib/pbench/test/unit/server/test_datasets_list.py
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ def convert(k: str, v: Any) -> Any:
else:
query["offset"] = str(next_offset)
next_url = (
f"http://localhost{server_config.rest_uri}/datasets?"
f"https://localhost{server_config.rest_uri}/datasets?"
+ urlencode_json(query)
)
else:
Expand Down
Loading

0 comments on commit fa225e2

Please sign in to comment.