Skip to content

Commit 12d1019

Browse files
committed
skip db user actions when its secret failed to sync on update
1 parent 1af4c50 commit 12d1019

File tree

4 files changed

+59
-16
lines changed

4 files changed

+59
-16
lines changed

pkg/cluster/sync.go

Lines changed: 36 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1064,19 +1064,26 @@ func (c *Cluster) syncSecrets() error {
10641064
currentTime := time.Now()
10651065

10661066
for secretUsername, generatedSecret := range generatedSecrets {
1067-
secret, err := c.KubeClient.Secrets(generatedSecret.Namespace).Create(context.TODO(), generatedSecret, metav1.CreateOptions{})
1067+
pgUserDegraded := false
1068+
createdSecret, err := c.KubeClient.Secrets(generatedSecret.Namespace).Create(context.TODO(), generatedSecret, metav1.CreateOptions{})
10681069
if err == nil {
1069-
c.Secrets[secret.UID] = secret
1070-
c.logger.Infof("created new secret %s, namespace: %s, uid: %s", util.NameFromMeta(secret.ObjectMeta), generatedSecret.Namespace, secret.UID)
1070+
c.Secrets[createdSecret.UID] = createdSecret
1071+
c.logger.Infof("created new secret %s, namespace: %s, uid: %s", util.NameFromMeta(createdSecret.ObjectMeta), generatedSecret.Namespace, createdSecret.UID)
10711072
continue
10721073
}
10731074
if k8sutil.ResourceAlreadyExists(err) {
1074-
if err = c.updateSecret(secretUsername, generatedSecret, &retentionUsers, currentTime); err != nil {
1075-
c.logger.Warningf("syncing secret %s failed: %v", util.NameFromMeta(secret.ObjectMeta), err)
1075+
updatedSecret, err := c.updateSecret(secretUsername, generatedSecret, &retentionUsers, currentTime)
1076+
if err == nil {
1077+
c.Secrets[updatedSecret.UID] = updatedSecret
1078+
continue
10761079
}
1080+
c.logger.Warningf("syncing secret %s failed: %v", util.NameFromMeta(updatedSecret.ObjectMeta), err)
1081+
pgUserDegraded = true
10771082
} else {
1078-
return fmt.Errorf("could not create secret for user %s: in namespace %s: %v", secretUsername, generatedSecret.Namespace, err)
1083+
c.logger.Warningf("could not create secret for user %s: in namespace %s: %v", secretUsername, generatedSecret.Namespace, err)
1084+
pgUserDegraded = true
10791085
}
1086+
c.updatePgUser(secretUsername, pgUserDegraded)
10801087
}
10811088

10821089
// remove rotation users that exceed the retention interval
@@ -1105,7 +1112,7 @@ func (c *Cluster) updateSecret(
11051112
secretUsername string,
11061113
generatedSecret *v1.Secret,
11071114
retentionUsers *[]string,
1108-
currentTime time.Time) error {
1115+
currentTime time.Time) (*v1.Secret, error) {
11091116
var (
11101117
secret *v1.Secret
11111118
err error
@@ -1115,7 +1122,7 @@ func (c *Cluster) updateSecret(
11151122

11161123
// get the secret first
11171124
if secret, err = c.KubeClient.Secrets(generatedSecret.Namespace).Get(context.TODO(), generatedSecret.Name, metav1.GetOptions{}); err != nil {
1118-
return fmt.Errorf("could not get current secret: %v", err)
1125+
return generatedSecret, fmt.Errorf("could not get current secret: %v", err)
11191126
}
11201127
c.Secrets[secret.UID] = secret
11211128

@@ -1211,24 +1218,22 @@ func (c *Cluster) updateSecret(
12111218
if updateSecret {
12121219
c.logger.Infof("%s", updateSecretMsg)
12131220
if secret, err = c.KubeClient.Secrets(secret.Namespace).Update(context.TODO(), secret, metav1.UpdateOptions{}); err != nil {
1214-
return fmt.Errorf("could not update secret %s: %v", secretName, err)
1221+
return secret, fmt.Errorf("could not update secret %s: %v", secretName, err)
12151222
}
1216-
c.Secrets[secret.UID] = secret
12171223
}
12181224

12191225
if changed, _ := c.compareAnnotations(secret.Annotations, generatedSecret.Annotations, nil); changed {
12201226
patchData, err := metaAnnotationsPatch(generatedSecret.Annotations)
12211227
if err != nil {
1222-
return fmt.Errorf("could not form patch for secret %q annotations: %v", secret.Name, err)
1228+
return secret, fmt.Errorf("could not form patch for secret %q annotations: %v", secret.Name, err)
12231229
}
12241230
secret, err = c.KubeClient.Secrets(secret.Namespace).Patch(context.TODO(), secret.Name, types.MergePatchType, []byte(patchData), metav1.PatchOptions{})
12251231
if err != nil {
1226-
return fmt.Errorf("could not patch annotations for secret %q: %v", secret.Name, err)
1232+
return secret, fmt.Errorf("could not patch annotations for secret %q: %v", secret.Name, err)
12271233
}
1228-
c.Secrets[secret.UID] = secret
12291234
}
12301235

1231-
return nil
1236+
return secret, nil
12321237
}
12331238

12341239
func (c *Cluster) rotatePasswordInSecret(
@@ -1334,6 +1339,23 @@ func (c *Cluster) rotatePasswordInSecret(
13341339
return updateSecretMsg, nil
13351340
}
13361341

1342+
func (c *Cluster) updatePgUser(secretUsername string, degraded bool) {
1343+
for key, pgUser := range c.pgUsers {
1344+
if pgUser.Name == secretUsername {
1345+
pgUser.Degraded = degraded
1346+
c.pgUsers[key] = pgUser
1347+
return
1348+
}
1349+
}
1350+
for key, pgUser := range c.systemUsers {
1351+
if pgUser.Name == secretUsername {
1352+
pgUser.Degraded = degraded
1353+
c.systemUsers[key] = pgUser
1354+
return
1355+
}
1356+
}
1357+
}
1358+
13371359
func (c *Cluster) syncRoles() (err error) {
13381360
c.setProcessName("syncing roles")
13391361

pkg/cluster/sync_test.go

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,12 @@ import (
1212

1313
v1 "k8s.io/api/core/v1"
1414
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
15+
"k8s.io/apimachinery/pkg/runtime"
1516
"k8s.io/apimachinery/pkg/types"
17+
k8stesting "k8s.io/client-go/testing"
1618

1719
"github.com/golang/mock/gomock"
20+
"github.com/pkg/errors"
1821
"github.com/sirupsen/logrus"
1922
"github.com/stretchr/testify/assert"
2023
"github.com/zalando/postgres-operator/mocks"
@@ -50,6 +53,16 @@ func newFakeK8sSyncClient() (k8sutil.KubernetesClient, *fake.Clientset) {
5053
}
5154

5255
func newFakeK8sSyncSecretsClient() (k8sutil.KubernetesClient, *fake.Clientset) {
56+
// add a reactor that checks namespace existence before creating secrets
57+
clientSet.PrependReactor("create", "secrets", func(action k8stesting.Action) (bool, runtime.Object, error) {
58+
createAction := action.(k8stesting.CreateAction)
59+
secret := createAction.GetObject().(*v1.Secret)
60+
if secret.Namespace != "default" {
61+
return true, nil, errors.New("namespace does not exist")
62+
}
63+
return false, nil, nil
64+
})
65+
5366
return k8sutil.KubernetesClient{
5467
SecretsGetter: clientSet.CoreV1(),
5568
}, clientSet
@@ -810,7 +823,7 @@ func TestUpdateSecret(t *testing.T) {
810823
},
811824
Spec: acidv1.PostgresSpec{
812825
Databases: map[string]string{dbname: dbowner},
813-
Users: map[string]acidv1.UserFlags{appUser: {}, "bar": {}, dbowner: {}},
826+
Users: map[string]acidv1.UserFlags{appUser: {}, "bar": {}, dbowner: {}, "not-exist.test_user": {}},
814827
UsersIgnoringSecretRotation: []string{"bar"},
815828
UsersWithInPlaceSecretRotation: []string{dbowner},
816829
Streams: []acidv1.Stream{
@@ -842,6 +855,7 @@ func TestUpdateSecret(t *testing.T) {
842855
PasswordRotationInterval: 1,
843856
PasswordRotationUserRetention: 3,
844857
},
858+
EnableCrossNamespaceSecret: true,
845859
Resources: config.Resources{
846860
ClusterLabels: map[string]string{"application": "spilo"},
847861
ClusterNameLabel: "cluster-name",
@@ -864,7 +878,9 @@ func TestUpdateSecret(t *testing.T) {
864878

865879
allUsers := make(map[string]spec.PgUser)
866880
for _, pgUser := range cluster.pgUsers {
867-
allUsers[pgUser.Name] = pgUser
881+
if !pgUser.Degraded {
882+
allUsers[pgUser.Name] = pgUser
883+
}
868884
}
869885
for _, systemUser := range cluster.systemUsers {
870886
allUsers[systemUser.Name] = systemUser

pkg/spec/types.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ type PgUser struct {
5858
IsDbOwner bool `yaml:"is_db_owner"`
5959
Deleted bool `yaml:"deleted"`
6060
Rotated bool `yaml:"rotated"`
61+
Degraded bool `yaml:"degraded"`
6162
}
6263

6364
func (user *PgUser) Valid() bool {

pkg/util/users/users.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ func (strategy DefaultUserSyncStrategy) ProduceSyncRequests(dbUsers spec.PgUserM
4848
if newUser.Deleted {
4949
continue
5050
}
51+
// when the secret of the user could not be created or updated skip any database actions
52+
if newUser.Degraded {
53+
continue
54+
}
5155
dbUser, exists := dbUsers[name]
5256
if !exists {
5357
reqs = append(reqs, spec.PgSyncUserRequest{Kind: spec.PGSyncUserAdd, User: newUser})

0 commit comments

Comments
 (0)