Browse Source

Implement SecretExists in AWS ParameterStore (#4377)

* Implement SecretExists in AWS ParameterStore

Signed-off-by: Ami Rahav <amirahav@users.noreply.github.com>

* Add missing prefix

Signed-off-by: Ami Rahav <amirahav@users.noreply.github.com>

---------

Signed-off-by: Ami Rahav <amirahav@users.noreply.github.com>
Co-authored-by: Amiram Rahav <arahav@blacksky.com>
Co-authored-by: Gergely Brautigam <182850+Skarlso@users.noreply.github.com>
Amiram Rahav 1 year ago
parent
commit
61ddb598d8

+ 24 - 2
pkg/provider/aws/parameterstore/parameterstore.go

@@ -151,8 +151,30 @@ func (pm *ParameterStore) DeleteSecret(ctx context.Context, remoteRef esv1beta1.
 	return nil
 }
 
-func (pm *ParameterStore) SecretExists(_ context.Context, _ esv1beta1.PushSecretRemoteRef) (bool, error) {
-	return false, errors.New("not implemented")
+func (pm *ParameterStore) SecretExists(ctx context.Context, pushSecretRef esv1beta1.PushSecretRemoteRef) (bool, error) {
+	secretName := pm.prefix + pushSecretRef.GetRemoteKey()
+
+	secretValue := ssm.GetParameterInput{
+		Name: &secretName,
+	}
+
+	_, err := pm.client.GetParameterWithContext(ctx, &secretValue)
+
+	if err != nil {
+		var aerr awserr.Error
+		if ok := errors.As(err, &aerr); !ok {
+			return false, err
+		}
+		if aerr.Code() == ssm.ErrCodeResourceNotFoundException {
+			return false, nil
+		}
+		if aerr.Code() == ssm.ErrCodeParameterNotFound {
+			return false, nil
+		}
+		return false, err
+	}
+
+	return true, nil
 }
 
 func (pm *ParameterStore) PushSecret(ctx context.Context, secret *corev1.Secret, data esv1beta1.PushSecretData) error {

+ 87 - 0
pkg/provider/aws/parameterstore/parameterstore_test.go

@@ -906,3 +906,90 @@ func getTagSlice() []*ssm.Tag {
 		},
 	}
 }
+
+func TestSecretExists(t *testing.T) {
+	parameterOutput := &ssm.GetParameterOutput{
+		Parameter: &ssm.Parameter{
+			Value: aws.String("sensitive"),
+		},
+	}
+
+	blankParameterOutput := &ssm.GetParameterOutput{}
+	getParameterCorrectErr := ssm.ResourceNotFoundException{}
+	getParameterWrongErr := ssm.InvalidParameters{}
+
+	pushSecretDataWithoutProperty := fake.PushSecretData{SecretKey: "fake-secret-key", RemoteKey: fakeSecretKey, Property: ""}
+
+	type args struct {
+		store          *esv1beta1.AWSProvider
+		client         fakeps.Client
+		pushSecretData fake.PushSecretData
+	}
+
+	type want struct {
+		err       error
+		wantError bool
+	}
+
+	tests := map[string]struct {
+		args args
+		want want
+	}{
+		"SecretExistsReturnsTrueForExistingParameter": {
+			args: args{
+				store: makeValidParameterStore().Spec.Provider.AWS,
+				client: fakeps.Client{
+					GetParameterWithContextFn: fakeps.NewGetParameterWithContextFn(parameterOutput, nil),
+				},
+				pushSecretData: pushSecretDataWithoutProperty,
+			},
+			want: want{
+				err:       nil,
+				wantError: true,
+			},
+		},
+		"SecretExistsReturnsFalseForNonExistingParameter": {
+			args: args{
+				store: makeValidParameterStore().Spec.Provider.AWS,
+				client: fakeps.Client{
+					GetParameterWithContextFn: fakeps.NewGetParameterWithContextFn(blankParameterOutput, &getParameterCorrectErr),
+				},
+				pushSecretData: pushSecretDataWithoutProperty,
+			},
+			want: want{
+				err:       nil,
+				wantError: false,
+			},
+		},
+		"SecretExistsReturnsFalseForErroredParameter": {
+			args: args{
+				store: makeValidParameterStore().Spec.Provider.AWS,
+				client: fakeps.Client{
+					GetParameterWithContextFn: fakeps.NewGetParameterWithContextFn(blankParameterOutput, &getParameterWrongErr),
+				},
+				pushSecretData: pushSecretDataWithoutProperty,
+			},
+			want: want{
+				err:       &getParameterWrongErr,
+				wantError: false,
+			},
+		},
+	}
+
+	for name, tc := range tests {
+		t.Run(name, func(t *testing.T) {
+			ps := &ParameterStore{
+				client: &tc.args.client,
+			}
+			got, err := ps.SecretExists(context.Background(), tc.args.pushSecretData)
+
+			assert.Equal(
+				t,
+				tc.want,
+				want{
+					err:       err,
+					wantError: got,
+				})
+		})
+	}
+}