---
apiVersion: v1
kind: ConfigMap
metadata:
  name: credentials-sync
data:
  # Patch this ConfigMap with additional values needed for your cloud
  KUBE_SECRET: my-registry-token  # does not yet exist -- will be created in the same Namespace
  SYNC_PERIOD: "3600"  # tokens expire; refresh faster than that

---
# This Deployment frequently fetches registry tokens and applies them as an imagePullSecret.
# It's done as a 1-replica Deployment rather than a CronJob, because CronJob scheduling can
# block cluster bootstraps and cold-reboots from obtaining registry tokens for a considerable time.
# This deployment will immediately fetch a token, which reduces latency for working image updates.
apiVersion: apps/v1
kind: Deployment
metadata:
  name: credentials-sync
  namespace: flux-system
spec:
  replicas: 1
  strategy:
    type: Recreate
  template:
    spec:
      serviceAccount: credentials-sync
      containers:
      - image: busybox  # override this with a cloud-specific image
        name: sync
        envFrom:
        - configMapRef:
            name: credentials-sync
        env:
        - name: RECONCILE_SH  # override this env var with a shell function in a kustomize patch
          value: |-
            reconcile() {
              echo reconciling...
            }
        command:
        - bash
        - -ceu
        - |-
          # template reconcile() into the script
          # env var is expanded by k8s before the pod starts
          $(RECONCILE_SH)

          apply-secret() {
            /kbin/kubectl create secret docker-registry "${1}" \
              --docker-server="${2}" \
              --docker-username="${3}" \
              --docker-password="${4}" \
              --dry-run=client -o=yaml \
              | grep -v "creationTimestamp:" \
              | /kbin/kubectl apply -f -
          }

          pause_loop() {
            sleep "${SYNC_PERIOD:-3600}" || true
          }

          graceful_exit() {
            echo "Trapped signal -- $(date)"
            job_ids="$(
              jobs \
                | grep "pause_loop" \
                | cut -d] -f1 \
                | tr [ %
              )"
            # shellcheck disable=SC2086
            if [ "${job_ids}" ]; then
              kill ${job_ids}
            fi
            wait
            echo "Graceful exit -- $(date)"
          }

          trap graceful_exit INT TERM

          echo "Loop started (period: ${SYNC_PERIOD} s) -- $(date)"
          while true; do
            reconcile & wait $!
            pause_loop & wait $!
          done
        resources: {}


# RBAC necessary for our Deployment to apply our imagePullSecret
---
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: credentials-sync
  namespace: flux-system
rules:
- apiGroups: [""]
  resources:
  - secrets
  verbs:
  - get
  - create
  - update
  - patch
  # # Lock this down to the specific Secret name  (Optional)
  resourceNames:
  - $(KUBE_SECRET)  # templated from kustomize vars referencing ConfigMap, also see kustomizeconfig.yaml
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
  name: credentials-sync
  namespace: flux-system
subjects:
- kind: ServiceAccount
  name: credentials-sync
roleRef:
  kind: Role
  name: credentials-sync
  apiGroup: rbac.authorization.k8s.io
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: credentials-sync
  namespace: flux-system