From a240deb6182fd169dd91f7aa4d0f5b23dc84f638 Mon Sep 17 00:00:00 2001 From: Scot Wells Date: Sat, 21 Feb 2026 20:57:18 -0600 Subject: [PATCH] feat: add Telepresence Traffic Manager for remote debugging - Add telepresence component with HelmRelease for Traffic Manager - Add reusable Telepresence tasks to Taskfile (install, connect, intercept, status, quit) - Include telepresence in cluster deployment Co-Authored-By: Claude Opus 4.5 --- Taskfile.yml | 130 +++++++++++++++++++ cluster/kustomization.yaml | 1 + components/telepresence/helm-repository.yaml | 8 ++ components/telepresence/kustomization.yaml | 7 + components/telepresence/namespace.yaml | 6 + components/telepresence/telepresence-hr.yaml | 38 ++++++ 6 files changed, 190 insertions(+) create mode 100644 components/telepresence/helm-repository.yaml create mode 100644 components/telepresence/kustomization.yaml create mode 100644 components/telepresence/namespace.yaml create mode 100644 components/telepresence/telepresence-hr.yaml diff --git a/Taskfile.yml b/Taskfile.yml index 86eac77..4c43a4b 100644 --- a/Taskfile.yml +++ b/Taskfile.yml @@ -111,6 +111,13 @@ tasks: - echo " kind-load-image Load images into KIND" - echo " kind-save-image Save image tarball artifact" - echo "" + - echo "🔌 Remote Debugging (Telepresence):" + - echo " telepresence:install Install Telepresence CLI" + - echo " telepresence:connect Connect to the cluster" + - echo " telepresence:intercept Intercept a service (SERVICE=name NAMESPACE=ns PORT=port)" + - echo " telepresence:status Show connection status" + - echo " telepresence:quit Disconnect" + - echo "" - 'echo "For detailed help: task --list"' - 'echo "To run a command: task "' @@ -485,3 +492,126 @@ tasks: msg: 'ERROR: set TAR= as argument' cmds: - docker save "{{.IMAGE}}" | gzip > "{{.TAR}}" + + # ------------------------------------------------------------------ + # Telepresence - Remote debugging + # ------------------------------------------------------------------ + telepresence:install: + desc: "Install Telepresence CLI for remote debugging" + silent: true + cmds: + - | + set -e + OS=$(uname -s | tr '[:upper:]' '[:lower:]') + ARCH=$(uname -m) + case "$ARCH" in + x86_64) ARCH="amd64" ;; + aarch64|arm64) ARCH="arm64" ;; + esac + + if command -v telepresence &> /dev/null; then + CURRENT_VERSION=$(telepresence version 2>/dev/null | head -1 | awk '{print $2}') + echo "Telepresence already installed: $CURRENT_VERSION" + echo "Run 'telepresence version' to check for updates" + exit 0 + fi + + echo "Downloading Telepresence for $OS/$ARCH..." + + case "$OS" in + darwin) + brew install datawire/blackbird/telepresence + ;; + linux) + curl -fL https://app.getambassador.io/download/tel2oss/releases/download/v2.18.0/telepresence-${OS}-${ARCH} -o /tmp/telepresence + chmod +x /tmp/telepresence + sudo mv /tmp/telepresence /usr/local/bin/telepresence + ;; + *) + echo "❌ Unsupported OS: $OS" + exit 1 + ;; + esac + + echo "✅ Telepresence installed successfully" + telepresence version + + telepresence:connect: + desc: "Connect Telepresence to the cluster" + silent: true + cmds: + - | + set -e + + if [ ! -f "{{.KUBECONFIG_FILE}}" ]; then + echo "❌ Kubeconfig not found at {{.KUBECONFIG_FILE}}" + echo "💡 Run 'task cluster-up' first to create the cluster" + exit 1 + fi + + # Install traffic manager if not present + if ! kubectl --kubeconfig {{.KUBECONFIG_FILE}} get deploy traffic-manager -n ambassador >/dev/null 2>&1; then + echo "Installing Telepresence Traffic Manager..." + KUBECONFIG={{.KUBECONFIG_FILE}} telepresence helm install + fi + + KUBECONFIG={{.KUBECONFIG_FILE}} telepresence connect + echo "" + echo "✅ Connected to cluster via Telepresence" + echo "" + echo "You can now:" + echo " - Access cluster services directly (e.g., curl http://service.namespace)" + echo " - Intercept services: task telepresence:intercept SERVICE= NAMESPACE=" + echo " - Disconnect: telepresence quit" + + telepresence:intercept: + desc: "Intercept a service for local debugging (SERVICE=name NAMESPACE=ns PORT=port)" + silent: true + vars: + SERVICE: '{{.SERVICE}}' + NAMESPACE: '{{.NAMESPACE | default "default"}}' + PORT: '{{.PORT | default "8080"}}' + preconditions: + - sh: '[ -n "{{.SERVICE}}" ]' + msg: 'ERROR: set SERVICE= as argument' + cmds: + - | + set -e + + if [ ! -f "{{.KUBECONFIG_FILE}}" ]; then + echo "❌ Kubeconfig not found at {{.KUBECONFIG_FILE}}" + echo "💡 Run 'task cluster-up' first to create the cluster" + exit 1 + fi + + # Connect if not already connected + if ! telepresence status 2>/dev/null | grep -q "Connected"; then + echo "Not connected. Connecting first..." + KUBECONFIG={{.KUBECONFIG_FILE}} telepresence connect + fi + + KUBECONFIG={{.KUBECONFIG_FILE}} telepresence intercept {{.SERVICE}} \ + --namespace {{.NAMESPACE}} \ + --port {{.PORT}}:{{.PORT}} \ + --env-file /tmp/telepresence-{{.SERVICE}}.env + + echo "" + echo "✅ Intercepting {{.SERVICE}}" + echo "" + echo "Environment variables saved to: /tmp/telepresence-{{.SERVICE}}.env" + echo "Source them with: source /tmp/telepresence-{{.SERVICE}}.env" + echo "" + echo "To stop: telepresence leave {{.SERVICE}}" + + telepresence:status: + desc: "Show Telepresence connection and intercept status" + silent: true + cmds: + - telepresence status + + telepresence:quit: + desc: "Disconnect from Telepresence" + silent: true + cmds: + - telepresence quit + - echo "✅ Disconnected from Telepresence" diff --git a/cluster/kustomization.yaml b/cluster/kustomization.yaml index 2af8cb0..b104141 100644 --- a/cluster/kustomization.yaml +++ b/cluster/kustomization.yaml @@ -8,3 +8,4 @@ resources: - ../components/cert-manager - ../components/kyverno - ../components/envoy-gateway-operator + - ../components/telepresence diff --git a/components/telepresence/helm-repository.yaml b/components/telepresence/helm-repository.yaml new file mode 100644 index 0000000..569a209 --- /dev/null +++ b/components/telepresence/helm-repository.yaml @@ -0,0 +1,8 @@ +apiVersion: source.toolkit.fluxcd.io/v1 +kind: HelmRepository +metadata: + name: datawire + namespace: ambassador +spec: + interval: 1h + url: https://app.getambassador.io diff --git a/components/telepresence/kustomization.yaml b/components/telepresence/kustomization.yaml new file mode 100644 index 0000000..f584a75 --- /dev/null +++ b/components/telepresence/kustomization.yaml @@ -0,0 +1,7 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization +namespace: ambassador +resources: + - namespace.yaml + - helm-repository.yaml + - telepresence-hr.yaml diff --git a/components/telepresence/namespace.yaml b/components/telepresence/namespace.yaml new file mode 100644 index 0000000..2b3333e --- /dev/null +++ b/components/telepresence/namespace.yaml @@ -0,0 +1,6 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: ambassador + labels: + app.kubernetes.io/name: telepresence diff --git a/components/telepresence/telepresence-hr.yaml b/components/telepresence/telepresence-hr.yaml new file mode 100644 index 0000000..98cbbe5 --- /dev/null +++ b/components/telepresence/telepresence-hr.yaml @@ -0,0 +1,38 @@ +apiVersion: helm.toolkit.fluxcd.io/v2 +kind: HelmRelease +metadata: + name: traffic-manager + namespace: ambassador +spec: + interval: 1h + chart: + spec: + chart: telepresence + version: "2.x" + sourceRef: + kind: HelmRepository + name: datawire + namespace: ambassador + install: + crds: CreateReplace + remediation: + retries: 3 + upgrade: + crds: CreateReplace + remediation: + retries: 3 + values: + # Traffic Manager configuration + image: + registry: docker.io/datawire + name: tel2 + logLevel: info + # RBAC settings + rbac: + create: true + # Allow intercepting services + intercept: + disableGlobal: false + # Agent injector settings + agentInjector: + enabled: true