Browse Source

Merge branch 'external-secrets:main' into main

KianTigger 4 years ago
parent
commit
3375969bc4
4 changed files with 353 additions and 52 deletions
  1. 2 2
      go.mod
  2. 4 6
      go.sum
  3. 178 31
      pkg/provider/ibm/provider.go
  4. 169 13
      pkg/provider/ibm/provider_test.go

+ 2 - 2
go.mod

@@ -37,8 +37,8 @@ require (
 	github.com/Azure/go-autorest/autorest/azure/auth v0.5.7
 	github.com/Azure/go-autorest/autorest/to v0.4.0 // indirect
 	github.com/Azure/go-autorest/autorest/validation v0.3.1 // indirect
-	github.com/IBM/go-sdk-core/v5 v5.4.5
-	github.com/IBM/secrets-manager-go-sdk v0.1.21
+	github.com/IBM/go-sdk-core/v5 v5.5.0
+	github.com/IBM/secrets-manager-go-sdk v1.0.23
 	github.com/aws/aws-sdk-go v1.38.6
 	github.com/crossplane/crossplane-runtime v0.13.0
 	github.com/fatih/color v1.10.0 // indirect

+ 4 - 6
go.sum

@@ -63,11 +63,10 @@ github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ
 github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ=
-github.com/IBM/go-sdk-core/v5 v5.4.2/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0=
-github.com/IBM/go-sdk-core/v5 v5.4.5 h1:fP/SLOMxRzhHaqS+I5XN+1CWrAAWn8fdzWuZvbR5KxE=
-github.com/IBM/go-sdk-core/v5 v5.4.5/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0=
-github.com/IBM/secrets-manager-go-sdk v0.1.21 h1:llT2ryUHpSvNwqzNQ+8cxInIXi7WgRtgUz9ycerJKvA=
-github.com/IBM/secrets-manager-go-sdk v0.1.21/go.mod h1:aw+EgLmbwxGDxlcohb/ye46O4nLeBSapAapHmWLZ2fY=
+github.com/IBM/go-sdk-core/v5 v5.5.0 h1:etP4m0kzMCxjZRI4Bu6cRTfK9YDvY3xFuagXugkCyxc=
+github.com/IBM/go-sdk-core/v5 v5.5.0/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0=
+github.com/IBM/secrets-manager-go-sdk v1.0.23 h1:YvRB2jmCfXVwTiTozCNVIRfl6q9Qcl2JiL4x6chOSI4=
+github.com/IBM/secrets-manager-go-sdk v1.0.23/go.mod h1:ruP6eQ0/J/zHBbnMfUyWeMsTe9vgnGL4rDeLiSKhZhU=
 github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ=
 github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c=
 github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=
@@ -527,7 +526,6 @@ github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7J
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc=
-github.com/onsi/gomega v1.12.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
 github.com/onsi/gomega v1.13.0 h1:7lLHu94wT9Ij0o6EWWclhu0aOh32VxhkwEJvzuWPeak=
 github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=

+ 178 - 31
pkg/provider/ibm/provider.go

@@ -17,6 +17,7 @@ import (
 	"context"
 	"encoding/json"
 	"fmt"
+	"strings"
 
 	"github.com/IBM/go-sdk-core/v5/core"
 	sm "github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1"
@@ -95,51 +96,197 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
 	if utils.IsNil(ibm.IBMClient) {
 		return nil, fmt.Errorf(errUninitalizedIBMProvider)
 	}
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
-			ID:         &ref.Key,
-		})
 
-	if err != nil {
-		return nil, err
+	secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
+	secretName := ref.Key
+	nameSplitted := strings.Split(secretName, "/")
+
+	if len(nameSplitted) > 1 {
+		secretType = nameSplitted[0]
+		secretName = nameSplitted[1]
 	}
 
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData.(map[string]interface{})
-	arbitrarySecretPayload := secretData["payload"].(string)
-	return []byte(arbitrarySecretPayload), nil
+	switch secretType {
+	case sm.GetSecretOptionsSecretTypeArbitraryConst:
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := secret.SecretData.(map[string]interface{})
+		arbitrarySecretPayload := secretData["payload"].(string)
+		return []byte(arbitrarySecretPayload), nil
+
+	case sm.CreateSecretOptionsSecretTypeUsernamePasswordConst:
+		if ref.Property == "" {
+			return nil, fmt.Errorf("remoteRef.property required for secret type username_password")
+		}
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := secret.SecretData.(map[string]interface{})
+
+		if val, ok := secretData[ref.Property]; ok {
+			return []byte(val.(string)), nil
+		}
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+
+	case sm.CreateSecretOptionsSecretTypeIamCredentialsConst:
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := *secret.APIKey
+
+		return []byte(secretData), nil
+
+	case sm.CreateSecretOptionsSecretTypeImportedCertConst:
+		if ref.Property == "" {
+			return nil, fmt.Errorf("remoteRef.property required for secret type imported_cert")
+		}
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := secret.SecretData.(map[string]interface{})
+
+		if val, ok := secretData[ref.Property]; ok {
+			return []byte(val.(string)), nil
+		}
+		return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
+
+	default:
+		return nil, fmt.Errorf("unknown secret type %s", secretType)
+	}
 }
 
 func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
 	if utils.IsNil(ibm.IBMClient) {
 		return nil, fmt.Errorf(errUninitalizedIBMProvider)
 	}
-	response, _, err := ibm.IBMClient.GetSecret(
-		&sm.GetSecretOptions{
-			SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
-			ID:         &ref.Key,
-		})
-	if err != nil {
-		return nil, err
-	}
 
-	secret := response.Resources[0].(*sm.SecretResource)
-	secretData := secret.SecretData.(map[string]interface{})
-	arbitrarySecretPayload := secretData["payload"].(string)
+	secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
+	secretName := ref.Key
+	nameSplitted := strings.Split(secretName, "/")
 
-	kv := make(map[string]string)
-	err = json.Unmarshal([]byte(arbitrarySecretPayload), &kv)
-	if err != nil {
-		return nil, fmt.Errorf(errJSONSecretUnmarshal, err)
+	if len(nameSplitted) > 1 {
+		secretType = nameSplitted[0]
+		secretName = nameSplitted[1]
 	}
 
-	secretMap := make(map[string][]byte)
-	for k, v := range kv {
-		secretMap[k] = []byte(v)
-	}
+	switch secretType {
+	case sm.GetSecretOptionsSecretTypeArbitraryConst:
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
+				ID:         &ref.Key,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := secret.SecretData.(map[string]interface{})
+		arbitrarySecretPayload := secretData["payload"].(string)
+
+		kv := make(map[string]string)
+		err = json.Unmarshal([]byte(arbitrarySecretPayload), &kv)
+		if err != nil {
+			return nil, fmt.Errorf(errJSONSecretUnmarshal, err)
+		}
+
+		secretMap := make(map[string][]byte)
+		for k, v := range kv {
+			secretMap[k] = []byte(v)
+		}
+
+		return secretMap, nil
+
+	case sm.CreateSecretOptionsSecretTypeUsernamePasswordConst:
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := secret.SecretData.(map[string]interface{})
+
+		secretMap := make(map[string][]byte)
+		for k, v := range secretData {
+			secretMap[k] = []byte(v.(string))
+		}
 
-	return secretMap, nil
+		return secretMap, nil
+
+	case sm.CreateSecretOptionsSecretTypeIamCredentialsConst:
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := *secret.APIKey
+
+		secretMap := make(map[string][]byte)
+		secretMap["apikey"] = []byte(secretData)
+
+		return secretMap, nil
+
+	case sm.CreateSecretOptionsSecretTypeImportedCertConst:
+		response, _, err := ibm.IBMClient.GetSecret(
+			&sm.GetSecretOptions{
+				SecretType: core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
+				ID:         &secretName,
+			})
+		if err != nil {
+			return nil, err
+		}
+
+		secret := response.Resources[0].(*sm.SecretResource)
+		secretData := secret.SecretData.(map[string]interface{})
+
+		secretMap := make(map[string][]byte)
+		for k, v := range secretData {
+			secretMap[k] = []byte(v.(string))
+		}
+
+		return secretMap, nil
+
+	default:
+		return nil, fmt.Errorf("unknown secret type %s", secretType)
+	}
 }
 
 func (ibm *providerIBM) Close() error {

+ 169 - 13
pkg/provider/ibm/provider_test.go

@@ -78,7 +78,7 @@ func makeValidAPIOutput() *sm.GetSecret {
 	return &sm.GetSecret{
 		Resources: []sm.SecretResourceIntf{
 			&sm.SecretResource{
-				Type:       utilpointer.StringPtr("testytype"),
+				SecretType: utilpointer.StringPtr("testytype"),
 				Name:       utilpointer.StringPtr("testyname"),
 				SecretData: secretData,
 			},
@@ -111,34 +111,120 @@ var setNilMockClient = func(smtc *secretManagerTestCase) {
 // make sure correct values are passed and errors are handled accordingly.
 func TestIBMSecretManagerGetSecret(t *testing.T) {
 	secretData := make(map[string]interface{})
-	secretValue := "changedvalue"
-	secretData["payload"] = secretValue
+	secretString := "changedvalue"
+	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{
-				Type:       utilpointer.StringPtr("testytype"),
+				SecretType: utilpointer.StringPtr("testytype"),
 				Name:       utilpointer.StringPtr("testyname"),
 				SecretData: secretData,
 			}}
 
 		smtc.apiOutput.Resources = resources
-		smtc.expectedSecret = secretValue
+		smtc.expectedSecret = secretString
 	}
 
 	// good case: custom version set
 	setCustomKey := func(smtc *secretManagerTestCase) {
 		resources := []sm.SecretResourceIntf{
 			&sm.SecretResource{
-				Type:       utilpointer.StringPtr("testytype"),
+				SecretType: utilpointer.StringPtr("testytype"),
 				Name:       utilpointer.StringPtr("testyname"),
 				SecretData: secretData,
 			}}
 		smtc.ref.Key = "testyname"
 		smtc.apiInput.ID = utilpointer.StringPtr("testyname")
 		smtc.apiOutput.Resources = resources
-		smtc.expectedSecret = secretValue
+		smtc.expectedSecret = secretString
+	}
+
+	// bad case: username_password type without property
+	secretUserPass := "username_password/test-secret"
+	badSecretUserPass := func(smtc *secretManagerTestCase) {
+		resources := []sm.SecretResourceIntf{
+			&sm.SecretResource{
+				SecretType: utilpointer.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				SecretData: secretData,
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
+		smtc.apiOutput.Resources = resources
+		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.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				SecretData: secretData,
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = secretUserPass
+		smtc.ref.Property = "password"
+		smtc.expectedSecret = secretPassword
+	}
+
+	// good case: iam_credenatials type
+	setSecretIam := func(smtc *secretManagerTestCase) {
+		resources := []sm.SecretResourceIntf{
+			&sm.SecretResource{
+				SecretType: utilpointer.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				APIKey:     utilpointer.StringPtr(secretAPIKey),
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = "iam_credentials/test-secret"
+		smtc.expectedSecret = secretAPIKey
+	}
+
+	// good case: imported_cert type with property
+	secretCert := "imported_cert/test-secret"
+	setSecretCert := func(smtc *secretManagerTestCase) {
+		resources := []sm.SecretResourceIntf{
+			&sm.SecretResource{
+				SecretType: utilpointer.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				SecretData: secretData,
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = secretCert
+		smtc.ref.Property = "certificate"
+		smtc.expectedSecret = secretCertificate
+	}
+
+	// bad case: imported_cert type without property
+	badSecretCert := func(smtc *secretManagerTestCase) {
+		resources := []sm.SecretResourceIntf{
+			&sm.SecretResource{
+				SecretType: utilpointer.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				SecretData: secretData,
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = secretCert
+		smtc.expectError = "remoteRef.property required for secret type imported_cert"
 	}
 
 	successCases := []*secretManagerTestCase{
@@ -147,6 +233,11 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 		makeValidSecretManagerTestCaseCustom(setCustomKey),
 		makeValidSecretManagerTestCaseCustom(setAPIErr),
 		makeValidSecretManagerTestCaseCustom(setNilMockClient),
+		makeValidSecretManagerTestCaseCustom(badSecretUserPass),
+		makeValidSecretManagerTestCaseCustom(setSecretUserPass),
+		makeValidSecretManagerTestCaseCustom(setSecretIam),
+		makeValidSecretManagerTestCaseCustom(setSecretCert),
+		makeValidSecretManagerTestCaseCustom(badSecretCert),
 	}
 
 	sm := providerIBM{}
@@ -163,17 +254,25 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
 }
 
 func TestGetSecretMap(t *testing.T) {
+	secretUsername := "user1"
+	secretPassword := "P@ssw0rd"
+	secretAPIKey := "01234567890"
+	secretCertificate := "certificate_value"
+	secretPrivateKey := "private_key_value"
+	secretIntermediate := "intermediate_value"
+
 	// good case: default version & deserialization
 	setDeserialization := func(smtc *secretManagerTestCase) {
 		secretData := make(map[string]interface{})
-		secretValue := `{"foo":"bar"}`
-		secretData["payload"] = secretValue
+		secretData["payload"] = `{"foo":"bar"}`
+
 		resources := []sm.SecretResourceIntf{
 			&sm.SecretResource{
-				Type:       utilpointer.StringPtr("testytype"),
+				SecretType: utilpointer.StringPtr("testytype"),
 				Name:       utilpointer.StringPtr("testyname"),
 				SecretData: secretData,
 			}}
+
 		smtc.apiOutput.Resources = resources
 		smtc.expectedData["foo"] = []byte("bar")
 	}
@@ -181,26 +280,83 @@ func TestGetSecretMap(t *testing.T) {
 	// bad case: invalid json
 	setInvalidJSON := func(smtc *secretManagerTestCase) {
 		secretData := make(map[string]interface{})
-
 		secretData["payload"] = `-----------------`
 
 		resources := []sm.SecretResourceIntf{
 			&sm.SecretResource{
-				Type:       utilpointer.StringPtr("testytype"),
+				SecretType: utilpointer.StringPtr("testytype"),
 				Name:       utilpointer.StringPtr("testyname"),
 				SecretData: secretData,
 			}}
 
 		smtc.apiOutput.Resources = resources
-
 		smtc.expectError = "unable to unmarshal secret: invalid character '-' in numeric literal"
 	}
 
+	// 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.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				SecretData: secretData,
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = "username_password/test-secret"
+		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.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				APIKey:     utilpointer.StringPtr(secretAPIKey),
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = "iam_credentials/test-secret"
+		smtc.expectedData["apikey"] = []byte(secretAPIKey)
+	}
+
+	// good case: imported_cert
+	setSecretCert := 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.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst),
+				Name:       utilpointer.StringPtr("testyname"),
+				SecretData: secretData,
+			}}
+
+		smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
+		smtc.apiOutput.Resources = resources
+		smtc.ref.Key = "imported_cert/test-secret"
+		smtc.expectedData["certificate"] = []byte(secretCertificate)
+		smtc.expectedData["private_key"] = []byte(secretPrivateKey)
+		smtc.expectedData["intermediate"] = []byte(secretIntermediate)
+	}
+
 	successCases := []*secretManagerTestCase{
 		makeValidSecretManagerTestCaseCustom(setDeserialization),
 		makeValidSecretManagerTestCaseCustom(setInvalidJSON),
 		makeValidSecretManagerTestCaseCustom(setNilMockClient),
 		makeValidSecretManagerTestCaseCustom(setAPIErr),
+		makeValidSecretManagerTestCaseCustom(setSecretUserPass),
+		makeValidSecretManagerTestCaseCustom(setSecretIam),
+		makeValidSecretManagerTestCaseCustom(setSecretCert),
 	}
 
 	sm := providerIBM{}