mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
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>
This commit is contained in:
parent
ddfe51d715
commit
405c12c314
5 changed files with 482 additions and 525 deletions
2
go.mod
2
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
|
||||
|
|
4
go.sum
4
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=
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 := response.Resources[0].(*sm.SecretResource)
|
||||
secretData := secret.SecretData
|
||||
|
||||
if val, ok := secretData[ref.Property]; ok {
|
||||
return []byte(val.(string)), nil
|
||||
secret, ok := response.(*sm.PublicCertificate)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(errExtractingSecret, *secretName, sm.Secret_SecretType_PublicCert)
|
||||
}
|
||||
|
||||
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]
|
||||
}
|
||||
|
||||
secretMap := make(map[string][]byte)
|
||||
response, err := getSecretData(ibm, &secretName)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
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
|
||||
case sm.Secret_SecretType_Arbitrary:
|
||||
secretData, ok := response.(*sm.ArbitrarySecret)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_Arbitrary)
|
||||
}
|
||||
secretMap[arbitraryConst] = []byte(*secretData.Payload)
|
||||
return secretMap, nil
|
||||
|
||||
secret := response.Resources[0].(*sm.SecretResource)
|
||||
secretData := secret.SecretData
|
||||
arbitrarySecretPayload := secretData["payload"].(string)
|
||||
|
||||
kv := make(map[string]interface{})
|
||||
err = json.Unmarshal([]byte(arbitrarySecretPayload), &kv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errJSONSecretUnmarshal, err)
|
||||
case sm.Secret_SecretType_UsernamePassword:
|
||||
secretData, ok := response.(*sm.UsernamePasswordSecret)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf(errExtractingSecret, secretName, sm.Secret_SecretType_UsernamePassword)
|
||||
}
|
||||
|
||||
secretMap := byteArrayMap(kv)
|
||||
secretMap[usernameConst] = []byte(*secretData.Username)
|
||||
secretMap[passwordConst] = []byte(*secretData.Password)
|
||||
|
||||
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_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.SecretData
|
||||
|
||||
secretMap := byteArrayMap(secretData)
|
||||
secretMap[apikeyConst] = []byte(*secretData.ApiKey)
|
||||
|
||||
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_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.APIKey
|
||||
|
||||
secretMap := make(map[string][]byte)
|
||||
secretMap["apikey"] = []byte(secretData)
|
||||
secretMap[certificateConst] = []byte(*secretData.Certificate)
|
||||
secretMap[intermediateConst] = []byte(*secretData.Intermediate)
|
||||
secretMap[privateKeyConst] = []byte(*secretData.PrivateKey)
|
||||
|
||||
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_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.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_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.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
|
||||
}
|
||||
|
||||
secret := response.Resources[0].(*sm.SecretResource)
|
||||
secretData := secret.SecretData
|
||||
|
||||
secretMap := byteArrayMap(secretData)
|
||||
|
||||
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),
|
||||
|
|
|
@ -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)
|
||||
// good case: public_cert
|
||||
setSecretPrivateCert := funcCertTest(sm.CreateSecretOptionsSecretTypePrivateCertConst)
|
||||
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
|
||||
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)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue