laniakea-api-server 0.2.6__tar.gz → 0.2.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/PKG-INFO +1 -1
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/auth.py +21 -32
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/config.py +2 -1
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/queue.py +4 -4
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/pyproject.toml +1 -1
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/.github/workflows/publish.yml +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/.gitignore +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/LICENSE +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/README.md +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/__init__.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/cli.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/credential_parser.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/database.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/installer.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/main.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/models.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/.health.py.swp +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/__init__.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/agent.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/agents.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/credentials.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/deployments.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/health.py +0 -0
- {laniakea_api_server-0.2.6 → laniakea_api_server-0.2.8}/laniakea_api/routers/tfstate.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: laniakea-api-server
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.8
|
|
4
4
|
Summary: Laniakea Queue API — OIDC-authenticated gateway for cloud deployment orchestration
|
|
5
5
|
Project-URL: Homepage, https://github.com/laniakea/laniakea-api
|
|
6
6
|
Project-URL: Issues, https://github.com/laniakea/laniakea-api/issues
|
|
@@ -10,45 +10,34 @@ import httpx
|
|
|
10
10
|
import jwt
|
|
11
11
|
from fastapi import Depends, HTTPException, status
|
|
12
12
|
from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
|
|
13
|
-
from laniakea_api.config import (
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
)
|
|
13
|
+
from laniakea_api.config import (SECRET_KEY, ALGORITHM, SESSION_TTL_MINUTES,
|
|
14
|
+
OIDC_DISCOVERY_URLS, AGENT_MASTER_PASSWORD)
|
|
15
|
+
|
|
17
16
|
|
|
18
17
|
# Initialize security OAuth2 Bearer Token
|
|
19
18
|
_bearer = HTTPBearer()
|
|
20
19
|
|
|
21
20
|
async def fetch_userinfo(oidc_token: str) -> dict:
|
|
22
21
|
"""
|
|
23
|
-
|
|
24
|
-
|
|
22
|
+
Validate the token against every trusted issuer, first match wins.
|
|
23
|
+
Supports federated logins (IAM ReCaS + Keycloak).
|
|
25
24
|
"""
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
)
|
|
43
|
-
return resp.json()
|
|
44
|
-
except HTTPException:
|
|
45
|
-
raise
|
|
46
|
-
except Exception as exc:
|
|
47
|
-
raise HTTPException(
|
|
48
|
-
status_code=status.HTTP_401_UNAUTHORIZED,
|
|
49
|
-
detail=f"OIDC validation failed: {exc}",
|
|
50
|
-
)
|
|
51
|
-
|
|
25
|
+
last_status = None
|
|
26
|
+
async with httpx.AsyncClient(timeout=10) as client:
|
|
27
|
+
for discovery_url in OIDC_DISCOVERY_URLS:
|
|
28
|
+
try:
|
|
29
|
+
discovery = await client.get(discovery_url)
|
|
30
|
+
discovery.raise_for_status()
|
|
31
|
+
userinfo_url = discovery.json()["userinfo_endpoint"]
|
|
32
|
+
resp = await client.get(userinfo_url,
|
|
33
|
+
headers={"Authorization": f"Bearer {oidc_token}"})
|
|
34
|
+
if resp.status_code == 200:
|
|
35
|
+
return resp.json()
|
|
36
|
+
last_status = resp.status_code
|
|
37
|
+
except Exception:
|
|
38
|
+
continue
|
|
39
|
+
raise HTTPException(status_code=status.HTTP_401_UNAUTHORIZED,
|
|
40
|
+
detail=f"Token rejected by all trusted issuers (last: {last_status})")
|
|
52
41
|
|
|
53
42
|
def create_session_token(user_info: dict) -> tuple:
|
|
54
43
|
"""
|
|
@@ -9,7 +9,8 @@ import os
|
|
|
9
9
|
SECRET_KEY = os.getenv("SECRET_KEY", "")
|
|
10
10
|
ALGORITHM = "HS256"
|
|
11
11
|
SESSION_TTL_MINUTES = int(os.getenv("SESSION_TTL_MINUTES", "60")) # NOTE: maybe longer
|
|
12
|
-
OIDC_DISCOVERY_URL = os.getenv("OIDC_DISCOVERY_URL", "")
|
|
12
|
+
#OIDC_DISCOVERY_URL = os.getenv("OIDC_DISCOVERY_URL", "")
|
|
13
|
+
OIDC_DISCOVERY_URLS = [u.strip() for u in os.getenv("OIDC_DISCOVERY_URL", "").split(",") if u.strip()]
|
|
13
14
|
|
|
14
15
|
# Agent pool password
|
|
15
16
|
# to revoke ALL agents: change this value and restart API + all agents.
|
|
@@ -120,7 +120,7 @@ def _sc_path(user_sub: str, name: str = "") -> str:
|
|
|
120
120
|
return f"{base}/{name}" if name else base
|
|
121
121
|
|
|
122
122
|
def vault_list_service_creds(user_sub: str) -> list:
|
|
123
|
-
client =
|
|
123
|
+
client = vault_client()
|
|
124
124
|
try:
|
|
125
125
|
resp = client.secrets.kv.v2.list_secrets(path=_sc_path(user_sub), mount_point=VAULT_MOUNT)
|
|
126
126
|
names = [k.rstrip("/") for k in resp["data"]["keys"]]
|
|
@@ -133,7 +133,7 @@ def vault_list_service_creds(user_sub: str) -> list:
|
|
|
133
133
|
return out
|
|
134
134
|
|
|
135
135
|
def vault_read_service_creds(user_sub: str, name: str) -> dict:
|
|
136
|
-
client =
|
|
136
|
+
client = vault_client()
|
|
137
137
|
try:
|
|
138
138
|
resp = client.secrets.kv.v2.read_secret_version(path=_sc_path(user_sub, name), mount_point=VAULT_MOUNT)
|
|
139
139
|
return resp["data"]["data"] or {}
|
|
@@ -141,11 +141,11 @@ def vault_read_service_creds(user_sub: str, name: str) -> dict:
|
|
|
141
141
|
return {}
|
|
142
142
|
|
|
143
143
|
def vault_write_service_creds(user_sub: str, name: str, data: dict) -> None:
|
|
144
|
-
client =
|
|
144
|
+
client = vault_client()
|
|
145
145
|
client.secrets.kv.v2.create_or_update_secret(
|
|
146
146
|
path=_sc_path(user_sub, name), secret=data, mount_point=VAULT_MOUNT)
|
|
147
147
|
|
|
148
148
|
def vault_delete_service_creds(user_sub: str, name: str) -> None:
|
|
149
|
-
client =
|
|
149
|
+
client = vault_client()
|
|
150
150
|
client.secrets.kv.v2.delete_metadata_and_all_versions(
|
|
151
151
|
path=_sc_path(user_sub, name), mount_point=VAULT_MOUNT)
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "laniakea-api-server"
|
|
7
|
-
version = "0.2.
|
|
7
|
+
version = "0.2.8"
|
|
8
8
|
description = "Laniakea Queue API — OIDC-authenticated gateway for cloud deployment orchestration"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
license = { text = "MIT" }
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|