diff --git a/charts/postgres-operator/values-crd.yaml b/charts/postgres-operator/values-crd.yaml index 9c482e0a4..d14c9d335 100644 --- a/charts/postgres-operator/values-crd.yaml +++ b/charts/postgres-operator/values-crd.yaml @@ -145,8 +145,10 @@ configKubernetes: # Postgres pods are terminated forcefully after this timeout pod_terminate_grace_period: 5m - # template for database user secrets generated by the operator - secret_name_template: "{namespace}.{username}.{cluster}.credentials.{tprkind}.{tprgroup}" + # template for database user secrets generated by the operator, + # here username contains the namespace in the format namespace.username + # if the user is in different namespace than cluster + secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" # set user and group for the spilo container (required to run Spilo as non-root process) # spilo_runasuser: "101" # spilo_runasgroup: "103" diff --git a/charts/postgres-operator/values.yaml b/charts/postgres-operator/values.yaml index 3c6349bcc..8827a13f1 100644 --- a/charts/postgres-operator/values.yaml +++ b/charts/postgres-operator/values.yaml @@ -137,8 +137,10 @@ configKubernetes: # Postgres pods are terminated forcefully after this timeout pod_terminate_grace_period: 5m - # template for database user secrets generated by the operator - secret_name_template: "{namespace}.{username}.{cluster}.credentials.{tprkind}.{tprgroup}" + # template for database user secrets generated by the operator, + # here username contains the namespace in the format namespace.username + # if the user is in different namespace than cluster + secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" # set user and group for the spilo container (required to run Spilo as non-root process) # spilo_runasuser: "101" # spilo_runasgroup: "103" diff --git a/docs/reference/operator_parameters.md b/docs/reference/operator_parameters.md index 980e27c4c..59dd4297d 100644 --- a/docs/reference/operator_parameters.md +++ b/docs/reference/operator_parameters.md @@ -275,12 +275,13 @@ configuration they are grouped under the `kubernetes` key. * **secret_name_template** a template for the name of the database user secrets generated by the - operator. `{namesapce}` is replaced with name of the namespace (if any, - otherwise empty), `{username}` is replaced with name of the secret, + operator. `{namespace}` is replaced with name of the namespace (if any, + otherwise the secret is in cluster's namespace and in that case it is not + present in secret name), `{username}` is replaced with name of the secret, `{cluster}` with the name of the cluster, `{tprkind}` with the kind of CRD (formerly known as TPR) and `{tprgroup}` with the group of the CRD. No other placeholders are allowed. The default is - `{namesapce}.{username}.{cluster}.credentials.{tprkind}.{tprgroup}`. + `{namespace}.{username}.{cluster}.credentials.{tprkind}.{tprgroup}`. * **cluster_domain** defines the default DNS domain for the kubernetes cluster the operator is diff --git a/e2e/tests/test_e2e.py b/e2e/tests/test_e2e.py index 7a414379f..bd3566d5f 100644 --- a/e2e/tests/test_e2e.py +++ b/e2e/tests/test_e2e.py @@ -594,7 +594,13 @@ class EndToEndTestCase(unittest.TestCase): ''' app_namespace = "appspace" k8s = self.k8s - k8s.api.core_v1.create_namespace(app_namespace) + v1_appnamespace = client.V1Namespace(metadata=client.V1ObjectMeta(name=app_namespace)) + try: + k8s.api.core_v1.create_namespace(v1_appnamespace) + except timeout_decorator.TimeoutError: + print('Operator log: {}'.format(k8s.get_operator_log())) + raise + k8s.api.custom_objects_api.patch_namespaced_custom_object( 'acid.zalan.do', 'v1', 'default', 'postgresqls', 'acid-minimal-cluster', @@ -606,7 +612,7 @@ class EndToEndTestCase(unittest.TestCase): } }) self.eventuallyEqual(lambda: k8s.count_secrets_in_namespace(app_namespace), - 1, "Secret not created in user namespace") + 1, "Secret not created for user in namespace", app_namespace) @timeout_decorator.timeout(TEST_TIMEOUT_SEC) def test_lazy_spilo_upgrade(self): diff --git a/manifests/configmap.yaml b/manifests/configmap.yaml index 7898735bd..b379975eb 100644 --- a/manifests/configmap.yaml +++ b/manifests/configmap.yaml @@ -113,7 +113,7 @@ data: resync_period: 30m ring_log_lines: "100" role_deletion_suffix: "_deleted" - secret_name_template: "{namespace}.{username}.{cluster}.credentials" + secret_name_template: "{username}.{cluster}.credentials" # sidecar_docker_images: "" # set_memory_request_to_limit: "false" spilo_allow_privilege_escalation: "true" diff --git a/manifests/postgresql-operator-default-configuration.yaml b/manifests/postgresql-operator-default-configuration.yaml index 1af4a9ce4..65dfd6ce4 100644 --- a/manifests/postgresql-operator-default-configuration.yaml +++ b/manifests/postgresql-operator-default-configuration.yaml @@ -78,7 +78,7 @@ configuration: pod_service_account_name: postgres-pod # pod_service_account_role_binding_definition: "" pod_terminate_grace_period: 5m - secret_name_template: "{namespace}.{username}.{cluster}.credentials.{tprkind}.{tprgroup}" + secret_name_template: "{username}.{cluster}.credentials.{tprkind}.{tprgroup}" spilo_allow_privilege_escalation: true # spilo_runasuser: 101 # spilo_runasgroup: 103 diff --git a/pkg/cluster/cluster_test.go b/pkg/cluster/cluster_test.go index c118e82a4..8859d2730 100644 --- a/pkg/cluster/cluster_test.go +++ b/pkg/cluster/cluster_test.go @@ -907,7 +907,7 @@ func TestCrossNamespacedSecrets(t *testing.T) { err := cluster.initRobotUsers() if err != nil { - t.Errorf("%s Could not create namespaced users with error: %s", testName, err) + t.Errorf("Could not create secret for namespaced users with error: %s", err) } for _, u := range cluster.pgUsers { @@ -920,7 +920,7 @@ func TestCrossNamespacedSecrets(t *testing.T) { func TestValidUsernames(t *testing.T) { testName := "test username validity" - invalidUsernames := []string{"_", ".", ".user", "appspace.", "appspace.user.extra", "user_", "_user", "-user", "user-", ",", ",user", "user,", "namespace,user"} + invalidUsernames := []string{"_", ".", ".user", "appspace.", "appspace.user.extra", "user_", "_user", "-user", "user-", ",", "-", ",user", "user,", "namespace,user"} for _, username := range invalidUsernames { if isValidUsername(username) { diff --git a/pkg/cluster/sync.go b/pkg/cluster/sync.go index b8068b6e9..ac64747be 100644 --- a/pkg/cluster/sync.go +++ b/pkg/cluster/sync.go @@ -556,13 +556,26 @@ func (c *Cluster) syncRoles() (err error) { // create list of database roles to query for _, u := range c.pgUsers { - pg_role := u.Name + pgRole := u.Name if u.Namespace != c.Namespace { // to avoid the conflict of having multiple users of same name // but each in different namespace. - pg_role = fmt.Sprintf("%s.%s", u.Name, u.Namespace) + pgRole = fmt.Sprintf("%s.%s", u.Name, u.Namespace) + } + userNames = append(userNames, pgRole) + // add team member role name with rename suffix in case we need to rename it back + if u.Origin == spec.RoleOriginTeamsAPI && c.OpConfig.EnableTeamMemberDeprecation { + deletedUsers[u.Name+c.OpConfig.RoleDeletionSuffix] = u.Name + userNames = append(userNames, u.Name+c.OpConfig.RoleDeletionSuffix) + } + } + + // add team members that exist only in cache + // to trigger a rename of the role in ProduceSyncRequests + for _, cachedUser := range c.pgUsersCache { + if _, exists := c.pgUsers[cachedUser.Name]; !exists { + userNames = append(userNames, cachedUser.Name) } - userNames = append(userNames, pg_role) } // add pooler user to list of pgUsers, too