[bitnami/common] add psql and mysql required password validations (#3374)

* feat(common): add psql and mysql required password validations
This commit is contained in:
Daniel Arteaga
2020-08-10 12:16:53 +02:00
committed by GitHub
parent 28dfe8395c
commit 1a4419e15d
4 changed files with 133 additions and 56 deletions

View File

@@ -1,8 +1,8 @@
apiVersion: v1
name: common
# Please make sure that version and appVersion are always the same.
version: 0.4.0
appVersion: 0.4.0
version: 0.5.0
appVersion: 0.5.0
description: A Library Helm Chart for grouping common logic between bitnami charts. This chart is not deployable by itself.
keywords:
- common

View File

@@ -41,77 +41,79 @@ The following table lists the helpers available in the library which are scoped
**Names**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.names.name` | Expand the name of the chart or use `.Values.nameOverride` | `.` Chart context |
| `common.names.fullname` | Create a default fully qualified app name. | `.` Chart context |
| `common.names.chart` | Chart name plus version | `.` Chart context |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.names.name` | Expand the name of the chart or use `.Values.nameOverride` | `.` Chart context |
| `common.names.fullname` | Create a default fully qualified app name. | `.` Chart context |
| `common.names.chart` | Chart name plus version | `.` Chart context |
**Images**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.images.image` | Return the proper and full image name | `dict "imageRoot" .Values.path.to.the.image "global" $`, see [ImageRoot](#imageroot) for the structure. |
| `common.images.pullSecrets` | Return the proper Docker Image Registry Secret Names | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" $` |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.images.image` | Return the proper and full image name | `dict "imageRoot" .Values.path.to.the.image "global" $`, see [ImageRoot](#imageroot) for the structure. |
| `common.images.pullSecrets` | Return the proper Docker Image Registry Secret Names | `dict "images" (list .Values.path.to.the.image1, .Values.path.to.the.image2) "global" $` |
**Labels**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.labels.standard` | Return Kubernetes standard labels | `.` Chart context |
| `common.labels.matchLabels` | Return the proper Docker Image Registry Secret Names | `.` Chart context |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.labels.standard` | Return Kubernetes standard labels | `.` Chart context |
| `common.labels.matchLabels` | Return the proper Docker Image Registry Secret Names | `.` Chart context |
**Storage**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.storage.class` | Return the proper Storage Class | `dict "persistence" .Values.path.to.the.persistence "global" $`, see [Persistence](#persistence) for the structure. |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.storage.class` | Return the proper Storage Class | `dict "persistence" .Values.path.to.the.persistence "global" $`, see [Persistence](#persistence) for the structure. |
**TplValues**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.tplvalues.render` | Renders a value that contains template | `dict "value" .Values.path.to.the.Value "context" $`, value is the value should rendered as template, context frecuently is the chart context `$` or `.` |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.tplvalues.render` | Renders a value that contains template | `dict "value" .Values.path.to.the.Value "context" $`, value is the value should rendered as template, context frecuently is the chart context `$` or `.` |
**Capabilities**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.capabilities.deployment.apiVersion` | Return the appropriate apiVersion for deployment. | `.` Chart context |
| `common.capabilities.ingress.apiVersion` | Return the appropriate apiVersion for ingress. | `.` Chart context |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.capabilities.deployment.apiVersion` | Return the appropriate apiVersion for deployment. | `.` Chart context |
| `common.capabilities.ingress.apiVersion` | Return the appropriate apiVersion for ingress. | `.` Chart context |
**Validations**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.validations.values.single.empty` | Validate a value must not be empty. | `dict "valueKey" "path.to.value" "secret" "secret.name" "field" "my-password" "context" $` secret and field are optional. In case they are given, the helper will generate a how to get instruction. See [ValidateValue](#validatevalue) |
| `common.validations.values.multiple.empty` | Validate a multiple values must not be empty. It returns a shared error for all the values. | `dict "required" (list $validateValueConf00 $validateValueConf01) "context" $`. See [ValidateValue](#validatevalue) |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.validations.values.single.empty` | Validate a value must not be empty. | `dict "valueKey" "path.to.value" "secret" "secret.name" "field" "my-password" "context" $` secret and field are optional. In case they are given, the helper will generate a how to get instruction. See [ValidateValue](#validatevalue) |
| `common.validations.values.multiple.empty` | Validate a multiple values must not be empty. It returns a shared error for all the values. | `dict "required" (list $validateValueConf00 $validateValueConf01) "context" $`. See [ValidateValue](#validatevalue) |
| `common.validations.values.mariadb.passwords` | When a chart is using `bitnami/mariadb` as subchart you should use this to validate required password are not empty. It returns a shared error for all the values. | `dict "secret" "mariadb-secret" "context" $` |
| `common.validations.values.postgresql.passwords` | This helper will ensure required password are not empty. It returns a shared error for all the values. | `dict "secret" "postgresql-secret" "subchart" "true" "context" $` subchart field is optional and could be true or false it depends on where you will use postgresql chart and the helper. |
**Warnings**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.warnings.rollingTag` | Warning about using rolling tag. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.warnings.rollingTag` | Warning about using rolling tag. | `ImageRoot` see [ImageRoot](#imageroot) for the structure. |
**Errors**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.errors.upgrade.passwords.empty` | It will use `common.validations.values.multiple.empty` to ensure required passwords are given when we are upgrading a chart. If there is any missing required password it will throw an error and will stop the upgrade action. | `dict "required" (list $requiredPasswordConf00 $requiredPasswordConf01) "context" $` |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.errors.upgrade.passwords.empty` | It will ensure required passwords are given when we are upgrading a chart. If `validationErrors` is not empty it will throw an error and will stop the upgrade action. | `dict "validationErrors" (list $validationError00 $validationError01) "context" $` |
**Utils**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.utils.fieldToEnvVar` | Build environment variable name given a field. | `dict "field" "my-password"` |
| `common.utils.secret.getvalue` | Print instructions to get a secret value. | `dict "secret" "secret-name" "field" "secret-value-field" "context" $` |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.utils.fieldToEnvVar` | Build environment variable name given a field. | `dict "field" "my-password"` |
| `common.utils.secret.getvalue` | Print instructions to get a secret value. | `dict "secret" "secret-name" "field" "secret-value-field" "context" $` |
**Secrets**
| Helper identifier | Description | Expected Input |
|---------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.secrets.name` | Generate the name of the secret. | `dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $` see [ExistingSecret](#existingsecret) for the structure. |
| `common.secrets.key` | Generate secret key. | `dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName"` see [ExistingSecret](#existingsecret) for the structure. |
| Helper identifier | Description | Expected Input |
|--------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `common.secrets.name` | Generate the name of the secret. | `dict "existingSecret" .Values.path.to.the.existingSecret "defaultNameSuffix" "mySuffix" "context" $` see [ExistingSecret](#existingsecret) for the structure. |
| `common.secrets.key` | Generate secret key. | `dict "existingSecret" .Values.path.to.the.existingSecret "key" "keyName"` see [ExistingSecret](#existingsecret) for the structure. |
## Special input schemas
@@ -251,7 +253,7 @@ keyMapping:
{{- $validateValueConf00 := (dict "valueKey" "path.to.value00" "secret" "secretName" "field" "password-00") -}}
{{- $validateValueConf01 := (dict "valueKey" "path.to.value01" "secret" "secretName" "field" "password-01") -}}
{{ include "common.validations.values.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }}
{{ include "common.validations.values.multiple.empty" (dict "required" (list $validateValueConf00 $validateValueConf01) "context" $) }}
```
If we force those values to be empty we will see some alerts

View File

@@ -3,23 +3,18 @@
Through error when upgrading using empty passwords values that must not be empty.
Usage:
{{- $requiredPasswordConf00 := (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}}
{{- $requiredPasswordConf01 := (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}}
{{ include "common.errors.upgrade.passwords.empty" (dict "required" (list $requiredPasswordConf00 $requiredPasswordConf01) "context" $) }}
{{- $validationError00 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password00" "secret" "secretName" "field" "password-00") -}}
{{- $validationError01 := include "common.validations.values.single.empty" (dict "valueKey" "path.to.password01" "secret" "secretName" "field" "password-01") -}}
{{ include "common.errors.upgrade.passwords.empty" (dict "validationErrors" (list $validationError00 $validationError01) "context" $) }}
Required password params:
- valueKey - String - Required. The path to the required password in the values.yaml, e.g: "mysql.password"
- secret - String - Required. Name of the secret where the password is generated/stored, e.g: "mysql-passwords-secret"
- field - String - Required. Name of the field in the secret data, e.g: "mysql-password"
- validationErrors - String - Required. List of validation strings to be return, if it is empty it won't throw error.
- context - Context - Required. Parent context.
*/}}
{{- define "common.errors.upgrade.passwords.empty" -}}
{{- if .context.Release.IsUpgrade -}}
{{- $validationErrors := include "common.validations.values.multiple.empty" . -}}
{{- if $validationErrors -}}
{{- $validationErrors := join "" .validationErrors -}}
{{- if and $validationErrors .context.Release.IsUpgrade -}}
{{- $errorString := "\nPASSWORDS ERROR: you must provide your current passwords when upgrade the release%s" -}}
{{- printf $errorString $validationErrors | fail -}}
{{- end -}}
{{- end -}}
{{- end -}}

View File

@@ -54,3 +54,83 @@ Validate value params:
{{- printf "\n '%s' must not be empty, please add '--set %s=$%s' to the command.%s" .valueKey .valueKey $varname $getCurrentValue -}}
{{- end -}}
{{- end -}}
{{/*
Validate a mariadb required password must not be empty.
Usage:
{{ include "common.validations.values.mariadb.passwords" (dict "secret" "secretName" "context" $) }}
Validate value params:
- secret - String - Required. Name of the secret where mysql values are stored, e.g: "mysql-passwords-secret"
*/}}
{{- define "common.validations.values.mariadb.passwords" -}}
{{- if and (not .context.Values.mariadb.existingSecret) .context.Values.mariadb.enabled -}}
{{- $requiredPasswords := list -}}
{{- $requiredRootMariadbPassword := dict "valueKey" "mariadb.rootUser.password" "secret" .secretName "field" "mariadb-root-password" -}}
{{- $requiredPasswords = append $requiredPasswords $requiredRootMariadbPassword -}}
{{- if not (empty .context.Values.mariadb.db.user) -}}
{{- $requiredMariadbPassword := dict "valueKey" "mariadb.db.password" "secret" .secretName "field" "mariadb-password" -}}
{{- $requiredPasswords = append $requiredPasswords $requiredMariadbPassword -}}
{{- end -}}
{{- if .context.Values.mariadb.replication.enabled -}}
{{- $requiredReplicationPassword := dict "valueKey" "mariadb.replication.password" "secret" .secretName "field" "mariadb-replication-password" -}}
{{- $requiredPasswords = append $requiredPasswords $requiredReplicationPassword -}}
{{- end -}}
{{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}}
{{- end -}}
{{- end -}}
{{/*
Validate a postgresql required password must not be empty.
Usage:
{{ include "common.validations.values.postgresql.passwords" (dict "secret" "secretName" "subchart" false "context" $) }}
Validate value params:
- secret - String - Required. Name of the secret where postgresql values are stored, e.g: "mysql-passwords-secret"
- subchart - Boolean - Optional. Whether postgresql is used as subchart or not. Default: false
*/}}
{{- define "common.validations.values.postgresql.passwords" -}}
{{- $existingSecret := false -}}
{{- $existingSecretGlobal := false -}}
{{- if .context.Values.global -}}
{{- if .context.Values.global.postgresql -}}
{{- $existingSecretGlobal = .context.Values.global.postgresql.existingSecret -}}
{{- end -}}
{{- end -}}
{{- $enabled := true -}}
{{- $valueKeyPostgresqlPassword := "postgresqlPassword" -}}
{{- $enabledReplication := false -}}
{{- $valueKeyPostgresqlReplicationEnabled := "replication.password" -}}
{{- if .subchart -}}
{{- $existingSecret = .context.Values.postgresql.existingSecret -}}
{{- $existingSecretGlobal = false -}}
{{- $enabled = .context.Values.postgresql.enabled -}}
{{- $valueKeyPostgresqlPassword = "postgresql.postgresqlPassword" -}}
{{- $enabledReplication = .context.Values.postgresql.replication.enabled -}}
{{- $valueKeyPostgresqlReplicationEnabled = "postgresql.replication.password" -}}
{{- else -}}
{{- $existingSecret = .context.Values.existingSecret -}}
{{- $enabledReplication = .context.Values.replication.enabled -}}
{{- end -}}
{{- if and (not $existingSecret) (not $existingSecretGlobal) $enabled -}}
{{- $requiredPasswords := list -}}
{{- $requiredPostgresqlPassword := dict "valueKey" $valueKeyPostgresqlPassword "secret" .secret "field" "postgresql-password" -}}
{{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlPassword -}}
{{- if $enabledReplication -}}
{{- $requiredPostgresqlReplicationPassword := dict "valueKey" $valueKeyPostgresqlReplicationEnabled "secret" .secret "field" "postgresql-replication-password" -}}
{{- $requiredPasswords = append $requiredPasswords $requiredPostgresqlReplicationPassword -}}
{{- end -}}
{{- include "common.validations.values.multiple.empty" (dict "required" $requiredPasswords "context" .context) -}}
{{- end -}}
{{- end -}}