From 14e52f29b0b38cbaf2d04167375e69c9141f98d4 Mon Sep 17 00:00:00 2001 From: asoria-lf <115982586+asoria-lf@users.noreply.github.com> Date: Sun, 13 Nov 2022 18:28:07 +0100 Subject: [PATCH] helm: Add new job to create service accounts (#15939) --- helm/minio/README.md | 16 +++ .../templates/_helper_create_svcacct.txt | 97 +++++++++++++++ helm/minio/templates/_helper_create_user.txt | 2 +- helm/minio/templates/configmap.yaml | 2 + .../post-install-create-svcacct-job.yaml | 111 ++++++++++++++++++ .../post-install-create-user-job.yaml | 2 +- helm/minio/values.yaml | 44 ++++++- 7 files changed, 266 insertions(+), 8 deletions(-) create mode 100644 helm/minio/templates/_helper_create_svcacct.txt create mode 100644 helm/minio/templates/post-install-create-svcacct-job.yaml diff --git a/helm/minio/README.md b/helm/minio/README.md index b3812d43d..b4256e4cb 100644 --- a/helm/minio/README.md +++ b/helm/minio/README.md @@ -219,6 +219,22 @@ Description of the configuration parameters used above - - `users[].existingSecretKey` - data key in existingSecret secret containing the secretKey - `users[].policy` - name of the policy to assign to user +### Create service account after install + +Install the chart, specifying the service accounts you want to create after install: + +```bash +helm install --set svcaccts[0].accessKey=accessKey,svcaccts[0].secretKey=secretKey,svcaccts[0].user=parentUser,svcaccts[1].accessKey=accessKey2,svcaccts[1].secretRef=existingSecret,svcaccts[1].secretKey=password,svcaccts[1].user=parentUser2 minio/minio +``` + +Description of the configuration parameters used above - + +- `svcaccts[].accessKey` - accessKey of service account +- `svcaccts[].secretKey` - secretKey of svcacctsecretRef +- `svcaccts[].existingSecret` - secret name that contains the secretKey of service account +- `svcaccts[].existingSecretKey` - data key in existingSecret secret containing the secretKey +- `svcaccts[].user` - name of the parent user to assign to service account + ## Uninstalling the Chart Assuming your release is named as `my-release`, delete it using the command: diff --git a/helm/minio/templates/_helper_create_svcacct.txt b/helm/minio/templates/_helper_create_svcacct.txt new file mode 100644 index 000000000..99f5fb053 --- /dev/null +++ b/helm/minio/templates/_helper_create_svcacct.txt @@ -0,0 +1,97 @@ +#!/bin/sh +set -e ; # Have script exit in the event of a failed command. + +{{- if .Values.configPathmc }} +MC_CONFIG_DIR="{{ .Values.configPathmc }}" +MC="/usr/bin/mc --insecure --config-dir ${MC_CONFIG_DIR}" +{{- else }} +MC="/usr/bin/mc --insecure" +{{- end }} + +# AccessKey and secretkey credentials file are added to prevent shell execution errors caused by special characters. +# Special characters for example : ',",<,>,{,} +MINIO_ACCESSKEY_SECRETKEY_TMP="/tmp/accessKey_and_secretKey_svcacct_tmp" + +# connectToMinio +# Use a check-sleep-check loop to wait for MinIO service to be available +connectToMinio() { + SCHEME=$1 + ATTEMPTS=0 ; LIMIT=29 ; # Allow 30 attempts + set -e ; # fail if we can't read the keys. + ACCESS=$(cat /config/rootUser) ; SECRET=$(cat /config/rootPassword) ; + set +e ; # The connections to minio are allowed to fail. + echo "Connecting to MinIO server: $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT" ; + MC_COMMAND="${MC} alias set myminio $SCHEME://$MINIO_ENDPOINT:$MINIO_PORT $ACCESS $SECRET" ; + $MC_COMMAND ; + STATUS=$? ; + until [ $STATUS = 0 ] + do + ATTEMPTS=`expr $ATTEMPTS + 1` ; + echo \"Failed attempts: $ATTEMPTS\" ; + if [ $ATTEMPTS -gt $LIMIT ]; then + exit 1 ; + fi ; + sleep 2 ; # 2 second intervals between attempts + $MC_COMMAND ; + STATUS=$? ; + done ; + set -e ; # reset `e` as active + return 0 +} + +# checkSvcacctExists () +# Check if the svcacct exists, by using the exit code of `mc admin user svcacct info` +checkSvcacctExists() { + CMD=$(${MC} admin user svcacct info myminio $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) > /dev/null 2>&1) + return $? +} + +# createSvcacct ($user) +createSvcacct () { + USER=$1 + #check accessKey_and_secretKey_tmp file + if [[ ! -f $MINIO_ACCESSKEY_SECRETKEY_TMP ]];then + echo "credentials file does not exist" + return 1 + fi + if [[ $(cat $MINIO_ACCESSKEY_SECRETKEY_TMP|wc -l) -ne 2 ]];then + echo "credentials file is invalid" + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP + return 1 + fi + SVCACCT=$(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) + # Create the svcacct if it does not exist + if ! checkSvcacctExists ; then + echo "Creating svcacct '$SVCACCT'" + ${MC} admin user svcacct add --access-key $(head -1 $MINIO_ACCESSKEY_SECRETKEY_TMP) --secret-key $(tail -n1 $MINIO_ACCESSKEY_SECRETKEY_TMP) myminio $USER + else + echo "Svcacct '$SVCACCT' already exists." + fi + #clean up credentials files. + rm -f $MINIO_ACCESSKEY_SECRETKEY_TMP +} + +# Try connecting to MinIO instance +{{- if .Values.tls.enabled }} +scheme=https +{{- else }} +scheme=http +{{- end }} +connectToMinio $scheme + +{{ if .Values.svcaccts }} +{{ $global := . }} +# Create the svcaccts +{{- range .Values.svcaccts }} +echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP +{{- if .existingSecret }} +cat /config/secrets/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +# Add a new line if it doesn't exist +sed -i '$a\' $MINIO_ACCESSKEY_SECRETKEY_TMP +createSvcacct {{ .user }} +{{ else }} +echo {{ .secretKey }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +createSvcacct {{ .user }} +{{- end }} +{{- end }} +{{- end }} diff --git a/helm/minio/templates/_helper_create_user.txt b/helm/minio/templates/_helper_create_user.txt index ea2b3b675..324bc9d48 100644 --- a/helm/minio/templates/_helper_create_user.txt +++ b/helm/minio/templates/_helper_create_user.txt @@ -93,7 +93,7 @@ connectToMinio $scheme {{- range .Values.users }} echo {{ tpl .accessKey $global }} > $MINIO_ACCESSKEY_SECRETKEY_TMP {{- if .existingSecret }} -cat /config/secrets/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP +cat /config/secrets/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} >> $MINIO_ACCESSKEY_SECRETKEY_TMP # Add a new line if it doesn't exist sed -i '$a\' $MINIO_ACCESSKEY_SECRETKEY_TMP createUser {{ .policy }} diff --git a/helm/minio/templates/configmap.yaml b/helm/minio/templates/configmap.yaml index 95a7c6038..524f191a6 100644 --- a/helm/minio/templates/configmap.yaml +++ b/helm/minio/templates/configmap.yaml @@ -20,5 +20,7 @@ data: policy_{{ $idx }}.json: |- {{ include (print $.Template.BasePath "/_helper_policy.tpl") . | indent 4 }} {{ end }} + add-svcacct: |- +{{ include (print $.Template.BasePath "/_helper_create_svcacct.txt") . | indent 4 }} custom-command: |- {{ include (print $.Template.BasePath "/_helper_custom_command.txt") . | indent 4 }} diff --git a/helm/minio/templates/post-install-create-svcacct-job.yaml b/helm/minio/templates/post-install-create-svcacct-job.yaml new file mode 100644 index 000000000..ddda34b72 --- /dev/null +++ b/helm/minio/templates/post-install-create-svcacct-job.yaml @@ -0,0 +1,111 @@ +{{- $global := . -}} +{{- if .Values.svcaccts }} +apiVersion: batch/v1 +kind: Job +metadata: + name: {{ template "minio.fullname" . }}-make-svcacct-job + namespace: {{ .Release.Namespace | quote }} + labels: + app: {{ template "minio.name" . }}-make-svcacct-job + chart: {{ template "minio.chart" . }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + "helm.sh/hook": post-install,post-upgrade + "helm.sh/hook-delete-policy": hook-succeeded,before-hook-creation +{{- with .Values.makeServiceAccountJob.annotations }} +{{ toYaml . | indent 4 }} +{{- end }} +spec: + template: + metadata: + labels: + app: {{ template "minio.name" . }}-job + release: {{ .Release.Name }} +{{- if .Values.podLabels }} +{{ toYaml .Values.podLabels | indent 8 }} +{{- end }} +{{- if .Values.makeServiceAccountJob.podAnnotations }} + annotations: +{{ toYaml .Values.makeServiceAccountJob.podAnnotations | indent 8 }} +{{- end }} + spec: + restartPolicy: OnFailure +{{- include "minio.imagePullSecrets" . | indent 6 }} +{{- if .Values.nodeSelector }} + nodeSelector: +{{ toYaml .Values.makeServiceAccountJob.nodeSelector | indent 8 }} +{{- end }} +{{- with .Values.makeServiceAccountJob.affinity }} + affinity: +{{ toYaml . | indent 8 }} +{{- end }} +{{- with .Values.makeServiceAccountJob.tolerations }} + tolerations: +{{ toYaml . | indent 8 }} +{{- end }} +{{- if .Values.makeServiceAccountJob.securityContext.enabled }} + securityContext: + runAsUser: {{ .Values.makeServiceAccountJob.securityContext.runAsUser }} + runAsGroup: {{ .Values.makeServiceAccountJob.securityContext.runAsGroup }} + fsGroup: {{ .Values.makeServiceAccountJob.securityContext.fsGroup }} +{{- end }} + volumes: + - name: minio-configuration + projected: + sources: + - configMap: + name: {{ template "minio.fullname" . }} + - secret: + name: {{ template "minio.secretName" . }} + {{- range .Values.svcaccts }} + {{- if .existingSecret }} + - secret: + name: {{ tpl .existingSecret $global }} + items: + - key: {{ .existingSecretKey }} + path: secrets/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} + {{- end }} + {{- end }} + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + secret: + secretName: {{ .Values.tls.certSecret }} + items: + - key: {{ .Values.tls.publicCrt }} + path: CAs/public.crt + {{ end }} + {{- if .Values.makeServiceAccountJob.extraVolumes }} + {{- toYaml .Values.makeServiceAccountJob.extraVolumes | nindent 8 }} + {{- end }} +{{ if .Values.serviceAccount.create }} + serviceAccountName: {{ .Values.serviceAccount.name }} +{{- end }} + containers: + - name: minio-mc + image: "{{ .Values.mcImage.repository }}:{{ .Values.mcImage.tag }}" + imagePullPolicy: {{ .Values.mcImage.pullPolicy }} + {{- if .Values.makeServiceAccountJob.exitCommand }} + command: ["/bin/sh", "-c"] + args: ["/bin/sh /config/add-svcacct; x=$(echo $?); {{ .Values.makeServiceAccountJob.exitCommand }} && exit $x" ] + {{- else }} + command: ["/bin/sh", "/config/add-svcacct"] + {{- end }} + env: + - name: MINIO_ENDPOINT + value: {{ template "minio.fullname" . }} + - name: MINIO_PORT + value: {{ .Values.service.port | quote }} + volumeMounts: + - name: minio-configuration + mountPath: /config + {{- if .Values.tls.enabled }} + - name: cert-secret-volume-mc + mountPath: {{ .Values.configPathmc }}certs + {{ end }} + {{- if .Values.makeServiceAccountJob.extraVolumeMounts }} + {{- toYaml .Values.makeServiceAccountJob.extraVolumeMounts | nindent 10 }} + {{- end }} + resources: +{{ toYaml .Values.makeServiceAccountJob.resources | indent 10 }} +{{- end }} diff --git a/helm/minio/templates/post-install-create-user-job.yaml b/helm/minio/templates/post-install-create-user-job.yaml index 8ccc6c000..01e0dba9c 100644 --- a/helm/minio/templates/post-install-create-user-job.yaml +++ b/helm/minio/templates/post-install-create-user-job.yaml @@ -64,7 +64,7 @@ spec: name: {{ tpl .existingSecret $global }} items: - key: {{ .existingSecretKey }} - path: secrets/{{ tpl .existingSecretKey $global }} + path: secrets/{{ tpl .existingSecret $global }}/{{ tpl .existingSecretKey $global }} {{- end }} {{- end }} {{- if .Values.tls.enabled }} diff --git a/helm/minio/values.yaml b/helm/minio/values.yaml index 9b318c072..34d120d08 100644 --- a/helm/minio/values.yaml +++ b/helm/minio/values.yaml @@ -351,7 +351,6 @@ users: # existingSecretKey: password # policy: readonly - ## Additional Annotations for the Kubernetes Job makeUserJob makeUserJob: podAnnotations: {} @@ -372,6 +371,39 @@ makeUserJob: # Command to run after the main command on exit exitCommand: "" +## List of service accounts to be created after minio install +## +# svcaccts: + ## accessKey, secretKey and parent user to be assigned to the service accounts + ## Add new service accounts as explained here https://min.io/docs/minio/kubernetes/upstream/administration/identity-access-management/minio-user-management.html#service-accounts + # - accessKey: console-svcacct + # secretKey: console123 + # user: console + ## Or you can refer to specific secret + # - accessKey: externalSecret + # existingSecret: my-secret + # existingSecretKey: password + # user: console + +makeServiceAccountJob: + podAnnotations: {} + annotations: {} + securityContext: + enabled: false + runAsUser: 1000 + runAsGroup: 1000 + fsGroup: 1000 + resources: + requests: + memory: 128Mi + nodeSelector: {} + tolerations: [] + affinity: {} + extraVolumes: [] + extraVolumeMounts: [] + # Command to run after the main command on exit + exitCommand: "" + ## List of buckets to be created after minio install ## buckets: @@ -386,14 +418,14 @@ buckets: # # bucket [true|false] # versioning: false # # set objectlocking for - # # bucket [true|false] NOTE: versioning is enabled by default if you use locking + # # bucket [true|false] NOTE: versioning is enabled by default if you use locking # objectlocking: false # - name: bucket2 # policy: none # purge: false # versioning: true # # set objectlocking for - # # bucket [true|false] NOTE: versioning is enabled by default if you use locking + # # bucket [true|false] NOTE: versioning is enabled by default if you use locking # objectlocking: false ## Additional Annotations for the Kubernetes Job makeBucketJob @@ -415,7 +447,7 @@ makeBucketJob: extraVolumeMounts: [] # Command to run after the main command on exit exitCommand: "" - + ## List of command to run after minio install ## NOTE: the mc command TARGET is always "myminio" customCommands: @@ -438,7 +470,7 @@ customCommandJob: affinity: {} # Command to run after the main command on exit exitCommand: "" - + ## Use this field to add environment variables relevant to MinIO server. These fields will be passed on to MinIO container(s) ## when Chart is deployed environment: @@ -490,7 +522,7 @@ metrics: serviceMonitor: enabled: false # scrape each node/pod individually for additional metrics - includeNode: false + includeNode: false public: true additionalLabels: {} # for node metrics