Skip to content

Commit 595d62f

Browse files
authored
Merge branch 'master' into fix-keep-secret-values
2 parents 2f7e59c + 1d9e64b commit 595d62f

File tree

8 files changed

+115
-38
lines changed

8 files changed

+115
-38
lines changed

README.md

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,5 @@
11
# External PostgreSQL server operator for Kubernetes
22

3-
---------------------------------------------------------
4-
### IMPORTANT UPDATE
5-
6-
### Restoring pushes to DockerHub repository `movetokube/postgres-operator`
7-
8-
Some history about this:
9-
10-
About 10 days after announcing the decition to sunset free organisations in dockerhub and receiving heavily negative community feedback
11-
Docker revoked their decision, did a 180-degree turn and did not sunset free legacy organisations.
12-
13-
Thus, new images of this operator will be pushed to both `movetokube/postgres-operator` and `ghcr.io/movetokube/postgres-operator` for your convenience.
14-
15-
Starting with ext-postgres-operator Helm chart version **1.2.3** images will be pulled from ghcr by default, you can change this if you like.
16-
17-
Here's how to install it (please install with care according to your configuration):
18-
```shell
19-
helm repo add ext-postgres-operator https://movetokube.github.io/postgres-operator/
20-
helm upgrade --install -n operators ext-postgres-operator ext-postgres-operator/ext-postgres-operator --version 1.2.3
21-
```
22-
23-
----------------------------------------------------------
243
## Sponsors
254

265
Please consider sponsoring my work
@@ -39,6 +18,7 @@ None
3918
* Creates Kubernetes secret with postgres_uri in the same namespace as CR
4019
* Support for AWS RDS and Azure Database for PostgresSQL
4120
* Support for managing CRs in dynamically created namespaces
21+
* Template secret values
4222

4323
## Cloud specific configuration
4424

@@ -173,6 +153,8 @@ spec:
173153
privileges: OWNER # Can be OWNER/READ/WRITE
174154
annotations: # Annotations to be propagated to the secrets metadata section (optional)
175155
foo: "bar"
156+
secretTemplate: # Output secrets can be customized using standard Go templates
157+
PQ_URL: "host={{.Host}} user={{.Role}} password={{.Password}} dbname={{.Database}}"
176158
```
177159

178160
This creates a user role `username-<hash>` and grants role `test-db-group`, `test-db-writer` or `test-db-reader` depending on `privileges` property. Its credentials are put in secret `my-secret-my-db-user` (unless `KEEP_SECRET_NAME` is enabled).
@@ -203,6 +185,21 @@ With the help of annotations it is possible to create annotation-based copies of
203185

204186
For more information and an example, see [kubernetes-replicator#pull-based-replication](https://github.com/mittwald/kubernetes-replicator#pull-based-replication)
205187

188+
#### Template Use Case
189+
190+
Users can specify the structure and content of secrets based on their unique requirements using standard
191+
[Go templates](https://pkg.go.dev/text/template#hdr-Actions). This flexibility allows for a more tailored approach to
192+
meeting the specific needs of different applications.
193+
194+
Available context:
195+
196+
| Variable | Meaning |
197+
|-------------|--------------------------|
198+
| `.Host` | Database host |
199+
| `.Role` | Generated user/role name |
200+
| `.Database` | Referenced database name |
201+
| `.Password` | Generated role password |
202+
206203
### Contribution
207204

208205
You can contribute to this project by opening a PR to merge to `master`, or one of the `vX.X.X` branches.

charts/ext-postgres-operator/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,10 @@ type: application
1111
# This is the chart version. This version number should be incremented each time you make changes
1212
# to the chart and its templates, including the app version.
1313
# Versions are expected to follow Semantic Versioning (https://semver.org/)
14-
version: 1.2.3
14+
version: 1.2.5
1515

1616
# This is the version number of the application being deployed. This version number should be
1717
# incremented each time you make changes to the application. Versions are not expected to
1818
# follow Semantic Versioning. They should reflect the version the application is using.
1919
# It is recommended to use it with quotes.
20-
appVersion: "1.2.3"
20+
appVersion: "1.3.2"

charts/ext-postgres-operator/crds/db.movetokube.com_postgresusers_crd.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ spec:
3131
spec:
3232
description: PostgresUserSpec defines the desired state of PostgresUser
3333
properties:
34+
annotations:
35+
additionalProperties:
36+
type: string
37+
type: object
3438
database:
3539
type: string
3640
privileges:
@@ -39,6 +43,10 @@ spec:
3943
type: string
4044
secretName:
4145
type: string
46+
secretTemplate:
47+
additionalProperties:
48+
type: string
49+
type: object
4250
required:
4351
- database
4452
- role

charts/ext-postgres-operator/values.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ image:
88
repository: ghcr.io/movetokube/postgres-operator
99
pullPolicy: IfNotPresent
1010
# Overrides the image tag whose default is the chart appVersion.
11-
tag: "latest"
11+
tag: ""
1212

1313
# Override chart name, defaults to Chart.name
1414
nameOverride: ""

deploy/crds/db.movetokube.com_postgresusers_crd.yaml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ spec:
3131
spec:
3232
description: PostgresUserSpec defines the desired state of PostgresUser
3333
properties:
34+
annotations:
35+
additionalProperties:
36+
type: string
37+
type: object
3438
database:
3539
type: string
3640
privileges:
@@ -39,6 +43,10 @@ spec:
3943
type: string
4044
secretName:
4145
type: string
46+
secretTemplate:
47+
additionalProperties:
48+
type: string
49+
type: object
4250
required:
4351
- database
4452
- role

pkg/apis/db/v1alpha1/postgresuser_types.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ type PostgresUserSpec struct {
1414
Database string `json:"database"`
1515
SecretName string `json:"secretName"`
1616
// +optional
17+
SecretTemplate map[string]string `json:"secretTemplate,omitempty"` // key-value, where key is secret field, value is go template
18+
// +optional
1719
Privileges string `json:"privileges"`
1820
// +optional
1921
Annotations map[string]string `json:"annotations,omitempty"`

pkg/apis/db/v1alpha1/zz_generated.deepcopy.go

Lines changed: 16 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/controller/postgresuser/postgresuser_controller.go

Lines changed: 60 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
package postgresuser
22

33
import (
4+
"bytes"
45
"context"
56
goerr "errors"
67
"fmt"
8+
"text/template"
79

810
"github.com/movetokube/postgres-operator/pkg/config"
911

@@ -221,7 +223,10 @@ func (r *ReconcilePostgresUser) Reconcile(request reconcile.Request) (reconcile.
221223
return r.requeue(instance, err)
222224
}
223225

224-
secret := r.newSecretForCR(instance, role, password, login)
226+
secret, err := r.newSecretForCR(instance, role, password, login)
227+
if err != nil {
228+
return r.requeue(instance, err)
229+
}
225230

226231
// Set PostgresUser instance as the owner and controller
227232
if err := controllerutil.SetControllerReference(instance, secret, r.scheme); err != nil {
@@ -270,7 +275,7 @@ func (r *ReconcilePostgresUser) addFinalizer(reqLogger logr.Logger, m *dbv1alpha
270275
return nil
271276
}
272277

273-
func (r *ReconcilePostgresUser) newSecretForCR(cr *dbv1alpha1.PostgresUser, role, password, login string) *corev1.Secret {
278+
func (r *ReconcilePostgresUser) newSecretForCR(cr *dbv1alpha1.PostgresUser, role, password, login string) (*corev1.Secret, error) {
274279
pgUserUrl := fmt.Sprintf("postgresql://%s:%s@%s/%s", role, password, r.pgHost, cr.Status.DatabaseName)
275280
pgJDBCUrl := fmt.Sprintf("jdbc:postgresql://%s/%s", r.pgHost, cr.Status.DatabaseName)
276281
pgDotnetUrl := fmt.Sprintf("User ID=%s;Password=%s;Host=%s;Port=5432;Database=%s;", role, password, r.pgHost, cr.Status.DatabaseName)
@@ -283,24 +288,40 @@ func (r *ReconcilePostgresUser) newSecretForCR(cr *dbv1alpha1.PostgresUser, role
283288
name = cr.Spec.SecretName
284289
}
285290

291+
templateData, err := renderTemplate(cr.Spec.SecretTemplate, templateContext{
292+
Role: role,
293+
Host: r.pgHost,
294+
Database: cr.Status.DatabaseName,
295+
Password: password,
296+
})
297+
if err != nil {
298+
return nil, fmt.Errorf("render templated keys: %w", err)
299+
}
300+
301+
data := map[string][]byte{
302+
"POSTGRES_URL": []byte(pgUserUrl),
303+
"POSTGRES_JDBC_URL": []byte(pgJDBCUrl),
304+
"POSTGRES_DOTNET_URL": []byte(pgDotnetUrl),
305+
"HOST": []byte(r.pgHost),
306+
"DATABASE_NAME": []byte(cr.Status.DatabaseName),
307+
"ROLE": []byte(role),
308+
"PASSWORD": []byte(password),
309+
"LOGIN": []byte(login),
310+
}
311+
// templates may override standard keys
312+
for k, v := range templateData {
313+
data[k] = v
314+
}
315+
286316
return &corev1.Secret{
287317
ObjectMeta: metav1.ObjectMeta{
288318
Name: name,
289319
Namespace: cr.Namespace,
290320
Labels: labels,
291321
Annotations: annotations,
292322
},
293-
Data: map[string][]byte{
294-
"POSTGRES_URL": []byte(pgUserUrl),
295-
"POSTGRES_JDBC_URL": []byte(pgJDBCUrl),
296-
"POSTGRES_DOTNET_URL": []byte(pgDotnetUrl),
297-
"HOST": []byte(r.pgHost),
298-
"DATABASE_NAME": []byte(cr.Status.DatabaseName),
299-
"ROLE": []byte(role),
300-
"PASSWORD": []byte(password),
301-
"LOGIN": []byte(login),
302-
},
303-
}
323+
Data: data,
324+
}, nil
304325
}
305326

306327
func (r *ReconcilePostgresUser) requeue(cr *dbv1alpha1.PostgresUser, reason error) (reconcile.Result, error) {
@@ -354,3 +375,29 @@ func (r *ReconcilePostgresUser) addOwnerRef(reqLogger logr.Logger, instance *dbv
354375
err = r.client.Update(context.TODO(), instance)
355376
return err
356377
}
378+
379+
type templateContext struct {
380+
Host string
381+
Role string
382+
Database string
383+
Password string
384+
}
385+
386+
func renderTemplate(data map[string]string, tc templateContext) (map[string][]byte, error) {
387+
if len(data) == 0 {
388+
return nil, nil
389+
}
390+
var out = make(map[string][]byte, len(data))
391+
for key, templ := range data {
392+
parsed, err := template.New("").Parse(templ)
393+
if err != nil {
394+
return nil, fmt.Errorf("parse template %q: %w", key, err)
395+
}
396+
var content bytes.Buffer
397+
if err := parsed.Execute(&content, tc); err != nil {
398+
return nil, fmt.Errorf("execute template %q: %w", key, err)
399+
}
400+
out[key] = content.Bytes()
401+
}
402+
return out, nil
403+
}

0 commit comments

Comments
 (0)