Browse Source

fix(kubernetes): replace entire remote secret when pushing rather than merging (#6485)

Signed-off-by: Riccardo M. Cefala <riccardo@cefala.net>
Riccardo M. Cefala 2 weeks ago
parent
commit
453d3761dd
2 changed files with 82 additions and 4 deletions
  1. 5 2
      providers/v1/kubernetes/client.go
  2. 77 2
      providers/v1/kubernetes/client_test.go

+ 5 - 2
providers/v1/kubernetes/client.go

@@ -176,9 +176,12 @@ func (c *Client) mergePushSecretData(remoteRef esv1.PushSecretData, pushMeta *me
 	remoteSecret.ObjectMeta.Labels = targetLabels
 	remoteSecret.ObjectMeta.Annotations = targetAnnotations
 
-	// case 1: push the whole secret
+	// case 1: push the whole secret so remote data is replaced entirely
 	if remoteRef.GetProperty() == "" {
-		maps.Copy(remoteSecret.Data, localSecret.Data)
+		remoteSecret.Data = maps.Clone(localSecret.Data)
+		if remoteSecret.Data == nil {
+			remoteSecret.Data = make(map[string][]byte)
+		}
 		return nil
 	}
 

+ 77 - 2
providers/v1/kubernetes/client_test.go

@@ -904,7 +904,7 @@ func TestPushSecret(t *testing.T) {
 			},
 		},
 		{
-			name: "push the whole secret if neither remote property or secretKey is defined but keep existing keys",
+			name: "push the whole secret if neither remote property or secretKey is defined replacing the destination",
 			fields: fields{
 				Client: &fakeClient{
 					t: t,
@@ -931,12 +931,87 @@ func TestPushSecret(t *testing.T) {
 						Annotations: map[string]string{},
 					},
 					Data: map[string][]byte{
-						"token":  []byte(`foo`),
 						"token2": []byte(`foo`),
 					},
 				},
 			},
 		},
+		{
+			name: "push the whole secret removeing keys that no longer exist in source",
+			fields: fields{
+				Client: &fakeClient{
+					t: t,
+					secretMap: map[string]*v1.Secret{
+						"mysec": {
+							Data: map[string][]byte{
+								"a": []byte("a1"),
+								"b": []byte("b1"),
+								"c": []byte("c1"),
+							},
+						},
+					},
+				},
+			},
+			data: testingfake.PushSecretData{
+				RemoteKey: "mysec",
+			},
+			secret: &v1.Secret{
+				Data: map[string][]byte{
+					"a": []byte("a2"),
+					"b": []byte("b2"),
+				},
+			},
+			wantSecretMap: map[string]*v1.Secret{
+				"mysec": {
+					ObjectMeta: metav1.ObjectMeta{
+						Name:        "mysec",
+						Labels:      map[string]string{},
+						Annotations: map[string]string{},
+					},
+					Data: map[string][]byte{
+						"a": []byte("a2"),
+						"b": []byte("b2"),
+					},
+				},
+			},
+		},
+		{
+			name: "push with property doesn't touch other properties on the remote",
+			fields: fields{
+				Client: &fakeClient{
+					t: t,
+					secretMap: map[string]*v1.Secret{
+						"mysec": {
+							Data: map[string][]byte{
+								"owned-by-other": []byte(`untouched`),
+								"token":          []byte(`old`),
+							},
+						},
+					},
+				},
+			},
+			data: testingfake.PushSecretData{
+				SecretKey: secretKey,
+				RemoteKey: "mysec",
+				Property:  "token",
+			},
+			secret: &v1.Secret{
+				Data: map[string][]byte{secretKey: []byte("new")},
+			},
+			wantSecretMap: map[string]*v1.Secret{
+				"mysec": {
+					ObjectMeta: metav1.ObjectMeta{
+						Name:        "mysec",
+						Labels:      map[string]string{},
+						Annotations: map[string]string{},
+					},
+					Data: map[string][]byte{
+						"owned-by-other": []byte(`untouched`),
+						"token":          []byte(`new`),
+					},
+				},
+			},
+		},
 		{
 			name: "push the whole secret while secret exists into a single property",
 			fields: fields{