"""Per-cloud console URL resolution. Powers the "打开云 Console" button on the cloud scope detail page. The button is a one-click pivot from a Helix scope to the cloud vendor's web console — IAM Identity Center start page for AWS/Azure SSO setups, the cloud's own management console for the rest. Resolution order (most specific wins): 1. ``Integration.config_public['console_url']`` — admin-set per-integration override (lives next to the integration's other config in the admin Integrations page). Use this when one organization has multiple AWS Orgs that pivot through different SSO portals. 2. ``platform_settings`` row keyed ``cloud.console_url.`` — global per-provider-type default that the admin can edit without touching every integration row. 3. ``_BUILTIN_DEFAULTS[provider]`` — hardcoded baseline so the button works on a fresh install with no admin setup. 4. ``None`` — provider has no known console; the frontend renders no button. Resolution is read-only and cached only in the request scope (no process-level cache) — admins editing the URL through the platform settings page get the new value on the next page load. """ from __future__ import annotations from typing import Any from sqlalchemy import select from sqlalchemy.ext.asyncio import AsyncSession from app.integrations.models import Integration, PlatformSetting # Defaults are PingCAP-specific because the user's first three # integrations are PingCAP's own SSO portals — but admins on other # tenants will override these via Integration.config_public or # platform_settings without a code change. _BUILTIN_DEFAULTS: dict[str, str] = { "aws": "https://pingcap.awsapps.com/start/#/", "azure": "https://portal.azure.com/#home", "gcp": "https://console.cloud.google.com/", # AliCloud (both domestic + intl) pivot through PingCAP's Alibaba # Cloud SSO portal (Google-login start page), same shape as the # AWS ``pingcap.awsapps.com/start`` portal above. "alicloud": "https://signin-cn-shanghai.alibabacloudsso.com/google/login", "alicloud_intl": "https://signin-cn-shanghai.alibabacloudsso.com/google/login", "tencent": "https://console.cloud.tencent.com/", "ucloud": "https://console.ucloud.cn/", "ksyun": "https://console.ksyun.com/", } def _settings_key(provider: str) -> str: return f"cloud.console_url.{provider.strip().lower()}" async def resolve_console_url( db: AsyncSession, integration: Integration, ) -> str | None: """Resolve the console URL for one integration. See module docstring.""" cfg: dict[str, Any] = integration.config_public or {} per_integration = cfg.get("console_url") if isinstance(per_integration, str) and per_integration.strip(): return per_integration.strip() provider = (integration.provider or "").strip().lower() if not provider: return None row = (await db.execute( select(PlatformSetting).where( PlatformSetting.key == _settings_key(provider), ) )).scalar_one_or_none() if row is not None: val = row.value if isinstance(val, str) and val.strip(): return val.strip() return _BUILTIN_DEFAULTS.get(provider) def builtin_default(provider: str) -> str | None: """Public read for the hardcoded baseline. Used by the admin settings page to show "(默认: )" hint text next to the override field, so admins can see what they'd revert to by clearing the override.""" return _BUILTIN_DEFAULTS.get((provider or "").strip().lower())