Repository: external-secrets/external-secrets (go)

Issue:
Implement Pushsecrets `updatePolicy: IfNotExists` for AWS Secrets Manager
**Describe the bug**
Just tried to push a secret and did not work. v0.9.15-2

**To Reproduce**
```
apiVersion: external-secrets.io/v1alpha1
kind: PushSecret
metadata:
  name: postgresql
  namespace: controlplane
spec:
  updatePolicy: IfNotExists
  deletionPolicy: Delete
  refreshInterval: 168h
  secretStoreRefs:
    - name: default
      kind: ClusterSecretStore
  selector:
    secret:
      name: postgresql
  data:
    - match:
        remoteRef:
          remoteKey: controlplane/postgresql-smg
```

**Expected behavior**
The secret to be pushed

**Screenshots**
``
{"level":"error","ts":1713276193.4958684,"msg":"Reconciler error","controller":"pushsecret","controllerGroup":"external-secrets.io","controllerKind":"PushSecret","PushSecret":{"name":"postgresql","namespace":"controlplane"},"namespace":"controlplane","name":"postgresql","reconcileID":"8012f29d-4fe7-4c13-a811-d08d54b51574","error":"could  not verify if secret exists in store: not implemented","stacktrace":"sigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).reconcileHandler\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.2/pkg/internal/controller/controller.go:329\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).proc  essNextWorkItem\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.2/pkg/internal/controller/controller.go:266\nsigs.k8s.io/controller-runtime/pkg/internal/controller.(*Controller).Start.func2.2\n\t/home/runner/go/pkg/mod/sigs.k8s.io/controller-runtime@v0.17.2/pkg/internal/controller/controller.go:227"}   
{"level":"info","ts":1713276208.7876587,"logger":"provider.aws","msg":"using aws session","region":"eu-west-1","external id":"","credentials":null}
``

Pull request description:
Implemented `updatePolicy: IfNotExists` for AWS Secret Store
## Problem Statement

What is the problem you're trying to solve?
Currently, `pdatePolicy: IfNotExists` with aws secret store does not work. The push secret checks if secret exist for the secret manager which is set to `not implemented` so push controller can't proceed with creating the secret

## Related Issue

Fixes #3380

## Proposed Changes

How do you like to solve the issue and why?
Implemented a check on the `SecretExist` which will return either true or false with err depending on the reponse received from the aws client. If the secret exist check return ResourceNotFound Err then it will return true and push_controller will be able to continue with its process

## Checklist

- [x] I have read the [contribution guidelines](https://external-secrets.io/latest/contributing/process/#submitting-a-pull-request)
- [x] All commits are signed with `git commit --signoff`
- [ ] My changes have reasonable test coverage
- [x] All tests pass with `make test`
- [x] I ensured my PR is ready for review with `make reviewable`


Patch:
diff --git a/pkg/provider/aws/secretsmanager/secretsmanager.go b/pkg/provider/aws/secretsmanager/secretsmanager.go
index 1a3bf9a66..40c50747b 100644
--- a/pkg/provider/aws/secretsmanager/secretsmanager.go
+++ b/pkg/provider/aws/secretsmanager/secretsmanager.go
@@ -212,8 +212,27 @@ func (sm *SecretsManager) DeleteSecret(ctx context.Context, remoteRef esv1beta1.
 	return err
 }
 
-func (sm *SecretsManager) SecretExists(_ context.Context, _ esv1beta1.PushSecretRemoteRef) (bool, error) {
-	return false, fmt.Errorf("not implemented")
+func (sm *SecretsManager) SecretExists(ctx context.Context, pushSecretRef esv1beta1.PushSecretRemoteRef) (bool, error) {
+	secretName := pushSecretRef.GetRemoteKey()
+	secretValue := awssm.GetSecretValueInput{
+		SecretId: &secretName,
+	}
+	_, err := sm.client.GetSecretValueWithContext(ctx, &secretValue)
+	if err != nil {
+		return sm.handleSecretError(err)
+	}
+	return true, nil
+}
+
+func (sm *SecretsManager) handleSecretError(err error) (bool, error) {
+	var aerr awserr.Error
+	if ok := errors.As(err, &aerr); !ok {
+		return false, err
+	}
+	if aerr.Code() == awssm.ErrCodeResourceNotFoundException {
+		return true, nil
+	}
+	return false, err
 }
 
 func (sm *SecretsManager) PushSecret(ctx context.Context, secret *corev1.Secret, psd esv1beta1.PushSecretData) error {


Test patch:
diff --git a/pkg/provider/aws/secretsmanager/secretsmanager_test.go b/pkg/provider/aws/secretsmanager/secretsmanager_test.go
index 51c2880b4..d0f514f36 100644
--- a/pkg/provider/aws/secretsmanager/secretsmanager_test.go
+++ b/pkg/provider/aws/secretsmanager/secretsmanager_test.go
@@ -1316,6 +1316,94 @@ func TestSecretsManagerValidate(t *testing.T) {
 		})
 	}
 }
+func TestSecretExists(t *testing.T) {
+	arn := "arn:aws:secretsmanager:us-east-1:702902267788:secret:foo-bar5-Robbgh"
+	defaultVersion := "00000000-0000-0000-0000-000000000002"
+	secretValueOutput := &awssm.GetSecretValueOutput{
+		ARN:       &arn,
+		VersionId: &defaultVersion,
+	}
+
+	blankSecretValueOutput := &awssm.GetSecretValueOutput{}
+
+	getSecretCorrectErr := awssm.ResourceNotFoundException{}
+	getSecretWrongErr := awssm.InvalidRequestException{}
+
+	pushSecretDataWithoutProperty := fake.PushSecretData{SecretKey: "fake-secret-key", RemoteKey: "fake-key", Property: ""}
+
+	type args struct {
+		store          *esv1beta1.AWSProvider
+		client         fakesm.Client
+		pushSecretData fake.PushSecretData
+	}
+
+	type want struct {
+		err       error
+		wantError bool
+	}
+
+	tests := map[string]struct {
+		args args
+		want want
+	}{
+		"SecretExistsReturnsTrueForExistingSecret": {
+			args: args{
+				store: makeValidSecretStore().Spec.Provider.AWS,
+				client: fakesm.Client{
+					GetSecretValueWithContextFn: fakesm.NewGetSecretValueWithContextFn(secretValueOutput, nil),
+				},
+				pushSecretData: pushSecretDataWithoutProperty,
+			},
+			want: want{
+				err:       nil,
+				wantError: true,
+			},
+		},
+		"SecretExistsReturnsTrueForNonExistingSecret": {
+			args: args{
+				store: makeValidSecretStore().Spec.Provider.AWS,
+				client: fakesm.Client{
+					GetSecretValueWithContextFn: fakesm.NewGetSecretValueWithContextFn(blankSecretValueOutput, &getSecretCorrectErr),
+				},
+				pushSecretData: pushSecretDataWithoutProperty,
+			},
+			want: want{
+				err:       nil,
+				wantError: true,
+			},
+		},
+		"SecretExistsReturnsFalseForErroredSecret": {
+			args: args{
+				store: makeValidSecretStore().Spec.Provider.AWS,
+				client: fakesm.Client{
+					GetSecretValueWithContextFn: fakesm.NewGetSecretValueWithContextFn(blankSecretValueOutput, &getSecretWrongErr),
+				},
+				pushSecretData: pushSecretDataWithoutProperty,
+			},
+			want: want{
+				err:       &getSecretWrongErr,
+				wantError: false,
+			},
+		},
+	}
+
+	for name, tc := range tests {
+		t.Run(name, func(t *testing.T) {
+			sm := &SecretsManager{
+				client: &tc.args.client,
+			}
+			got, err := sm.SecretExists(context.Background(), tc.args.pushSecretData)
+
+			assert.Equal(
+				t,
+				tc.want,
+				want{
+					err:       err,
+					wantError: got,
+				})
+		})
+	}
+}
 
 // FakeCredProvider implements the AWS credentials.Provider interface
 // It is used to inject an error into the AWS session to cause a