prole/tests/installer/test_gke_clusters.py
chrisfu bfa712273e Implement split-cluster host ownership and context-safe deploy wiring
- move Supabase k8s ingress defaults to env-indexed api/db hostnames and remove legacy host bleed-through

- enforce explicit APP/DB kubecontext role validation across cluster ops and init scripts

- align env/default derivation and extend tests for hostname rendering and context checks

Co-authored-by: Junie <junie@jetbrains.com>
2026-04-12 21:00:20 -07:00

155 lines
5.1 KiB
Python

from pathlib import Path
import sys
import pytest
PROJECT_ROOT = Path(__file__).resolve().parents[2]
if str(PROJECT_ROOT) not in sys.path:
sys.path.insert(0, str(PROJECT_ROOT))
from subprocess import CompletedProcess
from knoe.core.ops import gke_clusters
def test_build_kubectl_env_for_cluster_sets_explicit_role_and_context():
env = gke_clusters.build_kubectl_env_for_cluster(
base_env={"EXISTING": "1"},
kubecontext="ctx-app",
cluster_name="knoe-dev-0",
cluster_role="app",
)
assert env["EXISTING"] == "1"
assert env["KUBECTL_CONTEXT"] == "ctx-app"
assert env["CLUSTER_NAME"] == "knoe-dev-0"
assert env["KNOE_CLUSTER_ROLE"] == "app"
assert env["KNOE_APP_CLUSTER_NAME"] == "knoe-dev-0"
def test_build_kubectl_env_for_cluster_requires_explicit_context_when_missing():
with pytest.raises(ValueError, match="Missing required kube context"):
gke_clusters.build_kubectl_env_for_cluster(
base_env={},
kubecontext="",
cluster_name="knoe-dev-0",
cluster_role="app",
)
def test_build_kubectl_env_for_cluster_rejects_mismatched_required_role_context():
with pytest.raises(ValueError, match="expected APP_CLUSTER_KUBECONTEXT"):
gke_clusters.build_kubectl_env_for_cluster(
base_env={"APP_CLUSTER_KUBECONTEXT": "ctx-app"},
kubecontext="ctx-other",
cluster_name="knoe-dev-0",
cluster_role="app",
)
def test_build_kubectl_env_for_cluster_rejects_cross_role_context_usage():
with pytest.raises(ValueError, match="matches DB_CLUSTER_KUBECONTEXT"):
gke_clusters.build_kubectl_env_for_cluster(
base_env={
"APP_CLUSTER_KUBECONTEXT": "ctx-app",
"DB_CLUSTER_KUBECONTEXT": "ctx-db",
},
kubecontext="ctx-db",
cluster_name="knoe-dev-0",
cluster_role="app",
)
def test_get_cluster_credentials_builds_expected_gcloud_command(monkeypatch):
called = {}
def fake_run(cmd, capture_output, text):
called["cmd"] = cmd
return CompletedProcess(cmd, 0, stdout="", stderr="")
monkeypatch.setattr(gke_clusters.subprocess, "run", fake_run)
context = gke_clusters.get_cluster_credentials(
project_id="proj-1",
cluster_name="knoe-cnpg-0",
location="us-central1",
)
assert context == "gke_proj-1_us-central1_knoe-cnpg-0"
assert called["cmd"] == [
"gcloud",
"container",
"clusters",
"get-credentials",
"knoe-cnpg-0",
"--project",
"proj-1",
"--region",
"us-central1",
"--quiet",
]
def test_ensure_db_cluster_creates_standard_cluster_with_db_node_labels(monkeypatch):
commands = []
def fake_run(cmd, log=None):
commands.append(cmd)
if cmd[:4] == ["gcloud", "container", "clusters", "describe"]:
return CompletedProcess(cmd, 1, stdout="", stderr="not found")
return CompletedProcess(cmd, 0, stdout="created", stderr="")
monkeypatch.setattr(gke_clusters, "_run", fake_run)
spec = gke_clusters.GkeClusterSpec(
name="knoe-cnpg-0",
mode="standard",
location="us-central1",
machine_type="e2-small",
node_count=1,
node_pool_name="cnpg-db-pool",
)
gke_clusters.ensure_db_cluster(project_id="proj-1", spec=spec)
create_cmd = commands[-1]
assert create_cmd[:5] == ["gcloud", "container", "clusters", "create", "knoe-cnpg-0"]
assert "--num-nodes" in create_cmd
assert create_cmd[create_cmd.index("--num-nodes") + 1] == "1"
assert "--node-labels" in create_cmd
assert create_cmd[create_cmd.index("--node-labels") + 1] == "workload=db"
def test_ensure_db_cluster_existing_cluster_adds_labeled_db_pool(monkeypatch):
commands = []
def fake_run(cmd, log=None):
commands.append(cmd)
if cmd[:4] == ["gcloud", "container", "clusters", "describe"]:
return CompletedProcess(cmd, 0, stdout="knoe-cnpg-0", stderr="")
if cmd[:4] == ["gcloud", "container", "node-pools", "describe"]:
return CompletedProcess(cmd, 1, stdout="", stderr="not found")
return CompletedProcess(cmd, 0, stdout="ok", stderr="")
monkeypatch.setattr(gke_clusters, "_run", fake_run)
spec = gke_clusters.GkeClusterSpec(
name="knoe-cnpg-0",
mode="standard",
location="us-central1-a",
machine_type="e2-standard-2",
node_count=3,
node_pool_name="cnpg-db-pool",
)
gke_clusters.ensure_db_cluster(project_id="proj-1", spec=spec)
create_pool_cmd = commands[-1]
assert create_pool_cmd[:4] == ["gcloud", "container", "node-pools", "create"]
assert create_pool_cmd[4] == "cnpg-db-pool"
assert "--machine-type" in create_pool_cmd
assert create_pool_cmd[create_pool_cmd.index("--machine-type") + 1] == "e2-standard-2"
assert "--num-nodes" in create_pool_cmd
assert create_pool_cmd[create_pool_cmd.index("--num-nodes") + 1] == "3"
assert "--node-labels" in create_pool_cmd
assert create_pool_cmd[create_pool_cmd.index("--node-labels") + 1] == "workload=db"