rename fields, allow secretname, update docs
This commit is contained in:
parent
53e049af9a
commit
d6c686a70d
41
docs/user.md
41
docs/user.md
|
|
@ -150,21 +150,44 @@ user. There are two ways to define them:
|
||||||
|
|
||||||
#### Infrastructure roles secret
|
#### Infrastructure roles secret
|
||||||
|
|
||||||
The infrastructure roles secret is specified by the `infrastructure_roles_secret_name`
|
Infrastructure roles can be specified by the `infrastructure_roles_secrets`
|
||||||
parameter. The role definition looks like this (values are base64 encoded):
|
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 with incremented indexes.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
user1: ZGJ1c2Vy
|
apiVersion: v1
|
||||||
password1: c2VjcmV0
|
kind: Secret
|
||||||
inrole1: b3BlcmF0b3I=
|
metadata:
|
||||||
|
name: postgresql-infrastructure-roles
|
||||||
|
data:
|
||||||
|
user1: ZGJ1c2Vy
|
||||||
|
password1: c2VjcmV0
|
||||||
|
inrole1: b3BlcmF0b3I=
|
||||||
|
user2: ...
|
||||||
```
|
```
|
||||||
|
|
||||||
The block above describes the infrastructure role 'dbuser' with password
|
The block above describes the infrastructure role 'dbuser' with password
|
||||||
'secret' that is a member of the 'operator' role. For the following definitions
|
'secret' that is a member of the 'operator' role. The resulting role will
|
||||||
one must increase the index, i.e. the next role will be defined as 'user2' and
|
automatically be a login role.
|
||||||
so on. The resulting role will automatically be a login role.
|
|
||||||
|
|
||||||
Note that with definitions that solely use the infrastructure roles secret
|
With the new option the user can configure the names of secret keys that
|
||||||
|
contain the user name, password etc. If the secret uses a template for
|
||||||
|
multiple roles as described above, the `template` flag must be set to `true`.
|
||||||
|
The secret itself is referenced by the `secretname` key. Please, refer to the
|
||||||
|
example manifests to understand who `infrastructure_roles_secrets` has to be
|
||||||
|
configured for the [configmap](../manifests/configmap.yaml) (can only
|
||||||
|
reference one existing secret) or [CRD configuration](../manifests/postgresql-operator-default-configuration.yaml)
|
||||||
|
(reference multiple secret definitions in an array).
|
||||||
|
|
||||||
|
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. To migrate to the new format use the same names for the
|
||||||
|
secret keys as in the example above and unset the
|
||||||
|
`infrastructure_roles_secret_name`.
|
||||||
|
|
||||||
|
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
|
there is no way to specify role options (like superuser or nologin) or role
|
||||||
memberships. This is where the ConfigMap comes into play.
|
memberships. This is where the ConfigMap comes into play.
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -47,7 +47,8 @@ data:
|
||||||
# etcd_host: ""
|
# etcd_host: ""
|
||||||
# gcp_credentials: ""
|
# gcp_credentials: ""
|
||||||
# kubernetes_use_configmaps: "false"
|
# kubernetes_use_configmaps: "false"
|
||||||
# infrastructure_roles_secret_name: postgresql-infrastructure-roles
|
# infrastructure_roles_secret_name: "postgresql-infrastructure-roles"
|
||||||
|
# infrastructure_roles_secrets: "secretname:monitoring-roles,userkey:user,passwordkey:password,rolekey:inrole,template:true"
|
||||||
# inherited_labels: application,environment
|
# inherited_labels: application,environment
|
||||||
# kube_iam_role: ""
|
# kube_iam_role: ""
|
||||||
# log_s3_bucket: ""
|
# log_s3_bucket: ""
|
||||||
|
|
|
||||||
|
|
@ -39,6 +39,16 @@ configuration:
|
||||||
enable_pod_disruption_budget: true
|
enable_pod_disruption_budget: true
|
||||||
enable_sidecars: true
|
enable_sidecars: true
|
||||||
# infrastructure_roles_secret_name: "postgresql-infrastructure-roles"
|
# infrastructure_roles_secret_name: "postgresql-infrastructure-roles"
|
||||||
|
# infrastructure_roles_secrets:
|
||||||
|
# - secretname: "monitoring-roles"
|
||||||
|
# userkey: "user"
|
||||||
|
# passwordkey: "password"
|
||||||
|
# rolekey: "inrole"
|
||||||
|
# template: true
|
||||||
|
# - secretname: "other-infrastructure-role"
|
||||||
|
# userkey: "other-user-key"
|
||||||
|
# passwordkey: "other-password-key"
|
||||||
|
# template: false
|
||||||
# inherited_labels:
|
# inherited_labels:
|
||||||
# - application
|
# - application
|
||||||
# - environment
|
# - environment
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,10 @@ func (c *Controller) importConfigurationFromCRD(fromCRD *acidv1.OperatorConfigur
|
||||||
result.InfrastructureRoles = append(
|
result.InfrastructureRoles = append(
|
||||||
result.InfrastructureRoles,
|
result.InfrastructureRoles,
|
||||||
&config.InfrastructureRole{
|
&config.InfrastructureRole{
|
||||||
SecretName: secret.SecretName,
|
SecretName: secret.SecretName,
|
||||||
Name: secret.Name,
|
UserKey: secret.UserKey,
|
||||||
Role: secret.Role,
|
RoleKey: secret.RoleKey,
|
||||||
Password: secret.Password,
|
PasswordKey: secret.PasswordKey,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
v1 "k8s.io/api/core/v1"
|
v1 "k8s.io/api/core/v1"
|
||||||
|
|
@ -132,6 +133,8 @@ func (c *Controller) getInfrastructureRoleDefinitions() []*config.Infrastructure
|
||||||
// form key1: value1, key2: value2), which has to be used together with
|
// form key1: value1, key2: value2), which has to be used together with
|
||||||
// an old secret name.
|
// an old secret name.
|
||||||
|
|
||||||
|
var secretName spec.NamespacedName
|
||||||
|
var err error
|
||||||
propertySep := ","
|
propertySep := ","
|
||||||
valueSep := ":"
|
valueSep := ":"
|
||||||
|
|
||||||
|
|
@ -139,11 +142,6 @@ func (c *Controller) getInfrastructureRoleDefinitions() []*config.Infrastructure
|
||||||
// convert it to a proper definition
|
// convert it to a proper definition
|
||||||
properties := strings.Split(c.opConfig.InfrastructureRolesDefs, propertySep)
|
properties := strings.Split(c.opConfig.InfrastructureRolesDefs, propertySep)
|
||||||
|
|
||||||
roleDef = config.InfrastructureRole{
|
|
||||||
SecretName: c.opConfig.InfrastructureRolesSecretName,
|
|
||||||
Template: false,
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, property := range properties {
|
for _, property := range properties {
|
||||||
values := strings.Split(property, valueSep)
|
values := strings.Split(property, valueSep)
|
||||||
if len(values) < 2 {
|
if len(values) < 2 {
|
||||||
|
|
@ -153,15 +151,24 @@ func (c *Controller) getInfrastructureRoleDefinitions() []*config.Infrastructure
|
||||||
value := strings.TrimSpace(values[1])
|
value := strings.TrimSpace(values[1])
|
||||||
|
|
||||||
switch name {
|
switch name {
|
||||||
case "name":
|
case "secretname":
|
||||||
roleDef.Name = value
|
if err = secretName.DecodeWorker(value, "default"); err != nil {
|
||||||
case "password":
|
c.logger.Warningf("Could not marshal secret name %s: %v", value, err)
|
||||||
roleDef.Password = value
|
} else {
|
||||||
case "role":
|
roleDef.SecretName = secretName
|
||||||
roleDef.Role = value
|
}
|
||||||
|
case "userkey":
|
||||||
|
roleDef.UserKey = value
|
||||||
|
case "passwordkey":
|
||||||
|
roleDef.PasswordKey = value
|
||||||
|
case "rolekey":
|
||||||
|
roleDef.RoleKey = value
|
||||||
|
case "template":
|
||||||
|
if roleDef.Template, err = strconv.ParseBool(value); err != nil {
|
||||||
|
c.logger.Warningf("Could not extract template information %s: %v", value, err)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
c.logger.Warningf("Role description is not known: %s",
|
c.logger.Warningf("Role description is not known: %s", properties)
|
||||||
c.opConfig.InfrastructureRolesSecretName)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -169,17 +176,17 @@ func (c *Controller) getInfrastructureRoleDefinitions() []*config.Infrastructure
|
||||||
// via existing definition structure and remember that it's just a
|
// via existing definition structure and remember that it's just a
|
||||||
// template, the real values are in user1,password1,inrole1 etc.
|
// template, the real values are in user1,password1,inrole1 etc.
|
||||||
roleDef = config.InfrastructureRole{
|
roleDef = config.InfrastructureRole{
|
||||||
SecretName: c.opConfig.InfrastructureRolesSecretName,
|
SecretName: c.opConfig.InfrastructureRolesSecretName,
|
||||||
Name: "user",
|
UserKey: "user",
|
||||||
Password: "password",
|
PasswordKey: "password",
|
||||||
Role: "inrole",
|
RoleKey: "inrole",
|
||||||
Template: true,
|
Template: true,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if roleDef.Name != "" &&
|
if roleDef.UserKey != "" &&
|
||||||
roleDef.Password != "" &&
|
roleDef.PasswordKey != "" &&
|
||||||
roleDef.Role != "" {
|
roleDef.RoleKey != "" {
|
||||||
rolesDefs = append(rolesDefs, &roleDef)
|
rolesDefs = append(rolesDefs, &roleDef)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -280,9 +287,9 @@ func (c *Controller) getInfrastructureRole(
|
||||||
Users:
|
Users:
|
||||||
for i := 1; i <= len(secretData); i++ {
|
for i := 1; i <= len(secretData); i++ {
|
||||||
properties := []string{
|
properties := []string{
|
||||||
infraRole.Name,
|
infraRole.UserKey,
|
||||||
infraRole.Password,
|
infraRole.PasswordKey,
|
||||||
infraRole.Role,
|
infraRole.RoleKey,
|
||||||
}
|
}
|
||||||
t := spec.PgUser{Origin: spec.RoleOriginInfrastructure}
|
t := spec.PgUser{Origin: spec.RoleOriginInfrastructure}
|
||||||
for _, p := range properties {
|
for _, p := range properties {
|
||||||
|
|
@ -327,9 +334,9 @@ func (c *Controller) getInfrastructureRole(
|
||||||
return nil, fmt.Errorf("could not decode yaml role: %v", err)
|
return nil, fmt.Errorf("could not decode yaml role: %v", err)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
roleDescr.Name = string(secretData[infraRole.Name])
|
roleDescr.Name = string(secretData[infraRole.UserKey])
|
||||||
roleDescr.Password = string(secretData[infraRole.Password])
|
roleDescr.Password = string(secretData[infraRole.PasswordKey])
|
||||||
roleDescr.MemberOf = append(roleDescr.MemberOf, string(secretData[infraRole.Role]))
|
roleDescr.MemberOf = append(roleDescr.MemberOf, string(secretData[infraRole.RoleKey]))
|
||||||
}
|
}
|
||||||
|
|
||||||
if roleDescr.Valid() {
|
if roleDescr.Valid() {
|
||||||
|
|
|
||||||
|
|
@ -132,11 +132,11 @@ func TestOldInfrastructureRoleFormat(t *testing.T) {
|
||||||
roles, errors := utilTestController.getInfrastructureRoles(
|
roles, errors := utilTestController.getInfrastructureRoles(
|
||||||
[]*config.InfrastructureRole{
|
[]*config.InfrastructureRole{
|
||||||
&config.InfrastructureRole{
|
&config.InfrastructureRole{
|
||||||
SecretName: test.secretName,
|
SecretName: test.secretName,
|
||||||
Name: "user",
|
UserKey: "user",
|
||||||
Password: "password",
|
PasswordKey: "password",
|
||||||
Role: "inrole",
|
RoleKey: "inrole",
|
||||||
Template: true,
|
Template: true,
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
@ -231,11 +231,11 @@ func TestNewInfrastructureRoleFormat(t *testing.T) {
|
||||||
definitions := []*config.InfrastructureRole{}
|
definitions := []*config.InfrastructureRole{}
|
||||||
for _, secret := range test.secrets {
|
for _, secret := range test.secrets {
|
||||||
definitions = append(definitions, &config.InfrastructureRole{
|
definitions = append(definitions, &config.InfrastructureRole{
|
||||||
SecretName: secret,
|
SecretName: secret,
|
||||||
Name: "user",
|
UserKey: "user",
|
||||||
Password: "password",
|
PasswordKey: "password",
|
||||||
Role: "inrole",
|
RoleKey: "inrole",
|
||||||
Template: false,
|
Template: false,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -287,10 +287,10 @@ func TestInfrastructureRoleDefinitions(t *testing.T) {
|
||||||
Namespace: v1.NamespaceDefault,
|
Namespace: v1.NamespaceDefault,
|
||||||
Name: testInfrastructureRolesNewSecretName,
|
Name: testInfrastructureRolesNewSecretName,
|
||||||
},
|
},
|
||||||
Name: "user",
|
UserKey: "user",
|
||||||
Password: "password",
|
PasswordKey: "password",
|
||||||
Role: "inrole",
|
RoleKey: "inrole",
|
||||||
Template: false,
|
Template: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
spec.NamespacedName{},
|
spec.NamespacedName{},
|
||||||
|
|
@ -301,10 +301,10 @@ func TestInfrastructureRoleDefinitions(t *testing.T) {
|
||||||
Namespace: v1.NamespaceDefault,
|
Namespace: v1.NamespaceDefault,
|
||||||
Name: testInfrastructureRolesNewSecretName,
|
Name: testInfrastructureRolesNewSecretName,
|
||||||
},
|
},
|
||||||
Name: "user",
|
UserKey: "user",
|
||||||
Password: "password",
|
PasswordKey: "password",
|
||||||
Role: "inrole",
|
RoleKey: "inrole",
|
||||||
Template: false,
|
Template: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -322,10 +322,10 @@ func TestInfrastructureRoleDefinitions(t *testing.T) {
|
||||||
Namespace: v1.NamespaceDefault,
|
Namespace: v1.NamespaceDefault,
|
||||||
Name: testInfrastructureRolesOldSecretName,
|
Name: testInfrastructureRolesOldSecretName,
|
||||||
},
|
},
|
||||||
Name: "user",
|
UserKey: "user",
|
||||||
Password: "password",
|
PasswordKey: "password",
|
||||||
Role: "inrole",
|
RoleKey: "inrole",
|
||||||
Template: true,
|
Template: true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -336,17 +336,17 @@ func TestInfrastructureRoleDefinitions(t *testing.T) {
|
||||||
Namespace: v1.NamespaceDefault,
|
Namespace: v1.NamespaceDefault,
|
||||||
Name: testInfrastructureRolesOldSecretName,
|
Name: testInfrastructureRolesOldSecretName,
|
||||||
},
|
},
|
||||||
"name: test-user, password: test-password, role: test-role",
|
"secretname: infrastructureroles-old-test, userkey: test-user, passwordkey: test-password, rolekey: test-role, template: false",
|
||||||
[]*config.InfrastructureRole{
|
[]*config.InfrastructureRole{
|
||||||
&config.InfrastructureRole{
|
&config.InfrastructureRole{
|
||||||
SecretName: spec.NamespacedName{
|
SecretName: spec.NamespacedName{
|
||||||
Namespace: v1.NamespaceDefault,
|
Namespace: v1.NamespaceDefault,
|
||||||
Name: testInfrastructureRolesOldSecretName,
|
Name: testInfrastructureRolesOldSecretName,
|
||||||
},
|
},
|
||||||
Name: "test-user",
|
UserKey: "test-user",
|
||||||
Password: "test-password",
|
PasswordKey: "test-password",
|
||||||
Role: "test-role",
|
RoleKey: "test-role",
|
||||||
Template: false,
|
Template: false,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -364,7 +364,7 @@ func TestInfrastructureRoleDefinitions(t *testing.T) {
|
||||||
{
|
{
|
||||||
[]*config.InfrastructureRole{},
|
[]*config.InfrastructureRole{},
|
||||||
spec.NamespacedName{},
|
spec.NamespacedName{},
|
||||||
"name: test-user, password: test-password, role: test-role",
|
"userkey: test-user, passwordkey: test-password, rolekey: test-role, template: false",
|
||||||
[]*config.InfrastructureRole{},
|
[]*config.InfrastructureRole{},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -57,18 +57,18 @@ type InfrastructureRole struct {
|
||||||
// configmap with an extra information
|
// configmap with an extra information
|
||||||
SecretName spec.NamespacedName
|
SecretName spec.NamespacedName
|
||||||
|
|
||||||
Name string
|
UserKey string
|
||||||
Password string
|
PasswordKey string
|
||||||
Role string
|
RoleKey string
|
||||||
|
|
||||||
// This field point out the detailed yaml definition of the role, if exists
|
// This field point out the detailed yaml definition of the role, if exists
|
||||||
Details string
|
Details string
|
||||||
|
|
||||||
// Specify if a secret contains multiple fields in the following format:
|
// Specify if a secret contains multiple fields in the following format:
|
||||||
//
|
//
|
||||||
// %(name)idx: ...
|
// %(userkey)idx: ...
|
||||||
// %(password)idx: ...
|
// %(passwordkey)idx: ...
|
||||||
// %(role)idx: ...
|
// %(rolekey)idx: ...
|
||||||
//
|
//
|
||||||
// If it does, Name/Password/Role are interpreted not as unique field
|
// If it does, Name/Password/Role are interpreted not as unique field
|
||||||
// names, but as a template.
|
// names, but as a template.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue