From 8540d8a1207f838fc302468de53d8043a7b4609a Mon Sep 17 00:00:00 2001 From: Cole Arendt Date: Tue, 10 May 2022 06:28:37 -0400 Subject: [PATCH] allow uuid being created and managed by kubernetes We utilize Helm's `lookup` command to store a generated `uuid` in an "internal" secret in Kubernetes. This allows generating the `uuid`, making it persistent, and notifying the user (in `NOTES.txt`) that this auto-generation happened. We also tell the user how to disable the message by making that value persistent in values. close #39 --- couchdb/Chart.yaml | 2 +- couchdb/NEWS.md | 7 ++++ couchdb/README.md | 61 ++++++++++----------------------- couchdb/ci/required-values.yaml | 3 -- couchdb/templates/NOTES.txt | 11 ++++++ couchdb/templates/_helpers.tpl | 32 +++++++++++++---- couchdb/templates/secrets.yaml | 15 +++++++- 7 files changed, 77 insertions(+), 54 deletions(-) diff --git a/couchdb/Chart.yaml b/couchdb/Chart.yaml index a2ad72f..1015f31 100644 --- a/couchdb/Chart.yaml +++ b/couchdb/Chart.yaml @@ -1,6 +1,6 @@ apiVersion: v1 name: couchdb -version: 4.6.3 +version: 4.6.4 appVersion: 3.5.1 description: A database featuring seamless multi-master sync, that scales from big data to mobile, with an intuitive HTTP/JSON API and designed for diff --git a/couchdb/NEWS.md b/couchdb/NEWS.md index 050f9c4..633ff43 100644 --- a/couchdb/NEWS.md +++ b/couchdb/NEWS.md @@ -1,12 +1,19 @@ # NEWS +## 4.6.4 + +- Auto-generate `couchdbConfig.couchdb.uuid` value on install + ## 4.6.3 + - Update default CouchDB version to 3.5.1 ## 4.6.2 + - Added options to specify `erlangCookie` and `cookieAuthSecret` within the extra secret ## 4.6.1 + - Update default CouchDB version to 3.5.0 ## 4.5.7 diff --git a/couchdb/README.md b/couchdb/README.md index 4a2cf65..a11bd4b 100644 --- a/couchdb/README.md +++ b/couchdb/README.md @@ -16,11 +16,10 @@ storage volumes to each Pod in the Deployment. ## TL;DR ```bash -$ helm repo add couchdb https://apache.github.io/couchdb-helm -$ helm install couchdb/couchdb \ - --version=4.6.3 \ - --set allowAdminParty=true \ - --set couchdbConfig.couchdb.uuid=$(curl https://www.uuidgenerator.net/api/version4 2>/dev/null | tr -d -) +helm repo add couchdb https://apache.github.io/couchdb-helm +helm install couchdb/couchdb \ + --version=4.6.4 \ + --set allowAdminParty=true ``` ## Prerequisites @@ -35,17 +34,10 @@ To install the chart with the release name `my-release`: Add the CouchDB Helm repository: ```bash -$ helm repo add couchdb https://apache.github.io/couchdb-helm -``` - -Afterwards install the chart replacing the UUID -`decafbaddecafbaddecafbaddecafbad` with a custom one: - -```bash -$ helm install \ +helm repo add couchdb https://apache.github.io/couchdb-helm +helm install \ --name my-release \ - --version=4.6.3 \ - --set couchdbConfig.couchdb.uuid=decafbaddecafbaddecafbaddecafbad \ + --version=4.6.4 \ couchdb/couchdb ``` @@ -53,21 +45,21 @@ This will create a Secret containing the admin credentials for the cluster. Those credentials can be retrieved as follows: ```bash -$ kubectl get secret my-release-couchdb -o go-template='{{ .data.adminPassword }}' | base64 --decode +kubectl get secret my-release-couchdb -o go-template='{{ .data.adminPassword }}' | base64 --decode ``` If you prefer to configure the admin credentials directly you can create a -Secret containing `adminUsername`, `adminPassword` and `cookieAuthSecret` keys: +Secret containing `adminUsername`, `adminPassword`, `cookieAuthSecret` and `erlangCookie` keys: ```bash -$ kubectl create secret generic my-release-couchdb --from-literal=adminUsername=foo --from-literal=adminPassword=bar --from-literal=cookieAuthSecret=baz +kubectl create secret generic my-release-couchdb --from-literal=adminUsername=foo --from-literal=adminPassword=bar --from-literal=cookieAuthSecret=baz --from-literal=cookieAuthSecret=beep ``` If you want to set the `adminHash` directly to achieve consistent salts between different nodes you need to add it to the secret: ```bash -$ kubectl create secret generic my-release-couchdb \ +kubectl create secret generic my-release-couchdb \ --from-literal=adminUsername=foo \ --from-literal=cookieAuthSecret=baz \ --from-literal=adminHash=-pbkdf2-d4b887da.... @@ -76,11 +68,10 @@ $ kubectl create secret generic my-release-couchdb \ and then install the chart while overriding the `createAdminSecret` setting: ```bash -$ helm install \ +helm install \ --name my-release \ - --version=4.6.3 \ + --version=4.6.4 \ --set createAdminSecret=false \ - --set couchdbConfig.couchdb.uuid=decafbaddecafbaddecafbaddecafbad \ couchdb/couchdb ``` @@ -95,7 +86,7 @@ the parameters that can be configured during installation. To uninstall/delete the `my-release` Deployment: ```bash -$ helm delete my-release +helm delete my-release ``` The command removes all the Kubernetes components associated with the chart and @@ -106,20 +97,6 @@ deletes the release. A major chart version change (like v0.2.3 -> v1.0.0) indicates that there is an incompatible breaking change needing manual actions. -### Upgrade to 3.0.0 - -Since version 3.0.0 setting the CouchDB server instance UUID is mandatory. -Therefore, you need to generate a UUID and supply it as a value during the -upgrade as follows: - -```bash -$ helm upgrade \ - --version=3.6.4 \ - --reuse-values \ - --set couchdbConfig.couchdb.uuid= \ - couchdb/couchdb -``` - ### Upgrade to 4.0.0 Breaking change between v3 and v4 is the `adminHash` in the secret that no longer uses @@ -132,8 +109,8 @@ This chart replaces the `stable/couchdb` chart previously hosted by Helm and con version semantics. You can upgrade directly from `stable/couchdb` to this chart using: ```bash -$ helm repo add couchdb https://apache.github.io/couchdb-helm -$ helm upgrade my-release --version=4.6.3 couchdb/couchdb +helm repo add couchdb https://apache.github.io/couchdb-helm +helm upgrade my-release --version=4.6.4 couchdb/couchdb ``` ## Configuration @@ -143,10 +120,10 @@ CouchDB chart and their default values: | Key | Type | Default | Description | |-----|------|---------|-------------| -| allowAdminParty | bool | `false` | If allowAdminParty is enabled the cluster will start up without any database administrator account; i.e., all users will be granted administrative access. Otherwise, the system will look for a Secret called -couchdb containing `adminUsername`, `adminPassword` and `cookieAuthSecret` keys. See the `createAdminSecret` flag. ref: https://kubernetes.io/docs/concepts/configuration/secret/ | +| allowAdminParty | bool | `false` | If allowAdminParty is enabled the cluster will start up without any database administrator account; i.e., all users will be granted administrative access. Otherwise, the system will look for a Secret called -couchdb containing `adminUsername`, `adminPassword`, `cookieAuthSecret`, and `erlangCookie` keys. See the `createAdminSecret` flag. ref: https://kubernetes.io/docs/concepts/configuration/secret/ | | clusterSize | int | `3` | the initial number of nodes in the CouchDB cluster. | | couchdbConfig | object | `{"chttpd":{"bind_address":"any","require_valid_user":false}}` | couchdbConfig will override default CouchDB configuration settings. The contents of this map are reformatted into a .ini file laid down by a ConfigMap object. ref: http://docs.couchdb.org/en/latest/config/index.html | -| createAdminSecret | bool | `true` | If createAdminSecret is enabled a Secret called -couchdb will be created containing auto-generated credentials. Users who prefer to set these values themselves have a couple of options: 1) The `adminUsername`, `adminPassword`, `adminHash`, and `cookieAuthSecret` can be defined directly in the chart's values. Note that all of a chart's values are currently stored in plaintext in a ConfigMap in the tiller namespace. 2) This flag can be disabled and a Secret with the required keys can be created ahead of time. | +| createAdminSecret | bool | `true` | If createAdminSecret is enabled a Secret called -couchdb will be created containing auto-generated credentials. Users who prefer to set these values themselves have a couple of options: 1) The `adminUsername`, `adminPassword`, `adminHash` and `cookieAuthSecret` can be defined directly in the chart's values. Note that all of a chart's values are currently stored in plaintext in a ConfigMap in the tiller namespace. 2) This flag can be disabled and a Secret with the required keys can be created ahead of time. | | enableSearch | bool | `false` | Flip this to flag to include the Search container in each Pod | | erlangFlags | object | `{"name":"couchdb"}` | erlangFlags is a map that is passed to the Erlang VM as flags using the ERL_FLAGS env. The `name` flag is required to establish connectivity between cluster nodes. ref: http://erlang.org/doc/man/erl.html#init_flags | | persistentVolume | object | `{"accessModes":["ReadWriteOnce"],"enabled":false,"size":"10Gi"}` | The storage volume used by each Pod in the StatefulSet. If a persistentVolume is not enabled, the Pods will use `emptyDir` ephemeral local storage. Setting the storageClass attribute to "-" disables dynamic provisioning of Persistent Volumes; leaving it unset will invoke the default provisioner. | @@ -157,7 +134,7 @@ required options to set: | Parameter | Description | Default | |---------------------------------|--------------------------------------------------------------------|----------------------------------------| -| `couchdb.uuid` | UUID for this CouchDB server instance ([Required in a cluster][5]) | | +| `couchdb.uuid` | UUID for this CouchDB server instance | auto-generated | | `chttpd.bind_address` | listens on all interfaces when set to any | any | | `chttpd.require_valid_user` | disables all the anonymous requests to the port 5984 when true | false | diff --git a/couchdb/ci/required-values.yaml b/couchdb/ci/required-values.yaml index 15b64b9..9f553b1 100644 --- a/couchdb/ci/required-values.yaml +++ b/couchdb/ci/required-values.yaml @@ -1,5 +1,2 @@ -couchdbConfig: - couchdb: - uuid: "decafbaddecafbaddecafbaddecafbad" annotations: foo: bar diff --git a/couchdb/templates/NOTES.txt b/couchdb/templates/NOTES.txt index 7a9dccd..95c239f 100644 --- a/couchdb/templates/NOTES.txt +++ b/couchdb/templates/NOTES.txt @@ -30,3 +30,14 @@ NOTE: You are using an auto-generated value for the Erlang Cookie kubectl -n {{ $.Release.Namespace }} get secret {{ include "couchdb.fullname" . }} --template='{{print "{{" }}index .data "erlangCookie" | base64decode{{ print "}}" }}' ``` {{- end }} + +{{- $uuidVar := index (.Values.couchdbConfig.couchdb | default dict) "uuid" -}} +{{- if (empty $uuidVar) }} +NOTE: You are using an auto-generated value for the Couch DB UUID + - We recommend making this value persistent by setting it in: `couchdbConfig.couchdb.uuid` + - Changing this value can cause problems for the Couch DB installation + - You can get the current value with: +``` +kubectl -n {{ $.Release.Namespace }} get secret {{ include "couchdb.fullname" . }}-internal --template='{{print "{{" }}index .data "uuid" | base64decode{{ print "}}" }}' +``` +{{- end }} diff --git a/couchdb/templates/_helpers.tpl b/couchdb/templates/_helpers.tpl index e33f85c..44ef93a 100644 --- a/couchdb/templates/_helpers.tpl +++ b/couchdb/templates/_helpers.tpl @@ -94,13 +94,6 @@ If serviceAccount.name is specified, use that, else use the couchdb instance nam {{- end -}} {{- end -}} -{{/* -Fail if couchdbConfig.couchdb.uuid is undefined -*/}} -{{- define "couchdb.uuid" -}} -{{- required "A value for couchdbConfig.couchdb.uuid must be set" (.Values.couchdbConfig.couchdb | default dict).uuid -}} -{{- end -}} - {{/* Repurpose volume claim metadata whether using the new volume claim template or existing volume claims. @@ -143,3 +136,28 @@ storageClassName: "{{ $context.Values.persistentVolume.storageClass }}" volumeName: {{ $claim.persistentVolumeName }} {{- end }} {{- end -}} + +{{/* + If couchdb UUID value is undefined: + - if the configmap already exists, look it up + - if not found or "dangerRegenerateAutomatedValues" is set, generate it + - otherwise use the previous value + Otherwise use what is defined in the chart + + Also warn in NOTES.txt if this value is not persistent +*/}} +{{- define "couchdb.uuid" -}} + +{{- $uuidVar := index (.Values.couchdbConfig.couchdb | default dict) "uuid" -}} +{{- if (empty $uuidVar) }} + {{- $secretName := print (include "couchdb.fullname" .) "-internal" }} + {{- $currentSecret := lookup "v1" "Secret" $.Release.Namespace $secretName}} + {{- if and $currentSecret (not .Values.dangerRegenerateAutomatedValues ) }} + {{- $uuidVar = get $currentSecret.data "uuid" | b64dec }} + {{- else }} + {{- $uuidVar = uuidv4 -}} + {{- end }} +{{- end }} +{{- print $uuidVar -}} + +{{- end -}} diff --git a/couchdb/templates/secrets.yaml b/couchdb/templates/secrets.yaml index 38dace0..ff80dca 100644 --- a/couchdb/templates/secrets.yaml +++ b/couchdb/templates/secrets.yaml @@ -18,4 +18,17 @@ data: {{- if .Values.adminHash }} adminHash: {{ .Values.adminHash | b64enc | quote }} {{- end -}} -{{- end -}} +{{- end }} +--- +apiVersion: v1 +kind: Secret +metadata: + name: {{ template "couchdb.fullname" . }}-internal + labels: + app: {{ template "couchdb.fullname" . }} + chart: "{{ .Chart.Name }}-{{ .Chart.Version }}" + release: "{{ .Release.Name }}" + heritage: "{{ .Release.Service }}" +type: Opaque +data: + uuid: {{- include "couchdb.uuid" . }}