diff --git a/couchdb/scripts/init.sh b/couchdb/scripts/init.sh new file mode 100755 index 0000000..9900375 --- /dev/null +++ b/couchdb/scripts/init.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env sh +set -eo pipefail +# need to build a .netrc file in our RAM disk (/tmp) in such a way credentials do not leak to the process table +# netrc has the format of 'machine login password ' + +# slice the port from couch address off so netrc matching works +echo -n "machine $COUCHDB_ADDRESS" | cut -d':' -f1 >> /tmp/.netrc +echo -n " login " >> /tmp/.netrc +# cat the contents of the secret file, strip any new lines, redirect the output to be appended to the .netrc file +cat $COUCHDB_ADMIN_PATH | tr -d '\n' >> /tmp/.netrc +echo -n " password " >> /tmp/.netrc +cat $COUCHDB_PASS_PATH | tr -d '\n' >> /tmp/.netrc + +set -x + +curl --netrc-file /tmp/.netrc --fail -s http://$COUCHDB_ADDRESS/_cluster_setup -X POST -H "Content-Type: application/json" -d "{\"action\": \"finish_cluster\"}" +export IFS="," +for db_name in $DEFAULT_DBS +do + curl --netrc-file /tmp/.netrc --fail -X PUT http://$COUCHDB_ADDRESS/$db_name +done diff --git a/couchdb/templates/job.yaml b/couchdb/templates/job.yaml index 544955b..fd1dd1e 100644 --- a/couchdb/templates/job.yaml +++ b/couchdb/templates/job.yaml @@ -1,9 +1,36 @@ {{- if .Values.autoSetup -}} {{- if and .Values.autoSetup.enabled .Values.service.enabled -}} +{{- $adminUserPath := "/var/opt/couchdb/admin_user" -}} +{{- $adminUserSecretKey := "adminUsername" -}} +{{- $adminPassPath := "/var/opt/couchdb/admin_pass" -}} +{{- $adminPassSecretKey := "adminPassword" -}} +{{- $initScriptPath := "/var/opt/couchdb/init.sh" -}} +{{- if .Values.enableSecretsAsFiles }} +--- +apiVersion: v1 +kind: ConfigMap +metadata: + name: {{ .Release.Name }}-init-scripts + namespace: {{ .Release.Namespace }} + labels: + app: {{ template "couchdb.name" . }} + chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} + release: {{ .Release.Name }} + heritage: {{ .Release.Service }} + annotations: + "helm.sh/hook": post-install + "helm.sh/resource-policy": delete + "helm.sh/hook-weight": "1" + "helm.sh/hook-delete-policy": "before-hook-creation" +data: +{{ (.Files.Glob "scripts/*").AsConfig | indent 2 }} +{{- end }} +--- apiVersion: batch/v1 kind: Job metadata: name: "{{ .Release.Name }}-post-install" + namespace: "{{ .Release.Namespace }}" labels: app.kubernetes.io/managed-by: {{ .Release.Service | quote }} app.kubernetes.io/instance: {{ .Release.Name | quote }} @@ -11,6 +38,9 @@ metadata: helm.sh/chart: {{ .Chart.Name }}-{{ .Chart.Version | replace "+" "_" }} annotations: "helm.sh/hook": post-install + "helm.sh/resource-policy": delete + "helm.sh/hook-weight": "2" + "helm.sh/hook-delete-policy": "before-hook-creation" spec: template: metadata: @@ -24,6 +54,23 @@ spec: {{- if .Values.podSecurityContext }} securityContext: {{ .Values.podSecurityContext | toYaml | nindent 8 }} {{- end }} + {{- if .Values.enableSecretsAsFiles }} + volumes: + - name: couchdb-admin-credentials + secret: + secretName: {{ template "couchdb.fullname" . }} + - name: tmp + emptyDir: + sizeLimit: 1Mi + medium: 'Memory' + - name: couchdb-init-scripts + configMap: + name: "{{ .Release.Name }}-init-scripts" + items: + - key: init.sh + path: init.sh + mode: 0755 + {{- end }} containers: - name: cluster-setup image: {{ .Values.autoSetup.image.repository }}:{{ .Values.autoSetup.image.tag }} @@ -31,26 +78,55 @@ spec: command: - 'sh' - '-c' + {{- if not .Values.enableSecretsAsFiles }} - 'curl -s http://$COUCHDB_ADDRESS/_cluster_setup -X POST -H "Content-Type: application/json" -d "{\"action\": \"finish_cluster\"}" -u $COUCHDB_ADMIN:$COUCHDB_PASS && export IFS=","; for db_name in $DEFAULT_DBS; do curl -X PUT http://$COUCHDB_ADDRESS/$db_name -u $COUCHDB_ADMIN:$COUCHDB_PASS; done' + {{- else }} + - '$COUCHDB_INIT_SCRIPT_PATH' + {{- end }} + {{- if .Values.enableSecretsAsFiles }} + volumeMounts: + - name: couchdb-admin-credentials + readOnly: true + mountPath: {{ $adminUserPath }} + subPath: {{ $adminUserSecretKey }} + - name: couchdb-admin-credentials + readOnly: true + mountPath: {{ $adminPassPath }} + subPath: {{ $adminPassSecretKey }} + - name: couchdb-init-scripts + mountPath: {{ $initScriptPath }} + subPath: init.sh + - name: tmp + mountPath: /tmp + {{- end }} env: - name: DEFAULT_DBS value: {{ join "," .Values.autoSetup.defaultDatabases }} - name: COUCHDB_ADDRESS value: "{{ template "couchdb.svcname" . }}.{{ .Release.Namespace }}.svc.{{ default "cluster.local" .Values.dns.clusterDomainSuffix }}:{{ .Values.service.externalPort}}" + {{- if not .Values.enableSecretsAsFiles }} - name: COUCHDB_ADMIN valueFrom: secretKeyRef: name: {{ template "couchdb.fullname" . }} - key: adminUsername + key: {{ $adminUserSecretKey}} - name: COUCHDB_PASS valueFrom: secretKeyRef: name: {{ template "couchdb.fullname" . }} - key: adminPassword + key: {{ $adminPassSecretKey}} + {{- else }} + - name: COUCHDB_ADMIN_PATH + value: {{ $adminUserPath }} + - name: COUCHDB_PASS_PATH + value: {{ $adminPassPath }} + - name: COUCHDB_INIT_SCRIPT_PATH + value: {{ $initScriptPath }} + {{- end }} {{- if .Values.containerSecurityContext }} securityContext: {{ .Values.containerSecurityContext | toYaml | nindent 12 }} {{- end }} - backoffLimit: 2 - ttlSecondsAfterFinished: 600 + backoffLimit: {{ .Values.autoSetup.backoffLimit }} + ttlSecondsAfterFinished: {{ .Values.autoSetup.ttlSecondsAfterFinished }} {{- end -}} {{- end -}} diff --git a/couchdb/values.yaml b/couchdb/values.yaml index cf4b5ce..8def9d4 100644 --- a/couchdb/values.yaml +++ b/couchdb/values.yaml @@ -16,7 +16,11 @@ allowAdminParty: false # a valid adminPassword in the secret. Also set the --wait flag when you install to # avoid first jobs failure (helm install --wait ...) autoSetup: - enabled: false + enabled: true + # -- how many attempts the job will make to complete successfully + backoffLimit: 2 + # -- how many seconds the resource sticks around after completion + ttlSecondsAfterFinished: 600 image: repository: curlimages/curl tag: latest @@ -100,6 +104,9 @@ searchImage: # -- Flip this to flag to include the Search container in each Pod enableSearch: false +# -- Flip this flag to project secrets as files instead of as environment variables +enableSecretsAsFiles: true + initImage: repository: busybox tag: latest @@ -210,8 +217,8 @@ erlangFlags: # by a ConfigMap object. # ref: http://docs.couchdb.org/en/latest/config/index.html couchdbConfig: - # couchdb: - # uuid: decafbaddecafbaddecafbaddecafbad # Unique identifier for this CouchDB server instance + couchdb: + uuid: decafbaddecafbaddecafbaddecafbad # Unique identifier for this CouchDB server instance # cluster: # q: 8 # Create 8 shards for each database chttpd: