apiVersion: batch/v1 kind: CronJob metadata: name: rabbitmq-apps-bootstrap namespace: rabbitmq spec: schedule: "*/10 * * * *" successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 2 concurrencyPolicy: Forbid jobTemplate: spec: template: spec: restartPolicy: OnFailure serviceAccountName: rabbitmq containers: - name: bootstrap image: alpine:3.20 command: ["/bin/sh", "-ec"] args: - | apk add --no-cache curl jq >/dev/null VAULT_ADDR="http://vault-vault-contour.vault.svc:8200" JWT="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" VAULT_TOKEN="$(curl -sS --request POST \ --data "{\"role\":\"rabbitmq\",\"jwt\":\"${JWT}\"}" \ "${VAULT_ADDR}/v1/auth/kubernetes/login" | jq -r '.auth.client_token')" [ -n "${VAULT_TOKEN}" ] && [ "${VAULT_TOKEN}" != "null" ] admin_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/rabbitmq/auth")" admin_user="$(echo "${admin_json}" | jq -r '.data.data.username')" admin_pass="$(echo "${admin_json}" | jq -r '.data.data.password')" list_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/metadata/rabbitmq/apps?list=true")" for app in $(echo "${list_json}" | jq -r '.data.keys[]?' | sed 's#/$##'); do app_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/rabbitmq/apps/${app}")" username="$(echo "${app_json}" | jq -r '.data.data.username')" password="$(echo "${app_json}" | jq -r '.data.data.password')" [ -z "${username}" ] && username="${app}" [ -z "${password}" ] && continue curl -sS -u "${admin_user}:${admin_pass}" -H "content-type:application/json" \ -X PUT "http://rabbitmq.rabbitmq.svc.cluster.local:15672/api/users/${username}" \ -d "{\"password\":\"${password}\",\"tags\":\"\"}" >/dev/null vhosts_count="$(echo "${app_json}" | jq -r '(.data.data.vhosts // []) | length')" if [ "${vhosts_count}" -gt 0 ]; then echo "${app_json}" | jq -c '.data.data.vhosts[]' | while read -r vhost_item; do vhost="$(echo "${vhost_item}" | jq -r '.name // "/"')" configure="$(echo "${vhost_item}" | jq -r '.permissions.configure // ".*"')" write="$(echo "${vhost_item}" | jq -r '.permissions.write // ".*"')" read="$(echo "${vhost_item}" | jq -r '.permissions.read // ".*"')" vhost_uri="$(jq -rn --arg v "${vhost}" '$v|@uri')" curl -sS -u "${admin_user}:${admin_pass}" -H "content-type:application/json" \ -X PUT "http://rabbitmq.rabbitmq.svc.cluster.local:15672/api/vhosts/${vhost_uri}" \ -d '{}' >/dev/null curl -sS -u "${admin_user}:${admin_pass}" -H "content-type:application/json" \ -X PUT "http://rabbitmq.rabbitmq.svc.cluster.local:15672/api/permissions/${vhost_uri}/${username}" \ -d "{\"configure\":\"${configure}\",\"write\":\"${write}\",\"read\":\"${read}\"}" >/dev/null done else vhost="$(echo "${app_json}" | jq -r '.data.data.vhost // "/"')" configure="$(echo "${app_json}" | jq -r '.data.data.permissions.configure // ".*"')" write="$(echo "${app_json}" | jq -r '.data.data.permissions.write // ".*"')" read="$(echo "${app_json}" | jq -r '.data.data.permissions.read // ".*"')" vhost_uri="$(jq -rn --arg v "${vhost}" '$v|@uri')" curl -sS -u "${admin_user}:${admin_pass}" -H "content-type:application/json" \ -X PUT "http://rabbitmq.rabbitmq.svc.cluster.local:15672/api/vhosts/${vhost_uri}" \ -d '{}' >/dev/null curl -sS -u "${admin_user}:${admin_pass}" -H "content-type:application/json" \ -X PUT "http://rabbitmq.rabbitmq.svc.cluster.local:15672/api/permissions/${vhost_uri}/${username}" \ -d "{\"configure\":\"${configure}\",\"write\":\"${write}\",\"read\":\"${read}\"}" >/dev/null fi done --- apiVersion: batch/v1 kind: CronJob metadata: name: minio-apps-bootstrap namespace: minio spec: schedule: "*/10 * * * *" successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 2 concurrencyPolicy: Forbid jobTemplate: spec: template: spec: restartPolicy: OnFailure serviceAccountName: minio-sa containers: - name: bootstrap image: alpine:3.20 command: ["/bin/sh", "-ec"] args: - | apk add --no-cache curl jq >/dev/null curl -fsSL -o /usr/local/bin/mc https://dl.min.io/client/mc/release/linux-amd64/mc chmod +x /usr/local/bin/mc VAULT_ADDR="http://vault-vault-contour.vault.svc:8200" JWT="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" VAULT_TOKEN="$(curl -sS --request POST \ --data "{\"role\":\"minio\",\"jwt\":\"${JWT}\"}" \ "${VAULT_ADDR}/v1/auth/kubernetes/login" | jq -r '.auth.client_token')" [ -n "${VAULT_TOKEN}" ] && [ "${VAULT_TOKEN}" != "null" ] admin_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/minio/admin")" root_user="$(echo "${admin_json}" | jq -r '.data.data.rootUser')" root_pass="$(echo "${admin_json}" | jq -r '.data.data.rootPassword')" /usr/local/bin/mc alias set local http://minio.minio.svc.cluster.local:9000 "${root_user}" "${root_pass}" list_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/metadata/minio/apps?list=true")" for app in $(echo "${list_json}" | jq -r '.data.keys[]?' | sed 's#/$##'); do app_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/minio/apps/${app}")" username="$(echo "${app_json}" | jq -r '.data.data.username')" password="$(echo "${app_json}" | jq -r '.data.data.password')" [ -z "${username}" ] && username="${app}" [ -z "${password}" ] && continue /usr/local/bin/mc admin user add local "${username}" "${password}" >/dev/null 2>&1 || true /usr/local/bin/mc admin user enable local "${username}" >/dev/null 2>&1 || true done --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role metadata: name: kafka-bootstrap-exec namespace: kafka rules: - apiGroups: [""] resources: ["pods"] verbs: ["get", "list"] - apiGroups: [""] resources: ["pods/exec"] verbs: ["create", "get"] --- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: kafka-bootstrap-exec namespace: kafka subjects: - kind: ServiceAccount name: kafka-kafka-contour namespace: kafka roleRef: apiGroup: rbac.authorization.k8s.io kind: Role name: kafka-bootstrap-exec --- apiVersion: batch/v1 kind: CronJob metadata: name: kafka-apps-bootstrap namespace: kafka spec: schedule: "*/10 * * * *" successfulJobsHistoryLimit: 1 failedJobsHistoryLimit: 2 concurrencyPolicy: Forbid jobTemplate: spec: template: spec: restartPolicy: OnFailure serviceAccountName: kafka-kafka-contour containers: - name: bootstrap image: alpine:3.20 command: ["/bin/sh", "-ec"] args: - | apk add --no-cache bash curl jq kubectl >/dev/null VAULT_ADDR="http://vault-vault-contour.vault.svc:8200" JWT="$(cat /var/run/secrets/kubernetes.io/serviceaccount/token)" VAULT_TOKEN="$(curl -sS --request POST \ --data "{\"role\":\"kafka\",\"jwt\":\"${JWT}\"}" \ "${VAULT_ADDR}/v1/auth/kubernetes/login" | jq -r '.auth.client_token')" [ -n "${VAULT_TOKEN}" ] && [ "${VAULT_TOKEN}" != "null" ] bootstrap_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/kafka/bootstrap")" inter_broker_password="$(echo "${bootstrap_json}" | jq -r '.data.data.interBrokerPassword')" list_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/metadata/kafka/apps?list=true")" target_pod="$(kubectl -n kafka get pod -l app.kubernetes.io/component=controller -o jsonpath='{.items[0].metadata.name}')" for app in $(echo "${list_json}" | jq -r '.data.keys[]?' | sed 's#/$##'); do app_json="$(curl -sS -H "X-Vault-Token: ${VAULT_TOKEN}" "${VAULT_ADDR}/v1/secrets/data/kafka/apps/${app}")" username="$(echo "${app_json}" | jq -r '.data.data.username')" password="$(echo "${app_json}" | jq -r '.data.data.password')" [ -z "${username}" ] && username="${app}" [ -z "${password}" ] && continue kubectl -n kafka exec "${target_pod}" -c kafka -- /bin/bash -lc "\ cat >/tmp/admin.properties </dev/null done