Skip to content

Commit

Permalink
[WIP] Extend infrastructure roles handling (zalando#1064)
Browse files Browse the repository at this point in the history
Extend infrastructure roles handling

Postgres Operator uses infrastructure roles to provide access to a database for
external users e.g. for monitoring purposes. Such infrastructure roles are
expected to be present in the form of k8s secrets with the following content:

    inrole1: some_encrypted_role
    password1: some_encrypted_password
    user1: some_entrypted_name

    inrole2: some_encrypted_role
    password2: some_encrypted_password
    user2: some_entrypted_name

The format of this content is implied implicitly and not flexible enough. In
case if we do not have possibility to change the format of a secret we want to
use in the Operator, we need to recreate it in this format.

To address this lets make the format of secret content explicitly. The idea is
to introduce a new configuration option for the Operator.

    infrastructure_roles_secrets:
    - secretname: k8s_secret_name
      userkey: some_encrypted_name
      passwordkey: some_encrypted_password
      rolekey: some_encrypted_role

    - secretname: k8s_secret_name
      userkey: some_encrypted_name
      passwordkey: some_encrypted_password
      rolekey: some_encrypted_role

This would allow Operator to use any avalable secrets to prepare infrastructure
roles. To make it backward compatible simulate the old behaviour if the new
option is not present.

The new configuration option is intended be used mainly from CRD, but it's also
available via Operator ConfigMap in a limited fashion. For ConfigMap one can
put there only a string with one secret definition in the following format (as
a string):

    infrastructure_roles_secrets: |
        secretname: k8s_secret_name,
        userkey: some_encrypted_name,
        passwordkey: some_encrypted_password,
        rolekey: some_encrypted_role

Note than only one secret could be specified this way, no multiple secrets are
allowed.

Eventually the resulting list of infrastructure roles would be a total sum of
all supported ways to describe it, namely legacy via
infrastructure_roles_secret_name and infrastructure_roles_secrets from both
ConfigMap and CRD.
  • Loading branch information
erthalion authored Aug 5, 2020
1 parent f3ddce8 commit 7cf2fae
Show file tree
Hide file tree
Showing 20 changed files with 1,366 additions and 612 deletions.
22 changes: 22 additions & 0 deletions charts/postgres-operator/crds/operatorconfigurations.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,28 @@ spec:
type: boolean
infrastructure_roles_secret_name:
type: string
infrastructure_roles_secrets:
type: array
nullable: true
items:
type: object
required:
- secretname
- userkey
- passwordkey
properties:
secretname:
type: string
userkey:
type: string
passwordkey:
type: string
rolekey:
type: string
details:
type: string
template:
type: boolean
inherited_labels:
type: array
items:
Expand Down
10 changes: 8 additions & 2 deletions docs/reference/operator_parameters.md
Original file line number Diff line number Diff line change
Expand Up @@ -252,8 +252,14 @@ configuration they are grouped under the `kubernetes` key.
teams API. The default is `postgresql-operator`.
* **infrastructure_roles_secret_name**
namespaced name of the secret containing infrastructure roles names and
passwords.
*deprecated*: namespaced name of the secret containing infrastructure roles
with user names, passwords and role membership.
* **infrastructure_roles_secrets**
array of infrastructure role definitions which reference existing secrets
and specify the key names from which user name, password and role membership
are extracted. For the ConfigMap this has to be a string which allows
referencing only one infrastructure roles secret. The default is empty.
* **pod_role_label**
name of the label assigned to the Postgres pods (and services/endpoints) by
Expand Down
61 changes: 50 additions & 11 deletions docs/user.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,23 +150,62 @@ user. There are two ways to define them:

#### Infrastructure roles secret

The infrastructure roles secret is specified by the `infrastructure_roles_secret_name`
parameter. The role definition looks like this (values are base64 encoded):
Infrastructure roles can be specified by the `infrastructure_roles_secrets`
parameter where you can reference multiple existing secrets. Prior to `v1.6.0`
the operator could only reference one secret with the
`infrastructure_roles_secret_name` option. However, this secret could contain
multiple roles using the same set of keys plus incrementing index.

```yaml
user1: ZGJ1c2Vy
password1: c2VjcmV0
inrole1: b3BlcmF0b3I=
apiVersion: v1
kind: Secret
metadata:
name: postgresql-infrastructure-roles
data:
user1: ZGJ1c2Vy
password1: c2VjcmV0
inrole1: b3BlcmF0b3I=
user2: ...
```
The block above describes the infrastructure role 'dbuser' with password
'secret' that is a member of the 'operator' role. For the following definitions
one must increase the index, i.e. the next role will be defined as 'user2' and
so on. The resulting role will automatically be a login role.
'secret' that is a member of the 'operator' role. The resulting role will
automatically be a login role.
With the new option users can configure the names of secret keys that contain
the user name, password etc. The secret itself is referenced by the
`secretname` key. If the secret uses a template for multiple roles as described
above list them separately.

Note that with definitions that solely use the infrastructure roles secret
there is no way to specify role options (like superuser or nologin) or role
memberships. This is where the ConfigMap comes into play.
```yaml
apiVersion: v1
kind: OperatorConfiguration
metadata:
name: postgresql-operator-configuration
configuration:
kubernetes:
infrastructure_roles_secrets:
- secretname: "postgresql-infrastructure-roles"
userkey: "user1"
passwordkey: "password1"
rolekey: "inrole1"
- secretname: "postgresql-infrastructure-roles"
userkey: "user2"
...
```

Note, only the CRD-based configuration allows for referencing multiple secrets.
As of now, the ConfigMap is restricted to either one or the existing template
option with `infrastructure_roles_secret_name`. Please, refer to the example
manifests to understand how `infrastructure_roles_secrets` has to be configured
for the [configmap](../manifests/configmap.yaml) or [CRD configuration](../manifests/postgresql-operator-default-configuration.yaml).

If both `infrastructure_roles_secret_name` and `infrastructure_roles_secrets`
are defined the operator will create roles for both of them. So make sure,
they do not collide. Note also, that with definitions that solely use the
infrastructure roles secret there is no way to specify role options (like
superuser or nologin) or role memberships. This is where the additional
ConfigMap comes into play.

#### Secret plus ConfigMap

Expand Down
3 changes: 3 additions & 0 deletions e2e/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
# An image to perform the actual test. Do not forget to copy all necessary test
# files here.
FROM ubuntu:18.04
LABEL maintainer="Team ACID @ Zalando <team-acid@zalando.de>"

COPY manifests ./manifests
COPY exec.sh ./exec.sh
COPY requirements.txt tests ./

RUN apt-get update \
Expand Down
2 changes: 2 additions & 0 deletions e2e/exec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env bash
kubectl exec -it $1 -- sh -c "$2"
Loading

0 comments on commit 7cf2fae

Please sign in to comment.