From 152f10ed8b29d78d9ac4ddef3157b07038030eca Mon Sep 17 00:00:00 2001 From: Hermes Agent service account Date: Thu, 4 Jun 2026 23:35:45 -0500 Subject: [PATCH] Add ArgoCD PostSync hook for Harbor robot accounts Manages robot accounts declaratively via GitOps: - tekton-builder: push/pull access for CI/CD pipelines - fastpass-cluster: pull-only access for K8s image pulls Implementation: - Kubernetes Job with argocd.argoproj.io/hook: PostSync annotation - Idempotent: checks if accounts exist before creating - Uses harbor-credentials ExternalSecret for admin password - BeforeHookCreation deletion policy for clean reruns Replaces manual robot account creation via Harbor API. --- .../platform/harbor/robot-accounts-sync.yaml | 87 +++++++++++++++++++ 1 file changed, 87 insertions(+) create mode 100644 cluster/platform/harbor/robot-accounts-sync.yaml diff --git a/cluster/platform/harbor/robot-accounts-sync.yaml b/cluster/platform/harbor/robot-accounts-sync.yaml new file mode 100644 index 0000000..a07ecad --- /dev/null +++ b/cluster/platform/harbor/robot-accounts-sync.yaml @@ -0,0 +1,87 @@ +--- +apiVersion: batch/v1 +kind: Job +metadata: + name: harbor-robot-accounts-sync + namespace: harbor + annotations: + argocd.argoproj.io/hook: PostSync + argocd.argoproj.io/hook-delete-policy: BeforeHookCreation +spec: + template: + metadata: + name: harbor-robot-accounts-sync + spec: + restartPolicy: Never + serviceAccountName: default + containers: + - name: sync-robot-accounts + image: curlimages/curl:latest + command: + - /bin/sh + - -c + - | + set -e + + HARBOR_URL="https://the-seas.local.mk-labs.cloud/api/v2.0" + ADMIN_USER="admin" + ADMIN_PASSWORD="$(cat /secrets/admin-password)" + + echo "Syncing Harbor robot accounts..." + + # Function to check if robot account exists + robot_exists() { + local robot_name="$1" + curl -k -s -u "${ADMIN_USER}:${ADMIN_PASSWORD}" \ + "${HARBOR_URL}/robots?q=name=${robot_name}" | grep -q "\"name\":\"robot\$${robot_name}\"" + } + + # Function to create robot account + create_robot() { + local name="$1" + local description="$2" + local permissions="$3" + + echo "Creating robot account: ${name}" + curl -k -s -u "${ADMIN_USER}:${ADMIN_PASSWORD}" \ + -X POST "${HARBOR_URL}/robots" \ + -H "Content-Type: application/json" \ + -d "{ + \"name\": \"${name}\", + \"description\": \"${description}\", + \"duration\": -1, + \"level\": \"system\", + \"permissions\": ${permissions} + }" || echo "Failed to create ${name}" + } + + # Tekton Builder - Push/Pull access + if ! robot_exists "tekton-builder"; then + create_robot "tekton-builder" \ + "Tekton CI/CD pipeline robot account with push/pull access" \ + '[{"kind":"project","namespace":"*","access":[{"resource":"repository","action":"push"},{"resource":"repository","action":"pull"},{"resource":"artifact","action":"read"},{"resource":"artifact","action":"list"}]}]' + else + echo "Robot account tekton-builder already exists" + fi + + # Fastpass Cluster - Pull-only access + if ! robot_exists "fastpass-cluster"; then + create_robot "fastpass-cluster" \ + "Fastpass Kubernetes cluster robot account with pull-only access" \ + '[{"kind":"project","namespace":"*","access":[{"resource":"repository","action":"pull"},{"resource":"artifact","action":"read"},{"resource":"artifact","action":"list"}]}]' + else + echo "Robot account fastpass-cluster already exists" + fi + + echo "Robot accounts sync complete" + volumeMounts: + - name: admin-credentials + mountPath: /secrets + readOnly: true + volumes: + - name: admin-credentials + secret: + secretName: harbor-credentials + items: + - key: HARBOR_ADMIN_PASSWORD + path: admin-password