From ec9d81ff6dc05d3cf1389fba9b57ab0dc71a1fa1 Mon Sep 17 00:00:00 2001 From: ogt Date: Tue, 14 Jul 2026 20:39:55 +0800 Subject: [PATCH] fix(wazuh): preserve degraded production readback --- apps/api/src/services/iwooos_wazuh_readonly_status.py | 8 ++++---- apps/api/tests/test_iwooos_wazuh_api.py | 4 ++-- apps/api/tests/test_iwooos_wazuh_prod_manifest.py | 10 +++++++--- apps/web/src/app/api/iwooos/wazuh/route.ts | 6 +++--- k8s/awoooi-prod/06-deployment-api.yaml | 9 +++++++++ 5 files changed, 25 insertions(+), 12 deletions(-) diff --git a/apps/api/src/services/iwooos_wazuh_readonly_status.py b/apps/api/src/services/iwooos_wazuh_readonly_status.py index c78a09d66..306199dfb 100644 --- a/apps/api/src/services/iwooos_wazuh_readonly_status.py +++ b/apps/api/src/services/iwooos_wazuh_readonly_status.py @@ -124,10 +124,10 @@ async def load_iwooos_wazuh_readonly_status() -> WazuhReadonlyStatus: base_url = https_url(env["base_url"]) if not base_url or not env["username"] or not env["password"]: - return boundary_status("misconfigured_missing_server_side_wazuh_env", 503) + return boundary_status("misconfigured_missing_server_side_wazuh_env") try: - auth_header = b64encode(f"{env['username']}:{env['password']}".encode("utf-8")).decode("ascii") + auth_header = b64encode(f"{env['username']}:{env['password']}".encode()).decode("ascii") async with httpx.AsyncClient(timeout=REQUEST_TIMEOUT_SECONDS) as client: auth = await fetch_json( client, @@ -136,7 +136,7 @@ async def load_iwooos_wazuh_readonly_status() -> WazuhReadonlyStatus: ) token = (auth.get("data") or {}).get("token") if not token: - return boundary_status("wazuh_auth_token_missing", 502) + return boundary_status("wazuh_auth_token_missing") bearer_headers = {"Authorization": f"Bearer {token}"} status_payload = await fetch_json( @@ -150,7 +150,7 @@ async def load_iwooos_wazuh_readonly_status() -> WazuhReadonlyStatus: bearer_headers, ) except (httpx.HTTPError, ValueError): - return boundary_status("wazuh_readonly_metadata_unavailable", 502) + return boundary_status("wazuh_readonly_metadata_unavailable") connection = ((status_payload.get("data") or {}).get("connection") or {}) affected_items = ((agents_payload.get("data") or {}).get("affected_items") or []) diff --git a/apps/api/tests/test_iwooos_wazuh_api.py b/apps/api/tests/test_iwooos_wazuh_api.py index 08a712183..a733d9b35 100644 --- a/apps/api/tests/test_iwooos_wazuh_api.py +++ b/apps/api/tests/test_iwooos_wazuh_api.py @@ -45,7 +45,7 @@ def test_iwooos_wazuh_v1_route_rejects_missing_server_side_env(monkeypatch: pyte response = _client().get("/api/v1/iwooos/wazuh") - assert response.status_code == 503 + assert response.status_code == 200 data = response.json() assert data["status"] == "misconfigured_missing_server_side_wazuh_env" assert data["configured"] is False @@ -61,7 +61,7 @@ def test_iwooos_wazuh_rejects_non_https_base_url(monkeypatch: pytest.MonkeyPatch response = _client().get("/api/iwooos/wazuh") - assert response.status_code == 503 + assert response.status_code == 200 data = response.json() assert data["status"] == "misconfigured_missing_server_side_wazuh_env" assert data["boundaries"]["secret_value_collection_allowed"] is False diff --git a/apps/api/tests/test_iwooos_wazuh_prod_manifest.py b/apps/api/tests/test_iwooos_wazuh_prod_manifest.py index 427447eb9..98bb31713 100644 --- a/apps/api/tests/test_iwooos_wazuh_prod_manifest.py +++ b/apps/api/tests/test_iwooos_wazuh_prod_manifest.py @@ -4,7 +4,6 @@ from pathlib import Path import yaml - REPO_ROOT = Path(__file__).resolve().parents[3] DEPLOYMENT_PATH = REPO_ROOT / "k8s" / "awoooi-prod" / "06-deployment-api.yaml" @@ -34,8 +33,13 @@ def test_iwooos_wazuh_readonly_live_metadata_enabled_by_gitops_flag_only() -> No assert env["IWOOOS_WAZUH_EXPECTED_MIN_AGENT_COUNT"]["value"] == "6" -def test_iwooos_wazuh_prod_manifest_does_not_inline_secret_values() -> None: +def test_iwooos_wazuh_prod_manifest_references_secret_values_without_inlining() -> None: env = _api_env() for name in ("WAZUH_API_BASE_URL", "WAZUH_API_USERNAME", "WAZUH_API_PASSWORD"): - assert name not in env + assert "value" not in env[name] + assert env[name]["valueFrom"]["secretKeyRef"] == { + "name": "awoooi-secrets", + "key": name, + "optional": True, + } diff --git a/apps/web/src/app/api/iwooos/wazuh/route.ts b/apps/web/src/app/api/iwooos/wazuh/route.ts index 243541b12..87b655b9d 100644 --- a/apps/web/src/app/api/iwooos/wazuh/route.ts +++ b/apps/web/src/app/api/iwooos/wazuh/route.ts @@ -128,7 +128,7 @@ export async function GET() { const baseUrl = requireHttpsBaseUrl(WAZUH_API_BASE_URL); if (!baseUrl || !WAZUH_API_USERNAME || !WAZUH_API_PASSWORD) { - return boundaryResponse('misconfigured_missing_server_side_wazuh_env', 503); + return boundaryResponse('misconfigured_missing_server_side_wazuh_env'); } try { @@ -143,7 +143,7 @@ export async function GET() { ); const token = auth.data?.token; if (!token) { - return boundaryResponse('wazuh_auth_token_missing', 502); + return boundaryResponse('wazuh_auth_token_missing'); } const [status, agents] = await Promise.all([ @@ -209,6 +209,6 @@ export async function GET() { }, }); } catch { - return boundaryResponse('wazuh_readonly_metadata_unavailable', 502); + return boundaryResponse('wazuh_readonly_metadata_unavailable'); } } diff --git a/k8s/awoooi-prod/06-deployment-api.yaml b/k8s/awoooi-prod/06-deployment-api.yaml index 5eee89ec2..7a6a65311 100644 --- a/k8s/awoooi-prod/06-deployment-api.yaml +++ b/k8s/awoooi-prod/06-deployment-api.yaml @@ -192,6 +192,15 @@ spec: value: "true" - name: IWOOOS_WAZUH_EXPECTED_MIN_AGENT_COUNT value: "6" + - name: WAZUH_API_BASE_URL + valueFrom: + secretKeyRef: {name: awoooi-secrets, key: WAZUH_API_BASE_URL, optional: true} + - name: WAZUH_API_USERNAME + valueFrom: + secretKeyRef: {name: awoooi-secrets, key: WAZUH_API_USERNAME, optional: true} + - name: WAZUH_API_PASSWORD + valueFrom: + secretKeyRef: {name: awoooi-secrets, key: WAZUH_API_PASSWORD, optional: true} - name: USE_AI_ROUTER value: "true" - name: ENABLE_NEMOTRON_COLLABORATION