Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 48 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -173,7 +173,7 @@ metadata:
postgres.db.movetokube.com/instance: POSTGRES_INSTANCE
spec:
role: username
database: my-db # This references the Postgres CR
database: my-db # This references the Postgres CR (deprecated; use `databases`)
secretName: my-secret
privileges: OWNER # Can be OWNER/READ/WRITE
annotations: # Annotations to be propagated to the secrets metadata section (optional)
Expand Down Expand Up @@ -235,6 +235,53 @@ Available context:
| `.Hostname` | Database host (without port) |
| `.Port` | Database port |

### Multi-Database PostgresUser

You can grant a single login role access to multiple databases. Use `spec.databases[]` to reference one or more
`Postgres` CRs in the same namespace, with per-database privileges.

Example:

```yaml
---
apiVersion: db.movetokube.com/v1alpha1
kind: Postgres
metadata:
name: foo-db
namespace: app
spec:
database: foo
---
apiVersion: db.movetokube.com/v1alpha1
kind: Postgres
metadata:
name: bar-db
namespace: app
spec:
database: bar
---
apiVersion: db.movetokube.com/v1alpha1
kind: PostgresUser
metadata:
name: app-user
namespace: app
spec:
role: app
databases:
- name: foo-db
privileges: OWNER
- name: bar-db
privileges: OWNER
secretName: my-secret
```

Notes:
- The operator creates a single login role (with random suffix) and grants it the proper group roles for each database.
- `status.grants[]` records the database-to-group mapping. Fields `status.databaseName` and `status.postgresGroup`
remain for backward compatibility and reflect the first database.
- Secrets still include a single `DATABASE_NAME` and URL values; for multi-DB users these point to the first referenced
database. Customize via `spec.secretTemplate` if needed.

### Compatibility

Postgres operator uses Operator SDK, which uses kubernetes client. Kubernetes client compatibility with Kubernetes cluster
Expand Down
34 changes: 30 additions & 4 deletions api/v1alpha1/postgresuser_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,26 +9,52 @@ import (

// PostgresUserSpec defines the desired state of PostgresUser
type PostgresUserSpec struct {
Role string `json:"role"`
Database string `json:"database"`
Role string `json:"role"`
// Deprecated: use Databases instead
Database string `json:"database,omitempty"`
SecretName string `json:"secretName"`
// +optional
SecretTemplate map[string]string `json:"secretTemplate,omitempty"` // key-value, where key is secret field, value is go template
// +optional
Privileges string `json:"privileges"`
// Deprecated: use Databases[].privileges instead
Privileges string `json:"privileges,omitempty"`
// +optional
Annotations map[string]string `json:"annotations,omitempty"`
// +optional
Labels map[string]string `json:"labels,omitempty"`
// +optional
// +listType=map
// +listMapKey=name
Databases []PostgresUserDatabaseRef `json:"databases,omitempty"`
}

// PostgresUserDatabaseRef references a Postgres CR and desired privileges
type PostgresUserDatabaseRef struct {
// name of the Postgres CR in the same namespace
Name string `json:"name"`
// Privileges: one of OWNER, WRITE, READ
Privileges string `json:"privileges"`
}

// PostgresUserStatus defines the observed state of PostgresUser
type PostgresUserStatus struct {
Succeeded bool `json:"succeeded"`
PostgresRole string `json:"postgresRole"`
PostgresLogin string `json:"postgresLogin"`
PostgresGroup string `json:"postgresGroup"`
// Deprecated: for multi-db, use Grants
PostgresGroup string `json:"postgresGroup,omitempty"`
// Deprecated: for multi-db, use Grants
DatabaseName string `json:"databaseName,omitempty"`
// +optional
// +listType=map
// +listMapKey=databaseName
Grants []PostgresUserDatabaseGrant `json:"grants,omitempty"`
}

// PostgresUserDatabaseGrant stores the granted group per database
type PostgresUserDatabaseGrant struct {
DatabaseName string `json:"databaseName"`
PostgresGroup string `json:"postgresGroup"`
}

// +kubebuilder:object:root=true
Expand Down
42 changes: 41 additions & 1 deletion api/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,18 @@ spec:
additionalProperties:
type: string
type: object
databases:
items:
properties:
name:
type: string
privileges:
type: string
required:
- name
- privileges
type: object
type: array
privileges:
type: string
role:
Expand All @@ -52,7 +64,6 @@ spec:
type: string
type: object
required:
- database
- role
- secretName
type: object
Expand All @@ -61,6 +72,18 @@ spec:
properties:
databaseName:
type: string
grants:
items:
properties:
databaseName:
type: string
postgresGroup:
type: string
required:
- databaseName
- postgresGroup
type: object
type: array
postgresGroup:
type: string
postgresLogin:
Expand All @@ -70,8 +93,6 @@ spec:
succeeded:
type: boolean
required:
- databaseName
- postgresGroup
- postgresLogin
- postgresRole
- succeeded
Expand Down
43 changes: 40 additions & 3 deletions config/crd/bases/db.movetokube.com_postgresusers.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,33 @@ spec:
type: string
type: object
database:
description: 'Deprecated: use Databases instead'
type: string
databases:
items:
description: PostgresUserDatabaseRef references a Postgres CR and
desired privileges
properties:
name:
description: name of the Postgres CR in the same namespace
type: string
privileges:
description: 'Privileges: one of OWNER, WRITE, READ'
type: string
required:
- name
- privileges
type: object
type: array
x-kubernetes-list-map-keys:
- name
x-kubernetes-list-type: map
labels:
additionalProperties:
type: string
type: object
privileges:
description: 'Deprecated: use Databases[].privileges instead'
type: string
role:
type: string
Expand All @@ -60,16 +81,34 @@ spec:
type: string
type: object
required:
- database
- role
- secretName
type: object
status:
description: PostgresUserStatus defines the observed state of PostgresUser
properties:
databaseName:
description: 'Deprecated: for multi-db, use Grants'
type: string
grants:
items:
description: PostgresUserDatabaseGrant stores the granted group
per database
properties:
databaseName:
type: string
postgresGroup:
type: string
required:
- databaseName
- postgresGroup
type: object
type: array
x-kubernetes-list-map-keys:
- databaseName
x-kubernetes-list-type: map
postgresGroup:
description: 'Deprecated: for multi-db, use Grants'
type: string
postgresLogin:
type: string
Expand All @@ -78,8 +117,6 @@ spec:
succeeded:
type: boolean
required:
- databaseName
- postgresGroup
- postgresLogin
- postgresRole
- succeeded
Expand Down
55 changes: 32 additions & 23 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
kind: ClusterRole
metadata:
name: ext-postgres-operator
name: manager-role
rules:
- apiGroups:
- ""
resources:
- configmaps
- secrets
- services
verbs:
- "*"
- apiGroups:
- ""
resources:
- pods
verbs:
- "get"
- apiGroups:
- "apps"
resources:
- replicasets
- deployments
verbs:
- "get"
- apiGroups:
- db.movetokube.com
resources:
- postgres
- postgresusers
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- db.movetokube.com
resources:
- postgres/finalizers
- postgresusers/finalizers
verbs:
- update
- apiGroups:
- db.movetokube.com
resources:
- postgres/status
- postgresusers/status
verbs:
- get
- patch
- update
Loading