Skip to content

Commit 4ac92b3

Browse files
author
Andrei Neagu
committed
service always requires credentials now
1 parent 2d68a47 commit 4ac92b3

File tree

11 files changed

+79
-167
lines changed

11 files changed

+79
-167
lines changed

.env-devel

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -86,10 +86,10 @@ DIRECTOR_SERVICES_CUSTOM_CONSTRAINTS=null
8686
DIRECTOR_TRACING=null
8787

8888
DOCKER_API_PROXY_HOST=docker-api-proxy
89-
DOCKER_API_PROXY_PASSWORD=null
89+
DOCKER_API_PROXY_PASSWORD=admin
9090
DOCKER_API_PROXY_PORT=8888
9191
DOCKER_API_PROXY_SECURE=False
92-
DOCKER_API_PROXY_USER=null
92+
DOCKER_API_PROXY_USER=admin
9393

9494
EFS_USER_ID=8006
9595
EFS_USER_NAME=efs

packages/pytest-simcore/src/pytest_simcore/docker_api_proxy.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import logging
22

33
import pytest
4-
from aiohttp import ClientSession, ClientTimeout
4+
from aiohttp import BasicAuth, ClientSession, ClientTimeout
55
from pydantic import TypeAdapter
66
from settings_library.docker_api_proxy import DockerApiProxysettings
77
from tenacity import before_sleep_log, retry, stop_after_delay, wait_fixed
@@ -22,7 +22,13 @@
2222
async def _wait_till_docker_api_proxy_is_responsive(
2323
settings: DockerApiProxysettings,
2424
) -> None:
25-
async with ClientSession(timeout=ClientTimeout(1, 1, 1, 1, 1)) as client:
25+
async with ClientSession(
26+
timeout=ClientTimeout(1, 1, 1, 1, 1),
27+
auth=BasicAuth(
28+
settings.DOCKER_API_PROXY_USER,
29+
settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(),
30+
),
31+
) as client:
2632
response = await client.get(f"{settings.base_url}/version")
2733
assert response.status == 200, await response.text()
2834

@@ -44,6 +50,12 @@ async def docker_api_proxy_settings(
4450
{
4551
"DOCKER_API_PROXY_HOST": get_localhost_ip(),
4652
"DOCKER_API_PROXY_PORT": published_port,
53+
"DOCKER_API_PROXY_USER": env_vars_for_docker_compose[
54+
"DOCKER_API_PROXY_USER"
55+
],
56+
"DOCKER_API_PROXY_PASSWORD": env_vars_for_docker_compose[
57+
"DOCKER_API_PROXY_PASSWORD"
58+
],
4759
}
4860
)
4961

packages/service-library/src/servicelib/fastapi/docker.py

Lines changed: 7 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -30,32 +30,20 @@ async def remote_docker_client_lifespan(
3030
) -> AsyncIterator[State]:
3131
settings: DockerApiProxysettings = state[_DOCKER_API_PROXY_SETTINGS]
3232

33-
session: ClientSession | None = None
34-
if settings.DOCKER_API_PROXY_USER and settings.DOCKER_API_PROXY_PASSWORD:
35-
session = ClientSession(
36-
auth=aiohttp.BasicAuth(
37-
login=settings.DOCKER_API_PROXY_USER,
38-
password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(),
39-
)
40-
)
41-
4233
async with AsyncExitStack() as exit_stack:
43-
if settings.DOCKER_API_PROXY_USER and settings.DOCKER_API_PROXY_PASSWORD:
44-
await exit_stack.enter_async_context(
45-
ClientSession(
46-
auth=aiohttp.BasicAuth(
47-
login=settings.DOCKER_API_PROXY_USER,
48-
password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(),
49-
)
34+
session = await exit_stack.enter_async_context(
35+
ClientSession(
36+
auth=aiohttp.BasicAuth(
37+
login=settings.DOCKER_API_PROXY_USER,
38+
password=settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(),
5039
)
5140
)
41+
)
5242

53-
client = await exit_stack.enter_async_context(
43+
app.state.remote_docker_client = await exit_stack.enter_async_context(
5444
aiodocker.Docker(url=settings.base_url, session=session)
5545
)
5646

57-
app.state.remote_docker_client = client
58-
5947
await wait_till_docker_api_proxy_is_responsive(app)
6048

6149
# NOTE this has to be inside exit_stack scope

packages/settings-library/src/settings_library/docker_api_proxy.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ class DockerApiProxysettings(BaseCustomSettings):
1515
)
1616
DOCKER_API_PROXY_SECURE: bool = False
1717

18-
DOCKER_API_PROXY_USER: str | None = None
19-
DOCKER_API_PROXY_PASSWORD: SecretStr | None = None
18+
DOCKER_API_PROXY_USER: str
19+
DOCKER_API_PROXY_PASSWORD: SecretStr
2020

2121
@cached_property
2222
def base_url(self) -> str:

services/docker-api-proxy/Dockerfile

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
FROM alpine:3.21 AS base
1+
FROM caddy:2.10.0-alpine AS base
22

33
LABEL maintainer=GitHK
44

@@ -29,10 +29,11 @@ HEALTHCHECK \
2929
--start-period=20s \
3030
--start-interval=1s \
3131
--retries=5 \
32-
CMD curl http://localhost:8888/version || exit 1
32+
CMD curl --fail-with-body -u ${DOCKER_API_PROXY_USER}:${DOCKER_API_PROXY_PASSWORD} http://localhost:8888/version
3333

3434
COPY --chown=scu:scu services/docker-api-proxy/docker services/docker-api-proxy/docker
35-
RUN chmod +x services/docker-api-proxy/docker/*.sh
35+
RUN chmod +x services/docker-api-proxy/docker/*.sh && \
36+
mv services/docker-api-proxy/docker/Caddyfile /etc/caddy/Caddyfile
3637

3738
ENTRYPOINT [ "/bin/sh", "services/docker-api-proxy/docker/entrypoint.sh" ]
3839
CMD ["/bin/sh", "services/docker-api-proxy/docker/boot.sh"]
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
:8888 {
2+
handle {
3+
basicauth {
4+
{$DOCKER_API_PROXY_USER} {$DOCKER_API_PROXY_ECRYPTED_PASSWORD}
5+
}
6+
7+
reverse_proxy http://localhost:8889 {
8+
health_uri /version
9+
}
10+
}
11+
}

services/docker-api-proxy/docker/boot.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,7 @@ echo "$INFO" "User :$(id "$(whoami)")"
1212
#
1313
# RUNNING application
1414
#
15-
socat TCP-LISTEN:8888,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock
15+
socat TCP-LISTEN:8889,fork,reuseaddr UNIX-CONNECT:/var/run/docker.sock &
16+
17+
DOCKER_API_PROXY_ECRYPTED_PASSWORD=$(caddy hash-password --plaintext "$DOCKER_API_PROXY_PASSWORD") \
18+
caddy run --adapter caddyfile --config /etc/caddy/Caddyfile

services/docker-api-proxy/tests/integration/autentication-proxy-docker-compose.yaml

Lines changed: 0 additions & 14 deletions
This file was deleted.

services/docker-api-proxy/tests/integration/test_docker_api_proxy.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from pathlib import Path
88

99
import aiodocker
10+
import pytest
1011
from pytest_simcore.helpers.monkeypatch_envs import EnvVarsDict
1112
from settings_library.docker_api_proxy import DockerApiProxysettings
1213

@@ -17,7 +18,7 @@
1718
]
1819

1920

20-
async def test_unauthenticated_docker_client(
21+
async def test_authenticated_docker_client(
2122
docker_swarm: None,
2223
docker_api_proxy_settings: DockerApiProxysettings,
2324
setup_docker_client: Callable[
@@ -27,7 +28,37 @@ async def test_unauthenticated_docker_client(
2728
envs = {
2829
"DOCKER_API_PROXY_HOST": "127.0.0.1",
2930
"DOCKER_API_PROXY_PORT": "8014",
31+
"DOCKER_API_PROXY_USER": docker_api_proxy_settings.DOCKER_API_PROXY_USER,
32+
"DOCKER_API_PROXY_PASSWORD": docker_api_proxy_settings.DOCKER_API_PROXY_PASSWORD.get_secret_value(),
3033
}
3134
async with setup_docker_client(envs) as working_docker:
3235
info = await working_docker.system.info()
3336
print(json.dumps(info, indent=2))
37+
38+
39+
@pytest.mark.parametrize(
40+
"user, password",
41+
[
42+
("wrong", "wrong"),
43+
("wrong", "admin"),
44+
],
45+
)
46+
async def test_unauthenticated_docker_client(
47+
docker_swarm: None,
48+
docker_api_proxy_settings: DockerApiProxysettings,
49+
setup_docker_client: Callable[
50+
[EnvVarsDict], AbstractAsyncContextManager[aiodocker.Docker]
51+
],
52+
user: str,
53+
password: str,
54+
):
55+
envs = {
56+
"DOCKER_API_PROXY_HOST": "127.0.0.1",
57+
"DOCKER_API_PROXY_PORT": "8014",
58+
"DOCKER_API_PROXY_USER": user,
59+
"DOCKER_API_PROXY_PASSWORD": password,
60+
}
61+
async with setup_docker_client(envs) as working_docker:
62+
with pytest.raises(aiodocker.exceptions.DockerError) as exc:
63+
await working_docker.system.info()
64+
assert exc.value.status == 401

services/docker-api-proxy/tests/integration/test_docker_api_proxy_autenticated.py

Lines changed: 0 additions & 123 deletions
This file was deleted.

0 commit comments

Comments
 (0)