Skip to content
Merged
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
38 changes: 38 additions & 0 deletions config/constants/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,15 @@
DATADOG_APP_KEY_ENV,
DATADOG_SITE_ENV,
)
from config.constants.gitlab import GITLAB_AUTH_TOKEN_ENV, GITLAB_BASE_URL_ENV
from config.constants.groundcover import (
GROUNDCOVER_API_KEY_ENV,
GROUNDCOVER_BACKEND_ID_ENV,
GROUNDCOVER_MCP_TOKEN_ENV,
GROUNDCOVER_MCP_URL_ENV,
GROUNDCOVER_TENANT_UUID_ENV,
GROUNDCOVER_TIMEZONE_ENV,
)
from config.constants.honeycomb import (
HONEYCOMB_API_KEY_ENV,
HONEYCOMB_BASE_URL_ENV,
Expand All @@ -41,20 +50,30 @@
from config.constants.posthog import (
DEFAULT_POSTHOG_TIMEOUT_SECONDS,
DEFAULT_POSTHOG_URL,
POSTHOG_BASE_URL_ENV,
POSTHOG_CAPTURE_API_KEY,
POSTHOG_HOST,
POSTHOG_PERSONAL_API_KEY_ENV,
POSTHOG_PROJECT_ID_ENV,
POSTHOG_TIMEOUT_SECONDS_ENV,
)
from config.constants.sentry import (
DEFAULT_SENTRY_BASE_URL,
SENTRY_AUTH_TOKEN_ENV,
SENTRY_BASE_URL_ENV,
SENTRY_DSN,
SENTRY_ERROR_SAMPLE_RATE,
SENTRY_IN_APP_INCLUDE,
SENTRY_MAX_BREADCRUMBS,
SENTRY_ORGANIZATION_SLUG_ENV,
SENTRY_PROJECT_SLUG_ENV,
SENTRY_TRACES_SAMPLE_RATE,
)
from config.constants.telegram import (
TELEGRAM_BOT_TOKEN_ENV,
TELEGRAM_DEFAULT_CHAT_ID_ENV,
)
from config.constants.vercel import VERCEL_API_TOKEN_ENV, VERCEL_TEAM_ID_ENV

__all__ = [
"AZURE_OPENAI_API_KEY_ENV",
Expand All @@ -70,6 +89,15 @@
"DATADOG_SITE_ENV",
"DEFAULT_POSTHOG_TIMEOUT_SECONDS",
"DEFAULT_POSTHOG_URL",
"DEFAULT_SENTRY_BASE_URL",
"GITLAB_AUTH_TOKEN_ENV",
"GITLAB_BASE_URL_ENV",
"GROUNDCOVER_API_KEY_ENV",
"GROUNDCOVER_BACKEND_ID_ENV",
"GROUNDCOVER_MCP_TOKEN_ENV",
"GROUNDCOVER_MCP_URL_ENV",
"GROUNDCOVER_TENANT_UUID_ENV",
"GROUNDCOVER_TIMEZONE_ENV",
"HONEYCOMB_API_KEY_ENV",
"HONEYCOMB_BASE_URL_ENV",
"HONEYCOMB_DATASET_ENV",
Expand All @@ -79,16 +107,26 @@
"OPENSRE_HOME_DIR",
"OPENSRE_TMP_DIR",
"ORGANIZATION_ID_ENV",
"POSTHOG_BASE_URL_ENV",
"POSTHOG_CAPTURE_API_KEY",
"POSTHOG_HOST",
"POSTHOG_PERSONAL_API_KEY_ENV",
"POSTHOG_PROJECT_ID_ENV",
"POSTHOG_TIMEOUT_SECONDS_ENV",
"SENTRY_AUTH_TOKEN_ENV",
"SENTRY_BASE_URL_ENV",
"SENTRY_DSN",
"SENTRY_ERROR_SAMPLE_RATE",
"SENTRY_IN_APP_INCLUDE",
"SENTRY_MAX_BREADCRUMBS",
"SENTRY_ORGANIZATION_SLUG_ENV",
"SENTRY_PROJECT_SLUG_ENV",
"SENTRY_TRACES_SAMPLE_RATE",
"TELEGRAM_BOT_TOKEN_ENV",
"TELEGRAM_DEFAULT_CHAT_ID_ENV",
"USAGE_SECRET_ENV",
"VERCEL_API_TOKEN_ENV",
"VERCEL_TEAM_ID_ENV",
"WEBAPP_URL_ENV",
"ensure_opensre_tmp_dir",
"get_store_path",
Expand Down
12 changes: 12 additions & 0 deletions config/constants/gitlab.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
"""GitLab environment variable names."""

from __future__ import annotations

GITLAB_BASE_URL_ENV = "GITLAB_BASE_URL"
# Mirrors the ``auth_token`` credential; the names deliberately differ.
GITLAB_AUTH_TOKEN_ENV = "GITLAB_ACCESS_TOKEN"

__all__ = [
"GITLAB_AUTH_TOKEN_ENV",
"GITLAB_BASE_URL_ENV",
]
21 changes: 21 additions & 0 deletions config/constants/groundcover.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
"""Groundcover environment variable names."""

from __future__ import annotations

GROUNDCOVER_API_KEY_ENV = "GROUNDCOVER_API_KEY"
# Accepted as a fallback when GROUNDCOVER_API_KEY is unset; setup always writes
# the primary name.
GROUNDCOVER_MCP_TOKEN_ENV = "GROUNDCOVER_MCP_TOKEN"
GROUNDCOVER_MCP_URL_ENV = "GROUNDCOVER_MCP_URL"
GROUNDCOVER_TENANT_UUID_ENV = "GROUNDCOVER_TENANT_UUID"
GROUNDCOVER_BACKEND_ID_ENV = "GROUNDCOVER_BACKEND_ID"
GROUNDCOVER_TIMEZONE_ENV = "GROUNDCOVER_TIMEZONE"

__all__ = [
"GROUNDCOVER_API_KEY_ENV",
"GROUNDCOVER_BACKEND_ID_ENV",
"GROUNDCOVER_MCP_TOKEN_ENV",
"GROUNDCOVER_MCP_URL_ENV",
"GROUNDCOVER_TENANT_UUID_ENV",
"GROUNDCOVER_TIMEZONE_ENV",
]
14 changes: 13 additions & 1 deletion config/constants/posthog.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
"""Shared PostHog constants used across analytics and integrations."""
"""PostHog constants — OpenSRE's own product analytics, and the PostHog integration.

Two unrelated things share the vendor name. ``POSTHOG_CAPTURE_API_KEY`` is a
write-only key for *OpenSRE's* analytics project; the ``*_ENV`` names further
down identify the credentials a *user* supplies to let investigations query
*their* PostHog. Nothing is shared between them but the default host.
"""

from __future__ import annotations

Expand All @@ -9,3 +15,9 @@

DEFAULT_POSTHOG_URL: Final[str] = POSTHOG_HOST
DEFAULT_POSTHOG_TIMEOUT_SECONDS: Final[float] = 15.0

# --- The user's PostHog integration ---------------------------------------
POSTHOG_BASE_URL_ENV: Final[str] = "POSTHOG_BASE_URL"
POSTHOG_PROJECT_ID_ENV: Final[str] = "POSTHOG_PROJECT_ID"
POSTHOG_PERSONAL_API_KEY_ENV: Final[str] = "POSTHOG_PERSONAL_API_KEY"
POSTHOG_TIMEOUT_SECONDS_ENV: Final[str] = "POSTHOG_TIMEOUT_SECONDS"
17 changes: 16 additions & 1 deletion config/constants/sentry.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
"""Sentry constants for OpenSRE runtime error monitoring."""
"""Sentry constants — OpenSRE's own error monitoring, and the Sentry integration.

Two unrelated things share the vendor name. The values below configure the
Sentry SDK that reports *OpenSRE's* crashes to the project's own account; the
``*_ENV`` names further down identify the credentials a *user* supplies to let
investigations query *their* Sentry. Nothing is shared between them.
"""

from __future__ import annotations

Expand All @@ -12,3 +18,12 @@
SENTRY_TRACES_SAMPLE_RATE: Final[float] = 1.0
SENTRY_MAX_BREADCRUMBS: Final[int] = 100
SENTRY_IN_APP_INCLUDE: Final[tuple[str, ...]] = ("app",)

# --- The user's Sentry integration ---------------------------------------
# Mirror the ``base_url`` and ``organization_slug`` credentials; the names
# deliberately differ.
SENTRY_BASE_URL_ENV: Final[str] = "SENTRY_URL"
SENTRY_ORGANIZATION_SLUG_ENV: Final[str] = "SENTRY_ORG_SLUG"
SENTRY_AUTH_TOKEN_ENV: Final[str] = "SENTRY_AUTH_TOKEN"
SENTRY_PROJECT_SLUG_ENV: Final[str] = "SENTRY_PROJECT_SLUG"
DEFAULT_SENTRY_BASE_URL: Final[str] = "https://sentry.io"
11 changes: 11 additions & 0 deletions config/constants/vercel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
"""Vercel environment variable names."""

from __future__ import annotations

VERCEL_API_TOKEN_ENV = "VERCEL_API_TOKEN"
VERCEL_TEAM_ID_ENV = "VERCEL_TEAM_ID"

__all__ = [
"VERCEL_API_TOKEN_ENV",
"VERCEL_TEAM_ID_ENV",
]
47 changes: 32 additions & 15 deletions integrations/_catalog_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,28 @@
DATADOG_APP_KEY_ENV,
DATADOG_SITE_ENV,
)
from config.constants.gitlab import GITLAB_AUTH_TOKEN_ENV, GITLAB_BASE_URL_ENV
from config.constants.groundcover import (
GROUNDCOVER_API_KEY_ENV,
GROUNDCOVER_BACKEND_ID_ENV,
GROUNDCOVER_MCP_TOKEN_ENV,
GROUNDCOVER_MCP_URL_ENV,
GROUNDCOVER_TENANT_UUID_ENV,
GROUNDCOVER_TIMEZONE_ENV,
)
from config.constants.honeycomb import (
HONEYCOMB_API_KEY_ENV,
HONEYCOMB_BASE_URL_ENV,
HONEYCOMB_DATASET_ENV,
)
from config.constants.sentry import (
DEFAULT_SENTRY_BASE_URL,
SENTRY_AUTH_TOKEN_ENV,
SENTRY_BASE_URL_ENV,
SENTRY_ORGANIZATION_SLUG_ENV,
SENTRY_PROJECT_SLUG_ENV,
)
from config.constants.vercel import VERCEL_API_TOKEN_ENV, VERCEL_TEAM_ID_ENV
from config.llm_credentials import resolve_env_credential
from integrations.airflow.config import airflow_config_from_env
from integrations.airflow.config import classify as _classify_airflow
Expand Down Expand Up @@ -481,8 +498,8 @@ def load_env_integrations() -> list[dict[str, Any]]:
groundcover_api_key = ""
else:
groundcover_api_key = resolve_env_credential(
"GROUNDCOVER_API_KEY"
) or resolve_env_credential("GROUNDCOVER_MCP_TOKEN")
GROUNDCOVER_API_KEY_ENV
) or resolve_env_credential(GROUNDCOVER_MCP_TOKEN_ENV)
if groundcover_api_key:
# The groundcover config validates the MCP URL (HTTPS-or-loopback), which
# can raise on a bad GROUNDCOVER_MCP_URL. Guard it so one malformed value
Expand All @@ -491,10 +508,10 @@ def load_env_integrations() -> list[dict[str, Any]]:
groundcover_config = GroundcoverIntegrationConfig.model_validate(
{
"api_key": groundcover_api_key,
"mcp_url": os.getenv("GROUNDCOVER_MCP_URL", "").strip(),
"tenant_uuid": os.getenv("GROUNDCOVER_TENANT_UUID", "").strip(),
"backend_id": os.getenv("GROUNDCOVER_BACKEND_ID", "").strip(),
"timezone": os.getenv("GROUNDCOVER_TIMEZONE", "").strip(),
"mcp_url": os.getenv(GROUNDCOVER_MCP_URL_ENV, "").strip(),
"tenant_uuid": os.getenv(GROUNDCOVER_TENANT_UUID_ENV, "").strip(),
"backend_id": os.getenv(GROUNDCOVER_BACKEND_ID_ENV, "").strip(),
"timezone": os.getenv(GROUNDCOVER_TIMEZONE_ENV, "").strip(),
}
)
except Exception as exc:
Expand Down Expand Up @@ -647,16 +664,16 @@ def load_env_integrations() -> list[dict[str, Any]]:
)
)

sentry_org_slug = os.getenv("SENTRY_ORG_SLUG", "").strip()
sentry_auth_token = resolve_env_credential("SENTRY_AUTH_TOKEN")
sentry_org_slug = os.getenv(SENTRY_ORGANIZATION_SLUG_ENV, "").strip()
sentry_auth_token = resolve_env_credential(SENTRY_AUTH_TOKEN_ENV)
if sentry_org_slug and sentry_auth_token:
sentry_config = build_sentry_config(
{
"base_url": os.getenv("SENTRY_URL", "https://sentry.io").strip()
or "https://sentry.io",
"base_url": os.getenv(SENTRY_BASE_URL_ENV, DEFAULT_SENTRY_BASE_URL).strip()
or DEFAULT_SENTRY_BASE_URL,
"organization_slug": sentry_org_slug,
"auth_token": sentry_auth_token,
"project_slug": os.getenv("SENTRY_PROJECT_SLUG", "").strip(),
"project_slug": os.getenv(SENTRY_PROJECT_SLUG_ENV, "").strip(),
}
)
integrations.append(
Expand All @@ -666,11 +683,11 @@ def load_env_integrations() -> list[dict[str, Any]]:
)
)

gitlab_access_token = resolve_env_credential("GITLAB_ACCESS_TOKEN")
gitlab_access_token = resolve_env_credential(GITLAB_AUTH_TOKEN_ENV)
if gitlab_access_token:
gitlab_config = build_gitlab_config(
{
"base_url": os.getenv("GITLAB_BASE_URL", DEFAULT_GITLAB_BASE_URL).strip()
"base_url": os.getenv(GITLAB_BASE_URL_ENV, DEFAULT_GITLAB_BASE_URL).strip()
or DEFAULT_GITLAB_BASE_URL,
"auth_token": gitlab_access_token,
}
Expand Down Expand Up @@ -789,13 +806,13 @@ def load_env_integrations() -> list[dict[str, Any]]:
)
)

vercel_api_token = resolve_env_credential("VERCEL_API_TOKEN")
vercel_api_token = resolve_env_credential(VERCEL_API_TOKEN_ENV)
if vercel_api_token:
try:
vercel_config = VercelConfig.model_validate(
{
"api_token": vercel_api_token,
"team_id": os.getenv("VERCEL_TEAM_ID", "").strip(),
"team_id": os.getenv(VERCEL_TEAM_ID_ENV, "").strip(),
}
)
except Exception as exc:
Expand Down
Loading