mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
Modified CRD according to the discussion
This commit is contained in:
parent
e24baa9db5
commit
f4d1b8dd22
28 changed files with 487 additions and 278 deletions
|
@ -118,25 +118,18 @@ type ExternalSecretData struct {
|
|||
|
||||
// ExternalSecretDataRemoteRef defines Provider data location.
|
||||
type ExternalSecretDataRemoteRef struct {
|
||||
// Used to select a specific version and property from the secret
|
||||
// +optional
|
||||
Extract ExternalSecretExtract `json:"extract,omitempty"`
|
||||
// Used to find secrets based on tags or regular expressions
|
||||
Find ExternalSecretFind `json:"find,omitempty"`
|
||||
}
|
||||
|
||||
type ExternalSecretExtract struct {
|
||||
// Key is the key used in the Provider
|
||||
// +optional
|
||||
Key string `json:"key,omitempty"`
|
||||
|
||||
// Used to select multiple secrets based on a pattern
|
||||
// +optional
|
||||
MatchKey string `json:"matchKey,omitempty"`
|
||||
|
||||
// List of tags used to filter the secrets
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
|
||||
// Used to select multiple secrets based on the name
|
||||
// +optional
|
||||
Name string `json:"name,omitempty"`
|
||||
|
||||
// Used to select multiple secrets based on a regular expression of the name
|
||||
// +optional
|
||||
RegExp string `json:"regexp,omitempty"`
|
||||
|
||||
// Used to select a specific version of the Provider value, if supported
|
||||
// +optional
|
||||
Version string `json:"version,omitempty"`
|
||||
|
@ -146,14 +139,21 @@ type ExternalSecretDataRemoteRef struct {
|
|||
Property string `json:"property,omitempty"`
|
||||
}
|
||||
|
||||
// type ExternalSecretDataRemoteMatchKey struct {
|
||||
type ExternalSecretFind struct {
|
||||
// Key is the key used in the Provider
|
||||
// +optional
|
||||
Name FindName `json:"name,omitempty"`
|
||||
|
||||
// //A regular expression used to get the secrets
|
||||
// //Name string `json:"name,omitempty"`
|
||||
// Used to select a specific version of the Provider value, if supported
|
||||
// +optional
|
||||
Tags map[string]string `json:"tags,omitempty"`
|
||||
}
|
||||
|
||||
// // List of tags used to filter the secrets
|
||||
// Tags map[string]string `json:"tags,omitempty"`
|
||||
// }
|
||||
type FindName struct {
|
||||
// Used to select multiple secrets based on a regular expression of the name
|
||||
// +optional
|
||||
RegExp string `json:"regexp,omitempty"`
|
||||
}
|
||||
|
||||
// ExternalSecretSpec defines the desired state of ExternalSecret.
|
||||
type ExternalSecretSpec struct {
|
||||
|
|
|
@ -405,6 +405,39 @@ func (in *ExternalSecretData) DeepCopy() *ExternalSecretData {
|
|||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalSecretDataRemoteRef) DeepCopyInto(out *ExternalSecretDataRemoteRef) {
|
||||
*out = *in
|
||||
out.Extract = in.Extract
|
||||
in.Find.DeepCopyInto(&out.Find)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretDataRemoteRef.
|
||||
func (in *ExternalSecretDataRemoteRef) DeepCopy() *ExternalSecretDataRemoteRef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalSecretDataRemoteRef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalSecretExtract) DeepCopyInto(out *ExternalSecretExtract) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretExtract.
|
||||
func (in *ExternalSecretExtract) DeepCopy() *ExternalSecretExtract {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalSecretExtract)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ExternalSecretFind) DeepCopyInto(out *ExternalSecretFind) {
|
||||
*out = *in
|
||||
out.Name = in.Name
|
||||
if in.Tags != nil {
|
||||
in, out := &in.Tags, &out.Tags
|
||||
*out = make(map[string]string, len(*in))
|
||||
|
@ -414,12 +447,12 @@ func (in *ExternalSecretDataRemoteRef) DeepCopyInto(out *ExternalSecretDataRemot
|
|||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretDataRemoteRef.
|
||||
func (in *ExternalSecretDataRemoteRef) DeepCopy() *ExternalSecretDataRemoteRef {
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ExternalSecretFind.
|
||||
func (in *ExternalSecretFind) DeepCopy() *ExternalSecretFind {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ExternalSecretDataRemoteRef)
|
||||
out := new(ExternalSecretFind)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
@ -610,6 +643,21 @@ func (in *ExternalSecretTemplateMetadata) DeepCopy() *ExternalSecretTemplateMeta
|
|||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *FindName) DeepCopyInto(out *FindName) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new FindName.
|
||||
func (in *FindName) DeepCopy() *FindName {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(FindName)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *GCPSMAuth) DeepCopyInto(out *GCPSMAuth) {
|
||||
*out = *in
|
||||
|
|
|
@ -59,34 +59,41 @@ spec:
|
|||
description: ExternalSecretDataRemoteRef defines Provider data
|
||||
location.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the key used in the Provider
|
||||
type: string
|
||||
matchKey:
|
||||
description: Used to select multiple secrets based on a
|
||||
pattern
|
||||
type: string
|
||||
name:
|
||||
description: Used to select multiple secrets based on the
|
||||
name
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
regexp:
|
||||
description: Used to select multiple secrets based on a
|
||||
regular expression of the name
|
||||
type: string
|
||||
tags:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: List of tags used to filter the secrets
|
||||
extract:
|
||||
description: Used to select a specific version and property
|
||||
from the secret
|
||||
properties:
|
||||
key:
|
||||
description: Key is the key used in the Provider
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the
|
||||
Provider value (if a map), if supported
|
||||
type: string
|
||||
version:
|
||||
description: Used to select a specific version of the
|
||||
Provider value, if supported
|
||||
type: string
|
||||
type: object
|
||||
find:
|
||||
description: Used to find secrets based on tags or regular
|
||||
expressions
|
||||
properties:
|
||||
name:
|
||||
description: Key is the key used in the Provider
|
||||
properties:
|
||||
regexp:
|
||||
description: Used to select multiple secrets based
|
||||
on a regular expression of the name
|
||||
type: string
|
||||
type: object
|
||||
tags:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Used to select a specific version of the
|
||||
Provider value, if supported
|
||||
type: object
|
||||
type: object
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
type: object
|
||||
secretKey:
|
||||
type: string
|
||||
|
@ -102,32 +109,40 @@ spec:
|
|||
items:
|
||||
description: ExternalSecretDataRemoteRef defines Provider data location.
|
||||
properties:
|
||||
key:
|
||||
description: Key is the key used in the Provider
|
||||
type: string
|
||||
matchKey:
|
||||
description: Used to select multiple secrets based on a pattern
|
||||
type: string
|
||||
name:
|
||||
description: Used to select multiple secrets based on the name
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
regexp:
|
||||
description: Used to select multiple secrets based on a regular
|
||||
expression of the name
|
||||
type: string
|
||||
tags:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: List of tags used to filter the secrets
|
||||
extract:
|
||||
description: Used to select a specific version and property
|
||||
from the secret
|
||||
properties:
|
||||
key:
|
||||
description: Key is the key used in the Provider
|
||||
type: string
|
||||
property:
|
||||
description: Used to select a specific property of the Provider
|
||||
value (if a map), if supported
|
||||
type: string
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
type: object
|
||||
find:
|
||||
description: Used to find secrets based on tags or regular expressions
|
||||
properties:
|
||||
name:
|
||||
description: Key is the key used in the Provider
|
||||
properties:
|
||||
regexp:
|
||||
description: Used to select multiple secrets based on
|
||||
a regular expression of the name
|
||||
type: string
|
||||
type: object
|
||||
tags:
|
||||
additionalProperties:
|
||||
type: string
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: object
|
||||
type: object
|
||||
version:
|
||||
description: Used to select a specific version of the Provider
|
||||
value, if supported
|
||||
type: string
|
||||
type: object
|
||||
type: array
|
||||
refreshInterval:
|
||||
|
|
|
@ -393,15 +393,15 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient p
|
|||
|
||||
// If tags were added get all secret by tags
|
||||
// Also if a regular expression was entered
|
||||
if len(remoteRef.Tags) > 0 || len(remoteRef.RegExp) > 0 {
|
||||
if len(remoteRef.Find.Tags) > 0 || len(remoteRef.Find.Name.RegExp) > 0 {
|
||||
secretMap, err = providerClient.GetAllSecrets(ctx, remoteRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Key, externalSecret.Name, err)
|
||||
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
|
||||
}
|
||||
} else {
|
||||
secretMap, err = providerClient.GetSecretMap(ctx, remoteRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Key, externalSecret.Name, err)
|
||||
return nil, fmt.Errorf(errGetSecretKey, remoteRef.Extract.Key, externalSecret.Name, err)
|
||||
}
|
||||
}
|
||||
providerData = utils.MergeByteMap(providerData, secretMap)
|
||||
|
@ -410,7 +410,7 @@ func (r *Reconciler) getProviderSecretData(ctx context.Context, providerClient p
|
|||
for _, secretRef := range externalSecret.Spec.Data {
|
||||
secretData, err := providerClient.GetSecret(ctx, secretRef.RemoteRef)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errGetSecretKey, secretRef.RemoteRef.Key, externalSecret.Name, err)
|
||||
return nil, fmt.Errorf(errGetSecretKey, secretRef.RemoteRef.Extract.Key, externalSecret.Name, err)
|
||||
}
|
||||
|
||||
providerData[secretRef.SecretKey] = secretData
|
||||
|
|
|
@ -218,8 +218,10 @@ var _ = Describe("ExternalSecret controller", func() {
|
|||
{
|
||||
SecretKey: targetProp,
|
||||
RemoteRef: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: remoteKey,
|
||||
Property: remoteProperty,
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: remoteKey,
|
||||
Property: remoteProperty,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
|
@ -482,7 +484,9 @@ var _ = Describe("ExternalSecret controller", func() {
|
|||
}
|
||||
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
{
|
||||
Key: "datamap",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "datamap",
|
||||
},
|
||||
},
|
||||
}
|
||||
fakeProvider.WithGetSecret([]byte(secretVal), nil)
|
||||
|
@ -648,7 +652,9 @@ var _ = Describe("ExternalSecret controller", func() {
|
|||
tc.externalSecret.Spec.Data = nil
|
||||
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
{
|
||||
Key: remoteKey,
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: remoteKey,
|
||||
},
|
||||
},
|
||||
}
|
||||
fakeProvider.WithGetSecretMap(map[string][]byte{
|
||||
|
@ -675,7 +681,9 @@ var _ = Describe("ExternalSecret controller", func() {
|
|||
|
||||
tc.externalSecret.Spec.DataFrom = []esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
{
|
||||
Key: remoteKey,
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: remoteKey,
|
||||
},
|
||||
},
|
||||
}
|
||||
fakeProvider.WithGetSecretMap(map[string][]byte{
|
||||
|
|
|
@ -115,13 +115,13 @@ func (a *Akeyless) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretD
|
|||
return nil, err
|
||||
}
|
||||
version := int32(0)
|
||||
if ref.Version != "" {
|
||||
i, err := strconv.ParseInt(ref.Version, 10, 32)
|
||||
if ref.Extract.Version != "" {
|
||||
i, err := strconv.ParseInt(ref.Extract.Version, 10, 32)
|
||||
if err == nil {
|
||||
version = int32(i)
|
||||
}
|
||||
}
|
||||
value, err := a.Client.GetSecretByType(ref.Key, token, version)
|
||||
value, err := a.Client.GetSecretByType(ref.Extract.Key, token, version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
|
|
@ -51,8 +51,10 @@ func makeValidAkeylessTestCase() *akeylessTestCase {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "test-secret",
|
||||
Version: "1",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "test-secret",
|
||||
Version: "1",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -116,26 +116,26 @@ func (kms *KeyManagementService) GetSecret(ctx context.Context, ref esv1alpha1.E
|
|||
return nil, fmt.Errorf(errUninitalizedAlibabaProvider)
|
||||
}
|
||||
kmsRequest := kmssdk.CreateGetSecretValueRequest()
|
||||
kmsRequest.VersionId = ref.Version
|
||||
kmsRequest.SecretName = ref.Key
|
||||
kmsRequest.VersionId = ref.Extract.Version
|
||||
kmsRequest.SecretName = ref.Extract.Key
|
||||
kmsRequest.SetScheme("https")
|
||||
secretOut, err := kms.Client.GetSecretValue(kmsRequest)
|
||||
if err != nil {
|
||||
return nil, util.SanitizeErr(err)
|
||||
}
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
if secretOut.SecretData != "" {
|
||||
return []byte(secretOut.SecretData), nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Key)
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Extract.Key)
|
||||
}
|
||||
var payload string
|
||||
if secretOut.SecretData != "" {
|
||||
payload = secretOut.SecretData
|
||||
}
|
||||
val := gjson.Get(payload, ref.Property)
|
||||
val := gjson.Get(payload, ref.Extract.Property)
|
||||
if !val.Exists() {
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
return []byte(val.String()), nil
|
||||
}
|
||||
|
@ -156,7 +156,7 @@ func (kms *KeyManagementService) GetSecretMap(ctx context.Context, ref esv1alpha
|
|||
kv := make(map[string]string)
|
||||
err = json.Unmarshal(data, &kv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
|
||||
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
|
||||
}
|
||||
secretData := make(map[string][]byte)
|
||||
for k, v := range kv {
|
||||
|
|
|
@ -62,7 +62,9 @@ func makeValidKMSTestCase() *keyManagementServiceTestCase {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: secretName,
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretName,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -127,7 +129,7 @@ func TestAlibabaKMSGetSecret(t *testing.T) {
|
|||
// good case: custom version set
|
||||
setCustomKey := func(kmstc *keyManagementServiceTestCase) {
|
||||
kmstc.apiOutput.SecretName = "test-example-other"
|
||||
kmstc.ref.Key = "test-example-other"
|
||||
kmstc.ref.Extract.Key = "test-example-other"
|
||||
kmstc.apiOutput.SecretData = secretValue
|
||||
kmstc.expectedSecret = secretValue
|
||||
}
|
||||
|
|
|
@ -50,23 +50,23 @@ func New(sess client.ConfigProvider) (*ParameterStore, error) {
|
|||
|
||||
// GetSecret returns a single secret from the provider.
|
||||
func (pm *ParameterStore) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||
log.Info("fetching secret value", "key", ref.Key)
|
||||
log.Info("fetching secret value", "key", ref.Extract.Key)
|
||||
out, err := pm.client.GetParameter(&ssm.GetParameterInput{
|
||||
Name: &ref.Key,
|
||||
Name: &ref.Extract.Key,
|
||||
WithDecryption: aws.Bool(true),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, util.SanitizeErr(err)
|
||||
}
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
if out.Parameter.Value != nil {
|
||||
return []byte(*out.Parameter.Value), nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid secret received. parameter value is nil for key: %s", ref.Key)
|
||||
return nil, fmt.Errorf("invalid secret received. parameter value is nil for key: %s", ref.Extract.Key)
|
||||
}
|
||||
val := gjson.Get(*out.Parameter.Value, ref.Property)
|
||||
val := gjson.Get(*out.Parameter.Value, ref.Extract.Property)
|
||||
if !val.Exists() {
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
return []byte(val.String()), nil
|
||||
}
|
||||
|
@ -80,7 +80,7 @@ func (pm *ParameterStore) GetAllSecrets(ctx context.Context, ref esv1alpha1.Exte
|
|||
|
||||
// GetSecretMap returns multiple k/v pairs from the provider.
|
||||
func (pm *ParameterStore) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||
log.Info("fetching secret map", "key", ref.Key)
|
||||
log.Info("fetching secret map", "key", ref.Extract.Key)
|
||||
data, err := pm.GetSecret(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -88,7 +88,7 @@ func (pm *ParameterStore) GetSecretMap(ctx context.Context, ref esv1alpha1.Exter
|
|||
kv := make(map[string]string)
|
||||
err = json.Unmarshal(data, &kv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
|
||||
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
|
||||
}
|
||||
secretData := make(map[string][]byte)
|
||||
for k, v := range kv {
|
||||
|
|
|
@ -68,7 +68,9 @@ func makeValidAPIOutput() *ssm.GetParameterOutput {
|
|||
|
||||
func makeValidRemoteRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "/baz",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -94,20 +96,20 @@ func TestGetSecret(t *testing.T) {
|
|||
setExtractProperty := func(pstc *parameterstoreTestCase) {
|
||||
pstc.apiOutput.Parameter.Value = aws.String(`{"/shmoo": "bang"}`)
|
||||
pstc.expectedSecret = "bang"
|
||||
pstc.remoteRef.Property = "/shmoo"
|
||||
pstc.remoteRef.Extract.Property = "/shmoo"
|
||||
}
|
||||
|
||||
// bad case: missing property
|
||||
setMissingProperty := func(pstc *parameterstoreTestCase) {
|
||||
pstc.apiOutput.Parameter.Value = aws.String(`{"/shmoo": "bang"}`)
|
||||
pstc.remoteRef.Property = "INVALPROP"
|
||||
pstc.remoteRef.Extract.Property = "INVALPROP"
|
||||
pstc.expectError = "key INVALPROP does not exist in secret"
|
||||
}
|
||||
|
||||
// bad case: extract property failure due to invalid json
|
||||
setPropertyFail := func(pstc *parameterstoreTestCase) {
|
||||
pstc.apiOutput.Parameter.Value = aws.String(`------`)
|
||||
pstc.remoteRef.Property = "INVALPROP"
|
||||
pstc.remoteRef.Extract.Property = "INVALPROP"
|
||||
pstc.expectError = "key INVALPROP does not exist in secret"
|
||||
}
|
||||
|
||||
|
|
|
@ -52,18 +52,18 @@ func New(sess client.ConfigProvider) (*SecretsManager, error) {
|
|||
|
||||
func (sm *SecretsManager) fetch(_ context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (*awssm.GetSecretValueOutput, error) {
|
||||
ver := "AWSCURRENT"
|
||||
if ref.Version != "" {
|
||||
ver = ref.Version
|
||||
if ref.Extract.Version != "" {
|
||||
ver = ref.Extract.Version
|
||||
}
|
||||
log.Info("fetching secret value", "key", ref.Key, "version", ver)
|
||||
log.Info("fetching secret value", "key", ref.Extract.Key, "version", ver)
|
||||
|
||||
cacheKey := fmt.Sprintf("%s#%s", ref.Key, ver)
|
||||
cacheKey := fmt.Sprintf("%s#%s", ref.Extract.Key, ver)
|
||||
if secretOut, found := sm.cache[cacheKey]; found {
|
||||
log.Info("found secret in cache", "key", ref.Key, "version", ver)
|
||||
log.Info("found secret in cache", "key", ref.Extract.Key, "version", ver)
|
||||
return secretOut, nil
|
||||
}
|
||||
secretOut, err := sm.client.GetSecretValue(&awssm.GetSecretValueInput{
|
||||
SecretId: &ref.Key,
|
||||
SecretId: &ref.Extract.Key,
|
||||
VersionStage: &ver,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -80,14 +80,14 @@ func (sm *SecretsManager) GetSecret(ctx context.Context, ref esv1alpha1.External
|
|||
if err != nil {
|
||||
return nil, util.SanitizeErr(err)
|
||||
}
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
if secretOut.SecretString != nil {
|
||||
return []byte(*secretOut.SecretString), nil
|
||||
}
|
||||
if secretOut.SecretBinary != nil {
|
||||
return secretOut.SecretBinary, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Key)
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string nor binary for key: %s", ref.Extract.Key)
|
||||
}
|
||||
var payload string
|
||||
if secretOut.SecretString != nil {
|
||||
|
@ -97,16 +97,16 @@ func (sm *SecretsManager) GetSecret(ctx context.Context, ref esv1alpha1.External
|
|||
payload = string(secretOut.SecretBinary)
|
||||
}
|
||||
|
||||
val := gjson.Get(payload, ref.Property)
|
||||
val := gjson.Get(payload, ref.Extract.Property)
|
||||
if !val.Exists() {
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
return []byte(val.String()), nil
|
||||
}
|
||||
|
||||
// GetSecretMap returns multiple k/v pairs from the provider.
|
||||
func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||
log.Info("fetching secret map", "key", ref.Key)
|
||||
log.Info("fetching secret map", "key", ref.Extract.Key)
|
||||
data, err := sm.GetSecret(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -114,7 +114,7 @@ func (sm *SecretsManager) GetSecretMap(ctx context.Context, ref esv1alpha1.Exter
|
|||
kv := make(map[string]json.RawMessage)
|
||||
err = json.Unmarshal(data, &kv)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Key, err)
|
||||
return nil, fmt.Errorf("unable to unmarshal secret %s: %w", ref.Extract.Key, err)
|
||||
}
|
||||
secretData := make(map[string][]byte)
|
||||
for k, v := range kv {
|
||||
|
|
|
@ -61,8 +61,10 @@ func makeValidSecretsManagerTestCase() *secretsManagerTestCase {
|
|||
|
||||
func makeValidRemoteRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Version: "AWSCURRENT",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "/baz",
|
||||
Version: "AWSCURRENT",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -108,20 +110,20 @@ func TestSecretsManagerGetSecret(t *testing.T) {
|
|||
// good case: extract property
|
||||
// Testing that the property exists in the SecretString
|
||||
setRemoteRefPropertyExistsInKey := func(smtc *secretsManagerTestCase) {
|
||||
smtc.remoteRef.Property = "/shmoo"
|
||||
smtc.remoteRef.Extract.Property = "/shmoo"
|
||||
smtc.apiOutput.SecretString = aws.String(`{"/shmoo": "bang"}`)
|
||||
smtc.expectedSecret = "bang"
|
||||
}
|
||||
|
||||
// bad case: missing property
|
||||
setRemoteRefMissingProperty := func(smtc *secretsManagerTestCase) {
|
||||
smtc.remoteRef.Property = "INVALPROP"
|
||||
smtc.remoteRef.Extract.Property = "INVALPROP"
|
||||
smtc.expectError = "key INVALPROP does not exist in secret"
|
||||
}
|
||||
|
||||
// bad case: extract property failure due to invalid json
|
||||
setRemoteRefMissingPropertyInvalidJSON := func(smtc *secretsManagerTestCase) {
|
||||
smtc.remoteRef.Property = "INVALPROP"
|
||||
smtc.remoteRef.Extract.Property = "INVALPROP"
|
||||
smtc.apiOutput.SecretString = aws.String(`------`)
|
||||
smtc.expectError = "key INVALPROP does not exist in secret"
|
||||
}
|
||||
|
@ -144,14 +146,14 @@ func TestSecretsManagerGetSecret(t *testing.T) {
|
|||
setNestedSecretValueJSONParsing := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretString = nil
|
||||
smtc.apiOutput.SecretBinary = []byte(`{"foobar":{"baz":"nestedval"}}`)
|
||||
smtc.remoteRef.Property = "foobar.baz"
|
||||
smtc.remoteRef.Extract.Property = "foobar.baz"
|
||||
smtc.expectedSecret = "nestedval"
|
||||
}
|
||||
|
||||
// good case: custom version set
|
||||
setCustomVersion := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiInput.VersionStage = aws.String("1234")
|
||||
smtc.remoteRef.Version = "1234"
|
||||
smtc.remoteRef.Extract.Version = "1234"
|
||||
smtc.apiOutput.SecretString = aws.String("FOOBA!")
|
||||
smtc.expectedSecret = "FOOBA!"
|
||||
}
|
||||
|
@ -190,26 +192,26 @@ func TestCaching(t *testing.T) {
|
|||
// over 1
|
||||
firstCall := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretString = aws.String(`{"foo":"bar", "bar":"vodka"}`)
|
||||
smtc.remoteRef.Property = "foo"
|
||||
smtc.remoteRef.Extract.Property = "foo"
|
||||
smtc.expectedSecret = "bar"
|
||||
smtc.expectedCounter = aws.Int(1)
|
||||
smtc.fakeClient = fakeClient
|
||||
}
|
||||
secondCall := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretString = aws.String(`{"foo":"bar", "bar":"vodka"}`)
|
||||
smtc.remoteRef.Property = "bar"
|
||||
smtc.remoteRef.Extract.Property = "bar"
|
||||
smtc.expectedSecret = "vodka"
|
||||
smtc.expectedCounter = aws.Int(1)
|
||||
smtc.fakeClient = fakeClient
|
||||
}
|
||||
notCachedCall := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretString = aws.String(`{"sheldon":"bazinga", "bar":"foo"}`)
|
||||
smtc.remoteRef.Property = "sheldon"
|
||||
smtc.remoteRef.Extract.Property = "sheldon"
|
||||
smtc.expectedSecret = "bazinga"
|
||||
smtc.expectedCounter = aws.Int(2)
|
||||
smtc.fakeClient = fakeClient
|
||||
smtc.apiInput.SecretId = aws.String("xyz")
|
||||
smtc.remoteRef.Key = "xyz" // it should reset the cache since the key is different
|
||||
smtc.remoteRef.Extract.Key = "xyz" // it should reset the cache since the key is different
|
||||
}
|
||||
|
||||
cachedCases := []*secretsManagerTestCase{
|
||||
|
|
|
@ -99,8 +99,8 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
|
|||
return nil, fmt.Errorf("%s name cannot be empty", objectType)
|
||||
}
|
||||
|
||||
if ref.Version != "" {
|
||||
version = ref.Version
|
||||
if ref.Extract.Version != "" {
|
||||
version = ref.Extract.Version
|
||||
}
|
||||
|
||||
switch objectType {
|
||||
|
@ -111,12 +111,12 @@ func (a *Azure) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretData
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
return []byte(*secretResp.Value), nil
|
||||
}
|
||||
res := gjson.Get(*secretResp.Value, ref.Property)
|
||||
res := gjson.Get(*secretResp.Value, ref.Extract.Property)
|
||||
if !res.Exists() {
|
||||
return nil, fmt.Errorf("property %s does not exist in key %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("property %s does not exist in key %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
return []byte(res.String()), err
|
||||
case "cert":
|
||||
|
@ -179,8 +179,8 @@ func (a *Azure) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretD
|
|||
func (a *Azure) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||
basicClient := a.baseClient
|
||||
secretsMap := make(map[string][]byte)
|
||||
checkTags := len(ref.Tags) > 0
|
||||
checkName := len(ref.RegExp) > 0
|
||||
checkTags := len(ref.Find.Tags) > 0
|
||||
checkName := len(ref.Find.Name.RegExp) > 0
|
||||
|
||||
secretListIter, err := basicClient.GetSecretsComplete(context.Background(), a.vaultURL, nil)
|
||||
|
||||
|
@ -219,13 +219,13 @@ func (a *Azure) GetAllSecrets(ctx context.Context, ref esv1alpha1.ExternalSecret
|
|||
}
|
||||
|
||||
func okByName(ref esv1alpha1.ExternalSecretDataRemoteRef, secretName string) bool {
|
||||
matches, _ := regexp.MatchString(ref.RegExp, secretName)
|
||||
matches, _ := regexp.MatchString(ref.Find.Name.RegExp, secretName)
|
||||
return matches
|
||||
}
|
||||
|
||||
func okByTags(ref esv1alpha1.ExternalSecretDataRemoteRef, secret keyvault.SecretItem) bool {
|
||||
tagsFound := true
|
||||
for k, v := range ref.Tags {
|
||||
for k, v := range ref.Find.Tags {
|
||||
if val, ok := secret.Tags[k]; !ok || *val != v {
|
||||
tagsFound = false
|
||||
break
|
||||
|
@ -333,7 +333,7 @@ func (a *Azure) Close(ctx context.Context) error {
|
|||
func getObjType(ref esv1alpha1.ExternalSecretDataRemoteRef) (string, string) {
|
||||
objectType := defaultObjType
|
||||
|
||||
secretName := ref.Key
|
||||
secretName := ref.Extract.Key
|
||||
nameSplitted := strings.Split(secretName, "/")
|
||||
|
||||
if len(nameSplitted) > 1 {
|
||||
|
|
|
@ -30,7 +30,7 @@ import (
|
|||
v1 "github.com/external-secrets/external-secrets/apis/meta/v1"
|
||||
fake "github.com/external-secrets/external-secrets/pkg/provider/azure/keyvault/fake"
|
||||
"github.com/external-secrets/external-secrets/pkg/provider/schema"
|
||||
utils "github.com/external-secrets/external-secrets/pkg/utils"
|
||||
"github.com/external-secrets/external-secrets/pkg/utils"
|
||||
)
|
||||
|
||||
type secretManagerTestCase struct {
|
||||
|
@ -187,7 +187,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
}
|
||||
|
||||
badNoNameSecret := func(smtc *secretManagerTestCase) {
|
||||
smtc.ref.Key = ""
|
||||
smtc.ref.Extract.Key = ""
|
||||
smtc.expectedSecret = ""
|
||||
smtc.secretName = "secret/"
|
||||
smtc.expectError = fmt.Sprintf("%s name cannot be empty", "secret")
|
||||
|
@ -198,8 +198,8 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &secretString,
|
||||
}
|
||||
smtc.ref.Version = "v1"
|
||||
smtc.secretVersion = smtc.ref.Version
|
||||
smtc.ref.Extract.Version = "v1"
|
||||
smtc.secretVersion = smtc.ref.Extract.Version
|
||||
}
|
||||
|
||||
setSecretWithProperty := func(smtc *secretManagerTestCase) {
|
||||
|
@ -208,7 +208,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &jsonString,
|
||||
}
|
||||
smtc.ref.Property = "Name"
|
||||
smtc.ref.Extract.Property = "Name"
|
||||
}
|
||||
|
||||
badSecretWithProperty := func(smtc *secretManagerTestCase) {
|
||||
|
@ -217,8 +217,8 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &jsonString,
|
||||
}
|
||||
smtc.ref.Property = "Age"
|
||||
smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Property, smtc.ref.Key)
|
||||
smtc.ref.Extract.Property = "Age"
|
||||
smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Extract.Property, smtc.ref.Extract.Key)
|
||||
smtc.apiErr = fmt.Errorf(smtc.expectError)
|
||||
}
|
||||
|
||||
|
@ -229,7 +229,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
smtc.keyOutput = keyvault.KeyBundle{
|
||||
Key: newKVJWK([]byte(jwkPubRSA)),
|
||||
}
|
||||
smtc.ref.Key = smtc.secretName
|
||||
smtc.ref.Extract.Key = smtc.secretName
|
||||
}
|
||||
|
||||
// // good case: key set
|
||||
|
@ -239,7 +239,7 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
smtc.keyOutput = keyvault.KeyBundle{
|
||||
Key: newKVJWK([]byte(jwkPubEC)),
|
||||
}
|
||||
smtc.ref.Key = smtc.secretName
|
||||
smtc.ref.Extract.Key = smtc.secretName
|
||||
}
|
||||
|
||||
// // good case: key set
|
||||
|
@ -250,14 +250,14 @@ func TestAzureKeyVaultSecretManagerGetSecret(t *testing.T) {
|
|||
smtc.certOutput = keyvault.CertificateBundle{
|
||||
Cer: &byteArrString,
|
||||
}
|
||||
smtc.ref.Key = smtc.secretName
|
||||
smtc.ref.Extract.Key = smtc.secretName
|
||||
}
|
||||
|
||||
badSecretType := func(smtc *secretManagerTestCase) {
|
||||
smtc.secretName = "name"
|
||||
smtc.expectedSecret = ""
|
||||
smtc.expectError = fmt.Sprintf("unknown Azure Keyvault object Type for %s", smtc.secretName)
|
||||
smtc.ref.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
|
||||
smtc.ref.Extract.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
|
||||
}
|
||||
|
||||
successCases := []*secretManagerTestCase{
|
||||
|
@ -312,7 +312,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &jsonString,
|
||||
}
|
||||
smtc.ref.Property = "Address"
|
||||
smtc.ref.Extract.Property = "Address"
|
||||
|
||||
smtc.expectedData["Street"] = []byte("Myroad st.")
|
||||
smtc.expectedData["CP"] = []byte("J4K4T4")
|
||||
|
@ -324,8 +324,8 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &jsonString,
|
||||
}
|
||||
smtc.ref.Property = "Age"
|
||||
smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Property, smtc.ref.Key)
|
||||
smtc.ref.Extract.Property = "Age"
|
||||
smtc.expectError = fmt.Sprintf("property %s does not exist in key %s", smtc.ref.Extract.Property, smtc.ref.Extract.Key)
|
||||
smtc.apiErr = fmt.Errorf(smtc.expectError)
|
||||
}
|
||||
|
||||
|
@ -335,7 +335,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
|
|||
smtc.keyOutput = keyvault.KeyBundle{
|
||||
Key: newKVJWK([]byte(jwkPubRSA)),
|
||||
}
|
||||
smtc.ref.Key = smtc.secretName
|
||||
smtc.ref.Extract.Key = smtc.secretName
|
||||
smtc.expectError = "cannot get use dataFrom to get key secret"
|
||||
}
|
||||
|
||||
|
@ -346,7 +346,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
|
|||
smtc.certOutput = keyvault.CertificateBundle{
|
||||
Cer: &byteArrString,
|
||||
}
|
||||
smtc.ref.Key = smtc.secretName
|
||||
smtc.ref.Extract.Key = smtc.secretName
|
||||
smtc.expectError = "cannot get use dataFrom to get certificate secret"
|
||||
}
|
||||
|
||||
|
@ -354,7 +354,7 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
|
|||
smtc.secretName = "name"
|
||||
smtc.expectedSecret = ""
|
||||
smtc.expectError = fmt.Sprintf("unknown Azure Keyvault object Type for %s", smtc.secretName)
|
||||
smtc.ref.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
|
||||
smtc.ref.Extract.Key = fmt.Sprintf("dummy/%s", smtc.secretName)
|
||||
}
|
||||
|
||||
successCases := []*secretManagerTestCase{
|
||||
|
@ -382,6 +382,12 @@ func TestAzureKeyVaultSecretManagerGetSecretMap(t *testing.T) {
|
|||
|
||||
func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
||||
secretString := "changedvalue"
|
||||
secretName := "example-1"
|
||||
wrongName := "not-valid"
|
||||
environment := "dev"
|
||||
author := "seb"
|
||||
regexp := "^example"
|
||||
enabled := true
|
||||
|
||||
getNextPage := func(ctx context.Context, list keyvault.SecretListResult) (result keyvault.SecretListResult, err error) {
|
||||
return keyvault.SecretListResult{
|
||||
|
@ -391,10 +397,7 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
|||
}
|
||||
|
||||
setOneSecretByName := func(smtc *secretManagerTestCase) {
|
||||
|
||||
smtc.ref.RegExp = "^example"
|
||||
secretName := "example-1"
|
||||
enabled := true
|
||||
smtc.ref.Find.Name.RegExp = regexp
|
||||
enabledAtt := keyvault.SecretAttributes{
|
||||
Enabled: &enabled,
|
||||
}
|
||||
|
@ -422,11 +425,7 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
|||
}
|
||||
|
||||
setTwoSecretsByName := func(smtc *secretManagerTestCase) {
|
||||
|
||||
smtc.ref.RegExp = "^example"
|
||||
secretName := "example-1"
|
||||
wrongName := "not-valid"
|
||||
enabled := true
|
||||
smtc.ref.Find.Name.RegExp = regexp
|
||||
enabledAtt := keyvault.SecretAttributes{
|
||||
Enabled: &enabled,
|
||||
}
|
||||
|
@ -460,11 +459,6 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
|||
}
|
||||
|
||||
setOneSecretByTag := func(smtc *secretManagerTestCase) {
|
||||
|
||||
secretName := "example-1"
|
||||
environment := "dev"
|
||||
|
||||
enabled := true
|
||||
enabledAtt := keyvault.SecretAttributes{
|
||||
Enabled: &enabled,
|
||||
}
|
||||
|
@ -488,16 +482,12 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &secretString,
|
||||
}
|
||||
smtc.ref.Tags = map[string]string{"environment": environment}
|
||||
smtc.ref.Find.Tags = map[string]string{"environment": environment}
|
||||
|
||||
smtc.expectedData["example-1"] = []byte(secretString)
|
||||
smtc.expectedData[secretName] = []byte(secretString)
|
||||
}
|
||||
|
||||
setTwoSecretsByTag := func(smtc *secretManagerTestCase) {
|
||||
|
||||
secretName := "example-1"
|
||||
environment := "dev"
|
||||
author := "seb"
|
||||
enabled := true
|
||||
enabledAtt := keyvault.SecretAttributes{
|
||||
Enabled: &enabled,
|
||||
|
@ -522,9 +512,9 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
|||
smtc.secretOutput = keyvault.SecretBundle{
|
||||
Value: &secretString,
|
||||
}
|
||||
smtc.ref.Tags = map[string]string{"environment": environment, "author": author}
|
||||
smtc.ref.Find.Tags = map[string]string{"environment": environment, "author": author}
|
||||
|
||||
smtc.expectedData["example-1"] = []byte(secretString)
|
||||
smtc.expectedData[secretName] = []byte(secretString)
|
||||
}
|
||||
|
||||
successCases := []*secretManagerTestCase{
|
||||
|
@ -549,7 +539,9 @@ func TestAzureKeyVaultSecretManagerGetAllSecrets(t *testing.T) {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
@ -167,24 +167,24 @@ func (sm *ProviderGCP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSec
|
|||
return nil, fmt.Errorf(errUninitalizedGCPProvider)
|
||||
}
|
||||
|
||||
version := ref.Version
|
||||
version := ref.Extract.Version
|
||||
if version == "" {
|
||||
version = defaultVersion
|
||||
}
|
||||
|
||||
req := &secretmanagerpb.AccessSecretVersionRequest{
|
||||
Name: fmt.Sprintf("projects/%s/secrets/%s/versions/%s", sm.projectID, ref.Key, version),
|
||||
Name: fmt.Sprintf("projects/%s/secrets/%s/versions/%s", sm.projectID, ref.Extract.Key, version),
|
||||
}
|
||||
result, err := sm.SecretManagerClient.AccessSecretVersion(ctx, req)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf(errClientGetSecretAccess, err)
|
||||
}
|
||||
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
if result.Payload.Data != nil {
|
||||
return result.Payload.Data, nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Key)
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Extract.Key)
|
||||
}
|
||||
|
||||
var payload string
|
||||
|
@ -192,9 +192,9 @@ func (sm *ProviderGCP) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSec
|
|||
payload = string(result.Payload.Data)
|
||||
}
|
||||
|
||||
val := gjson.Get(payload, ref.Property)
|
||||
val := gjson.Get(payload, ref.Extract.Property)
|
||||
if !val.Exists() {
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
return []byte(val.String()), nil
|
||||
}
|
||||
|
|
|
@ -58,8 +58,10 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Version: "default",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "/baz",
|
||||
Version: "default",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -111,9 +113,11 @@ func TestSecretManagerGetSecret(t *testing.T) {
|
|||
// good case: ref with
|
||||
setCustomRef := func(smtc *secretManagerTestCase) {
|
||||
smtc.ref = &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Version: "default",
|
||||
Property: "name.first",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "/baz",
|
||||
Version: "default",
|
||||
Property: "name.first",
|
||||
},
|
||||
}
|
||||
smtc.apiInput.Name = "projects/default/secrets//baz/versions/default"
|
||||
smtc.apiOutput.Payload.Data = []byte(
|
||||
|
@ -130,7 +134,7 @@ func TestSecretManagerGetSecret(t *testing.T) {
|
|||
|
||||
// good case: custom version set
|
||||
setCustomVersion := func(smtc *secretManagerTestCase) {
|
||||
smtc.ref.Version = "1234"
|
||||
smtc.ref.Extract.Version = "1234"
|
||||
smtc.apiInput.Name = "projects/default/secrets//baz/versions/1234"
|
||||
smtc.apiOutput.Payload.Data = []byte("FOOBA!")
|
||||
smtc.expectedSecret = "FOOBA!"
|
||||
|
|
|
@ -153,7 +153,7 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
|
|||
return nil, fmt.Errorf(errUninitalizedGitlabProvider)
|
||||
}
|
||||
// Need to replace hyphens with underscores to work with Gitlab API
|
||||
ref.Key = strings.ReplaceAll(ref.Key, "-", "_")
|
||||
ref.Extract.Key = strings.ReplaceAll(ref.Extract.Key, "-", "_")
|
||||
// Retrieves a gitlab variable in the form
|
||||
// {
|
||||
// "key": "TEST_VARIABLE_1",
|
||||
|
@ -161,16 +161,16 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
|
|||
// "value": "TEST_1",
|
||||
// "protected": false,
|
||||
// "masked": true
|
||||
data, _, err := g.client.GetVariable(g.projectID, ref.Key, nil) // Optional 'filter' parameter could be added later
|
||||
data, _, err := g.client.GetVariable(g.projectID, ref.Extract.Key, nil) // Optional 'filter' parameter could be added later
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
if data.Value != "" {
|
||||
return []byte(data.Value), nil
|
||||
}
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Key)
|
||||
return nil, fmt.Errorf("invalid secret received. no secret string for key: %s", ref.Extract.Key)
|
||||
}
|
||||
|
||||
var payload string
|
||||
|
@ -178,9 +178,9 @@ func (g *Gitlab) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDat
|
|||
payload = data.Value
|
||||
}
|
||||
|
||||
val := gjson.Get(payload, ref.Property)
|
||||
val := gjson.Get(payload, ref.Extract.Property)
|
||||
if !val.Exists() {
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
return []byte(val.String()), nil
|
||||
}
|
||||
|
@ -196,7 +196,7 @@ func (g *Gitlab) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecret
|
|||
// Gets a secret as normal, expecting secret value to be a json object
|
||||
data, err := g.GetSecret(ctx, ref)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting secret %s: %w", ref.Key, err)
|
||||
return nil, fmt.Errorf("error getting secret %s: %w", ref.Extract.Key, err)
|
||||
}
|
||||
|
||||
// Maps the json data to a string:string map
|
||||
|
|
|
@ -59,8 +59,10 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -106,7 +106,7 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
|
|||
}
|
||||
|
||||
secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
|
||||
secretName := ref.Key
|
||||
secretName := ref.Extract.Key
|
||||
nameSplitted := strings.Split(secretName, "/")
|
||||
|
||||
if len(nameSplitted) > 1 {
|
||||
|
@ -121,7 +121,7 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
|
|||
|
||||
case sm.CreateSecretOptionsSecretTypeUsernamePasswordConst:
|
||||
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
return nil, fmt.Errorf("remoteRef.property required for secret type username_password")
|
||||
}
|
||||
return getUsernamePasswordSecret(ibm, &secretName, ref)
|
||||
|
@ -132,8 +132,8 @@ func (ibm *providerIBM) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSe
|
|||
|
||||
case sm.CreateSecretOptionsSecretTypeImportedCertConst:
|
||||
|
||||
if ref.Property == "" {
|
||||
return nil, fmt.Errorf("remoteRef.property required for secret type imported_cert")
|
||||
if ref.Extract.Property == "" {
|
||||
return nil, fmt.Errorf("remoteRef.Extract.property required for secret type imported_cert")
|
||||
}
|
||||
|
||||
return getImportCertSecret(ibm, &secretName, ref)
|
||||
|
@ -171,10 +171,10 @@ func getImportCertSecret(ibm *providerIBM, secretName *string, ref esv1alpha1.Ex
|
|||
secret := response.Resources[0].(*sm.SecretResource)
|
||||
secretData := secret.SecretData.(map[string]interface{})
|
||||
|
||||
if val, ok := secretData[ref.Property]; ok {
|
||||
if val, ok := secretData[ref.Extract.Property]; ok {
|
||||
return []byte(val.(string)), nil
|
||||
}
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
|
||||
func getIamCredentialsSecret(ibm *providerIBM, secretName *string) ([]byte, error) {
|
||||
|
@ -206,10 +206,10 @@ func getUsernamePasswordSecret(ibm *providerIBM, secretName *string, ref esv1alp
|
|||
secret := response.Resources[0].(*sm.SecretResource)
|
||||
secretData := secret.SecretData.(map[string]interface{})
|
||||
|
||||
if val, ok := secretData[ref.Property]; ok {
|
||||
if val, ok := secretData[ref.Extract.Property]; ok {
|
||||
return []byte(val.(string)), nil
|
||||
}
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Property, ref.Key)
|
||||
return nil, fmt.Errorf("key %s does not exist in secret %s", ref.Extract.Property, ref.Extract.Key)
|
||||
}
|
||||
|
||||
func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||
|
@ -218,7 +218,7 @@ func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.Externa
|
|||
}
|
||||
|
||||
secretType := sm.GetSecretOptionsSecretTypeArbitraryConst
|
||||
secretName := ref.Key
|
||||
secretName := ref.Extract.Key
|
||||
nameSplitted := strings.Split(secretName, "/")
|
||||
|
||||
if len(nameSplitted) > 1 {
|
||||
|
@ -231,7 +231,7 @@ func (ibm *providerIBM) GetSecretMap(ctx context.Context, ref esv1alpha1.Externa
|
|||
response, _, err := ibm.IBMClient.GetSecret(
|
||||
&sm.GetSecretOptions{
|
||||
SecretType: core.StringPtr(sm.GetSecretOptionsSecretTypeArbitraryConst),
|
||||
ID: &ref.Key,
|
||||
ID: &ref.Extract.Key,
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
|
@ -63,8 +63,10 @@ func makeValidSecretManagerTestCase() *secretManagerTestCase {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -146,7 +148,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
|||
Name: utilpointer.StringPtr("testyname"),
|
||||
SecretData: secretData,
|
||||
}}
|
||||
smtc.ref.Key = "testyname"
|
||||
smtc.ref.Extract.Key = "testyname"
|
||||
smtc.apiInput.ID = utilpointer.StringPtr("testyname")
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.expectedSecret = secretString
|
||||
|
@ -164,7 +166,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = secretUserPass
|
||||
smtc.ref.Extract.Key = secretUserPass
|
||||
smtc.expectError = "remoteRef.property required for secret type username_password"
|
||||
}
|
||||
|
||||
|
@ -179,8 +181,8 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = secretUserPass
|
||||
smtc.ref.Property = "password"
|
||||
smtc.ref.Extract.Key = secretUserPass
|
||||
smtc.ref.Extract.Property = "password"
|
||||
smtc.expectedSecret = secretPassword
|
||||
}
|
||||
|
||||
|
@ -195,7 +197,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = "iam_credentials/test-secret"
|
||||
smtc.ref.Extract.Key = "iam_credentials/test-secret"
|
||||
smtc.expectedSecret = secretAPIKey
|
||||
}
|
||||
|
||||
|
@ -211,8 +213,8 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = secretCert
|
||||
smtc.ref.Property = "certificate"
|
||||
smtc.ref.Extract.Key = secretCert
|
||||
smtc.ref.Extract.Property = "certificate"
|
||||
smtc.expectedSecret = secretCertificate
|
||||
}
|
||||
|
||||
|
@ -227,8 +229,8 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
|||
|
||||
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"
|
||||
smtc.ref.Extract.Key = secretCert
|
||||
smtc.expectError = "remoteRef.Extract.property required for secret type imported_cert"
|
||||
}
|
||||
|
||||
successCases := []*secretManagerTestCase{
|
||||
|
@ -311,7 +313,7 @@ func TestGetSecretMap(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeUsernamePasswordConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = "username_password/test-secret"
|
||||
smtc.ref.Extract.Key = "username_password/test-secret"
|
||||
smtc.expectedData["username"] = []byte(secretUsername)
|
||||
smtc.expectedData["password"] = []byte(secretPassword)
|
||||
}
|
||||
|
@ -327,7 +329,7 @@ func TestGetSecretMap(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeIamCredentialsConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = "iam_credentials/test-secret"
|
||||
smtc.ref.Extract.Key = "iam_credentials/test-secret"
|
||||
smtc.expectedData["apikey"] = []byte(secretAPIKey)
|
||||
}
|
||||
|
||||
|
@ -347,7 +349,7 @@ func TestGetSecretMap(t *testing.T) {
|
|||
|
||||
smtc.apiInput.SecretType = core.StringPtr(sm.CreateSecretOptionsSecretTypeImportedCertConst)
|
||||
smtc.apiOutput.Resources = resources
|
||||
smtc.ref.Key = "imported_cert/test-secret"
|
||||
smtc.ref.Extract.Key = "imported_cert/test-secret"
|
||||
smtc.expectedData["certificate"] = []byte(secretCertificate)
|
||||
smtc.expectedData["private_key"] = []byte(secretPrivateKey)
|
||||
smtc.expectedData["intermediate"] = []byte(secretIntermediate)
|
||||
|
|
|
@ -132,8 +132,8 @@ func (vms *VaultManagementService) GetSecret(ctx context.Context, ref esv1alpha1
|
|||
|
||||
sec, err := vms.Client.GetSecretBundleByName(ctx, secrets.GetSecretBundleByNameRequest{
|
||||
VaultId: &vms.vault,
|
||||
SecretName: &ref.Key,
|
||||
Stage: secrets.GetSecretBundleByNameStageEnum(ref.Version),
|
||||
SecretName: &ref.Extract.Key,
|
||||
Stage: secrets.GetSecretBundleByNameStageEnum(ref.Extract.Version),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, util.SanitizeErr(err)
|
||||
|
@ -149,14 +149,14 @@ func (vms *VaultManagementService) GetSecret(ctx context.Context, ref esv1alpha1
|
|||
return nil, err
|
||||
}
|
||||
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
return payload, nil
|
||||
}
|
||||
|
||||
val := gjson.Get(string(payload), ref.Property)
|
||||
val := gjson.Get(string(payload), ref.Extract.Property)
|
||||
|
||||
if !val.Exists() {
|
||||
return nil, fmt.Errorf(errMissingKey, ref.Key)
|
||||
return nil, fmt.Errorf(errMissingKey, ref.Extract.Key)
|
||||
}
|
||||
|
||||
return []byte(val.String()), nil
|
||||
|
|
|
@ -55,8 +55,10 @@ func makeValidVaultTestCase() *vaultTestCase {
|
|||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "test-secret",
|
||||
Version: "default",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -148,19 +148,19 @@ func (c *connector) NewClient(ctx context.Context, store esv1alpha1.GenericStore
|
|||
}
|
||||
|
||||
func (v *client) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||
data, err := v.readSecret(ctx, ref.Key, ref.Version)
|
||||
data, err := v.readSecret(ctx, ref.Extract.Key, ref.Extract.Version)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
value, exists := data[ref.Property]
|
||||
value, exists := data[ref.Extract.Property]
|
||||
if !exists {
|
||||
return nil, fmt.Errorf(errSecretKeyFmt, ref.Property)
|
||||
return nil, fmt.Errorf(errSecretKeyFmt, ref.Extract.Property)
|
||||
}
|
||||
return value, nil
|
||||
}
|
||||
|
||||
func (v *client) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||
return v.readSecret(ctx, ref.Key, ref.Version)
|
||||
return v.readSecret(ctx, ref.Extract.Key, ref.Extract.Version)
|
||||
}
|
||||
|
||||
// Implements store.Client.GetAllSecrets Interface.
|
||||
|
|
|
@ -181,9 +181,9 @@ func (w *WebHook) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecre
|
|||
func (w *WebHook) getTemplateData(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef, secrets []esv1alpha1.WebhookSecret) (map[string]map[string]string, error) {
|
||||
data := map[string]map[string]string{
|
||||
"remoteRef": {
|
||||
"key": url.QueryEscape(ref.Key),
|
||||
"version": url.QueryEscape(ref.Version),
|
||||
"property": url.QueryEscape(ref.Property),
|
||||
"key": url.QueryEscape(ref.Extract.Key),
|
||||
"version": url.QueryEscape(ref.Extract.Version),
|
||||
"property": url.QueryEscape(ref.Extract.Property),
|
||||
},
|
||||
}
|
||||
for _, secref := range secrets {
|
||||
|
|
|
@ -270,8 +270,10 @@ func runTestCase(tc testCase, t *testing.T) {
|
|||
|
||||
func testGetSecretMap(tc testCase, t *testing.T, client provider.SecretsClient) {
|
||||
testRef := esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: tc.Args.Key,
|
||||
Version: tc.Args.Version,
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: tc.Args.Key,
|
||||
Version: tc.Args.Version,
|
||||
},
|
||||
}
|
||||
secretmap, err := client.GetSecretMap(context.Background(), testRef)
|
||||
errStr := ""
|
||||
|
@ -295,8 +297,10 @@ func testGetSecretMap(tc testCase, t *testing.T, client provider.SecretsClient)
|
|||
|
||||
func testGetSecret(tc testCase, t *testing.T, client provider.SecretsClient) {
|
||||
testRef := esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: tc.Args.Key,
|
||||
Version: tc.Args.Version,
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: tc.Args.Key,
|
||||
Version: tc.Args.Version,
|
||||
},
|
||||
}
|
||||
secret, err := client.GetSecret(context.Background(), testRef)
|
||||
errStr := ""
|
||||
|
|
|
@ -226,12 +226,12 @@ type lockboxSecretsClient struct {
|
|||
|
||||
// GetSecret returns a single secret from the provider.
|
||||
func (c *lockboxSecretsClient) GetSecret(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) ([]byte, error) {
|
||||
entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Key, ref.Version)
|
||||
entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Extract.Key, ref.Extract.Version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to request secret payload to get secret: %w", err)
|
||||
}
|
||||
|
||||
if ref.Property == "" {
|
||||
if ref.Extract.Property == "" {
|
||||
keyToValue := make(map[string]interface{}, len(entries))
|
||||
for _, entry := range entries {
|
||||
value, err := getValueAsIs(entry)
|
||||
|
@ -247,7 +247,7 @@ func (c *lockboxSecretsClient) GetSecret(ctx context.Context, ref esv1alpha1.Ext
|
|||
return out, nil
|
||||
}
|
||||
|
||||
entry, err := findEntryByKey(entries, ref.Property)
|
||||
entry, err := findEntryByKey(entries, ref.Extract.Property)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -263,7 +263,7 @@ func (c *lockboxSecretsClient) GetAllSecrets(ctx context.Context, ref esv1alpha1
|
|||
|
||||
// GetSecretMap returns multiple k/v pairs from the provider.
|
||||
func (c *lockboxSecretsClient) GetSecretMap(ctx context.Context, ref esv1alpha1.ExternalSecretDataRemoteRef) (map[string][]byte, error) {
|
||||
entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Key, ref.Version)
|
||||
entries, err := c.lockboxClient.GetPayloadEntries(ctx, c.iamToken, ref.Extract.Key, ref.Extract.Version)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("unable to request secret payload to get secret map: %w", err)
|
||||
}
|
||||
|
|
|
@ -131,7 +131,11 @@ func TestGetSecretForAllEntries(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.Equal(
|
||||
|
@ -169,7 +173,12 @@ func TestGetSecretForTextEntry(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.Equal(t, v1, string(data))
|
||||
|
@ -200,7 +209,12 @@ func TestGetSecretForBinaryEntry(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k2})
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Property: k2,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.Equal(t, v2, data)
|
||||
|
@ -229,7 +243,12 @@ func TestGetSecretByVersionID(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
|
||||
data, err := secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: oldVersionID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.Equal(t, map[string]string{oldKey: oldVal}, unmarshalStringMap(t, data))
|
||||
|
@ -239,11 +258,21 @@ func TestGetSecretByVersionID(t *testing.T) {
|
|||
textEntry(newKey, newVal),
|
||||
)
|
||||
|
||||
data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
|
||||
data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: oldVersionID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
tassert.Equal(t, map[string]string{oldKey: oldVal}, unmarshalStringMap(t, data))
|
||||
|
||||
data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: newVersionID})
|
||||
data, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: newVersionID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
tassert.Equal(t, map[string]string{newKey: newVal}, unmarshalStringMap(t, data))
|
||||
}
|
||||
|
@ -271,7 +300,11 @@ func TestGetSecretUnauthorized(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
},
|
||||
})
|
||||
tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
|
||||
}
|
||||
|
||||
|
@ -294,13 +327,22 @@ func TestGetSecretNotFound(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: "no-secret-with-this-id"})
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: "no-secret-with-this-id",
|
||||
},
|
||||
})
|
||||
tassert.EqualError(t, err, errSecretPayloadNotFound)
|
||||
|
||||
secretID, _ := lockboxBackend.CreateSecret(authorizedKey,
|
||||
textEntry("k1", "v1"),
|
||||
)
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: "no-version-with-this-id"})
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: "no-version-with-this-id",
|
||||
},
|
||||
})
|
||||
tassert.EqualError(t, err, "unable to request secret payload to get secret: version not found")
|
||||
}
|
||||
|
||||
|
@ -339,17 +381,37 @@ func TestGetSecretWithTwoNamespaces(t *testing.T) {
|
|||
secretsClient2, err := provider.NewClient(ctx, store2, k8sClient, namespace2)
|
||||
tassert.Nil(t, err)
|
||||
|
||||
data, err := secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
|
||||
data, err := secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID1,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Equal(t, v1, string(data))
|
||||
tassert.Nil(t, err)
|
||||
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
|
||||
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID2,
|
||||
Property: k2,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, data)
|
||||
tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
|
||||
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID1,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, data)
|
||||
tassert.EqualError(t, err, errSecretPayloadPermissionDenied)
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID2,
|
||||
Property: k2,
|
||||
},
|
||||
})
|
||||
tassert.Equal(t, v2, string(data))
|
||||
tassert.Nil(t, err)
|
||||
}
|
||||
|
@ -400,17 +462,37 @@ func TestGetSecretWithTwoApiEndpoints(t *testing.T) {
|
|||
|
||||
var data []byte
|
||||
|
||||
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
|
||||
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID1,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Equal(t, v1, string(data))
|
||||
tassert.Nil(t, err)
|
||||
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
|
||||
data, err = secretsClient1.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID2,
|
||||
Property: k2,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, data)
|
||||
tassert.EqualError(t, err, errSecretPayloadNotFound)
|
||||
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1, Property: k1})
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID1,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, data)
|
||||
tassert.EqualError(t, err, errSecretPayloadNotFound)
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2, Property: k2})
|
||||
data, err = secretsClient2.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID1,
|
||||
Property: k2,
|
||||
},
|
||||
})
|
||||
tassert.Equal(t, v2, string(data))
|
||||
tassert.Nil(t, err)
|
||||
}
|
||||
|
@ -442,19 +524,34 @@ func TestGetSecretWithIamTokenExpiration(t *testing.T) {
|
|||
|
||||
oldSecretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
|
||||
data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Equal(t, v1, string(data))
|
||||
tassert.Nil(t, err)
|
||||
|
||||
lockboxBackend.AdvanceClock(2 * tokenExpirationTime)
|
||||
|
||||
data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
|
||||
data, err = oldSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, data)
|
||||
tassert.EqualError(t, err, "unable to request secret payload to get secret: iam token expired")
|
||||
|
||||
newSecretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err = newSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Property: k1})
|
||||
data, err = newSecretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Property: k1,
|
||||
},
|
||||
})
|
||||
tassert.Equal(t, v1, string(data))
|
||||
tassert.Nil(t, err)
|
||||
}
|
||||
|
@ -499,7 +596,11 @@ func TestGetSecretWithIamTokenCleanup(t *testing.T) {
|
|||
// Access secretID1 with authorizedKey1, IAM token for authorizedKey1 should be cached
|
||||
secretsClient, err := provider.NewClient(ctx, store1, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID1})
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID1,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.True(t, provider.isIamTokenCached(authorizedKey1))
|
||||
|
@ -510,7 +611,11 @@ func TestGetSecretWithIamTokenCleanup(t *testing.T) {
|
|||
// Access secretID2 with authorizedKey2, IAM token for authorizedKey2 should be cached
|
||||
secretsClient, err = provider.NewClient(ctx, store2, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID2})
|
||||
_, err = secretsClient.GetSecret(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID2,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.True(t, provider.isIamTokenCached(authorizedKey1))
|
||||
|
@ -562,7 +667,11 @@ func TestGetSecretMap(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID})
|
||||
data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.Equal(
|
||||
|
@ -598,7 +707,12 @@ func TestGetSecretMapByVersionID(t *testing.T) {
|
|||
})
|
||||
secretsClient, err := provider.NewClient(ctx, store, k8sClient, namespace)
|
||||
tassert.Nil(t, err)
|
||||
data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
|
||||
data, err := secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: oldVersionID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
|
||||
tassert.Equal(t, map[string][]byte{oldKey: []byte(oldVal)}, data)
|
||||
|
@ -608,11 +722,21 @@ func TestGetSecretMapByVersionID(t *testing.T) {
|
|||
textEntry(newKey, newVal),
|
||||
)
|
||||
|
||||
data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: oldVersionID})
|
||||
data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: oldVersionID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
tassert.Equal(t, map[string][]byte{oldKey: []byte(oldVal)}, data)
|
||||
|
||||
data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{Key: secretID, Version: newVersionID})
|
||||
data, err = secretsClient.GetSecretMap(ctx, esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Extract: esv1alpha1.ExternalSecretExtract{
|
||||
Key: secretID,
|
||||
Version: newVersionID,
|
||||
},
|
||||
})
|
||||
tassert.Nil(t, err)
|
||||
tassert.Equal(t, map[string][]byte{newKey: []byte(newVal)}, data)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue