Browse Source

Developing unit tests and fixing provider files. In process of starting to write e2e test files

Kian 4 years ago
parent
commit
926e37448a

+ 11 - 2
apis/externalsecrets/v1alpha1/secretstore_oracle_types.go

@@ -22,8 +22,14 @@ type OracleProvider struct {
 	// Auth configures how secret-manager authenticates with the Oracle secrets manager.
 	Auth OracleAuth `json:"auth"`
 
+	// User is an access OCID specific to the account.
+	User string `json:"user,omitempty"`
+
+	// projectID is an access token specific to the secret.
+	Tenancy string `json:"tenancy,omitempty"`
+
 	// projectID is an access token specific to the secret.
-	ProjectID *string `json:"projectID,omitempty"`
+	Region string `json:"region,omitempty"`
 }
 
 type OracleAuth struct {
@@ -32,5 +38,8 @@ type OracleAuth struct {
 
 type OracleSecretRef struct {
 	// The Access Token is used for authentication
-	KeyId esmeta.SecretKeySelector `json:"token,omitempty"`
+	PrivateKey esmeta.SecretKeySelector `json:"privatekey,omitempty"`
+
+	// projectID is an access token specific to the secret.
+	Fingerprint esmeta.SecretKeySelector `json:"fingerprint,omitempty"`
 }

+ 2 - 6
apis/externalsecrets/v1alpha1/zz_generated.deepcopy.go

@@ -577,11 +577,6 @@ func (in *OracleAuth) DeepCopy() *OracleAuth {
 func (in *OracleProvider) DeepCopyInto(out *OracleProvider) {
 	*out = *in
 	in.Auth.DeepCopyInto(&out.Auth)
-	if in.ProjectID != nil {
-		in, out := &in.ProjectID, &out.ProjectID
-		*out = new(string)
-		**out = **in
-	}
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OracleProvider.
@@ -597,7 +592,8 @@ func (in *OracleProvider) DeepCopy() *OracleProvider {
 // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
 func (in *OracleSecretRef) DeepCopyInto(out *OracleSecretRef) {
 	*out = *in
-	in.KeyId.DeepCopyInto(&out.KeyId)
+	in.PrivateKey.DeepCopyInto(&out.PrivateKey)
+	in.Fingerprint.DeepCopyInto(&out.Fingerprint)
 }
 
 // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OracleSecretRef.

+ 73 - 0
deploy/crds/external-secrets.io_clustersecretstores.yaml

@@ -305,6 +305,79 @@ spec:
                     required:
                     - auth
                     type: object
+                  oracle:
+                    description: Oracle configures this store to sync secrets using
+                      Oracle Cloud provider
+                    properties:
+                      auth:
+                        description: Auth configures how secret-manager authenticates
+                          with the Oracle secrets manager.
+                        properties:
+                          secretRef:
+                            properties:
+                              fingerprint:
+                                description: projectID is an access token specific
+                                  to the secret.
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                              privatekey:
+                                description: The Access Token is used for authentication
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            type: object
+                        required:
+                        - secretRef
+                        type: object
+                      region:
+                        description: projectID is an access token specific to the
+                          secret.
+                        type: string
+                      tenancy:
+                        description: projectID is an access token specific to the
+                          secret.
+                        type: string
+                      user:
+                        description: User is an access OCID specific to the account.
+                        type: string
+                    required:
+                    - auth
+                    type: object
                   vault:
                     description: Vault configures this store to sync secrets using
                       Hashi provider

+ 73 - 0
deploy/crds/external-secrets.io_secretstores.yaml

@@ -305,6 +305,79 @@ spec:
                     required:
                     - auth
                     type: object
+                  oracle:
+                    description: Oracle configures this store to sync secrets using
+                      Oracle Cloud provider
+                    properties:
+                      auth:
+                        description: Auth configures how secret-manager authenticates
+                          with the Oracle secrets manager.
+                        properties:
+                          secretRef:
+                            properties:
+                              fingerprint:
+                                description: projectID is an access token specific
+                                  to the secret.
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                              privatekey:
+                                description: The Access Token is used for authentication
+                                properties:
+                                  key:
+                                    description: The key of the entry in the Secret
+                                      resource's `data` field to be used. Some instances
+                                      of this field may be defaulted, in others it
+                                      may be required.
+                                    type: string
+                                  name:
+                                    description: The name of the Secret resource being
+                                      referred to.
+                                    type: string
+                                  namespace:
+                                    description: Namespace of the resource being referred
+                                      to. Ignored if referent is not cluster-scoped.
+                                      cluster-scoped defaults to the namespace of
+                                      the referent.
+                                    type: string
+                                required:
+                                - name
+                                type: object
+                            type: object
+                        required:
+                        - secretRef
+                        type: object
+                      region:
+                        description: projectID is an access token specific to the
+                          secret.
+                        type: string
+                      tenancy:
+                        description: projectID is an access token specific to the
+                          secret.
+                        type: string
+                      user:
+                        description: User is an access OCID specific to the account.
+                        type: string
+                    required:
+                    - auth
+                    type: object
                   vault:
                     description: Vault configures this store to sync secrets using
                       Hashi provider

+ 46 - 0
e2e/suite/oracle/oracle.go

@@ -0,0 +1,46 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+limitations under the License.
+*/
+package oracle
+
+import (
+	"os"
+
+	// nolint
+	. "github.com/onsi/ginkgo"
+	// nolint
+	. "github.com/onsi/ginkgo/extensions/table"
+
+	"github.com/external-secrets/external-secrets/e2e/framework"
+	"github.com/external-secrets/external-secrets/e2e/suite/common"
+)
+
+var _ = Describe("[azure] ", func() {
+	f := framework.New("eso-azure")
+	vaultURL := os.Getenv("VAULT_URL")
+	tenantID := os.Getenv("TENANT_ID")
+	clientID := os.Getenv("AZURE_CLIENT_ID")
+	clientSecret := os.Getenv("AZURE_CLIENT_SECRET")
+	prov := newOracleProvider(f, clientID, clientSecret, tenantID, vaultURL)
+
+	DescribeTable("sync secrets", framework.TableFunc(f, prov),
+		Entry(common.SimpleDataSync(f)),
+		Entry(common.NestedJSONWithGJSON(f)),
+		Entry(common.JSONDataFromSync(f)),
+		Entry(common.JSONDataWithProperty(f)),
+		Entry(common.JSONDataWithTemplate(f)),
+		Entry(common.DockerJSONConfig(f)),
+		Entry(common.DataPropertyDockerconfigJSON(f)),
+		Entry(common.SSHKeySync(f)),
+		Entry(common.SSHKeySyncDataProperty(f)),
+	)
+})

+ 142 - 0
e2e/suite/oracle/provider.go

@@ -0,0 +1,142 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+limitations under the License.
+*/
+package oracle
+
+import (
+	"context"
+
+	// nolint
+	"github.com/Azure/azure-sdk-for-go/services/keyvault/v7.0/keyvault"
+	. "github.com/onsi/ginkgo"
+
+	// nolint
+	. "github.com/onsi/gomega"
+	v1 "k8s.io/api/core/v1"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+	utilpointer "k8s.io/utils/pointer"
+
+	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	esmeta "github.com/external-secrets/external-secrets/apis/meta/v1"
+	"github.com/external-secrets/external-secrets/e2e/framework"
+)
+
+type oracleProvider struct {
+	clientID     string
+	clientSecret string
+	tenantID     string
+	vaultURL     string
+	client       *keyvault.BaseClient
+	framework    *framework.Framework
+}
+
+func newOracleProvider(f *framework.Framework) *oracleProvider {
+	prov := &oracleProvider{
+		framework: f,
+	}
+	BeforeEach(prov.BeforeEach)
+	return prov
+}
+
+func (p *oracleProvider) CreateSecret(key, val string) {}
+
+func (p *oracleProvider) DeleteSecret(key string) {}
+
+func BeforeEach() {
+
+}
+
+// func neworacleProvider(f *framework.Framework) *oracleProvider {
+
+// 	clientCredentialsConfig := kvauth.NewClientCredentialsConfig(clientID, clientSecret, tenantID)
+// 	clientCredentialsConfig.Resource = "https://vault.azure.net"
+// 	authorizer, err := clientCredentialsConfig.Authorizer()
+// 	Expect(err).ToNot(HaveOccurred())
+// 	basicClient := keyvault.New()
+// 	basicClient.Authorizer = authorizer
+
+// 	prov := &azureProvider{
+// 		framework:    f,
+// 		clientID:     clientID,
+// 		clientSecret: clientSecret,
+// 		tenantID:     tenantID,
+// 		vaultURL:     vaultURL,
+// 		client:       &basicClient,
+// 	}
+// 	BeforeEach(prov.BeforeEach)
+// 	return prov
+// }
+
+func (s *azureProvider) CreateSecret(key, val string) {
+	_, err := s.client.SetSecret(
+		context.Background(),
+		s.vaultURL,
+		key,
+		keyvault.SecretSetParameters{
+			Value: &val,
+			SecretAttributes: &keyvault.SecretAttributes{
+				RecoveryLevel: keyvault.Purgeable,
+				Enabled:       utilpointer.BoolPtr(true),
+			},
+		})
+	Expect(err).ToNot(HaveOccurred())
+}
+
+func (s *azureProvider) DeleteSecret(key string) {
+	_, err := s.client.DeleteSecret(
+		context.Background(),
+		s.vaultURL,
+		key)
+	Expect(err).ToNot(HaveOccurred())
+}
+
+func (s *azureProvider) BeforeEach() {
+	azureCreds := &v1.Secret{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      "provider-secret",
+			Namespace: s.framework.Namespace.Name,
+		},
+		StringData: map[string]string{
+			"client-id":     s.clientID,
+			"client-secret": s.clientSecret,
+		},
+	}
+	err := s.framework.CRClient.Create(context.Background(), azureCreds)
+	Expect(err).ToNot(HaveOccurred())
+
+	secretStore := &esv1alpha1.SecretStore{
+		ObjectMeta: metav1.ObjectMeta{
+			Name:      s.framework.Namespace.Name,
+			Namespace: s.framework.Namespace.Name,
+		},
+		Spec: esv1alpha1.SecretStoreSpec{
+			Provider: &esv1alpha1.SecretStoreProvider{
+				AzureKV: &esv1alpha1.AzureKVProvider{
+					TenantID: &s.tenantID,
+					VaultURL: &s.vaultURL,
+					AuthSecretRef: &esv1alpha1.AzureKVAuth{
+						ClientID: &esmeta.SecretKeySelector{
+							Name: "provider-secret",
+							Key:  "client-id",
+						},
+						ClientSecret: &esmeta.SecretKeySelector{
+							Name: "provider-secret",
+							Key:  "client-secret",
+						},
+					},
+				},
+			},
+		},
+	}
+	err = s.framework.CRClient.Create(context.Background(), secretStore)
+	Expect(err).ToNot(HaveOccurred())
+}

+ 0 - 1
go.mod

@@ -58,7 +58,6 @@ require (
 	github.com/lestrrat-go/jwx v1.2.1
 	github.com/onsi/ginkgo v1.16.4
 	github.com/onsi/gomega v1.13.0
-	github.com/oracle/oci-go-sdk v24.3.0+incompatible
 	github.com/oracle/oci-go-sdk/v45 v45.2.0
 	github.com/pierrec/lz4 v2.5.2+incompatible // indirect
 	github.com/prometheus/client_golang v1.11.0

+ 0 - 2
go.sum

@@ -532,8 +532,6 @@ github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y
 github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
 github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
 github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
-github.com/oracle/oci-go-sdk v24.3.0+incompatible h1:x4mcfb4agelf1O4/1/auGlZ1lr97jXRSSN5MxTgG/zU=
-github.com/oracle/oci-go-sdk v24.3.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
 github.com/oracle/oci-go-sdk/v45 v45.2.0 h1:vCPoQlE+DOrM2heJn66rvPU6fbsc/0Cxtzs2jnFut6U=
 github.com/oracle/oci-go-sdk/v45 v45.2.0/go.mod h1:ZM6LGiRO5TPQJxTlrXbcHMbClE775wnGD5U/EerCsRw=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=

+ 43 - 0
pkg/provider/oracle/fake/fake.go

@@ -0,0 +1,43 @@
+/*
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+    http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+package fake
+
+import (
+	"context"
+
+	vault "github.com/oracle/oci-go-sdk/v45/vault"
+)
+
+type OracleMockClient struct {
+	getSecret func(ctx context.Context, request vault.GetSecretRequest) (response vault.GetSecretResponse, err error)
+}
+
+func (mc *OracleMockClient) GetSecret(ctx context.Context, request vault.GetSecretRequest) (response vault.GetSecretResponse, err error) {
+	return mc.getSecret(ctx, request)
+}
+
+func (mc *OracleMockClient) WithValue(input vault.GetSecretRequest) (output vault.GetSecretResponse, err error) {
+	if mc != nil {
+		mc.getSecret = func(ctx context.Context, paramReq vault.GetSecretRequest) (vault.GetSecretResponse, error) {
+			// type secretmanagerpb.AccessSecretVersionRequest contains unexported fields
+			// use cmpopts.IgnoreUnexported to ignore all the unexported fields in the cmp.
+			// if !cmp.Equal(paramReq, input, cmpopts.IgnoreUnexported(vault.Secret{})) {
+			// 	return nil, fmt.Errorf("unexpected test argument")
+			// }
+			return output, err
+		}
+	}
+	return output, nil
+	// not sure why I need this as other providers don't require extra return function
+}

+ 53 - 49
pkg/provider/oracle/oracle.go

@@ -38,10 +38,14 @@ const (
 
 	errOracleClient                          = "cannot setup new oracle client: %w"
 	errORACLECredSecretName                  = "invalid oracle SecretStore resource: missing oracle APIKey"
-	errUninitalizedORACLEProvider            = "provider oracle is not initialized"
+	errUninitalizedOracleProvider            = "provider oracle is not initialized"
 	errInvalidClusterStoreMissingSKNamespace = "invalid ClusterStore, missing namespace"
 	errFetchSAKSecret                        = "could not fetch SecretAccessKey secret: %w"
-	errMissingSAK                            = "missing SecretAccessKey"
+	errMissingPK                             = "missing PrivateKey"
+	errMissingUser                           = "missing User ID"
+	errMissingTenancy                        = "missing Tenancy ID"
+	errMissingRegion                         = "missing Region"
+	errMissingFingerprint                    = "missing Fingerprint"
 	errJSONSecretUnmarshal                   = "unable to unmarshal secret: %w"
 )
 
@@ -56,6 +60,7 @@ type client struct {
 	user        string
 	region      string
 	fingerprint string
+	privateKey  string
 }
 
 // // Oracle struct with values for *oracle.Client and projectID.
@@ -76,30 +81,9 @@ type SMInterface interface {
 	GetSecret(ctx context.Context, request vault.GetSecretRequest) (response vault.GetSecretResponse, err error)
 }
 
-// ConfigurationProvider wraps information about the account owner
-type ConfigurationProvider interface {
-	TenancyOCID() (string, error)
-	UserOCID() (string, error)
-	KeyFingerprint() (string, error)
-	Region() (string, error)
-	// AuthType() is used for specify the needed auth type, like UserPrincipal, InstancePrincipal, etc.
-	//AuthType() (AuthConfig, error)
-}
-
-type customConfig struct {
-	tenancy     string
-	user        string
-	region      string
-	fingerprint string
-}
-
-// func (oracle *providerOracle) Close() error {
-// 	return nil
-// }
-
 func (c *client) setAuth(ctx context.Context) error {
 	credentialsSecret := &corev1.Secret{}
-	credentialsSecretName := c.store.Auth.SecretRef.KeyId.Name
+	credentialsSecretName := c.store.Auth.SecretRef.PrivateKey.Name
 	if credentialsSecretName == "" {
 		return fmt.Errorf(errORACLECredSecretName)
 	}
@@ -110,10 +94,10 @@ func (c *client) setAuth(ctx context.Context) error {
 
 	// only ClusterStore is allowed to set namespace (and then it's required)
 	if c.storeKind == esv1alpha1.ClusterSecretStoreKind {
-		if c.store.Auth.SecretRef.KeyId.Namespace == nil {
+		if c.store.Auth.SecretRef.PrivateKey.Namespace == nil {
 			return fmt.Errorf(errInvalidClusterStoreMissingSKNamespace)
 		}
-		objectKey.Namespace = *c.store.Auth.SecretRef.KeyId.Namespace
+		objectKey.Namespace = *c.store.Auth.SecretRef.PrivateKey.Namespace
 	}
 
 	err := c.kube.Get(ctx, objectKey, credentialsSecret)
@@ -121,22 +105,41 @@ func (c *client) setAuth(ctx context.Context) error {
 		return fmt.Errorf(errFetchSAKSecret, err)
 	}
 
-	c.credentials = credentialsSecret.Data[c.store.Auth.SecretRef.KeyId.Key]
-	if (c.credentials == nil) || (len(c.credentials) == 0) {
-		return fmt.Errorf(errMissingSAK)
+	c.privateKey = string(credentialsSecret.Data[c.store.Auth.SecretRef.PrivateKey.Key])
+	if (c.privateKey == "") || (len(c.privateKey) == 0) {
+		return fmt.Errorf(errMissingPK)
+	}
+
+	c.fingerprint = string(credentialsSecret.Data[c.store.Auth.SecretRef.Fingerprint.Key])
+	if (c.fingerprint == "") || (len(c.fingerprint) == 0) {
+		return fmt.Errorf(errMissingFingerprint)
+	}
+
+	c.user = string(c.store.User)
+	if (c.user == "") || (len(c.user) == 0) {
+		return fmt.Errorf(errMissingUser)
 	}
+
+	c.tenancy = string(c.store.Tenancy)
+	if (c.tenancy == "") || (len(c.tenancy) == 0) {
+		return fmt.Errorf(errMissingTenancy)
+	}
+
+	c.region = string(c.store.Region)
+	if (c.region == "") || (len(c.region) == 0) {
+		return fmt.Errorf(errMissingRegion)
+	}
+
 	return nil
 }
 
 func (kms *KeyManagementService) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	kmsRequest := vault.CreateSecretRequest{}
-	// kmsRequest.CompartmentId = &ref.Version
-	// kmsRequest.SecretName = &ref.Key
-	// kmsRequest.VaultId = kms.VaultId
-	//kmsRequest.SecretContent = vault.SecretContentDetails.GetName()
-	fmt.Println(kmsRequest)
-	client2, err := vault.NewVaultsClientWithConfigurationProvider(common.DefaultConfigProvider())
-	secretOut, err := client2.CreateSecret(context.Background(), kmsRequest)
+	
+	
+	kmsRequest := vault.GetSecretRequest{
+		SecretId: &ref.Key,
+	}
+	secretOut, err := kms.Client.GetSecret(context.Background(), kmsRequest)
 	if err != nil {
 		return nil, util.SanitizeErr(err)
 	}
@@ -183,27 +186,25 @@ func (kms *KeyManagementService) NewClient(ctx context.Context, store esv1alpha1
 	storeSpec := store.GetSpec()
 	oracleSpec := storeSpec.Provider.Oracle
 
-	iStore := &client{
+	oracleStore := &client{
 		kube:      kube,
 		store:     oracleSpec,
 		namespace: namespace,
 		storeKind: store.GetObjectKind().GroupVersionKind().Kind,
 	}
-	if err := iStore.setAuth(ctx); err != nil {
+	if err := oracleStore.setAuth(ctx); err != nil {
 		return nil, err
 	}
-	config := common.DefaultConfigProvider()
-	// config.KeyFingerprint = iStore.fingerprint
-	// oracleRegion := iStore.region
 
-	// ConfigurationProvider.KeyFingerprint()
-	// oracleKeyID := iStore.keyID
-	// oracleSecretKey := iStore.accessKey
-	// keyManagementService, err := identity.NewIdentityClientWithConfigurationProvider(ConfigurationProvider)
+	oracleTenancy := oracleStore.tenancy
+	oracleUser := oracleStore.user
+	oracleRegion := oracleStore.region
+	oracleFingerprint := oracleStore.fingerprint
+	oraclePrivateKey := oracleStore.privateKey
 
-	//keyManagementService, err := identity.NewIdentityClientWithConfigurationProvider(config)
+	configurationProvider := common.NewRawConfigurationProvider(oracleTenancy, oracleUser, oracleRegion, oracleFingerprint, oraclePrivateKey, nil)
 
-	keyManagementService, err := vault.NewVaultsClientWithConfigurationProvider(config)
+	keyManagementService, err := vault.NewVaultsClientWithConfigurationProvider(configurationProvider)
 	if err != nil {
 		return nil, fmt.Errorf(errOracleClient, err)
 	}
@@ -226,7 +227,10 @@ func init() {
 	})
 }
 
-// func fakeMain(o *providerOracle) {
+// func fakeMain(kms *KeyManagementService) {
+
+// 	configurationProvider := common.NewRawConfigurationProvider("", "", "", "", "", nil)
+
 // 	c, err := identity.NewIdentityClientWithConfigurationProvider(common.DefaultConfigProvider())
 // 	o.client = c
 // 	fmt.Println("Client:", o.client)

+ 166 - 0
pkg/provider/oracle/oracle_test.go

@@ -11,6 +11,172 @@ limitations under the License.
 */
 package oracle
 
+import (
+	"context"
+	"fmt"
+	"reflect"
+	"strings"
+	"testing"
+
+	
+
+	vault "github.com/oracle/oci-go-sdk/v45/vault"
+	utilpointer "k8s.io/utils/pointer"
+
+	esv1alpha1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1alpha1"
+	fakeoracle "github.com/external-secrets/external-secrets/pkg/provider/oracle/fake"
+)
+
+type secretManagerTestCase struct {
+	mockClient     *fakeoracle.OracleMockClient
+	apiInput       *vault.GetSecretRequest
+	apiOutput      *vault.GetSecretResponse
+	ref            *esv1alpha1.ExternalSecretDataRemoteRef
+	apiErr         error
+	expectError    string
+	expectedSecret string
+	// for testing secretmap
+	expectedData map[string][]byte
+}
+
+func makeValidSecretManagerTestCase() *secretManagerTestCase {
+	smtc := secretManagerTestCase{
+		mockClient:     &fakeoracle.OracleMockClient{},
+		apiInput:       makeValidAPIInput(),
+		ref:            makeValidRef(),
+		apiOutput:      makeValidAPIOutput(),
+		apiErr:         nil,
+		expectError:    "",
+		expectedSecret: "",
+		expectedData:   map[string][]byte{},
+	}
+	smtc.mockClient.WithValue(*smtc.apiInput)
+	return &smtc
+}
+
+func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
+	return &esv1alpha1.ExternalSecretDataRemoteRef{
+		Key:     "test-secret",
+		Version: "default",
+	}
+}
+
+func makeValidAPIInput() *vault.GetSecretRequest {
+	return &vault.GetSecretRequest{
+		SecretId: utilpointer.StringPtr("i have no idea what should go here TEST CHECK"),
+	}
+}
+
+func makeValidAPIOutput() *vault.GetSecretResponse {
+	return &vault.GetSecretResponse{
+		Etag:   utilpointer.StringPtr("i have no idea if I need this TEST CHECK"),
+		Secret: vault.Secret{},
+	}
+}
+
+func makeValidSecretManagerTestCaseCustom(tweaks ...func(smtc *secretManagerTestCase)) *secretManagerTestCase {
+	smtc := makeValidSecretManagerTestCase()
+	for _, fn := range tweaks {
+		fn(smtc)
+	}
+	smtc.mockClient.WithValue(*smtc.apiInput) //HAVING ONLY 1 VARIABLE SEEMS WRONG TEST CHECK
+	return smtc
+}
+
+// This case can be shared by both GetSecret and GetSecretMap tests.
+// bad case: set apiErr.
+var setAPIErr = func(smtc *secretManagerTestCase) {
+	smtc.apiErr = fmt.Errorf("oh no")
+	smtc.expectError = "oh no"
+}
+
+var setNilMockClient = func(smtc *secretManagerTestCase) {
+	smtc.mockClient = nil
+	smtc.expectError = errUninitalizedOracleProvider
+}
+
+func TestOracleSecretManagerGetSecret(t *testing.T) {
+	secretValue := "changedvalue"
+	// good case: default version is set
+	// key is passed in, output is sent back
+
+	setSecretString := func(smtc *secretManagerTestCase) {
+		smtc.apiOutput = &vault.GetSecretResponse{
+			Etag: utilpointer.StringPtr("i have no idea if I need this TEST CHECK"),
+			Secret: vault.Secret{
+				CompartmentId:  utilpointer.StringPtr("i have no idea if I need this TEST CHECK"),
+				Id:             utilpointer.StringPtr("i have no idea if I need this TEST CHECK"),
+				LifecycleState: vault.SecretLifecycleStateEnum("Unsure TEST CHECK"),
+				SecretName:     utilpointer.StringPtr("changedvalue"),
+			},
+			// Key:   "testkey",
+			// Value: "changedvalue",
+		}
+		smtc.expectedSecret = secretValue
+	}
+
+	successCases := []*secretManagerTestCase{
+		makeValidSecretManagerTestCaseCustom(setSecretString),
+		makeValidSecretManagerTestCaseCustom(setAPIErr),
+		makeValidSecretManagerTestCaseCustom(setNilMockClient),
+	}
+
+	sm := KeyManagementService{}
+	for k, v := range successCases {
+		sm.Client = v.mockClient
+		out, err := sm.GetSecret(context.Background(), *v.ref)
+		if !ErrorContains(err, v.expectError) {
+			t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
+		}
+		if string(out) != v.expectedSecret {
+			t.Errorf("[%d] unexpected secret: expected %s, got %s", k, v.expectedSecret, string(out))
+		}
+	}
+}
+
+func TestGetSecretMap(t *testing.T) {
+	// good case: default version & deserialization
+	setDeserialization := func(smtc *secretManagerTestCase) {
+		smtc.apiOutput.SecretName = utilpointer.StringPtr(`{"foo":"bar"}`)
+		smtc.expectedData["foo"] = []byte("bar")
+	}
+
+	// bad case: invalid json
+	setInvalidJSON := func(smtc *secretManagerTestCase) {
+		smtc.apiOutput.SecretName = utilpointer.StringPtr(`-----------------`)
+		smtc.expectError = "unable to unmarshal secret"
+	}
+
+	successCases := []*secretManagerTestCase{
+		makeValidSecretManagerTestCaseCustom(setDeserialization),
+		makeValidSecretManagerTestCaseCustom(setInvalidJSON),
+		makeValidSecretManagerTestCaseCustom(setNilMockClient),
+		makeValidSecretManagerTestCaseCustom(setAPIErr),
+	}
+
+	sm := KeyManagementService{}
+	for k, v := range successCases {
+		sm.Client = v.mockClient
+		out, err := sm.GetSecretMap(context.Background(), *v.ref)
+		if !ErrorContains(err, v.expectError) {
+			t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
+		}
+		if err == nil && !reflect.DeepEqual(out, v.expectedData) {
+			t.Errorf("[%d] unexpected secret data: expected %#v, got %#v", k, v.expectedData, out)
+		}
+	}
+}
+
+func ErrorContains(out error, want string) bool {
+	if out == nil {
+		return want == ""
+	}
+	if want == "" {
+		return false
+	}
+	return strings.Contains(out.Error(), want)
+}
+
 // func TestCreateOracleClient(t *testing.T) {
 // 	//credentials := OracleCredentials{Token: ORACLETOKEN}
 // 	oracle := NewOracleProvider()

+ 1 - 0
pkg/provider/register/register.go

@@ -21,5 +21,6 @@ import (
 	_ "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/gcp/secretmanager"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/ibm"
+	_ "github.com/external-secrets/external-secrets/pkg/provider/oracle"
 	_ "github.com/external-secrets/external-secrets/pkg/provider/vault"
 )