fix(obs): split SigNoz health and public routes
This commit is contained in:
@@ -1,7 +1,10 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from src.api.v1.monitoring import public_monitoring_tool_payload
|
||||
from src.services.public_redaction import redact_public_lan_text, redact_public_lan_topology
|
||||
from src.services.public_redaction import (
|
||||
redact_public_lan_text,
|
||||
redact_public_lan_topology,
|
||||
)
|
||||
|
||||
|
||||
def test_redact_public_lan_text_replaces_internal_endpoints_with_aliases() -> None:
|
||||
@@ -28,13 +31,13 @@ def test_redact_public_lan_text_replaces_internal_endpoints_with_aliases() -> No
|
||||
def test_redact_public_lan_topology_recurses_json_values() -> None:
|
||||
payload = {
|
||||
"safe_key": "unchanged",
|
||||
"nested": [{"endpoint": "192.168.0.188:3301"}],
|
||||
"nested": [{"endpoint": "192.168.0.110:8080"}],
|
||||
}
|
||||
|
||||
redacted = redact_public_lan_topology(payload)
|
||||
|
||||
assert redacted["safe_key"] == "unchanged"
|
||||
assert redacted["nested"][0]["endpoint"] == "host:observability-a/signoz"
|
||||
assert redacted["nested"][0]["endpoint"] == "host:public-gateway/signoz"
|
||||
|
||||
|
||||
def test_redact_public_lan_text_replaces_internal_work_context_terms() -> None:
|
||||
@@ -80,7 +83,7 @@ def test_public_monitoring_tool_payload_uses_public_route_when_available() -> No
|
||||
{
|
||||
"name": "SigNoz",
|
||||
"status": "up",
|
||||
"url": "http://192.168.0.188:3301",
|
||||
"url": "http://192.168.0.110:8080",
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
172
apps/api/tests/test_signoz_canonical_health_route.py
Normal file
172
apps/api/tests/test_signoz_canonical_health_route.py
Normal file
@@ -0,0 +1,172 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from datetime import UTC, datetime
|
||||
from pathlib import Path
|
||||
from types import SimpleNamespace
|
||||
|
||||
import pytest
|
||||
import yaml
|
||||
|
||||
from src.api.v1 import health as health_module
|
||||
from src.api.v1 import monitoring as monitoring_module
|
||||
from src.core import deep_linking as deep_linking_module
|
||||
from src.core.config import Settings
|
||||
from src.services import signoz_client as signoz_client_module
|
||||
from src.services.host_aggregator import HOST_CONFIGS
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parents[3]
|
||||
INTERNAL_URL = "http://192.168.0.110:8080"
|
||||
PUBLIC_URL = "https://signoz.wooo.work"
|
||||
LEGACY_URL = "192.168.0.188:3301"
|
||||
|
||||
|
||||
def _configmap(relative_path: str) -> dict:
|
||||
return yaml.safe_load((REPO_ROOT / relative_path).read_text(encoding="utf-8"))
|
||||
|
||||
|
||||
def test_settings_split_internal_health_from_public_deep_links() -> None:
|
||||
fields = Settings.model_fields
|
||||
|
||||
assert fields["SIGNOZ_INTERNAL_URL"].default == INTERNAL_URL
|
||||
assert fields["SIGNOZ_PUBLIC_URL"].default == PUBLIC_URL
|
||||
assert "SIGNOZ_URL" not in fields
|
||||
assert fields["OTEL_EXPORTER_OTLP_ENDPOINT"].default == "192.168.0.188:24317"
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_health_check_uses_exact_canonical_internal_path(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
calls: list[tuple[str, str, str]] = []
|
||||
expected = SimpleNamespace(status="up")
|
||||
|
||||
async def fake_http_health_check(name: str, base_url: str, path: str):
|
||||
calls.append((name, base_url, path))
|
||||
return expected
|
||||
|
||||
monkeypatch.setattr(health_module.settings, "SIGNOZ_INTERNAL_URL", INTERNAL_URL)
|
||||
monkeypatch.setattr(
|
||||
health_module,
|
||||
"_http_health_check",
|
||||
fake_http_health_check,
|
||||
)
|
||||
|
||||
assert await health_module.check_signoz() is expected
|
||||
assert calls == [("signoz", INTERNAL_URL, "/api/v1/health")]
|
||||
|
||||
|
||||
@pytest.mark.asyncio
|
||||
async def test_monitoring_probe_uses_internal_route_but_returns_replaceable_url(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
requested_urls: list[str] = []
|
||||
|
||||
class FakeClient:
|
||||
async def get(self, url: str, *, timeout: float):
|
||||
requested_urls.append(url)
|
||||
assert timeout == monitoring_module.TIMEOUT
|
||||
return SimpleNamespace(status_code=200)
|
||||
|
||||
monkeypatch.setattr(monitoring_module.settings, "SIGNOZ_INTERNAL_URL", INTERNAL_URL)
|
||||
|
||||
probe = await monitoring_module._probe_signoz(FakeClient())
|
||||
|
||||
assert requested_urls == [f"{INTERNAL_URL}/api/v1/health"]
|
||||
assert probe["url"] == INTERNAL_URL
|
||||
assert monitoring_module.public_monitoring_tool_payload(probe)["url"] == PUBLIC_URL
|
||||
|
||||
|
||||
def test_user_facing_deep_links_use_public_route(
|
||||
monkeypatch: pytest.MonkeyPatch,
|
||||
) -> None:
|
||||
monkeypatch.setattr(deep_linking_module.settings, "SIGNOZ_PUBLIC_URL", PUBLIC_URL)
|
||||
monkeypatch.setattr(signoz_client_module.settings, "SIGNOZ_PUBLIC_URL", PUBLIC_URL)
|
||||
monkeypatch.setattr(signoz_client_module.settings, "SIGNOZ_INTERNAL_URL", INTERNAL_URL)
|
||||
|
||||
trace_id = "0af7651916cd43dd8448eb211c80319c"
|
||||
assert deep_linking_module.DeepLinking.signoz_trace_url(trace_id) == (
|
||||
f"{PUBLIC_URL}/trace/{trace_id}"
|
||||
)
|
||||
assert deep_linking_module.DeepLinking.signoz_service_url() == (
|
||||
f"{PUBLIC_URL}/services/awoooi-api"
|
||||
)
|
||||
assert deep_linking_module.DeepLinking.signoz_logs_url(trace_id).startswith(
|
||||
f"{PUBLIC_URL}/logs?"
|
||||
)
|
||||
|
||||
client = signoz_client_module.SignOzClient()
|
||||
generated = client.generate_trace_url(
|
||||
"awoooi-api",
|
||||
alert_timestamp=datetime(2026, 7, 15, tzinfo=UTC),
|
||||
)
|
||||
assert generated.startswith(f"{PUBLIC_URL}/traces?service=awoooi-api&")
|
||||
assert INTERNAL_URL not in generated
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"relative_path",
|
||||
[
|
||||
"k8s/awoooi-prod/04-configmap.yaml",
|
||||
"k8s/awoooi-dev/02-configmap.yaml",
|
||||
],
|
||||
)
|
||||
def test_configmaps_publish_split_routes_and_preserve_otlp(
|
||||
relative_path: str,
|
||||
) -> None:
|
||||
data = _configmap(relative_path)["data"]
|
||||
|
||||
assert data["SIGNOZ_INTERNAL_URL"] == INTERNAL_URL
|
||||
assert data["SIGNOZ_PUBLIC_URL"] == PUBLIC_URL
|
||||
assert "SIGNOZ_URL" not in data
|
||||
assert data["OTEL_EXPORTER_OTLP_ENDPOINT"] == "http://192.168.0.188:24317"
|
||||
|
||||
|
||||
def test_prod_network_policy_allows_exact_canonical_signoz_health_route() -> None:
|
||||
policy_path = REPO_ROOT / "k8s/awoooi-prod/02-network-policy.yaml"
|
||||
policies = [
|
||||
document
|
||||
for document in yaml.safe_load_all(policy_path.read_text(encoding="utf-8"))
|
||||
if document
|
||||
]
|
||||
policy = next(
|
||||
document
|
||||
for document in policies
|
||||
if document["metadata"]["name"] == "allow-required-egress"
|
||||
)
|
||||
|
||||
canonical_rules = [
|
||||
rule
|
||||
for rule in policy["spec"]["egress"]
|
||||
if rule.get("to") == [{"ipBlock": {"cidr": "192.168.0.110/32"}}]
|
||||
]
|
||||
assert len(canonical_rules) == 1
|
||||
assert {"protocol": "TCP", "port": 8080} in canonical_rules[0]["ports"]
|
||||
|
||||
legacy_rules = [
|
||||
rule
|
||||
for rule in policy["spec"]["egress"]
|
||||
if rule.get("to") == [{"ipBlock": {"cidr": "192.168.0.188/32"}}]
|
||||
]
|
||||
assert len(legacy_rules) == 1
|
||||
assert {"protocol": "TCP", "port": 3301} not in legacy_rules[0]["ports"]
|
||||
assert {"protocol": "TCP", "port": 24317} in legacy_rules[0]["ports"]
|
||||
assert {"protocol": "TCP", "port": 24318} in legacy_rules[0]["ports"]
|
||||
|
||||
|
||||
def test_active_api_source_has_no_legacy_signoz_ui_route() -> None:
|
||||
source_root = REPO_ROOT / "apps/api/src"
|
||||
offenders = [
|
||||
str(path.relative_to(REPO_ROOT))
|
||||
for path in source_root.rglob("*.py")
|
||||
if LEGACY_URL in path.read_text(encoding="utf-8")
|
||||
]
|
||||
|
||||
assert offenders == []
|
||||
|
||||
|
||||
def test_host_asset_map_places_signoz_on_the_canonical_query_host() -> None:
|
||||
canonical_services = HOST_CONFIGS["192.168.0.110"]["services"]
|
||||
legacy_services = HOST_CONFIGS["192.168.0.188"]["services"]
|
||||
|
||||
assert ("SigNoz", 8080, "http", "/api/v1/health") in canonical_services
|
||||
assert not any(service[0] == "SigNoz" for service in legacy_services)
|
||||
@@ -52,7 +52,11 @@ async def test_openclaw_marks_signoz_unavailable_when_metrics_query_fails(
|
||||
get_gold_metrics=AsyncMock(side_effect=RuntimeError("clickhouse unavailable")),
|
||||
generate_trace_url=lambda **_kwargs: "https://unused.example/traces",
|
||||
)
|
||||
monkeypatch.setattr(signoz_module.settings, "SIGNOZ_URL", "https://signoz.example")
|
||||
monkeypatch.setattr(
|
||||
signoz_module.settings,
|
||||
"SIGNOZ_PUBLIC_URL",
|
||||
"https://signoz.example",
|
||||
)
|
||||
|
||||
metrics, trace_url = await service.get_signoz_context("node-exporter-110")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user