feat(opax-mcp): add deployment status sanitizer

This commit is contained in:
Chris Christiansen 2026-09-23 04:05:11 +00:00
parent 1122fb5b3a
commit c3fde1e38c
2 changed files with 119 additions and 0 deletions

View File

@ -18,6 +18,9 @@ CLOUD_RUN_SERVICE = os.environ.get("CLOUD_RUN_SERVICE", "osvauco-agent")
MCP_SECRET = os.environ.get("MCP_SECRET", "") MCP_SECRET = os.environ.get("MCP_SECRET", "")
BUILD_TRIGGER_ID = os.environ.get("CLOUD_BUILD_TRIGGER_ID", "38423976-91ff-4ff4-859e-1f262344c609") BUILD_TRIGGER_ID = os.environ.get("CLOUD_BUILD_TRIGGER_ID", "38423976-91ff-4ff4-859e-1f262344c609")
_OPAX_MCP_SERVICE = "opax-mcp"
_OPAX_MCP_REGION = "us-central1"
def verify_token(request: Request, x_mcp_key: str = Header(default="")): def verify_token(request: Request, x_mcp_key: str = Header(default="")):
# Aksepter både X-MCP-Key og api-key (Perplexity MCP connector bruker api-key) # Aksepter både X-MCP-Key og api-key (Perplexity MCP connector bruker api-key)
@ -70,6 +73,49 @@ def _parse_ts(ts):
return None return None
def _sanitize_opax_deployment_status(service_data: dict) -> dict:
"""
Takes a decoded Cloud Run v2 service JSON object and returns a sanitized
dict conforming to the minimal v1 output contract.
"""
def _validate_generation(val):
if isinstance(val, bool):
return None
if isinstance(val, int) and val >= 0:
return val
if isinstance(val, str) and val.isascii() and val.isdecimal():
return int(val)
return None
def _validate_update_time(val):
from datetime import datetime, timezone
if (
not isinstance(val, str)
or not val.endswith("Z")
or val.endswith("ZZ")
or len(val) < 20
or val[10] != "T"
):
return None
try:
normalized_val = val[:-1] + "+00:00"
dt = datetime.fromisoformat(normalized_val)
if dt.tzinfo is None:
return None # Reject timezone-naive
return dt.astimezone(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
except ValueError:
return None
return {
"service": _OPAX_MCP_SERVICE,
"region": _OPAX_MCP_REGION,
"generation": _validate_generation(service_data.get("generation")),
"observed_generation": _validate_generation(service_data.get("observedGeneration")),
"last_update_time": _validate_update_time(service_data.get("updateTime")),
"reason_code": None,
}
class PushStaticRequest(BaseModel): class PushStaticRequest(BaseModel):
file_path: str file_path: str
content: str content: str

View File

@ -0,0 +1,73 @@
import unittest
from agents.mcp_server.server import _sanitize_opax_deployment_status
class TestSanitizeOpaxDeploymentStatus(unittest.TestCase):
def test_valid_inputs(self):
"""Tests valid integer/string generations and a valid UTC timestamp."""
service_data = {
"generation": 10,
"observedGeneration": "9",
"updateTime": "2023-10-27T10:00:00Z"
}
result = _sanitize_opax_deployment_status(service_data)
self.assertEqual(result["generation"], 10)
self.assertEqual(result["observed_generation"], 9)
self.assertEqual(result["last_update_time"], "2023-10-27T10:00:00Z")
self.assertIsNone(result["reason_code"])
def test_zero_values(self):
"""Tests handling of zero for generation values."""
service_data = {"generation": 0, "observedGeneration": "0"}
result = _sanitize_opax_deployment_status(service_data)
self.assertEqual(result["generation"], 0)
self.assertEqual(result["observed_generation"], 0)
def test_invalid_generation_values(self):
"""Tests various invalid generation inputs."""
invalid_inputs = [
True, False, -1, 1.5, "-1", " 1 ", "abc", "١", None, {}, []
]
for val in invalid_inputs:
with self.subTest(val=val):
res1 = _sanitize_opax_deployment_status({"generation": val})
res2 = _sanitize_opax_deployment_status({"observedGeneration": val})
self.assertIsNone(res1["generation"])
self.assertIsNone(res2["observed_generation"])
def test_fractional_second_timestamp_is_truncated(self):
"""Tests that fractional seconds are correctly truncated."""
service_data = {"updateTime": "2023-10-27T10:00:00.123456Z"}
result = _sanitize_opax_deployment_status(service_data)
self.assertEqual(result["last_update_time"], "2023-10-27T10:00:00Z")
def test_invalid_and_non_z_timestamps(self):
"""Tests invalid, tz-naive, missing, and non-Z timestamps."""
invalid_timestamps = [
"2023-10-27T10:00:00", # Missing Z (naive)
"2023-10-27T10:00:00ZZ", # Multiple Z
"2023-10-27T11:00:00+01:00", # Valid but not Z-suffix
"2023-10-27 10:00:00Z", # Malformed
"not-a-timestamp", # Invalid
1698399600, # Not a string
None, # Missing
]
for ts in invalid_timestamps:
with self.subTest(ts=ts):
result = _sanitize_opax_deployment_status({"updateTime": ts})
self.assertIsNone(result["last_update_time"])
def test_exact_key_set_and_fixed_values(self):
"""Tests for exact key set and fixed service/region/reason_code."""
result = _sanitize_opax_deployment_status({})
expected_keys = {
"service", "region", "generation", "observed_generation",
"last_update_time", "reason_code"
}
self.assertEqual(set(result.keys()), expected_keys)
self.assertEqual(result["service"], "opax-mcp")
self.assertEqual(result["region"], "us-central1")
self.assertIsNone(result["reason_code"])
if __name__ == '__main__':
unittest.main()