feat(common): Add support for setting extra env to CNPG pods (#40673)

**Description**
<!--
Please include a summary of the change and which issue is fixed. Please
also include relevant motivation and context. List any dependencies that
are required for this change.
-->

This PR adds the ability to set extra environment variables to CNPG
pods.

I need this, as I need to set the `HTTP_PROXY`, `HTTPS_PROXY` and
`NO_PROXY` envs to the CNPG pods, so that backup/restore goes through my
Gluetun proxy.

This PR only adds support for CNPG, as with Volsync, this can be done by
setting environment variables on the Volsync controller itself (see
[release
notes](https://github.com/backube/volsync/blob/main/CHANGELOG.md#061)
for more info).

This PR, along with the other PRs I opened recently (#40000 , #40385,
#40523 , #40668) should be the last piece of the puzzle needed for
enabling backup/restore of clusters using a remote self-hosted S3
server.

⚒️ Fixes  # <!--(issue)-->

**⚙️ Type of change**

- [X] ⚙️ Feature/App addition
- [ ] 🪛 Bugfix
- [ ] ⚠️ Breaking change (fix or feature that would cause existing
functionality to not work as expected)
- [ ] 🔃 Refactor of current code
- [ ] 📜 Documentation Changes

**🧪 How Has This Been Tested?**
<!--
Please describe the tests that you ran to verify your changes. Provide
instructions so we can reproduce. Please also list any relevant details
for your test configuration
-->

What I have tested:

- Rendered a chart with various combinations of CNPG envs set and looked
ad produced output
- Tested along with the other PRs (#40523, #40668) to verify backup up
to my S3 server works though the Gluetun proxy

**📃 Notes:**
<!-- Please enter any other relevant information here -->

Note that these changes should not affect any work related towards the
migration to the CNPG's new plugin-based barman. As per the [migration
guide](https://cloudnative-pg.io/plugin-barman-cloud/docs/migration/),
the required changes are primarily to export the keys under the
`barmanObjectStore` to a new CRD called `ObjectStore`. The `env` and
`envFrom` keys added in this PR are outside this dictionary; thus, they
should not require any changes when adding support for the new
plugin-based barman.

---

- [CNPG CRD for env and
envFrom](https://github.com/cloudnative-pg/cloudnative-pg/blob/main/config/crd/bases/postgresql.cnpg.io_clusters.yaml#L2161-L2368)

**✔️ Checklist:**

- [X] ⚖️ My code follows the style guidelines of this project
- [X] 👀 I have performed a self-review of my own code
- [X] #️⃣ I have commented my code, particularly in hard-to-understand
areas
- [ ] 📄 I have made changes to the documentation
- [X] 🧪 I have added tests to this description that prove my fix is
effective or that my feature works
- [X] ⬆️ I increased versions for any altered app according to semantic
versioning
- [X] I made sure the title starts with `feat(chart-name):`,
`fix(chart-name):`, `chore(chart-name):`, `docs(chart-name):` or
`fix(docs):`

** App addition**

If this PR is an app addition please make sure you have done the
following.

- [ ] 🖼️ I have added an icon in the Chart's root directory called
`icon.png`

---

_Please don't blindly check all the boxes. Read them and only check
those that apply.
Those checkboxes are there for the reviewer to see what is this all
about and
the status of this PR with a quick glance._

---------

Signed-off-by: Kjeld Schouten <info@kjeldschouten.nl>
Co-authored-by: Kjeld Schouten <info@kjeldschouten.nl>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
astro-stan
2025-10-17 23:05:25 +01:00
committed by GitHub
parent e818f936ef
commit e892b37565
16 changed files with 975 additions and 63 deletions
@@ -701,3 +701,118 @@ tests:
key: custom-queries
- name: test-query3
key: test-key
- it: should create the correct env with env key
set:
configmap:
configmap-name:
enabled: true
data:
key1: value1
key2: value2
secret:
secret-name:
enabled: true
data:
key1: value1
key2: value2
postgres16Image:
repository: ghcr.io/cloudnative-pg/postgresql
tag: "16.3"
pullPolicy: IfNotPresent
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
password: test-password
cluster:
env:
VAR1: some-value
VAR2:
configMapKeyRef:
name: configmap-name
key: key1
VAR3:
secretKeyRef:
name: secret-name
key: key2
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
env:
- name: VAR1
value: some-value
- name: VAR2
valueFrom:
configMapKeyRef:
key: key1
name: test-release-name-common-test-configmap-name
- name: VAR3
valueFrom:
secretKeyRef:
key: key2
name: test-release-name-common-test-secret-name
- it: should create the correct env with envFrom key
set:
configmap:
configmap-name:
enabled: true
data:
key1: value1
key2: value2
secret:
secret-name:
enabled: true
data:
key3: value3
key4: value4
postgres16Image:
repository: ghcr.io/cloudnative-pg/postgresql
tag: "16.3"
pullPolicy: IfNotPresent
cnpg:
my-pg:
enabled: true
user: test-user
database: test-db
password: test-password
cluster:
envFrom:
- configMapRef:
name: configmap-name
- secretRef:
name: secret-name
asserts:
- documentIndex: *clusterDoc
isKind:
of: Cluster
- documentIndex: *clusterDoc
isAPIVersion:
of: postgresql.cnpg.io/v1
- documentIndex: *clusterDoc
equal:
path: metadata.name
value: test-release-name-common-test-cnpg-my-pg
- documentIndex: *clusterDoc
isSubset:
path: spec
content:
envFrom:
- configMapRef:
name: test-release-name-common-test-configmap-name
- secretRef:
name: test-release-name-common-test-secret-name
@@ -554,7 +554,7 @@ tests:
- compute
asserts:
- failedTemplate:
errorMessage: Container - Expected [fixedEnv.NVIDIA_CAPS] entry to be one of [all, compute, utility, graphics, video], but got [invalid]
errorMessage: Container - Expected [containers.container-name1.fixedEnv.NVIDIA_CAPS] entry to be one of [all, compute, utility, graphics, video], but got [invalid]
- it: it should fail with NVIDIA_CAPS not having unique values
set:
@@ -577,4 +577,4 @@ tests:
- compute
asserts:
- failedTemplate:
errorMessage: Container - Expected [fixedEnv.NVIDIA_CAPS] to have only unique values, but got [compute, compute]
errorMessage: Container - Expected [containers.container-name1.fixedEnv.NVIDIA_CAPS] to have only unique values, but got [compute, compute]
@@ -134,7 +134,7 @@ tests:
name: invalid-name
asserts:
- failedTemplate:
errorMessage: Container - Expected [envFrom] entry to have one of [configMapRef, secretRef]
errorMessage: Container - Expected [envFrom] entry in [containers.container-name1] to have one of [configMapRef, secretRef]
- it: it should fail with both refs in the same entry
set:
@@ -158,7 +158,7 @@ tests:
name: secret-name
asserts:
- failedTemplate:
errorMessage: Container - Expected [envFrom] entry to have only one of [configMapRef, secretRef], but got both
errorMessage: Container - Expected [envFrom] entry in [containers.container-name1] to have only one of [configMapRef, secretRef], but got both
- it: it should fail with empty name in configMapRef
set:
@@ -180,7 +180,7 @@ tests:
name: ""
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [envFrom.configMapRef.name]
errorMessage: Container - Expected non-empty [containers.container-name1.envFrom.configMapRef.name]
- it: it should fail with empty name in secretRef
set:
@@ -202,7 +202,7 @@ tests:
name: ""
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [envFrom.secretRef.name]
errorMessage: Container - Expected non-empty [containers.container-name1.envFrom.secretRef.name]
- it: it should fail without defined configmap
set:
@@ -230,7 +230,7 @@ tests:
name: configmap-other-name
asserts:
- failedTemplate:
errorMessage: Container - Expected ConfigMap [configmap-other-name] defined in [envFrom] to exist
errorMessage: Container - Expected ConfigMap [configmap-other-name] defined in [containers.container-name1.envFrom] to exist
- it: it should fail without defined secret
set:
@@ -258,7 +258,7 @@ tests:
name: secret-other-name
asserts:
- failedTemplate:
errorMessage: Container - Expected Secret [secret-other-name] defined in [envFrom] to exist
errorMessage: Container - Expected Secret [secret-other-name] defined in [containers.container-name1.envFrom] to exist
- it: it should fail empty expandObjectName
set:
@@ -117,4 +117,4 @@ tests:
value: some_value
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [envList.name]
errorMessage: Container - Expected non-empty [containers.container-name1.envList.name]
@@ -37,7 +37,7 @@ tests:
value: 123
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [VAR1] in [envList] tried to override the Environment Variable that is already defined in [env]
errorMessage: Container - Environment Variable [VAR1] in [containers.container-name1.envList] tried to override the Environment Variable that is already defined in [containers.container-name1.env]
- it: should fail with dupe env in env and envFrom configmap
set:
@@ -66,7 +66,7 @@ tests:
name: configmap-name
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [VAR1] in [env] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name]
errorMessage: Container - Environment Variable [VAR1] in [containers.container-name1.env] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name]
- it: should fail with dupe env in env and envFrom secret
set:
@@ -95,7 +95,7 @@ tests:
name: secret-name
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [VAR1] in [env] tried to override the Environment Variable that is already defined in [Secret - secret-name]
errorMessage: Container - Environment Variable [VAR1] in [containers.container-name1.env] tried to override the Environment Variable that is already defined in [Secret - secret-name]
- it: should fail with dupe env in envList and envFrom secret
set:
@@ -125,7 +125,7 @@ tests:
name: secret-name
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [VAR1] in [envList] tried to override the Environment Variable that is already defined in [Secret - secret-name]
errorMessage: Container - Environment Variable [VAR1] in [containers.container-name1.envList] tried to override the Environment Variable that is already defined in [Secret - secret-name]
- it: should fail with dupe env in envList and envFrom configmap
set:
@@ -155,7 +155,7 @@ tests:
name: configmap-name
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [VAR1] in [envList] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name]
errorMessage: Container - Environment Variable [VAR1] in [containers.container-name1.envList] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name]
- it: should fail with dupe env in fixedEnv and env
set:
@@ -176,7 +176,7 @@ tests:
TZ: some_value
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [TZ] in [env] tried to override the Environment Variable that is already defined in [fixedEnv]
errorMessage: Container - Environment Variable [TZ] in [containers.container-name1.env] tried to override the Environment Variable that is already defined in [containers.container-name1.fixedEnv]
- it: should fail with dupe env in fixedEnv and envList
set:
@@ -198,7 +198,7 @@ tests:
value: some_value
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [TZ] in [envList] tried to override the Environment Variable that is already defined in [fixedEnv]
errorMessage: Container - Environment Variable [TZ] in [containers.container-name1.envList] tried to override the Environment Variable that is already defined in [containers.container-name1.fixedEnv]
- it: should fail with dupe env in fixedEnv and envFrom configmap
set:
@@ -225,7 +225,7 @@ tests:
name: configmap-name
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [TZ] in [fixedEnv] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name]
errorMessage: Container - Environment Variable [TZ] in [containers.container-name1.fixedEnv] tried to override the Environment Variable that is already defined in [ConfigMap - configmap-name]
- it: should fail with dupe env in fixedEnv and envFrom secret
set:
@@ -252,4 +252,4 @@ tests:
name: secret-name
asserts:
- failedTemplate:
errorMessage: Container - Environment Variable [TZ] in [fixedEnv] tried to override the Environment Variable that is already defined in [Secret - secret-name]
errorMessage: Container - Environment Variable [TZ] in [containers.container-name1.fixedEnv] tried to override the Environment Variable that is already defined in [Secret - secret-name]
@@ -194,7 +194,7 @@ tests:
invalidKeyRef: {}
asserts:
- failedTemplate:
errorMessage: Container - Expected [env] with a ref to have one of [configMapKeyRef, secretKeyRef, fieldRef], but got [invalidKeyRef]
errorMessage: Container - Expected [env] in [containers.container-name1] with a ref to have one of [configMapKeyRef, secretKeyRef, fieldRef], but got [invalidKeyRef]
- it: it should fail with more than one ref
set:
@@ -217,7 +217,7 @@ tests:
secretKeyRef: {}
asserts:
- failedTemplate:
errorMessage: Container - Expected [env] with a ref to have one of [configMapKeyRef, secretKeyRef, fieldRef], but got [configMapKeyRef, secretKeyRef]
errorMessage: Container - Expected [env] in [containers.container-name1] with a ref to have one of [configMapKeyRef, secretKeyRef, fieldRef], but got [configMapKeyRef, secretKeyRef]
- it: it should fail with empty name in configMapKeyRef
set:
@@ -241,7 +241,7 @@ tests:
key: key
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [env.configMapKeyRef.name]
errorMessage: Container - Expected non-empty [containers.container-name1.env.configMapKeyRef.name]
- it: it should fail with empty key in configMapKeyRef
set:
@@ -265,7 +265,7 @@ tests:
key: ""
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [env.configMapKeyRef.key]
errorMessage: Container - Expected non-empty [containers.container-name1.env.configMapKeyRef.key]
- it: it should fail with empty name in secretKeyRef
set:
@@ -289,7 +289,7 @@ tests:
key: key
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [env.secretKeyRef.name]
errorMessage: Container - Expected non-empty [containers.container-name1.env.secretKeyRef.name]
- it: it should fail with empty key in secretKeyRef
set:
@@ -313,7 +313,7 @@ tests:
key: ""
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [env.secretKeyRef.key]
errorMessage: Container - Expected non-empty [containers.container-name1.env.secretKeyRef.key]
- it: it should fail with referenced secret not defined
set:
@@ -337,7 +337,7 @@ tests:
key: somekey
asserts:
- failedTemplate:
errorMessage: Container - Expected in [env] the referenced Secret [secret-name] to be defined
errorMessage: Container - Expected in [containers.container-name1.env] the referenced Secret [secret-name] to be defined
- it: it should fail with referenced configmap not defined
set:
@@ -361,7 +361,7 @@ tests:
key: somekey
asserts:
- failedTemplate:
errorMessage: Container - Expected in [env] the referenced Configmap [configmap-name] to be defined
errorMessage: Container - Expected in [containers.container-name1.env] the referenced Configmap [configmap-name] to be defined
- it: it should fail with referenced key in configmap not defined
set:
@@ -391,7 +391,7 @@ tests:
key: somekey
asserts:
- failedTemplate:
errorMessage: Container - Expected in [env] the referenced key [somekey] in Configmap [configmap-name] to be defined
errorMessage: Container - Expected in [containers.container-name1.env] the referenced key [somekey] in Configmap [configmap-name] to be defined
- it: it should fail with referenced key in secret not defined
set:
@@ -421,7 +421,7 @@ tests:
key: somekey
asserts:
- failedTemplate:
errorMessage: Container - Expected in [env] the referenced key [somekey] in Secret [secret-name] to be defined
errorMessage: Container - Expected in [containers.container-name1.env] the referenced key [somekey] in Secret [secret-name] to be defined
- it: it should fail with empty fieldPath in fieldRef
set:
@@ -444,7 +444,7 @@ tests:
fieldPath: ""
asserts:
- failedTemplate:
errorMessage: Container - Expected non-empty [env.fieldRef.fieldPath]
errorMessage: Container - Expected non-empty [containers.container-name1.env.fieldRef.fieldPath]
- it: it should fail empty expandObjectName
set:
+296
View File
@@ -0,0 +1,296 @@
---
title: CNPG Cluster
---
:::note
- Examples under each key are only to be used as a placement guide
- See the [Full Examples](/truecharts-common/cnpg/cluster#full-examples) section for complete examples.
- This page is targeted primarily at chart developers. If you are looking for
how to configure a CNPG backup/restore, visit the
[dedicated guide page](/truecharts/guides/backup%20%26%20restore/cnpg-backup-restore)
:::
## Appears in
- `.Values.cnpg.$name.cluster`
:::tip
- Replace references to `$name` with the actual name you want to use.
:::
---
## `labels`
Additional labels for CNPG cluster
| | |
| ---------- | --------------------------- |
| Key | `cnpg.$name.cluster.labels` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ✅ (On value only) |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
labels:
key: value
```
---
## `annotations`
Additional annotations for CNPG cluster
| | |
| ---------- | -------------------------------- |
| Key | `cnpg.$name.cluster.annotations` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ✅ (On value only) |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
annotations:
key: value
```
---
## `env`
Define additional environment variables for the cluster's pods
:::tip
See container env options in the [container env](/truecharts-common/container/env) section.
:::
| | |
| ---------- | ------------------------ |
| Key | `cnpg.$name.cluster.env` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
env:
key: value
```
---
## `envFrom`
Define additional environment variables for the cluster's pods
:::tip
See container envFrom options in the [container envFrom](/truecharts-common/container/envFrom) section.
:::
| | |
| ---------- | ------------------------ |
| Key | `cnpg.$name.cluster.envFrom` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `[]` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
envFrom:
- secretRef:
name: secret-name
expandObjectName: false
- configMapRef:
name: configmap-name
expandObjectName: true
```
---
## `instances`
Number of instances
| | |
| ---------- | ------------------------------ |
| Key | `cnpg.$name.cluster.instances` |
| Type | `int` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `2` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
instances: 2
```
---
## `singleNode`
Whether this is a single-node cluster.
Setting this to `true` would allow PVCs to be kept on instance restart.
:::note
If you are a chart developer, changing the default value is not recommended,
as users are expected to change this themselves **if** they are running your
chart on a single-node cluster.
:::
| | |
| ---------- | ------------------------------- |
| Key | `cnpg.$name.cluster.singleNode` |
| Type | `bool` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `false` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
singleNode: true
```
---
## `logLevel`
The cluster log level. Available values:
- `error`
- `warning`
- `info`
- `debug`
- `trace`
:::note
If you are a chart developer, changing the default value is not recommended,
as users are expected to change this themselves if they are running into
issues with CNPG.
:::
| | |
| ---------- | ----------------------------- |
| Key | `cnpg.$name.cluster.logLevel` |
| Type | `enum` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `info` |
Example
```yaml
cnpg:
cnpg-name:
cluster:
logLevel: info
```
---
## `primaryUpdateMethod`
TODO
---
## `primaryUpdateStrategy`
TODO
---
## `certificates`
TODO
---
## `postgresql`
TODO
---
## `initdb`
TODO
---
## Full Examples
```yaml
cnpg:
$name:
cluster:
labels:
label1: label1
label2: label2
annotations:
annotation1: annotation1
annotation2: annotation2
env:
key: value
envList:
- name: key
value: value
envFrom:
- secretRef:
name: my-secret
expandObjectName: true
- configMapRef:
name: my-configmap
expandObjectName: false
instances: 2
singleNode: false
logLevel: info
primaryUpdateMethod: # TODO
primaryUpdateStrategy: # TODO
certificates: # TODO
postgresql: # TODO
initdb: # TODO
primaryUpdateStrategy: # TODO
```
+463
View File
@@ -0,0 +1,463 @@
---
title: CNPG
---
:::note
- Examples under each key are only to be used as a placement guide
- See the [Full Examples](/truecharts-common/cnpg/cnpg#full-examples) section for complete examples.
- This page is targeted primarily at chart developers. If you are looking for
how to configure a CNPG backup/restore, visit the
[dedicated guide page](/truecharts/guides/backup%20%26%20restore/cnpg-backup-restore)
:::
## Appears in
- `.Values.cnpg`
## Naming scheme
- Primary: `$FullName-cnpg-$ResourceName` (release-name-chart-name-cnpg-main)
- Non-Primary: `$FullName-$RBACName-cnpg-$ResourceName` (release-name-chart-name-RBACName-cnpg-main)
:::tip
- Replace references to `$name` with the actual name you want to use.
:::
---
## `cnpg`
Define a CNPG cluster
| | |
| ---------- | --------------------------------------- |
| Key | `cnpg` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `{cnpg: {main: {enabled: false, ...}}}` |
Example
```yaml
cnpg:
main:
enabled: true
...
```
---
### `$name`
Define the cluster name.
:::tip
There is predefined cluster called `main`, which is configured with sensible
defaults (see common chart's `values.yaml`). It is **disabled** by default and
must be [enabled](/truecharts-common/cnpg/cnpg#enabled) if needed.
:::
| | |
| ---------- | ------------------------------- |
| Key | `cnpg.$name` |
| Type | `map` |
| Required | ✅ |
| Helm `tpl` | ❌ |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name: {}
```
---
#### `enabled`
Enables or Disables the cluster
| | |
| ---------- | --------------------------- |
| Key | `cnpg.$name.enabled` |
| Type | `bool` |
| Required | ✅ |
| Helm `tpl` | ✅ |
| Default | `false` |
Example
```yaml
cnpg:
cnpg-name:
enabled: true
```
---
#### `primary`
Sets the cluster as primary
| | |
| ---------- | -------------------- |
| Key | `cnpg.$name.primary` |
| Type | `bool` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `false` |
Example
```yaml
cnpg:
cnpg-name:
primary: true
```
---
#### `hibernate`
Puts the cluster in hibernation mode
| | |
| ---------- | ---------------------- |
| Key | `cnpg.$name.hibernate` |
| Type | `bool` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `false` |
Example
```yaml
cnpg:
cnpg-name:
hibernate: true
```
---
#### `labels`
Additional labels for all CNPG objects
| | |
| ---------- | -------------------- |
| Key | `cnpg.$name.labels` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ✅ (On value only) |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name:
labels:
key: value
```
---
#### `annotations`
Additional annotations for all CNPG objects
| | |
| ---------- | ------------------------ |
| Key | `cnpg.$name.annotations` |
| Type | `map` |
| Required | ❌ |
| Helm `tpl` | ✅ (On value only) |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name:
annotations:
key: value
```
---
#### `type`
Type of the CNPG database. Available types:
- `postgres`
- `postgis`
- `timescaledb`
- `vectors`
| | |
| ---------- | ----------------- |
| Key | `cnpg.$name.type` |
| Type | `enum` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `postgres` |
Example
```yaml
cnpg:
cnpg-name:
type: postgres
```
---
#### `pgVersion`
Version of Postgresql to use. Available types:
- `15`
- `16`
:::note
Changing this value affects the cluster naming scheme
:::
| | |
| ---------- | ---------------------- |
| Key | `cnpg.$name.pgVersion` |
| Type | `enum` |
| Required | ✅ |
| Helm `tpl` | ❌ |
| Default | `nil` |
Example
```yaml
cnpg:
cnpg-name:
pgVersion: 16
```
---
#### `mode`
Cluster mode of operation. Available modes:
- `standalone` (default mode, creates new or updates an existing CNPG cluster)
- `recovery` (same as standalone but creates a cluster from a backup, object store or via pg_basebackup)
:::note
If you are a chart developer, changing the default value is not recommended,
as users are expected to change this themselves **if** they want to configure
a CNPG restore.
:::
| | |
| ---------- | ------------------ |
| Key | `cnpg.$name.mode` |
| Type | `enum` |
| Required | ❌ |
| Helm `tpl` | ❌ |
| Default | `standalone` |
Example
```yaml
cnpg:
cnpg-name:
mode: standalone
```
---
#### `database`
Define the database name
| | |
| ---------- | ------------------------- |
| Key | `cnpg.$name.database` |
| Type | `string` |
| Required | ✅ |
| Helm `tpl` | ❌ |
| Default | `""` |
Example
```yaml
cnpg:
cnpg-name:
database: app
```
---
#### `user`
Define the database user
| | |
| ---------- | ------------------------- |
| Key | `cnpg.$name.user` |
| Type | `string` |
| Required | ✅ |
| Helm `tpl` | ❌ |
| Default | `""` |
Example
```yaml
cnpg:
cnpg-name:
user: app
```
---
#### `password`
Define the database password
:::tip
Chart users are strongly encouraged to override this setting with their own
secure password **during initial install**
:::
| | |
| ---------- | ------------------------- |
| Key | `cnpg.$name.password` |
| Type | `string` |
| Required | ✅ |
| Helm `tpl` | ❌ |
| Default | `""` |
Example
```yaml
cnpg:
cnpg-name:
password: supersecret
```
---
#### `cluster`
Database cluster configuration
See more details in [CNPG Cluster](/truecharts-common/cnpg/cluster)
| | |
| ---------- | ------------------------ |
| Key | `cnpg.$name.cluster` |
| Type | `string` |
| Required | ✅ |
| Helm `tpl` | ❌ |
| Default | `{}` |
Example
```yaml
cnpg:
cnpg-name:
cluster: {}
```
---
---
#### `monitoring`
TODO
---
#### `recovery`
:::note
See the dedicated [CNPG backup/restore guide](/truecharts/guides/backup%20%26%20restore/cnpg-backup-restore)
:::
TODO
---
#### `backups`
:::note
See the dedicated [CNPG backup/restore guide](/truecharts/guides/backup%20%26%20restore/cnpg-backup-restore)
:::
TODO
---
#### `pooler`
TODO
---
## Full Examples
```yaml
cnpg:
main:
enabled: true
primary: true
hibernate: false
type: postgres
pgVersion: 16
mode: standalone
database: "app"
user: "app"
password: "PLACEHOLDERPASSWORD"
cluster: {}
monitoring: {}
recovery: {}
backups: {}
pooler: {}
my-cluster-1:
enabled: true
primary: false
hibernate: false
labels:
label1: label1
label2: label2
annotations:
annotation1: annotation1
annotation2: annotation2
type: postgres
pgVersion: 16
mode: standalone
database: "my-app"
user: "my-user"
password: "supersecret"
cluster: {}
monitoring: {}
recovery: {}
backups: {}
pooler: {}
```
@@ -196,6 +196,20 @@ spec:
primaryUpdateMethod: {{ $primaryUpdateMethod }}
logLevel: {{ $logLevel }}
instances: {{ $instances }}
{{- /* Create a dict for storing env's so it can be checked for dupes */ -}}
{{- $_ := set $objectData.cluster "envDupe" dict -}}
{{- with (include "tc.v1.common.lib.container.envFrom" (dict
"rootCtx" $rootCtx "objectData" $objectData.cluster "caller" "CNPG Cluster"
"name" $objectData.shortName "key" "cluster") | trim) }}
envFrom:
{{- . | nindent 4 }}
{{- end }}
{{- with (include "tc.v1.common.lib.container.env" (dict
"rootCtx" $rootCtx "objectData" $objectData.cluster "caller" "CNPG Cluster"
"name" $objectData.shortName "key" "cluster") | trim) }}
env:
{{- . | nindent 4 }}
{{- end }}
{{- if or $objectData.cluster.postgresql $preloadLibraries }}
postgresql:
{{- with $objectData.cluster.postgresql }}
@@ -7,6 +7,7 @@ objectData: The object data to be used to render the container.
{{- define "tc.v1.common.helper.container.envDupeCheck" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $caller := .caller -}}
{{- $source := .source -}}
{{- $type := .type -}}
@@ -15,7 +16,7 @@ objectData: The object data to be used to render the container.
{{- $dupeEnv := (get $objectData.envDupe $key) -}}
{{- if $dupeEnv -}}
{{- fail (printf "Container - Environment Variable [%s] in [%s] tried to override the Environment Variable that is already defined in [%s]" $key $source $dupeEnv.source) -}}
{{- fail (printf "%s - Environment Variable [%s] in [%s] tried to override the Environment Variable that is already defined in [%s]" $caller $key $source $dupeEnv.source) -}}
{{- end -}}
{{- $_ := set $objectData.envDupe $key (dict "source" $source) -}}
@@ -7,9 +7,12 @@ objectData: The object data to be used to render the container.
{{- define "tc.v1.common.lib.container.env" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $key := .key -}}
{{- $name := (.name | toString) -}}
{{- $caller := .caller -}}
{{- range $k, $v := $objectData.env -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "env" "key" $k) }}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s.%s.env" $key $name) "key" $k "caller" $caller) }}
- name: {{ $k | quote }}
{{- if not (kindIs "map" $v) -}}
{{- $value := "" -}}
@@ -24,40 +27,40 @@ objectData: The object data to be used to render the container.
valueFrom:
{{- $refs := (list "configMapKeyRef" "secretKeyRef" "fieldRef") -}}
{{- if or (ne (len ($v | keys)) 1) (not (mustHas ($v | keys | first) $refs)) -}}
{{- fail (printf "Container - Expected [env] with a ref to have one of [%s], but got [%s]" (join ", " $refs) (join ", " ($v | keys | sortAlpha))) -}}
{{- fail (printf "%s - Expected [env] in [%s.%s] with a ref to have one of [%s], but got [%s]" $caller $key $name (join ", " $refs) (join ", " ($v | keys | sortAlpha))) -}}
{{- end -}}
{{- $name := "" -}}
{{- $refName := "" -}}
{{- range $key := (list "configMapKeyRef" "secretKeyRef") -}}
{{- if hasKey $v $key }}
{{ $key }}:
{{- $obj := get $v $key -}}
{{- range $ref := (list "configMapKeyRef" "secretKeyRef") -}}
{{- if hasKey $v $ref }}
{{ $ref }}:
{{- $obj := get $v $ref -}}
{{- if not $obj.name -}}
{{- fail (printf "Container - Expected non-empty [env.%s.name]" $key) -}}
{{- fail (printf "%s - Expected non-empty [%s.%s.env.%s.name]" $caller $key $name $ref) -}}
{{- end -}}
{{- if not $obj.key -}}
{{- fail (printf "Container - Expected non-empty [env.%s.key]" $key) -}}
{{- fail (printf "%s - Expected non-empty [%s.%s.env.%s.key]" $caller $key $name $ref) -}}
{{- end }}
key: {{ $obj.key | quote }}
{{- $name = tpl $obj.name $rootCtx -}}
{{- $refName = tpl $obj.name $rootCtx -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $rootCtx "objectData" $obj
"name" $k "caller" "Container"
"name" $k "caller" $caller
"key" "env")) -}}
{{- if eq $expandName "true" -}}
{{- $item := ($key | trimSuffix "KeyRef" | lower) -}}
{{- $item := ($ref | trimSuffix "KeyRef" | lower) -}}
{{- $data := (get $rootCtx.Values $item) -}}
{{- $data = (get $data $name) -}}
{{- $data = (get $data $refName) -}}
{{- if not $data -}}
{{- fail (printf "Container - Expected in [env] the referenced %s [%s] to be defined" ($item | camelcase | title) $name) -}}
{{- fail (printf "%s - Expected in [%s.%s.env] the referenced %s [%s] to be defined" $caller $key $name ($item | camelcase | title) $refName) -}}
{{- end -}}
{{- $found := false -}}
@@ -68,19 +71,19 @@ objectData: The object data to be used to render the container.
{{- end -}}
{{- if not $found -}}
{{- fail (printf "Container - Expected in [env] the referenced key [%s] in %s [%s] to be defined" $obj.key ($item | camelcase | title) $name) -}}
{{- fail (printf "%s - Expected in [%s.%s.env] the referenced key [%s] in %s [%s] to be defined" $caller $key $name $obj.key ($item | camelcase | title) $refName) -}}
{{- end -}}
{{- $name = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $name) -}}
{{- $refName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $refName) -}}
{{- end }}
name: {{ $name | quote }}
name: {{ $refName | quote }}
{{- end -}}
{{- end -}}
{{- if hasKey $v "fieldRef" }}
fieldRef:
{{- if not $v.fieldRef.fieldPath -}}
{{- fail "Container - Expected non-empty [env.fieldRef.fieldPath]" -}}
{{- fail (printf "%s - Expected non-empty [%s.%s.env.fieldRef.fieldPath]" $caller $key $name) -}}
{{- end }}
fieldPath: {{ $v.fieldRef.fieldPath | quote }}
{{- if $v.fieldRef.apiVersion }}
@@ -7,28 +7,31 @@ objectData: The object data to be used to render the container.
{{- define "tc.v1.common.lib.container.envFrom" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $key := .key -}}
{{- $name := (.name | toString) -}}
{{- $caller := .caller -}}
{{- $refs := (list "configMapRef" "secretRef") -}}
{{- range $envFrom := $objectData.envFrom -}}
{{- if and (not $envFrom.secretRef) (not $envFrom.configMapRef) -}}
{{- fail (printf "Container - Expected [envFrom] entry to have one of [%s]" (join ", " $refs)) -}}
{{- fail (printf "%s - Expected [envFrom] entry in [%s.%s] to have one of [%s]" $caller $key $name (join ", " $refs)) -}}
{{- end -}}
{{- if and $envFrom.secretRef $envFrom.configMapRef -}}
{{- fail (printf "Container - Expected [envFrom] entry to have only one of [%s], but got both" (join ", " $refs)) -}}
{{- fail (printf "%s - Expected [envFrom] entry in [%s.%s] to have only one of [%s], but got both" $caller $key $name (join ", " $refs)) -}}
{{- end -}}
{{- range $ref := $refs -}}
{{- with (get $envFrom $ref) -}}
{{- if not .name -}}
{{- fail (printf "Container - Expected non-empty [envFrom.%s.name]" $ref) -}}
{{- fail (printf "%s - Expected non-empty [%s.%s.envFrom.%s.name]" $caller $key $name $ref) -}}
{{- end -}}
{{- $objectName := tpl .name $rootCtx -}}
{{- $expandName := (include "tc.v1.common.lib.util.expandName" (dict
"rootCtx" $rootCtx "objectData" .
"name" $ref "caller" "Container"
"name" $ref "caller" $caller
"key" "envFrom")) -}}
{{- if eq $expandName "true" -}}
@@ -43,10 +46,10 @@ objectData: The object data to be used to render the container.
{{- end -}}
{{- if not $object -}}
{{- fail (printf "Container - Expected %s [%s] defined in [envFrom] to exist" $source $objectName) -}}
{{- fail (printf "%s - Expected %s [%s] defined in [%s.%s.envFrom] to exist" $caller $source $objectName $key $name) -}}
{{- end -}}
{{- range $k, $v := $object.data -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s - %s" $source $objectName) "key" $k) -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s - %s" $source $objectName) "key" $k "caller" $caller) -}}
{{- end -}}
{{- $objectName = (printf "%s-%s" (include "tc.v1.common.lib.chart.names.fullname" $rootCtx) $objectName) -}}
@@ -7,12 +7,15 @@ objectData: The object data to be used to render the container.
{{- define "tc.v1.common.lib.container.envList" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $key := .key -}}
{{- $name := (.name | toString) -}}
{{- $caller := .caller -}}
{{- range $env := $objectData.envList -}}
{{- if not $env.name -}}
{{- fail "Container - Expected non-empty [envList.name]" -}}
{{- fail (printf "%s - Expected non-empty [%s.%s.envList.name]" $caller $key $name) -}}
{{- end -}} {{/* Empty value is valid */}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "envList" "key" $env.name) -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s.%s.envList" $key $name) "key" $env.name "caller" $caller) -}}
{{- $value := $env.value -}}
{{- if kindIs "string" $env.value -}}
{{- $value = tpl $env.value $rootCtx -}}
@@ -7,6 +7,9 @@ objectData: The object data to be used to render the container.
{{- define "tc.v1.common.lib.container.fixedEnv" -}}
{{- $rootCtx := .rootCtx -}}
{{- $objectData := .objectData -}}
{{- $key := .key -}}
{{- $name := (.name | toString) -}}
{{- $caller := .caller -}}
{{/* Avoid nil pointers */}}
{{- if not (hasKey $objectData "fixedEnv") -}}
@@ -20,13 +23,13 @@ objectData: The object data to be used to render the container.
{{- end -}}
{{- if not (deepEqual $nvidiaCaps (mustUniq $nvidiaCaps)) -}}
{{- fail (printf "Container - Expected [fixedEnv.NVIDIA_CAPS] to have only unique values, but got [%s]" (join ", " $nvidiaCaps)) -}}
{{- fail (printf "%s - Expected [%s.%s.fixedEnv.NVIDIA_CAPS] to have only unique values, but got [%s]" $caller $key $name (join ", " $nvidiaCaps)) -}}
{{- end -}}
{{- $caps := (list "all" "compute" "utility" "graphics" "video") -}}
{{- range $cap := $nvidiaCaps -}}
{{- if not (mustHas $cap $caps) -}}
{{- fail (printf "Container - Expected [fixedEnv.NVIDIA_CAPS] entry to be one of [%s], but got [%s]" (join ", " $caps) $cap) -}}
{{- fail (printf "%s - Expected [%s.%s.fixedEnv.NVIDIA_CAPS] entry to be one of [%s], but got [%s]" $caller $key $name (join ", " $caps) $cap) -}}
{{- end -}}
{{- end -}}
@@ -90,7 +93,7 @@ objectData: The object data to be used to render the container.
{{- end -}}
{{- range $env := $fixed -}}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" "fixedEnv" "key" $env.k) }}
{{- include "tc.v1.common.helper.container.envDupeCheck" (dict "rootCtx" $rootCtx "objectData" $objectData "source" (printf "%s.%s.fixedEnv" $key $name) "key" $env.k "caller" $caller) }}
- name: {{ $env.k | quote }}
value: {{ (include "tc.v1.common.helper.makeIntOrNoop" $env.v) | quote }}
{{- end -}}
@@ -50,13 +50,21 @@ objectData: The object data to be used to render the Pod.
{{- include "tc.v1.common.lib.container.securityContext" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 }}
{{- /* Create a dict for storing env's so it can be checked for dupes */ -}}
{{- $_ := set $objectData "envDupe" dict -}}
{{- with (include "tc.v1.common.lib.container.envFrom" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim) }}
{{- with (include "tc.v1.common.lib.container.envFrom" (dict
"rootCtx" $rootCtx "objectData" $objectData "caller" "Container"
"name" $objectData.shortName "key" "containers") | trim) }}
envFrom:
{{- . | nindent 4 }}
{{- end }}
env:
{{- include "tc.v1.common.lib.container.fixedEnv" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 -}}
{{- include "tc.v1.common.lib.container.env" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 -}}
{{- include "tc.v1.common.lib.container.envList" (dict "rootCtx" $rootCtx "objectData" $objectData) | trim | nindent 4 -}}
{{- include "tc.v1.common.lib.container.fixedEnv" (dict
"rootCtx" $rootCtx "objectData" $objectData "caller" "Container"
"name" $objectData.shortName "key" "containers") | trim | nindent 4 -}}
{{- include "tc.v1.common.lib.container.env" (dict
"rootCtx" $rootCtx "objectData" $objectData "caller" "Container"
"name" $objectData.shortName "key" "containers") | trim | nindent 4 -}}
{{- include "tc.v1.common.lib.container.envList" (dict
"rootCtx" $rootCtx "objectData" $objectData "caller" "Container"
"name" $objectData.shortName "key" "containers") | trim | nindent 4 -}}
{{- $_ := unset $objectData "envDupe" -}}
{{- end -}}
+3
View File
@@ -1173,6 +1173,9 @@ cnpg:
# Additional Labels and annotations for cnpg cluster
labels: {}
annotations: {}
# Additional environment variables to set on all pods created in the cluster
env: {}
envFrom: {}
# Number of instances
instances: 2