2026-09-16 10:48:25 -04:00
|
|
|
.PHONY: init plan apply destroy clean kubeconfig talosconfig argocd-password bootstrap decrypt post-apply build-mcp-auth-proxy stream-url
|
2026-08-17 10:22:06 -04:00
|
|
|
|
2026-08-18 10:00:53 -04:00
|
|
|
SECRET ?= dumpnet
|
2026-08-22 17:56:03 -04:00
|
|
|
FORGEJO_REGISTRY ?= forge.keane.sh
|
|
|
|
|
FORGEJO_USER ?= ian
|
|
|
|
|
MCP_AUTH_PROXY_IMAGE=$(FORGEJO_REGISTRY)/$(FORGEJO_USER)/mcp-auth-proxy
|
2026-08-17 10:22:06 -04:00
|
|
|
TF_DIR=terraform
|
|
|
|
|
SOPS_FILES=controlplane.yaml worker.yaml talosconfig
|
|
|
|
|
|
|
|
|
|
# Cluster infrastructure
|
|
|
|
|
init:
|
|
|
|
|
cd $(TF_DIR) && terraform init
|
|
|
|
|
|
|
|
|
|
plan:
|
|
|
|
|
cd $(TF_DIR) && terraform plan
|
|
|
|
|
|
|
|
|
|
apply:
|
2026-08-18 10:00:53 -04:00
|
|
|
cd $(TF_DIR) && terraform apply -target=talos_cluster_kubeconfig.this
|
2026-08-18 13:17:40 -04:00
|
|
|
@echo "==> Waiting 60s for Kubernetes API to be ready..."
|
|
|
|
|
@sleep 60
|
2026-08-17 10:22:06 -04:00
|
|
|
cd $(TF_DIR) && terraform apply
|
|
|
|
|
|
|
|
|
|
destroy:
|
|
|
|
|
cd $(TF_DIR) && terraform destroy
|
|
|
|
|
|
2026-08-18 10:00:53 -04:00
|
|
|
# Full clean slate - run before destroy when recreating from scratch
|
|
|
|
|
# Removes resources that block terraform from recreating cleanly
|
|
|
|
|
clean:
|
|
|
|
|
@echo "==> Force-deleting Secrets Manager secret..."
|
|
|
|
|
-aws secretsmanager delete-secret --secret-id $(SECRET) --force-delete-without-recovery 2>/dev/null || true
|
|
|
|
|
@echo "==> Clearing stale kubeconfig contexts..."
|
|
|
|
|
-kubectl config delete-context admin@dumpnet 2>/dev/null || true
|
|
|
|
|
-kubectl config delete-cluster dumpnet 2>/dev/null || true
|
|
|
|
|
-kubectl config delete-user admin@dumpnet 2>/dev/null || true
|
|
|
|
|
@echo "==> Clearing stale talosctl contexts..."
|
|
|
|
|
-talosctl config remove dumpnet 2>/dev/null || true
|
|
|
|
|
-talosctl config remove dumpnet-1 2>/dev/null || true
|
|
|
|
|
@echo "==> Done. Run 'make destroy' then 'make apply' to rebuild from scratch."
|
|
|
|
|
|
2026-08-17 10:22:06 -04:00
|
|
|
# Bootstrap ArgoCD app of apps (run once after cluster is up)
|
|
|
|
|
bootstrap:
|
|
|
|
|
kubectl apply -f apps/apps.yaml
|
2026-08-19 10:45:59 -04:00
|
|
|
@echo "ArgoCD will now manage apps/ directory - future group changes are self-healing via git push"
|
2026-08-17 10:22:06 -04:00
|
|
|
|
2026-08-22 14:33:10 -04:00
|
|
|
# Images
|
|
|
|
|
build-mcp-auth-proxy:
|
2026-08-22 17:56:03 -04:00
|
|
|
@echo "==> Logging into Forgejo registry..."
|
|
|
|
|
$(eval REGISTRY_TOKEN=$(shell aws secretsmanager get-secret-value --secret-id $(SECRET) --query SecretString --output text | python3 -c "import sys,json; print(json.load(sys.stdin)['forgejo']['registry_token'])"))
|
|
|
|
|
echo "$(REGISTRY_TOKEN)" | docker login $(FORGEJO_REGISTRY) --username $(FORGEJO_USER) --password-stdin
|
|
|
|
|
docker build -t $(MCP_AUTH_PROXY_IMAGE):latest images/mcp-auth-proxy/
|
|
|
|
|
docker push $(MCP_AUTH_PROXY_IMAGE):latest
|
|
|
|
|
@echo "Pushed mcp-auth-proxy to $(MCP_AUTH_PROXY_IMAGE):latest"
|
2026-08-22 14:33:10 -04:00
|
|
|
|
2026-08-17 10:22:06 -04:00
|
|
|
# Credentials
|
|
|
|
|
talosconfig:
|
|
|
|
|
aws secretsmanager get-secret-value --secret-id $(SECRET) \
|
|
|
|
|
--query SecretString --output text | python3 -c \
|
2026-08-17 13:05:22 -04:00
|
|
|
"import sys,json; print(json.load(sys.stdin)['cluster']['talosconfig'])" \
|
2026-08-17 10:22:06 -04:00
|
|
|
> /tmp/talosconfig-dumpnet
|
|
|
|
|
talosctl config merge /tmp/talosconfig-dumpnet
|
|
|
|
|
rm /tmp/talosconfig-dumpnet
|
|
|
|
|
talosctl config context dumpnet
|
|
|
|
|
|
|
|
|
|
kubeconfig:
|
2026-08-18 10:00:53 -04:00
|
|
|
-kubectl config delete-context admin@dumpnet 2>/dev/null || true
|
|
|
|
|
-kubectl config delete-cluster dumpnet 2>/dev/null || true
|
|
|
|
|
-kubectl config delete-user admin@dumpnet 2>/dev/null || true
|
2026-08-17 10:22:06 -04:00
|
|
|
aws secretsmanager get-secret-value --secret-id $(SECRET) \
|
|
|
|
|
--query SecretString --output text | python3 -c \
|
2026-08-17 13:05:22 -04:00
|
|
|
"import sys,json; print(json.load(sys.stdin)['cluster']['kubeconfig'])" \
|
2026-08-17 10:22:06 -04:00
|
|
|
> /tmp/kubeconfig-dumpnet
|
|
|
|
|
KUBECONFIG=~/.kube/config:/tmp/kubeconfig-dumpnet kubectl config view --flatten > /tmp/merged
|
|
|
|
|
mv /tmp/merged ~/.kube/config
|
|
|
|
|
rm /tmp/kubeconfig-dumpnet
|
|
|
|
|
kubectl config use-context admin@dumpnet
|
|
|
|
|
|
|
|
|
|
argocd-password:
|
|
|
|
|
@aws secretsmanager get-secret-value --secret-id $(SECRET) \
|
|
|
|
|
--query SecretString --output text | python3 -c \
|
2026-08-17 13:05:22 -04:00
|
|
|
"import sys,json; print(json.load(sys.stdin)['cluster']['argocd_admin_password'])"
|
2026-08-17 10:22:06 -04:00
|
|
|
|
2026-09-16 10:48:25 -04:00
|
|
|
# Build the current RTMP publish URL from the dumpnet secret (mediamtx.*)
|
|
|
|
|
# — handy for testing without going through the IRC bot, since the
|
|
|
|
|
# zoitestream API is cluster-internal only.
|
|
|
|
|
stream-url:
|
|
|
|
|
@aws secretsmanager get-secret-value --secret-id $(SECRET) \
|
|
|
|
|
--query SecretString --output text | python3 -c \
|
|
|
|
|
"import sys, json; \
|
|
|
|
|
d = json.load(sys.stdin)['mediamtx']; \
|
|
|
|
|
print(f\"rtmp://stream.dumpnet.chat:1935/live?user=streamer&pass={d['publish_password']}\")"
|
|
|
|
|
|
2026-08-17 10:22:06 -04:00
|
|
|
# Decrypt sensitive files to /tmp for one-off talosctl use
|
|
|
|
|
# Files are never decrypted in the repo directory
|
|
|
|
|
decrypt:
|
|
|
|
|
@for f in $(SOPS_FILES); do \
|
|
|
|
|
if [ -f $$f ]; then \
|
|
|
|
|
echo "Decrypting $$f to /tmp/$$f..."; \
|
|
|
|
|
sops -d $$f > /tmp/$$f; \
|
|
|
|
|
fi; \
|
|
|
|
|
done
|
|
|
|
|
@echo "Decrypted files are in /tmp/ - they will not persist after reboot"
|
2026-08-17 10:29:21 -04:00
|
|
|
|
|
|
|
|
# Run all post-apply steps (run once after fresh cluster creation)
|
|
|
|
|
post-apply:
|
|
|
|
|
scripts/post-apply.sh
|