Browse Source

feat(kubernetes): implement SecretExists (#5973)

Co-authored-by: Gergely Bräutigam <gergely.brautigam@sap.com>
Sakari Tanskanen 1 month ago
parent
commit
441d838b0c
2 changed files with 89 additions and 3 deletions
  1. 14 3
      providers/v1/kubernetes/client.go
  2. 75 0
      providers/v1/kubernetes/client_test.go

+ 14 - 3
providers/v1/kubernetes/client.go

@@ -105,9 +105,20 @@ func (c *Client) DeleteSecret(ctx context.Context, remoteRef esv1.PushSecretRemo
 }
 
 // SecretExists checks if a secret exists in Kubernetes.
-// This method is not implemented and always returns an error.
-func (c *Client) SecretExists(_ context.Context, _ esv1.PushSecretRemoteRef) (bool, error) {
-	return false, errors.New("not implemented")
+func (c *Client) SecretExists(ctx context.Context, ref esv1.PushSecretRemoteRef) (bool, error) {
+	secret, err := c.userSecretClient.Get(ctx, ref.GetRemoteKey(), metav1.GetOptions{})
+	metrics.ObserveAPICall(constants.ProviderKubernetes, constants.CallKubernetesGetSecret, err)
+	if err != nil {
+		if apierrors.IsNotFound(err) {
+			return false, nil
+		}
+		return false, err
+	}
+	if ref.GetProperty() != "" {
+		_, ok := secret.Data[ref.GetProperty()]
+		return ok, nil
+	}
+	return true, nil
 }
 
 // PushSecret creates or updates a secret in Kubernetes.

+ 75 - 0
providers/v1/kubernetes/client_test.go

@@ -596,6 +596,81 @@ func TestGetAllSecrets(t *testing.T) {
 	}
 }
 
+func TestSecretExists(t *testing.T) {
+	tests := []struct {
+		name      string
+		secrets   map[string]*v1.Secret
+		clientErr error
+		ref       v1alpha1.PushSecretRemoteRef
+		want      bool
+		wantErr   bool
+	}{
+		{
+			name: "secret exists without property",
+			secrets: map[string]*v1.Secret{
+				"mysec": {
+					Data: map[string][]byte{
+						"token": []byte("foobar"),
+					},
+				},
+			},
+			ref:  v1alpha1.PushSecretRemoteRef{RemoteKey: "mysec"},
+			want: true,
+		},
+		{
+			name:    "secret does not exist",
+			secrets: map[string]*v1.Secret{},
+			ref:     v1alpha1.PushSecretRemoteRef{RemoteKey: "mysec"},
+			want:    false,
+		},
+		{
+			name: "secret exists and property exists",
+			secrets: map[string]*v1.Secret{
+				"mysec": {
+					Data: map[string][]byte{
+						"token": []byte("foobar"),
+					},
+				},
+			},
+			ref:  v1alpha1.PushSecretRemoteRef{RemoteKey: "mysec", Property: "token"},
+			want: true,
+		},
+		{
+			name: "secret exists but property does not",
+			secrets: map[string]*v1.Secret{
+				"mysec": {
+					Data: map[string][]byte{
+						"token": []byte("foobar"),
+					},
+				},
+			},
+			ref:  v1alpha1.PushSecretRemoteRef{RemoteKey: "mysec", Property: "missing"},
+			want: false,
+		},
+		{
+			name:      "client error is propagated",
+			clientErr: errors.New(errSomethingWentWrong),
+			ref:       v1alpha1.PushSecretRemoteRef{RemoteKey: "mysec"},
+			wantErr:   true,
+		},
+	}
+	for _, tt := range tests {
+		t.Run(tt.name, func(t *testing.T) {
+			p := &Client{
+				userSecretClient: &fakeClient{t: t, secretMap: tt.secrets, err: tt.clientErr},
+			}
+			got, err := p.SecretExists(context.Background(), tt.ref)
+			if (err != nil) != tt.wantErr {
+				t.Errorf("SecretExists() error = %v, wantErr %v", err, tt.wantErr)
+				return
+			}
+			if got != tt.want {
+				t.Errorf("SecretExists() = %v, want %v", got, tt.want)
+			}
+		})
+	}
+}
+
 func TestDeleteSecret(t *testing.T) {
 	type fields struct {
 		Client KClient