diff --git a/k8s/n8n/_tmp_generate-token.yaml b/k8s/n8n/_tmp_generate-token.yaml new file mode 100644 index 0000000..47cc409 --- /dev/null +++ b/k8s/n8n/_tmp_generate-token.yaml @@ -0,0 +1,65 @@ +# --- Garmin Token Generator Pod --- +# This pod is a temporary, interactive tool to generate Garmin Connect session tokens. +# +# --- WORKFLOW --- +# 1. Ensure the `garmin-credentials` secret is applied in the `n8n` namespace. +# 2. Apply this manifest: `kubectl apply -f token-generator-pod.yaml` +# 3. View the logs to see instructions: `kubectl logs -n n8n -f garmin-token-generator` +# 4. Exec into the pod and run the login command provided in the logs. +# 5. Retrieve the generated token data from within the pod. +# 6. Create the `garmin-tokens` Kubernetes secret. +# 7. Delete this pod: `kubectl delete pod -n n8n garmin-token-generator` +# +apiVersion: v1 +kind: Pod +metadata: + name: garmin-token-generator + namespace: n8n +spec: + volumes: + # This is temporary storage that will be deleted when the pod is deleted. + # We use it to hold the generated token files. + - name: garmin-connect-storage + emptyDir: {} + containers: + - name: helper + image: python:3.12-slim + # Mount the garmin-credentials secret as environment variables + envFrom: + - secretRef: + name: garmin-credentials + # The main command installs dependencies, prints instructions, and then sleeps. + # This keeps the pod running so you can exec into it. + command: ["/bin/sh", "-c"] + args: + - | + set -e + echo "--- Garmin Token Generator Pod ---" + echo "[Step 1/3] Installing dependencies (git and uv)..." + # Set debconf to non-interactive mode to prevent installation prompts and fix warnings. + export DEBIAN_FRONTEND=noninteractive + # Redirect noisy output to /dev/null + apt-get update > /dev/null && apt-get install -y git --no-install-recommends > /dev/null && rm -rf /var/lib/apt/lists/* + pip install uv > /dev/null + + echo "[Step 2/3] Setup complete. Pod is ready for interactive login." + echo "------------------------------------------------------------------" + echo "ACTION REQUIRED:" + echo "1. Ensure the 'garmin-credentials' secret has been applied to this namespace." + echo "2. Open a new terminal." + echo "3. Connect to this pod by running:" + echo " kubectl exec -it -n n8n garmin-token-generator -- /bin/sh" + echo "" + echo "4. Inside the pod's shell, run the following simplified command:" + echo " uvx --from garminconnect gcexport --username \"$GARMIN_EMAIL\" --password \"$GARMIN_PASSWORD\"" + echo "" + echo "5. Follow the prompts to enter your MFA code." + echo "6. Once successful, the tokens will be saved to /root/.garminconnect" + echo "------------------------------------------------------------------" + + echo "[Step 3/3] Sleeping indefinitely. This pod will remain running until you delete it." + sleep infinity + volumeMounts: + # Mount the temporary storage at the path where the library saves tokens. + - name: garmin-connect-storage + mountPath: "/root/.garminconnect" \ No newline at end of file diff --git a/k8s/n8n/garmin-mcp.yaml b/k8s/n8n/garmin-mcp.yaml new file mode 100644 index 0000000..c3d1d8d --- /dev/null +++ b/k8s/n8n/garmin-mcp.yaml @@ -0,0 +1,84 @@ +# --- Garmin MCP Server Deployment --- +# This manifest defines the desired state for the Garmin MCP server. +# It uses a standard Python image and installs the necessary tools and +# the application itself upon startup. +apiVersion: apps/v1 +kind: Deployment +metadata: + name: garmin-mcp-server + namespace: n8n + labels: + app: garmin-mcp-server +spec: + replicas: 1 + selector: + matchLabels: + app: garmin-mcp-server + template: + metadata: + labels: + app: garmin-mcp-server + spec: + containers: + - name: server + # Use a standard, slim Python image as the base. + image: python:3.12-slim + # Override the default command to perform setup and then run the server. + command: ["/bin/sh", "-c"] + args: + - | + set -e + echo "Step 1/4: Installing git client..." + # Update package lists and install git. --no-install-recommends keeps it minimal. + # rm -rf cleans up the apt cache to keep the running container lean. + apt-get update && apt-get install -y git --no-install-recommends && rm -rf /var/lib/apt/lists/* + + echo "Step 2/4: Installing uv package manager..." + pip install uv + + echo "Step 3/4: Launching server via uvx (will install from git)..." + # 'uvx' runs a command from a temporary environment. + # We specify the git repository to install the package from. + # The '--host 0.0.0.0' flag is crucial to ensure the server + # is accessible from outside its container within the cluster network. + uvx --from git+https://github.com/Taxuspt/garmin_mcp garmin-mcp --host 0.0.0.0 --port 8000 + + echo "Step 4/4: Server has been started." + + ports: + - name: http + containerPort: 8000 + protocol: TCP + # Mount the Garmin credentials from the Kubernetes secret as environment variables. + envFrom: + - secretRef: + name: garmin-credentials + # Basic readiness probe to ensure the service is not marked ready until the app is listening. + readinessProbe: + tcpSocket: + port: 8000 + initialDelaySeconds: 25 # Increased delay to account for git installation + periodSeconds: 10 +--- +# --- Garmin MCP Server Service --- +# This manifest creates a stable internal endpoint (ClusterIP service) +# for the Garmin MCP server deployment. Your n8n instance will use this +# service's DNS name to communicate with the server. +apiVersion: v1 +kind: Service +metadata: + name: garmin-mcp-service + namespace: n8n +spec: + # This service will be of type ClusterIP, only reachable from within the cluster. + type: ClusterIP + selector: + # This selector must match the labels of the pods created by the Deployment. + app: garmin-mcp-server + ports: + - name: http + protocol: TCP + # The port the service will be available on within the cluster. + port: 80 + # The port on the container that the service will forward traffic to. + targetPort: 8000 \ No newline at end of file diff --git a/k8s/n8n/garmin.secret.yaml b/k8s/n8n/garmin.secret.yaml new file mode 100644 index 0000000..0e453a1 Binary files /dev/null and b/k8s/n8n/garmin.secret.yaml differ