Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions chart/templates/configmap.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,6 @@ data:
S3PROXY_REDIS_URL: {{ .Values.externalRedis.url | quote }}
{{- end }}
S3PROXY_REDIS_UPLOAD_TTL_HOURS: {{ .Values.externalRedis.uploadTtlHours | quote }}
S3PROXY_ADMIN_UI: {{ .Values.admin.enabled | quote }}
S3PROXY_ADMIN_PATH: {{ .Values.admin.path | quote }}
S3PROXY_LOG_LEVEL: {{ .Values.logLevel | quote }}
4 changes: 4 additions & 0 deletions chart/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,10 @@ secrets:
awsAccessKeyId: ""
awsSecretAccessKey: ""

admin:
enabled: false
path: "/admin"

logLevel: "DEBUG"

resources:
Expand Down
3 changes: 3 additions & 0 deletions e2e/cluster.sh
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,9 @@ case "${1:-help}" in
echo "=========================================="
echo "Cluster is running in background."
echo ""
echo "Admin dashboard: http://localhost:4433/admin/"
echo "Login: minioadmin / minioadmin"
echo ""
echo "Run tests:"
echo " ./cluster.sh postgres"
echo " ./cluster.sh elasticsearch"
Expand Down
11 changes: 10 additions & 1 deletion e2e/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ services:
privileged: true
depends_on:
- registry
ports:
- "4433:4433"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- ..:/repo
Expand Down Expand Up @@ -437,7 +439,8 @@ services:
--set redis-ha.haproxy.checkInterval=5s \
--set redis-ha.haproxy.timeout.check=10s \
--set redis-ha.haproxy.timeout.server=60s \
--set redis-ha.haproxy.timeout.client=60s &
--set redis-ha.haproxy.timeout.client=60s \
--set admin.enabled=true &
S3PROXY_PID=$$!

# 8. Wait for ALL parallel tasks
Expand All @@ -464,11 +467,17 @@ services:
echo "S3 Proxy endpoint for databases: http://s3-gateway.s3proxy.svc.cluster.local:80"
echo "Direct MinIO (unencrypted): http://minio.minio.svc.cluster.local:9000"

# Start admin dashboard port-forward in background
kubectl port-forward --address 0.0.0.0 svc/s3proxy-python 4433:4433 -n s3proxy &

echo ""
echo "=========================================="
echo "Cluster is ready"
echo "=========================================="
echo ""
echo "Admin dashboard: http://localhost:4433/admin/"
echo "Login: minioadmin / minioadmin"
echo ""
echo "Run database tests with:"
echo " ./cluster.sh postgres"
echo " ./cluster.sh elasticsearch"
Expand Down
3 changes: 3 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ target-version = "py314"
[tool.ruff.lint]
select = ["E", "F", "I", "N", "W", "UP", "B", "C4", "SIM"]

[tool.ruff.lint.per-file-ignores]
"s3proxy/admin/templates.py" = ["E501"]

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
Expand Down
5 changes: 5 additions & 0 deletions s3proxy/admin/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
"""Admin dashboard for S3Proxy."""

from .router import create_admin_router

__all__ = ["create_admin_router"]
35 changes: 35 additions & 0 deletions s3proxy/admin/auth.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
"""Basic auth for admin dashboard."""

import secrets

from fastapi import Depends, HTTPException, status
from fastapi.security import HTTPBasic, HTTPBasicCredentials

security = HTTPBasic(realm="S3Proxy Admin")

_security_dep = Depends(security)


def create_auth_dependency(settings, credentials_store: dict[str, str]):
"""Create a Basic Auth dependency for the admin router."""
if settings.admin_username and settings.admin_password:
valid_username = settings.admin_username
valid_password = settings.admin_password
else:
if not credentials_store:
raise RuntimeError("No credentials configured for admin auth")
valid_username = next(iter(credentials_store.keys()))
valid_password = credentials_store[valid_username]

async def verify(credentials: HTTPBasicCredentials = _security_dep):
username_ok = secrets.compare_digest(credentials.username.encode(), valid_username.encode())
password_ok = secrets.compare_digest(credentials.password.encode(), valid_password.encode())
if not (username_ok and password_ok):
raise HTTPException(
status_code=status.HTTP_401_UNAUTHORIZED,
detail="Invalid credentials",
headers={"WWW-Authenticate": 'Basic realm="S3Proxy Admin"'},
)
return credentials

return verify
Loading
Loading