Browse Source

update ibm secrets manager provider version to v2 (#2254)

* update ibm secrets manager version to v2

Signed-off-by: tanishg6@gmail.com <tanishg6@gmail.com>

* update go.mod to point to v2.0.0

Signed-off-by: tanishg6@gmail.com <tanishg6@gmail.com>

---------

Signed-off-by: tanishg6@gmail.com <tanishg6@gmail.com>
Signed-off-by: Shanti G <81566195+Shanti-G@users.noreply.github.com>
Shanti G 3 years ago
parent
commit
405c12c314
5 changed files with 479 additions and 522 deletions
  1. 1 1
      go.mod
  2. 2 2
      go.sum
  3. 16 9
      pkg/provider/ibm/fake/fake.go
  4. 150 215
      pkg/provider/ibm/provider.go
  5. 310 295
      pkg/provider/ibm/provider_test.go

+ 1 - 1
go.mod

@@ -11,7 +11,7 @@ require (
 	github.com/Azure/go-autorest/autorest/azure/auth v0.5.12
 	github.com/AzureAD/microsoft-authentication-library-for-go v1.0.0
 	github.com/IBM/go-sdk-core/v5 v5.13.1
-	github.com/IBM/secrets-manager-go-sdk v1.2.0
+	github.com/IBM/secrets-manager-go-sdk/v2 v2.0.0
 	github.com/Masterminds/goutils v1.1.1 // indirect
 	github.com/Masterminds/sprig/v3 v3.2.3
 	github.com/PaesslerAG/jsonpath v0.1.1

+ 2 - 2
go.sum

@@ -91,8 +91,8 @@ github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob
 github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo=
 github.com/IBM/go-sdk-core/v5 v5.13.1 h1:zD6p3t1whAlRJo/VBmE69c8RcH9LCHL1n0/sO1MWlpw=
 github.com/IBM/go-sdk-core/v5 v5.13.1/go.mod h1:pVkN7IGmsSdmR1ZCU4E/cLcCclqRKMYgg7ya+O2Mk6g=
-github.com/IBM/secrets-manager-go-sdk v1.2.0 h1:bgFfBF+LjHLtUfV3hTLkfgE8EjFsJaeU2icA2Hg+M50=
-github.com/IBM/secrets-manager-go-sdk v1.2.0/go.mod h1:qv+tQg8Z3Vb11DQYxDjEGeROHDtTLQxUWuOIrIdWg6E=
+github.com/IBM/secrets-manager-go-sdk/v2 v2.0.0 h1:Lx4Bvim/MfoHEYR+n312bty5DirAJypBGGS9YZo3zCw=
+github.com/IBM/secrets-manager-go-sdk/v2 v2.0.0/go.mod h1:jagqWmjZ0zUEqh5jdGB42ApSQS40fu2LWw6pdg8JJko=
 github.com/Masterminds/goutils v1.1.1 h1:5nUrii3FMTL5diU80unEVvNevw1nH4+ZV4DSLVJLSYI=
 github.com/Masterminds/goutils v1.1.1/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver/v3 v3.2.0/go.mod h1:qvl/7zhW3nngYb5+80sSMF+FG2BjYrf8m9wsX0PNOMQ=

+ 16 - 9
pkg/provider/ibm/fake/fake.go

@@ -14,31 +14,38 @@ limitations under the License.
 package fake
 
 import (
+	"context"
 	"fmt"
 
 	"github.com/IBM/go-sdk-core/v5/core"
-	sm "github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1"
+	sm "github.com/IBM/secrets-manager-go-sdk/v2/secretsmanagerv2"
 	"github.com/google/go-cmp/cmp"
 	"github.com/google/go-cmp/cmp/cmpopts"
 )
 
 type IBMMockClient struct {
-	getSecret func(getSecretOptions *sm.GetSecretOptions) (result *sm.GetSecret, response *core.DetailedResponse, err error)
+	getSecretWithContext func(ctx context.Context, getSecretOptions *sm.GetSecretOptions) (result sm.SecretIntf, response *core.DetailedResponse, err error)
 }
 
-func (mc *IBMMockClient) GetSecret(getSecretOptions *sm.GetSecretOptions) (result *sm.GetSecret, response *core.DetailedResponse, err error) {
-	return mc.getSecret(getSecretOptions)
+type IBMMockClientParams struct {
+	GetSecretOptions *sm.GetSecretOptions
+	GetSecretOutput  sm.SecretIntf
+	GetSecretErr     error
 }
 
-func (mc *IBMMockClient) WithValue(input *sm.GetSecretOptions, output *sm.GetSecret, err error) {
+func (mc *IBMMockClient) GetSecretWithContext(ctx context.Context, getSecretOptions *sm.GetSecretOptions) (result sm.SecretIntf, response *core.DetailedResponse, err error) {
+	return mc.getSecretWithContext(ctx, getSecretOptions)
+}
+
+func (mc *IBMMockClient) WithValue(params IBMMockClientParams) {
 	if mc != nil {
-		mc.getSecret = func(paramReq *sm.GetSecretOptions) (*sm.GetSecret, *core.DetailedResponse, error) {
+		mc.getSecretWithContext = func(ctx context.Context, paramReq *sm.GetSecretOptions) (sm.SecretIntf, *core.DetailedResponse, 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(sm.GetSecret{})) {
-				return nil, nil, fmt.Errorf("unexpected test argument")
+			if !cmp.Equal(paramReq, params.GetSecretOptions, cmpopts.IgnoreUnexported(sm.Secret{})) {
+				return nil, nil, fmt.Errorf("unexpected test argument for GetSecret: %s, %s", *paramReq.ID, *params.GetSecretOptions.ID)
 			}
-			return output, nil, err
+			return params.GetSecretOutput, nil, params.GetSecretErr
 		}
 	}
 }

+ 150 - 215
pkg/provider/ibm/provider.go

@@ -23,11 +23,10 @@ import (
 	"time"
 
 	core "github.com/IBM/go-sdk-core/v5/core"
-	sm "github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1"
+	sm "github.com/IBM/secrets-manager-go-sdk/v2/secretsmanagerv2"
 	gjson "github.com/tidwall/gjson"
 	corev1 "k8s.io/api/core/v1"
 	types "k8s.io/apimachinery/pkg/types"
-	ctrl "sigs.k8s.io/controller-runtime"
 	kclient "sigs.k8s.io/controller-runtime/pkg/client"
 
 	esv1beta1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1beta1"
@@ -40,6 +39,14 @@ const (
 	STSEndpointEnv            = "IBM_STS_ENDPOINT"
 	SSMEndpointEnv            = "IBM_SSM_ENDPOINT"
 
+	certificateConst  = "certificate"
+	intermediateConst = "intermediate"
+	privateKeyConst   = "private_key"
+	usernameConst     = "username"
+	passwordConst     = "password"
+	apikeyConst       = "apikey"
+	arbitraryConst    = "arbitrary"
+
 	errIBMClient                             = "cannot setup new ibm client: %w"
 	errIBMCredSecretName                     = "invalid IBM SecretStore resource: missing IBM APIKey"
 	errUninitalizedIBMProvider               = "provider IBM is not initialized"
@@ -47,14 +54,17 @@ const (
 	errFetchSAKSecret                        = "could not fetch SecretAccessKey secret: %w"
 	errMissingSAK                            = "missing SecretAccessKey"
 	errJSONSecretUnmarshal                   = "unable to unmarshal secret: %w"
+	errExtractingSecret                      = "unable to extract the fetched secret %s of type %s"
 )
 
+var contextTimeout = time.Minute * 2
+
 // https://github.com/external-secrets/external-secrets/issues/644
 var _ esv1beta1.SecretsClient = &providerIBM{}
 var _ esv1beta1.Provider = &providerIBM{}
 
 type SecretManagerClient interface {
-	GetSecret(getSecretOptions *sm.GetSecretOptions) (result *sm.GetSecret, response *core.DetailedResponse, err error)
+	GetSecretWithContext(ctx context.Context, getSecretOptions *sm.GetSecretOptions) (result sm.SecretIntf, response *core.DetailedResponse, err error)
 }
 
 type providerIBM struct {
@@ -69,8 +79,6 @@ type client struct {
 	credentials []byte
 }
 
-var log = ctrl.Log.WithName("provider").WithName("ibm").WithName("secretsmanager")
-
 func (c *client) setAuth(ctx context.Context) error {
 	credentialsSecret := &corev1.Secret{}
 	credentialsSecretName := c.store.Auth.SecretRef.SecretAPIKey.Name
@@ -122,7 +130,7 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1beta1.ExternalSecre
 		return nil, fmt.Errorf(errUninitalizedIBMProvider)
 	}
 
-	secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
+	secretType := sm.Secret_SecretType_Arbitrary
 	secretName := ref.Key
 	nameSplitted := strings.Split(secretName, "/")
 
@@ -132,22 +140,21 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1beta1.ExternalSecre
 	}
 
 	switch secretType {
-	case sm.GetSecretOptionsSecretTypeArbitraryConst:
-
+	case sm.Secret_SecretType_Arbitrary:
 		return getArbitrarySecret(ibm, &secretName)
 
-	case sm.CreateSecretOptionsSecretTypeUsernamePasswordConst:
+	case sm.Secret_SecretType_UsernamePassword:
 
 		if ref.Property == "" {
 			return nil, fmt.Errorf("remoteRef.property required for secret type username_password")
 		}
 		return getUsernamePasswordSecret(ibm, &secretName, ref)
 
-	case sm.CreateSecretOptionsSecretTypeIamCredentialsConst:
+	case sm.Secret_SecretType_IamCredentials:
 
 		return getIamCredentialsSecret(ibm, &secretName)
 
-	case sm.CreateSecretOptionsSecretTypeImportedCertConst:
+	case sm.Secret_SecretType_ImportedCert:
 
 		if ref.Property == "" {
 			return nil, fmt.Errorf("remoteRef.property required for secret type imported_cert")
@@ -155,7 +162,7 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1beta1.ExternalSecre
 
 		return getImportCertSecret(ibm, &secretName, ref)
 
-	case sm.CreateSecretOptionsSecretTypePublicCertConst:
+	case sm.Secret_SecretType_PublicCert:
 
 		if ref.Property == "" {
 			return nil, fmt.Errorf("remoteRef.property required for secret type public_cert")
@@ -163,7 +170,7 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1beta1.ExternalSecre
 
 		return getPublicCertSecret(ibm, &secretName, ref)
 
-	case sm.CreateSecretOptionsSecretTypePrivateCertConst:
+	case sm.Secret_SecretType_PrivateCert:
 
 		if ref.Property == "" {
 			return nil, fmt.Errorf("remoteRef.property required for secret type private_cert")
@@ -171,7 +178,7 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1beta1.ExternalSecre
 
 		return getPrivateCertSecret(ibm, &secretName, ref)
 
-	case sm.CreateSecretOptionsSecretTypeKvConst:
+	case sm.Secret_SecretType_Kv:
 
 		return getKVSecret(ibm, &secretName, ref)
 
@@ -181,150 +188,130 @@ func (ibm *providerIBM) GetSecret(_ context.Context, ref esv1beta1.ExternalSecre
 }
 
 func getArbitrarySecret(ibm *providerIBM, secretName *string) ([]byte, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
-			ID:         secretName,
-		})
-	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
+	secret, ok := response.(*sm.ArbitrarySecret)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_Arbitrary)
+	}
 
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData
-	arbitrarySecretPayload := secretData["payload"].(string)
-	return []byte(arbitrarySecretPayload), nil
+	return []byte(*secret.Payload), nil
 }
 
 func getImportCertSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
-			ID:         secretName,
-		})
-	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
-
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData
-
-	if val, ok := secretData[ref.Property]; ok {
-		return []byte(val.(string)), nil
+	secret, ok := response.(*sm.ImportedCertificate)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_ImportedCert)
+	}
+	switch ref.Property {
+	case certificateConst:
+		return []byte(*secret.Certificate), nil
+	case intermediateConst:
+		return []byte(*secret.Intermediate), nil
+	case privateKeyConst:
+		return []byte(*secret.PrivateKey), nil
+	default:
+		return nil, fmt.Errorf("unknown property type %s", ref.Property)
 	}
-	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
 }
 
 func getPublicCertSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypePublicCertConst),
-			ID:         secretName,
-		})
-	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
+	secret, ok := response.(*sm.PublicCertificate)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_PublicCert)
+	}
 
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData
-
-	if val, ok := secretData[ref.Property]; ok {
-		return []byte(val.(string)), nil
+	switch ref.Property {
+	case certificateConst:
+		return []byte(*secret.Certificate), nil
+	case intermediateConst:
+		return []byte(*secret.Intermediate), nil
+	case privateKeyConst:
+		return []byte(*secret.PrivateKey), nil
+	default:
+		return nil, fmt.Errorf("unknown property type %s", ref.Property)
 	}
-	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
 }
 
 func getPrivateCertSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypePrivateCertConst),
-			ID:         secretName,
-		})
-	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
-
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData
-
-	if val, ok := secretData[ref.Property]; ok {
-		return []byte(val.(string)), nil
+	secret, ok := response.(*sm.PrivateCertificate)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_PrivateCert)
+	}
+	switch ref.Property {
+	case certificateConst:
+		return []byte(*secret.Certificate), nil
+	case privateKeyConst:
+		return []byte(*secret.PrivateKey), nil
+	default:
+		return nil, fmt.Errorf("unknown property type %s", ref.Property)
 	}
-	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
 }
 
 func getIamCredentialsSecret(ibm *providerIBM, secretName *string) ([]byte, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
-			ID:         secretName,
-		})
-	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
-
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := *secret.APIKey
-
-	return []byte(secretData), nil
+	secret, ok := response.(*sm.IAMCredentialsSecret)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_IamCredentials)
+	}
+	return []byte(*secret.ApiKey), nil
 }
 
 func getUsernamePasswordSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
-			ID:         secretName,
-		})
-	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
-
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData
-
-	if val, ok := secretData[ref.Property]; ok {
-		return []byte(val.(string)), nil
+	secret, ok := response.(*sm.UsernamePasswordSecret)
+	if !ok {
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_UsernamePassword)
+	}
+	switch ref.Property {
+	case "username":
+		return []byte(*secret.Username), nil
+	case "password":
+		return []byte(*secret.Password), nil
+	default:
+		return nil, fmt.Errorf("unknown property type %s", ref.Property)
 	}
-	return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
 }
 
 // Returns a secret of type kv and supports json path.
 func getKVSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSecretDataRemoteRef) ([]byte, error) {
-	secret, err := getSecretByType(ibm, secretName, sm.CreateSecretOptionsSecretTypeKvConst)
+	response, err := getSecretData(ibm, secretName)
 	if err != nil {
 		return nil, err
 	}
-
-	log.Info("fetching secret", "secretName", secretName, "key", ref.Key)
-
-	secretData := secret.SecretData
-
-	payload, ok := secretData["payload"]
+	secret, ok := response.(*sm.KVSecret)
 	if !ok {
-		return nil, fmt.Errorf("no payload returned for secret %s", ref.Key)
+		return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_Kv)
 	}
-
-	payloadJSON := payload
-
-	payloadJSONMap, ok := payloadJSON.(map[string]interface{})
-	if ok {
-		var payloadJSONByte []byte
-		payloadJSONByte, err = json.Marshal(payloadJSONMap)
-		if err != nil {
-			return nil, fmt.Errorf("marshaling payload from secret failed. %w", err)
-		}
-		payloadJSON = string(payloadJSONByte)
+	payloadJSONByte, err := json.Marshal(secret.Data)
+	if err != nil {
+		return nil, fmt.Errorf("marshaling payload from secret failed. %w", err)
 	}
+	payloadJSON := string(payloadJSONByte)
 
 	// no property requested, return the entire payload
 	if ref.Property == "" {
-		return []byte(payloadJSON.(string)), nil
+		return []byte(payloadJSON), nil
 	}
 
 	// returns the requested key
@@ -340,7 +327,7 @@ func getKVSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSec
 		if idx > 0 {
 			refProperty = strings.ReplaceAll(refProperty, ".", "\\.")
 
-			val := gjson.Get(payloadJSON.(string), refProperty)
+			val := gjson.Get(payloadJSON, refProperty)
 			if val.Exists() {
 				return []byte(val.String()), nil
 			}
@@ -348,7 +335,7 @@ func getKVSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSec
 
 		// b) "." is symbole for JSON path
 		// try to get value for this path
-		val := gjson.Get(payloadJSON.(string), ref.Property)
+		val := gjson.Get(payloadJSON, ref.Property)
 		if !val.Exists() {
 			return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
 		}
@@ -358,20 +345,19 @@ func getKVSecret(ibm *providerIBM, secretName *string, ref esv1beta1.ExternalSec
 	return nil, fmt.Errorf("no property provided for secret %s", ref.Key)
 }
 
-func getSecretByType(ibm *providerIBM, secretName *string, secretType string) (*sm.SecretResource, error) {
-	response, _, err := ibm.IBMClient.GetSecret(
+func getSecretData(ibm *providerIBM, secretName *string) (sm.SecretIntf, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), contextTimeout)
+	defer cancel()
+	response, _, err := ibm.IBMClient.GetSecretWithContext(
+		ctx,
 		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(secretType),
-			ID:         secretName,
+			ID: secretName,
 		})
 	metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
 	if err != nil {
 		return nil, err
 	}
-
-	secret := response.Resources[0].(*sm.SecretResource)
-
-	return secret, nil
+	return response, nil
 }
 
 func (ibm *providerIBM) GetSecretMap(_ context.Context, ref esv1beta1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
@@ -379,7 +365,7 @@ func (ibm *providerIBM) GetSecretMap(_ context.Context, ref esv1beta1.ExternalSe
 		return nil, fmt.Errorf(errUninitalizedIBMProvider)
 	}
 
-	secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
+	secretType := sm.Secret_SecretType_Arbitrary
 	secretName := ref.Key
 	nameSplitted := strings.Split(secretName, "/")
 
@@ -388,124 +374,73 @@ func (ibm *providerIBM) GetSecretMap(_ context.Context, ref esv1beta1.ExternalSe
 		secretName = nameSplitted[1]
 	}
 
-	switch secretType {
-	case sm.GetSecretOptionsSecretTypeArbitraryConst:
-		response, _, err := ibm.IBMClient.GetSecret(
-			&sm.GetSecretOptions{
-				SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
-				ID:         &ref.Key,
-			})
-		metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
-		if err != nil {
-			return nil, err
-		}
-
-		secret := response.Resources[0].(*sm.SecretResource)
-		secretData := secret.SecretData
-		arbitrarySecretPayload := secretData["payload"].(string)
+	secretMap := make(map[string][]byte)
+	response, err := getSecretData(ibm, &secretName)
+	if err != nil {
+		return nil, err
+	}
 
-		kv := make(map[string]interface{})
-		err = json.Unmarshal([]byte(arbitrarySecretPayload), &kv)
-		if err != nil {
-			return nil, fmt.Errorf(errJSONSecretUnmarshal, err)
+	switch secretType {
+	case sm.Secret_SecretType_Arbitrary:
+		secretData, ok := response.(*sm.ArbitrarySecret)
+		if !ok {
+			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_Arbitrary)
 		}
-
-		secretMap := byteArrayMap(kv)
-
+		secretMap[arbitraryConst] = []byte(*secretData.Payload)
 		return secretMap, nil
 
-	case sm.CreateSecretOptionsSecretTypeUsernamePasswordConst:
-		response, _, err := ibm.IBMClient.GetSecret(
-			&sm.GetSecretOptions{
-				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
-				ID:         &secretName,
-			})
-		metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
-		if err != nil {
-			return nil, err
+	case sm.Secret_SecretType_UsernamePassword:
+		secretData, ok := response.(*sm.UsernamePasswordSecret)
+		if !ok {
+			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_UsernamePassword)
 		}
-
-		secret := response.Resources[0].(*sm.SecretResource)
-		secretData := secret.SecretData
-
-		secretMap := byteArrayMap(secretData)
+		secretMap[usernameConst] = []byte(*secretData.Username)
+		secretMap[passwordConst] = []byte(*secretData.Password)
 
 		return secretMap, nil
 
-	case sm.CreateSecretOptionsSecretTypeIamCredentialsConst:
-		response, _, err := ibm.IBMClient.GetSecret(
-			&sm.GetSecretOptions{
-				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
-				ID:         &secretName,
-			})
-		metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
-		if err != nil {
-			return nil, err
+	case sm.Secret_SecretType_IamCredentials:
+		secretData, ok := response.(*sm.IAMCredentialsSecret)
+		if !ok {
+			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_IamCredentials)
 		}
-
-		secret := response.Resources[0].(*sm.SecretResource)
-		secretData := *secret.APIKey
-
-		secretMap := make(map[string][]byte)
-		secretMap["apikey"] = []byte(secretData)
+		secretMap[apikeyConst] = []byte(*secretData.ApiKey)
 
 		return secretMap, nil
 
-	case sm.CreateSecretOptionsSecretTypeImportedCertConst:
-		response, _, err := ibm.IBMClient.GetSecret(
-			&sm.GetSecretOptions{
-				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
-				ID:         &secretName,
-			})
-		metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
-		if err != nil {
-			return nil, err
+	case sm.Secret_SecretType_ImportedCert:
+		secretData, ok := response.(*sm.ImportedCertificate)
+		if !ok {
+			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_ImportedCert)
 		}
-
-		secret := response.Resources[0].(*sm.SecretResource)
-		secretData := secret.SecretData
-
-		secretMap := byteArrayMap(secretData)
+		secretMap[certificateConst] = []byte(*secretData.Certificate)
+		secretMap[intermediateConst] = []byte(*secretData.Intermediate)
+		secretMap[privateKeyConst] = []byte(*secretData.PrivateKey)
 
 		return secretMap, nil
 
-	case sm.CreateSecretOptionsSecretTypePublicCertConst:
-		response, _, err := ibm.IBMClient.GetSecret(
-			&sm.GetSecretOptions{
-				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypePublicCertConst),
-				ID:         &secretName,
-			})
-		metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
-		if err != nil {
-			return nil, err
+	case sm.Secret_SecretType_PublicCert:
+		secretData, ok := response.(*sm.PublicCertificate)
+		if !ok {
+			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_PublicCert)
 		}
-
-		secret := response.Resources[0].(*sm.SecretResource)
-		secretData := secret.SecretData
-
-		secretMap := byteArrayMap(secretData)
+		secretMap[certificateConst] = []byte(*secretData.Certificate)
+		secretMap[intermediateConst] = []byte(*secretData.Intermediate)
+		secretMap[privateKeyConst] = []byte(*secretData.PrivateKey)
 
 		return secretMap, nil
 
-	case sm.CreateSecretOptionsSecretTypePrivateCertConst:
-		response, _, err := ibm.IBMClient.GetSecret(
-			&sm.GetSecretOptions{
-				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypePrivateCertConst),
-				ID:         &secretName,
-			})
-		metrics.ObserveAPICall(metrics.ProviderIBMSM, metrics.CallIBMSMGetSecret, err)
-		if err != nil {
-			return nil, err
+	case sm.Secret_SecretType_PrivateCert:
+		secretData, ok := response.(*sm.PrivateCertificate)
+		if !ok {
+			return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_PrivateCert)
 		}
-
-		secret := response.Resources[0].(*sm.SecretResource)
-		secretData := secret.SecretData
-
-		secretMap := byteArrayMap(secretData)
+		secretMap[certificateConst] = []byte(*secretData.Certificate)
+		secretMap[privateKeyConst] = []byte(*secretData.PrivateKey)
 
 		return secretMap, nil
 
-	case sm.CreateSecretOptionsSecretTypeKvConst:
+	case sm.Secret_SecretType_Kv:
 		secret, err := getKVSecret(ibm, &secretName, ref)
 		if err != nil {
 			return nil, err
@@ -513,7 +448,7 @@ func (ibm *providerIBM) GetSecretMap(_ context.Context, ref esv1beta1.ExternalSe
 		m := make(map[string]interface{})
 		err = json.Unmarshal(secret, &m)
 		if err != nil {
-			return nil, err
+			return nil, fmt.Errorf(errJSONSecretUnmarshal, err)
 		}
 
 		secretMap := byteArrayMap(m)
@@ -618,7 +553,7 @@ func (ibm *providerIBM) NewClient(ctx context.Context, store esv1beta1.GenericSt
 	}
 
 	var err error
-	var secretsManager *sm.SecretsManagerV1
+	var secretsManager *sm.SecretsManagerV2
 	containerAuthProfile := iStore.store.Auth.ContainerAuth.Profile
 	if containerAuthProfile != "" {
 		// container-based auth
@@ -642,7 +577,7 @@ func (ibm *providerIBM) NewClient(ctx context.Context, store esv1beta1.GenericSt
 		if err != nil {
 			return nil, fmt.Errorf(errIBMClient, err)
 		}
-		secretsManager, err = sm.NewSecretsManagerV1(&sm.SecretsManagerV1Options{
+		secretsManager, err = sm.NewSecretsManagerV2(&sm.SecretsManagerV2Options{
 			URL:           *storeSpec.Provider.IBM.ServiceURL,
 			Authenticator: authenticator,
 		})
@@ -655,7 +590,7 @@ func (ibm *providerIBM) NewClient(ctx context.Context, store esv1beta1.GenericSt
 			return nil, err
 		}
 
-		secretsManager, err = sm.NewSecretsManagerV1(&sm.SecretsManagerV1Options{
+		secretsManager, err = sm.NewSecretsManagerV2(&sm.SecretsManagerV2Options{
 			URL: *storeSpec.Provider.IBM.ServiceURL,
 			Authenticator: &core.IamAuthenticator{
 				ApiKey: string(iStore.credentials),

+ 310 - 295
pkg/provider/ibm/provider_test.go

@@ -15,13 +15,14 @@ package ibm
 
 import (
 	"context"
+	"encoding/json"
 	"fmt"
 	"reflect"
 	"strings"
 	"testing"
 
 	"github.com/IBM/go-sdk-core/v5/core"
-	sm "github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1"
+	sm "github.com/IBM/secrets-manager-go-sdk/v2/secretsmanagerv2"
 	corev1 "k8s.io/api/core/v1"
 	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 	utilpointer "k8s.io/utils/pointer"
@@ -35,12 +36,14 @@ import (
 const (
 	errExpectedErr = "wanted error got nil"
 	secretKey      = "test-secret"
+	secretUUID     = "d5deb37a-7883-4fe2-a5e7-3c15420adc76"
 )
 
 type secretManagerTestCase struct {
+	name           string
 	mockClient     *fakesm.IBMMockClient
 	apiInput       *sm.GetSecretOptions
-	apiOutput      *sm.GetSecret
+	apiOutput      sm.SecretIntf
 	ref            *esv1beta1.ExternalSecretDataRemoteRef
 	serviceURL     *string
 	apiErr         error
@@ -62,37 +65,36 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
 		expectedSecret: "",
 		expectedData:   map[string][]byte{},
 	}
-	smtc.mockClient.WithValue(smtc.apiInput, smtc.apiOutput, smtc.apiErr)
+	mcParams := fakesm.IBMMockClientParams{
+		GetSecretOptions: smtc.apiInput,
+		GetSecretOutput:  smtc.apiOutput,
+		GetSecretErr:     smtc.apiErr,
+	}
+	smtc.mockClient.WithValue(mcParams)
 	return &smtc
 }
 
 func makeValidRef() *esv1beta1.ExternalSecretDataRemoteRef {
 	return &esv1beta1.ExternalSecretDataRemoteRef{
-		Key:     secretKey,
+		Key:     secretUUID,
 		Version: "default",
 	}
 }
 
 func makeValidAPIInput() *sm.GetSecretOptions {
 	return &sm.GetSecretOptions{
-		SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
-		ID:         utilpointer.String(secretKey),
+		ID: utilpointer.String(secretUUID),
 	}
 }
 
-func makeValidAPIOutput() *sm.GetSecret {
-	secretData := make(map[string]interface{})
-	secretData["payload"] = ""
-
-	return &sm.GetSecret{
-		Resources: []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String("testytype"),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			},
-		},
+func makeValidAPIOutput() sm.SecretIntf {
+	secret := &sm.Secret{
+		SecretType: utilpointer.String(sm.Secret_SecretType_Arbitrary),
+		Name:       utilpointer.String("testyname"),
+		ID:         utilpointer.String(secretUUID),
 	}
+	var i sm.SecretIntf = secret
+	return i
 }
 
 func makeValidSecretManagerTestCaseCustom(tweaks ...func(smtc *secretManagerTestCase)) *secretManagerTestCase {
@@ -100,7 +102,12 @@ func makeValidSecretManagerTestCaseCustom(tweaks ...func(smtc *secretManagerTest
 	for _, fn := range tweaks {
 		fn(smtc)
 	}
-	smtc.mockClient.WithValue(smtc.apiInput, smtc.apiOutput, smtc.apiErr)
+	mcParams := fakesm.IBMMockClientParams{
+		GetSecretOptions: smtc.apiInput,
+		GetSecretOutput:  smtc.apiOutput,
+		GetSecretErr:     smtc.apiErr,
+	}
+	smtc.mockClient.WithValue(mcParams)
 	return smtc
 }
 
@@ -168,71 +175,71 @@ func TestValidateStore(t *testing.T) {
 // test the sm<->gcp interface
 // make sure correct values are passed and errors are handled accordingly.
 func TestIBMSecretManagerGetSecret(t *testing.T) {
-	secretData := make(map[string]interface{})
 	secretString := "changedvalue"
+	secretUsername := "userName"
 	secretPassword := "P@ssw0rd"
 	secretAPIKey := "01234567890"
 	secretCertificate := "certificate_value"
 
-	secretData["payload"] = secretString
-	secretData["password"] = secretPassword
-	secretData["certificate"] = secretCertificate
-
 	// good case: default version is set
 	// key is passed in, output is sent back
 	setSecretString := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String("testytype"),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiOutput.Resources = resources
+		secret := &sm.ArbitrarySecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Arbitrary),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Payload:    &secretString,
+		}
+		smtc.name = "good case: default version is set"
+		smtc.apiOutput = secret
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
 		smtc.expectedSecret = secretString
 	}
 
 	// good case: custom version set
 	setCustomKey := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String("testytype"),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-		smtc.ref.Key = "testyname"
-		smtc.apiInput.ID = utilpointer.String("testyname")
-		smtc.apiOutput.Resources = resources
+		secret := &sm.ArbitrarySecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Arbitrary),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Payload:    &secretString,
+		}
+		smtc.name = "good case: custom version set"
+		smtc.ref.Key = "arbitrary/" + secretUUID
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.expectedSecret = secretString
 	}
 
 	// bad case: username_password type without property
-	secretUserPass := "username_password/test-secret"
+	secretUserPass := "username_password/" + secretUUID
 	badSecretUserPass := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.UsernamePasswordSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_UsernamePassword),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Username:   &secretUsername,
+			Password:   &secretPassword,
+		}
+		smtc.name = "bad case: username_password type without property"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretUserPass
 		smtc.expectError = "remoteRef.property required for secret type username_password"
 	}
 
 	// good case: username_password type with property
 	setSecretUserPass := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.UsernamePasswordSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_UsernamePassword),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Username:   &secretUsername,
+			Password:   &secretPassword,
+		}
+		smtc.name = "good case: username_password type with property"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretUserPass
 		smtc.ref.Property = "password"
 		smtc.expectedSecret = secretPassword
@@ -240,31 +247,25 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 	// good case: iam_credenatials type
 	setSecretIam := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
-				Name:       utilpointer.String("testyname"),
-				APIKey:     utilpointer.String(secretAPIKey),
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "iam_credentials/test-secret"
+		secret := &sm.IAMCredentialsSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_IamCredentials),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			ApiKey:     utilpointer.String(secretAPIKey),
+		}
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.name = "good case: iam_credenatials type"
+		smtc.apiOutput = secret
+		smtc.ref.Key = "iam_credentials/" + secretUUID
 		smtc.expectedSecret = secretAPIKey
 	}
 
-	funcSetCertSecretTest := func(certType string, good bool) func(*secretManagerTestCase) {
+	funcSetCertSecretTest := func(secret sm.SecretIntf, name, certType string, good bool) func(*secretManagerTestCase) {
 		return func(smtc *secretManagerTestCase) {
-			resources := []sm.SecretResourceIntf{
-				&sm.SecretResource{
-					SecretType: utilpointer.String(certType),
-					Name:       utilpointer.String("testyname"),
-					SecretData: secretData,
-				}}
-
-			smtc.apiInput.SecretType = core.StringPtr(certType)
-			smtc.apiOutput.Resources = resources
-			smtc.ref.Key = certType + "/" + secretKey
+			smtc.name = name
+			smtc.apiInput.ID = utilpointer.String(secretUUID)
+			smtc.apiOutput = secret
+			smtc.ref.Key = certType + "/" + secretUUID
 			if good {
 				smtc.ref.Property = "certificate"
 				smtc.expectedSecret = secretCertificate
@@ -275,61 +276,82 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 	}
 
 	// good case: imported_cert type with property
-	setSecretCert := funcSetCertSecretTest(sm.CreateSecretOptionsSecretTypeImportedCertConst, true)
+	importedCert := &sm.ImportedCertificate{
+		SecretType:   utilpointer.String(sm.Secret_SecretType_ImportedCert),
+		Name:         utilpointer.String("testyname"),
+		ID:           utilpointer.String(secretUUID),
+		Certificate:  utilpointer.String(secretCertificate),
+		Intermediate: utilpointer.String("intermediate"),
+		PrivateKey:   utilpointer.String("private_key"),
+	}
+	setSecretCert := funcSetCertSecretTest(importedCert, "good case: imported_cert type with property", sm.Secret_SecretType_ImportedCert, true)
 
 	// bad case: imported_cert type without property
-	badSecretCert := funcSetCertSecretTest(sm.CreateSecretOptionsSecretTypeImportedCertConst, false)
+	badSecretCert := funcSetCertSecretTest(importedCert, "bad case: imported_cert type without property", sm.Secret_SecretType_ImportedCert, false)
 
 	// good case: public_cert type with property
-	setSecretPublicCert := funcSetCertSecretTest(sm.CreateSecretOptionsSecretTypePublicCertConst, true)
+	publicCert := &sm.PublicCertificate{
+		SecretType:   utilpointer.String(sm.Secret_SecretType_PublicCert),
+		Name:         utilpointer.String("testyname"),
+		ID:           utilpointer.String(secretUUID),
+		Certificate:  utilpointer.String(secretCertificate),
+		Intermediate: utilpointer.String("intermediate"),
+		PrivateKey:   utilpointer.String("private_key"),
+	}
+	setSecretPublicCert := funcSetCertSecretTest(publicCert, "good case: public_cert type with property", sm.Secret_SecretType_PublicCert, true)
 
 	// bad case: public_cert type without property
-	badSecretPublicCert := funcSetCertSecretTest(sm.CreateSecretOptionsSecretTypePublicCertConst, false)
+	badSecretPublicCert := funcSetCertSecretTest(publicCert, "bad case: public_cert type without property", sm.Secret_SecretType_PublicCert, false)
 
 	// good case: private_cert type with property
-	setSecretPrivateCert := funcSetCertSecretTest(sm.CreateSecretOptionsSecretTypePrivateCertConst, true)
+	privateCert := &sm.PrivateCertificate{
+		SecretType:  utilpointer.String(sm.Secret_SecretType_PublicCert),
+		Name:        utilpointer.String("testyname"),
+		ID:          utilpointer.String(secretUUID),
+		Certificate: utilpointer.String(secretCertificate),
+		PrivateKey:  utilpointer.String("private_key"),
+	}
+	setSecretPrivateCert := funcSetCertSecretTest(privateCert, "good case: private_cert type with property", sm.Secret_SecretType_PrivateCert, true)
 
 	// bad case: private_cert type without property
-	badSecretPrivateCert := funcSetCertSecretTest(sm.CreateSecretOptionsSecretTypePrivateCertConst, false)
+	badSecretPrivateCert := funcSetCertSecretTest(privateCert, "bad case: private_cert type without property", sm.Secret_SecretType_PrivateCert, false)
 
 	secretDataKV := make(map[string]interface{})
-	secretKVPayload := make(map[string]interface{})
-	secretKVPayload["key1"] = "val1"
-	secretDataKV["payload"] = secretKVPayload
+	secretDataKV["key1"] = "val1"
 
 	secretDataKVComplex := make(map[string]interface{})
-	secretKVComplex := `{"key1":"val1","key2":"val2","key3":"val3","keyC":{"keyC1":"valC1", "keyC2":"valC2"}, "special.log": "file-content"}`
+	secretKVComplex := `{"key1":"val1","key2":"val2","key3":"val3","keyC":{"keyC1":"valC1","keyC2":"valC2"},"special.log":"file-content"}`
+	json.Unmarshal([]byte(secretKVComplex), &secretDataKVComplex)
 
-	secretDataKVComplex["payload"] = secretKVComplex
+	secretKV := "kv/" + secretUUID
 
-	secretKV := "kv/test-secret"
 	// bad case: kv type with key which is not in payload
 	badSecretKV := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretDataKV,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.KVSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Data:       secretDataKV,
+		}
+		smtc.name = "bad case: kv type with key which is not in payload"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretKV
 		smtc.ref.Property = "other-key"
-		smtc.expectError = "key other-key does not exist in secret kv/test-secret"
+		smtc.expectError = "key other-key does not exist in secret kv/" + secretUUID
 	}
 
 	// good case: kv type with property
 	setSecretKV := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretDataKV,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.KVSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Data:       secretDataKV,
+		}
+		smtc.name = "good case: kv type with property"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretKV
 		smtc.ref.Property = "key1"
 		smtc.expectedSecret = "val1"
@@ -337,15 +359,15 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 	// good case: kv type with property, returns specific value
 	setSecretKVWithKey := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretDataKVComplex,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.KVSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Data:       secretDataKVComplex,
+		}
+		smtc.name = "good case: kv type with property, returns specific value"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretKV
 		smtc.ref.Property = "key2"
 		smtc.expectedSecret = "val2"
@@ -353,15 +375,15 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 	// good case: kv type with property and path, returns specific value
 	setSecretKVWithKeyPath := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretDataKVComplex,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.KVSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Data:       secretDataKVComplex,
+		}
+		smtc.name = "good case: kv type with property and path, returns specific value"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretKV
 		smtc.ref.Property = "keyC.keyC2"
 		smtc.expectedSecret = "valC2"
@@ -369,15 +391,15 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 	// good case: kv type with property and dot, returns specific value
 	setSecretKVWithKeyDot := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretDataKVComplex,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.KVSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Data:       secretDataKVComplex,
+		}
+		smtc.name = "good case: kv type with property and dot, returns specific value"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretKV
 		smtc.ref.Property = "special.log"
 		smtc.expectedSecret = "file-content"
@@ -385,21 +407,20 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 	// good case: kv type without property, returns all
 	setSecretKVWithOutKey := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretDataKVComplex,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
+		secret := &sm.KVSecret{
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			Data:       secretDataKVComplex,
+		}
+		smtc.name = "good case: kv type without property, returns all"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
 		smtc.ref.Key = secretKV
 		smtc.expectedSecret = secretKVComplex
 	}
 
 	successCases := []*secretManagerTestCase{
-		makeValidSecretManagerTestCase(),
 		makeValidSecretManagerTestCaseCustom(setSecretString),
 		makeValidSecretManagerTestCaseCustom(setCustomKey),
 		makeValidSecretManagerTestCaseCustom(setAPIErr),
@@ -408,13 +429,13 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 		makeValidSecretManagerTestCaseCustom(setSecretUserPass),
 		makeValidSecretManagerTestCaseCustom(setSecretIam),
 		makeValidSecretManagerTestCaseCustom(setSecretCert),
-		makeValidSecretManagerTestCaseCustom(badSecretCert),
 		makeValidSecretManagerTestCaseCustom(setSecretKV),
 		makeValidSecretManagerTestCaseCustom(setSecretKVWithKey),
 		makeValidSecretManagerTestCaseCustom(setSecretKVWithKeyPath),
 		makeValidSecretManagerTestCaseCustom(setSecretKVWithKeyDot),
 		makeValidSecretManagerTestCaseCustom(setSecretKVWithOutKey),
 		makeValidSecretManagerTestCaseCustom(badSecretKV),
+		makeValidSecretManagerTestCaseCustom(badSecretCert),
 		makeValidSecretManagerTestCaseCustom(setSecretPublicCert),
 		makeValidSecretManagerTestCaseCustom(badSecretPublicCert),
 		makeValidSecretManagerTestCaseCustom(setSecretPrivateCert),
@@ -423,19 +444,20 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 
 	sm := providerIBM{}
 	for k, v := range successCases {
-		sm.IBMClient = 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))
-		}
+		t.Run(v.name, func(t *testing.T) {
+			sm.IBMClient = 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) {
-	secretKeyName := "kv/test-secret"
 	secretUsername := "user1"
 	secretPassword := "P@ssw0rd"
 	secretAPIKey := "01234567890"
@@ -454,89 +476,60 @@ func TestGetSecretMap(t *testing.T) {
 		},
 	}
 
-	// good case: default version & deserialization
-	setDeserialization := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["payload"] = `{"foo":"bar"}`
-
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String("testytype"),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiOutput.Resources = resources
-		smtc.expectedData["foo"] = []byte("bar")
-	}
-
-	// bad case: invalid json
-	setInvalidJSON := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["payload"] = `-----------------`
-
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String("testytype"),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiOutput.Resources = resources
-		smtc.expectError = "unable to unmarshal secret: invalid character '-' in numeric literal"
+	// good case: arbitrary
+	setArbitrary := func(smtc *secretManagerTestCase) {
+		payload := `{"foo":"bar"}`
+		secret := &sm.ArbitrarySecret{
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_Arbitrary),
+			Payload:    &payload,
+		}
+		smtc.name = "good case: arbitrary"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
+		smtc.ref.Key = secretUUID
+		smtc.expectedData["arbitrary"] = []byte(payload)
 	}
 
 	// good case: username_password
 	setSecretUserPass := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["username"] = secretUsername
-		secretData["password"] = secretPassword
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "username_password/test-secret"
+		secret := &sm.UsernamePasswordSecret{
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_UsernamePassword),
+			Username:   &secretUsername,
+			Password:   &secretPassword,
+		}
+		smtc.name = "good case: username_password"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
+		smtc.ref.Key = "username_password/" + secretUUID
 		smtc.expectedData["username"] = []byte(secretUsername)
 		smtc.expectedData["password"] = []byte(secretPassword)
 	}
 
 	// good case: iam_credentials
 	setSecretIam := func(smtc *secretManagerTestCase) {
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
-				Name:       utilpointer.String("testyname"),
-				APIKey:     utilpointer.String(secretAPIKey),
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = "iam_credentials/test-secret"
+		secret := &sm.IAMCredentialsSecret{
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_IamCredentials),
+			ApiKey:     utilpointer.String(secretAPIKey),
+		}
+		smtc.name = "good case: iam_credentials"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
+		smtc.ref.Key = "iam_credentials/" + secretUUID
 		smtc.expectedData["apikey"] = []byte(secretAPIKey)
 	}
 
-	funcCertTest := func(certType string) func(*secretManagerTestCase) {
+	funcCertTest := func(secret sm.SecretIntf, name, certType string) func(*secretManagerTestCase) {
 		return func(smtc *secretManagerTestCase) {
-			secretData := make(map[string]interface{})
-			secretData["certificate"] = secretCertificate
-			secretData["private_key"] = secretPrivateKey
-			secretData["intermediate"] = secretIntermediate
-
-			resources := []sm.SecretResourceIntf{
-				&sm.SecretResource{
-					SecretType: utilpointer.String(certType),
-					Name:       utilpointer.String("testyname"),
-					SecretData: secretData,
-				}}
-
-			smtc.apiInput.SecretType = core.StringPtr(certType)
-			smtc.apiOutput.Resources = resources
-			smtc.ref.Key = certType + "/test-secret"
+			smtc.name = name
+			smtc.apiInput.ID = utilpointer.String(secretUUID)
+			smtc.apiOutput = secret
+			smtc.ref.Key = certType + "/" + secretUUID
 			smtc.expectedData["certificate"] = []byte(secretCertificate)
 			smtc.expectedData["private_key"] = []byte(secretPrivateKey)
 			smtc.expectedData["intermediate"] = []byte(secretIntermediate)
@@ -544,27 +537,57 @@ func TestGetSecretMap(t *testing.T) {
 	}
 
 	// good case: imported_cert
-	setSecretCert := funcCertTest(sm.CreateSecretOptionsSecretTypeImportedCertConst)
-	// good case: public_cert
-	setSecretPublicCert := funcCertTest(sm.CreateSecretOptionsSecretTypePublicCertConst)
+	importedCert := &sm.ImportedCertificate{
+		SecretType:   utilpointer.String(sm.Secret_SecretType_ImportedCert),
+		Name:         utilpointer.String("testyname"),
+		ID:           utilpointer.String(secretUUID),
+		Certificate:  utilpointer.String(secretCertificate),
+		Intermediate: utilpointer.String(secretIntermediate),
+		PrivateKey:   utilpointer.String(secretPrivateKey),
+	}
+	setSecretCert := funcCertTest(importedCert, "good case: imported_cert", sm.Secret_SecretType_ImportedCert)
+
 	// good case: public_cert
-	setSecretPrivateCert := funcCertTest(sm.CreateSecretOptionsSecretTypePrivateCertConst)
+	publicCert := &sm.PublicCertificate{
+		SecretType:   utilpointer.String(sm.Secret_SecretType_PublicCert),
+		Name:         utilpointer.String("testyname"),
+		ID:           utilpointer.String(secretUUID),
+		Certificate:  utilpointer.String(secretCertificate),
+		Intermediate: utilpointer.String(secretIntermediate),
+		PrivateKey:   utilpointer.String(secretPrivateKey),
+	}
+	setSecretPublicCert := funcCertTest(publicCert, "good case: public_cert", sm.Secret_SecretType_PublicCert)
+
+	// good case: private_cert
+	setSecretPrivateCert := func(smtc *secretManagerTestCase) {
+		secret := &sm.PrivateCertificate{
+			Name:        utilpointer.String("testyname"),
+			ID:          utilpointer.String(secretUUID),
+			SecretType:  utilpointer.String(sm.Secret_SecretType_PrivateCert),
+			Certificate: &secretCertificate,
+			PrivateKey:  &secretPrivateKey,
+		}
+		smtc.name = "good case: private_cert"
+		smtc.apiInput.ID = utilpointer.String(secretUUID)
+		smtc.apiOutput = secret
+		smtc.ref.Key = "private_cert/" + secretUUID
+		smtc.expectedData["certificate"] = []byte(secretCertificate)
+		smtc.expectedData["private_key"] = []byte(secretPrivateKey)
+	}
 
+	secretKeyKV := "kv/" + secretUUID
 	// good case: kv, no property, return entire payload as key:value pairs
 	setSecretKV := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["payload"] = secretComplex
-
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretKeyName
+		secret := &sm.KVSecret{
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Data:       secretComplex,
+		}
+		smtc.name = "good case: kv, no property, return entire payload as key:value pairs"
+		smtc.apiInput.ID = core.StringPtr(secretUUID)
+		smtc.apiOutput = secret
+		smtc.ref.Key = secretKeyKV
 		smtc.expectedData["key1"] = []byte("val1")
 		smtc.expectedData["key2"] = []byte("val2")
 		smtc.expectedData["keyC"] = []byte(`{"keyC1":{"keyA":"valA","keyB":"valB"}}`)
@@ -572,65 +595,55 @@ func TestGetSecretMap(t *testing.T) {
 
 	// good case: kv, with property
 	setSecretKVWithProperty := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["payload"] = secretComplex
-
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
+		secret := &sm.KVSecret{
+			Name:       utilpointer.String("d5deb37a-7883-4fe2-a5e7-3c15420adc76"),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Data:       secretComplex,
+		}
+		smtc.name = "good case: kv, with property"
+		smtc.apiInput.ID = core.StringPtr(secretUUID)
 		smtc.ref.Property = "keyC"
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretKeyName
+		smtc.apiOutput = secret
+		smtc.ref.Key = secretKeyKV
 		smtc.expectedData["keyC1"] = []byte(`{"keyA":"valA","keyB":"valB"}`)
 	}
 
 	// good case: kv, with property and path
 	setSecretKVWithPathAndProperty := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["payload"] = secretComplex
-
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
+		secret := &sm.KVSecret{
+			Name:       utilpointer.String(secretUUID),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Data:       secretComplex,
+		}
+		smtc.name = "good case: kv, with property and path"
+		smtc.apiInput.ID = core.StringPtr(secretUUID)
 		smtc.ref.Property = "keyC.keyC1"
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretKeyName
+		smtc.apiOutput = secret
+		smtc.ref.Key = secretKeyKV
 		smtc.expectedData["keyA"] = []byte("valA")
 		smtc.expectedData["keyB"] = []byte("valB")
 	}
 
 	// bad case: kv, with property and path
 	badSecretKVWithUnknownProperty := func(smtc *secretManagerTestCase) {
-		secretData := make(map[string]interface{})
-		secretData["payload"] = secretComplex
-
-		resources := []sm.SecretResourceIntf{
-			&sm.SecretResource{
-				SecretType: utilpointer.String(sm.CreateSecretOptionsSecretTypeKvConst),
-				Name:       utilpointer.String("testyname"),
-				SecretData: secretData,
-			}}
-
-		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeKvConst)
+		secret := &sm.KVSecret{
+			Name:       utilpointer.String("testyname"),
+			ID:         utilpointer.String(secretUUID),
+			SecretType: utilpointer.String(sm.Secret_SecretType_Kv),
+			Data:       secretComplex,
+		}
+		smtc.name = "bad case: kv, with property and path"
+		smtc.apiInput.ID = core.StringPtr(secretUUID)
 		smtc.ref.Property = "unknown.property"
-		smtc.apiOutput.Resources = resources
-		smtc.ref.Key = secretKeyName
-		smtc.expectError = "key unknown.property does not exist in secret kv/test-secret"
+		smtc.apiOutput = secret
+		smtc.ref.Key = secretKeyKV
+		smtc.expectError = "key unknown.property does not exist in secret " + secretKeyKV
 	}
 
 	successCases := []*secretManagerTestCase{
-		makeValidSecretManagerTestCaseCustom(setDeserialization),
-		makeValidSecretManagerTestCaseCustom(setInvalidJSON),
+		makeValidSecretManagerTestCaseCustom(setArbitrary),
 		makeValidSecretManagerTestCaseCustom(setNilMockClient),
 		makeValidSecretManagerTestCaseCustom(setAPIErr),
 		makeValidSecretManagerTestCaseCustom(setSecretUserPass),
@@ -646,14 +659,16 @@ func TestGetSecretMap(t *testing.T) {
 
 	sm := providerIBM{}
 	for k, v := range successCases {
-		sm.IBMClient = 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)
-		}
+		t.Run(v.name, func(t *testing.T) {
+			sm.IBMClient = v.mockClient
+			out, err := sm.GetSecretMap(context.Background(), *v.ref)
+			if !ErrorContains(err, v.expectError) {
+				t.Errorf(" unexpected error: %s, expected: '%s'", 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)
+			}
+		})
 	}
 }