mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
handle special case for imported cert secret type (#2629)
Signed-off-by: shanti.gundumalla@ibm.com <shanti.gundumalla@ibm.com> Co-authored-by: shanti.gundumalla@ibm.com <shanti.gundumalla@ibm.com>
This commit is contained in:
parent
e5fd5a90a9
commit
bccb12c8ff
3 changed files with 74 additions and 20 deletions
|
@ -197,7 +197,7 @@ Below example creates a kubernetes secret based on ID of the secret in Secrets M
|
||||||
{% include 'ibm-external-secret.yaml' %}
|
{% include 'ibm-external-secret.yaml' %}
|
||||||
```
|
```
|
||||||
|
|
||||||
Alternatively, secret name can be specified instead of secret ID.
|
Alternatively, secret name can be specified instead of secret ID. However, note that ESO makes an additional call to fetch the relevant secret ID for the specified secret name.
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
{% include 'ibm-external-secret-by-name.yaml' %}
|
{% include 'ibm-external-secret-by-name.yaml' %}
|
||||||
|
|
|
@ -227,8 +227,14 @@ func getImportCertSecret(ibm *providerIBM, secretName *string, ref esv1beta1.Ext
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if val, ok := secMap[ref.Property]; ok {
|
val, ok := secMap[ref.Property]
|
||||||
|
if ok {
|
||||||
return []byte(val.(string)), nil
|
return []byte(val.(string)), nil
|
||||||
|
} else if ref.Property == privateKeyConst {
|
||||||
|
// we want to return an empty string in case the secret doesn't contain a private key
|
||||||
|
// this is to ensure that secret of type 'kubernetes.io/tls' gets created as expected, even with an empty private key
|
||||||
|
fmt.Printf("warn: %s is empty for secret %s\n", privateKeyConst, *secretName)
|
||||||
|
return []byte(""), 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.Property, ref.Key)
|
||||||
}
|
}
|
||||||
|
@ -418,6 +424,7 @@ func (ibm *providerIBM) GetSecretMap(_ context.Context, ref esv1beta1.ExternalSe
|
||||||
}
|
}
|
||||||
|
|
||||||
secretMap := make(map[string][]byte)
|
secretMap := make(map[string][]byte)
|
||||||
|
secMapBytes := make(map[string][]byte)
|
||||||
response, err := getSecretData(ibm, &secretName, secretType)
|
response, err := getSecretData(ibm, &secretName, secretType)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -430,36 +437,42 @@ func (ibm *providerIBM) GetSecretMap(_ context.Context, ref esv1beta1.ExternalSe
|
||||||
if ref.MetadataPolicy == esv1beta1.ExternalSecretMetadataPolicyFetch {
|
if ref.MetadataPolicy == esv1beta1.ExternalSecretMetadataPolicyFetch {
|
||||||
secretMap = populateSecretMap(secretMap, secMap)
|
secretMap = populateSecretMap(secretMap, secMap)
|
||||||
}
|
}
|
||||||
|
secMapBytes = populateSecretMap(secMapBytes, secMap)
|
||||||
|
|
||||||
switch secretType {
|
switch secretType {
|
||||||
case sm.Secret_SecretType_Arbitrary:
|
case sm.Secret_SecretType_Arbitrary:
|
||||||
secretMap[arbitraryConst] = []byte(fmt.Sprintf("%v", secMap[payloadConst]))
|
secretMap[arbitraryConst] = secMapBytes[payloadConst]
|
||||||
return secretMap, nil
|
return secretMap, nil
|
||||||
|
|
||||||
case sm.Secret_SecretType_UsernamePassword:
|
case sm.Secret_SecretType_UsernamePassword:
|
||||||
secretMap[usernameConst] = []byte(fmt.Sprintf("%v", secMap[usernameConst]))
|
secretMap[usernameConst] = secMapBytes[usernameConst]
|
||||||
secretMap[passwordConst] = []byte(fmt.Sprintf("%v", secMap[passwordConst]))
|
secretMap[passwordConst] = secMapBytes[passwordConst]
|
||||||
return secretMap, nil
|
return secretMap, nil
|
||||||
|
|
||||||
case sm.Secret_SecretType_IamCredentials:
|
case sm.Secret_SecretType_IamCredentials:
|
||||||
secretMap[apikeyConst] = []byte(fmt.Sprintf("%v", secMap[smAPIKeyConst]))
|
secretMap[apikeyConst] = secMapBytes[smAPIKeyConst]
|
||||||
return secretMap, nil
|
return secretMap, nil
|
||||||
|
|
||||||
case sm.Secret_SecretType_ImportedCert:
|
case sm.Secret_SecretType_ImportedCert:
|
||||||
secretMap[certificateConst] = []byte(fmt.Sprintf("%v", secMap[certificateConst]))
|
secretMap[certificateConst] = secMapBytes[certificateConst]
|
||||||
secretMap[intermediateConst] = []byte(fmt.Sprintf("%v", secMap[intermediateConst]))
|
secretMap[intermediateConst] = secMapBytes[intermediateConst]
|
||||||
secretMap[privateKeyConst] = []byte(fmt.Sprintf("%v", secMap[privateKeyConst]))
|
if v, ok := secMapBytes[privateKeyConst]; ok {
|
||||||
|
secretMap[privateKeyConst] = v
|
||||||
|
} else {
|
||||||
|
fmt.Printf("warn: %s is empty for secret %s\n", privateKeyConst, secretName)
|
||||||
|
secretMap[privateKeyConst] = []byte("")
|
||||||
|
}
|
||||||
return secretMap, nil
|
return secretMap, nil
|
||||||
|
|
||||||
case sm.Secret_SecretType_PublicCert:
|
case sm.Secret_SecretType_PublicCert:
|
||||||
secretMap[certificateConst] = []byte(fmt.Sprintf("%v", secMap[certificateConst]))
|
secretMap[certificateConst] = secMapBytes[certificateConst]
|
||||||
secretMap[intermediateConst] = []byte(fmt.Sprintf("%v", secMap[intermediateConst]))
|
secretMap[intermediateConst] = secMapBytes[intermediateConst]
|
||||||
secretMap[privateKeyConst] = []byte(fmt.Sprintf("%v", secMap[privateKeyConst]))
|
secretMap[privateKeyConst] = secMapBytes[privateKeyConst]
|
||||||
return secretMap, nil
|
return secretMap, nil
|
||||||
|
|
||||||
case sm.Secret_SecretType_PrivateCert:
|
case sm.Secret_SecretType_PrivateCert:
|
||||||
secretMap[certificateConst] = []byte(fmt.Sprintf("%v", secMap[certificateConst]))
|
secretMap[certificateConst] = secMapBytes[certificateConst]
|
||||||
secretMap[privateKeyConst] = []byte(fmt.Sprintf("%v", secMap[privateKeyConst]))
|
secretMap[privateKeyConst] = secMapBytes[privateKeyConst]
|
||||||
return secretMap, nil
|
return secretMap, nil
|
||||||
|
|
||||||
case sm.Secret_SecretType_Kv:
|
case sm.Secret_SecretType_Kv:
|
||||||
|
|
|
@ -340,6 +340,22 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
||||||
}
|
}
|
||||||
setSecretCert := funcSetCertSecretTest(importedCert, "good case: imported_cert type with property", sm.Secret_SecretType_ImportedCert, true)
|
setSecretCert := funcSetCertSecretTest(importedCert, "good case: imported_cert type with property", sm.Secret_SecretType_ImportedCert, true)
|
||||||
|
|
||||||
|
// good case: imported_cert type without a private_key
|
||||||
|
importedCertNoPvtKey := func(smtc *secretManagerTestCase) {
|
||||||
|
secret := &sm.ImportedCertificate{
|
||||||
|
SecretType: utilpointer.To(sm.Secret_SecretType_ImportedCert),
|
||||||
|
Name: utilpointer.To("testyname"),
|
||||||
|
ID: utilpointer.To(secretUUID),
|
||||||
|
Certificate: utilpointer.To(secretCertificate),
|
||||||
|
}
|
||||||
|
smtc.name = "good case: imported cert without private key"
|
||||||
|
smtc.apiInput.ID = utilpointer.To(secretUUID)
|
||||||
|
smtc.apiOutput = secret
|
||||||
|
smtc.ref.Key = "imported_cert/" + secretUUID
|
||||||
|
smtc.ref.Property = "private_key"
|
||||||
|
smtc.expectedSecret = ""
|
||||||
|
}
|
||||||
|
|
||||||
// bad case: imported_cert type without property
|
// bad case: imported_cert type without property
|
||||||
badSecretCert := funcSetCertSecretTest(importedCert, "bad case: imported_cert type without property", sm.Secret_SecretType_ImportedCert, false)
|
badSecretCert := funcSetCertSecretTest(importedCert, "bad case: imported_cert type without property", sm.Secret_SecretType_ImportedCert, false)
|
||||||
|
|
||||||
|
@ -493,6 +509,7 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretKVWithOutKey),
|
makeValidSecretManagerTestCaseCustom(setSecretKVWithOutKey),
|
||||||
makeValidSecretManagerTestCaseCustom(badSecretKV),
|
makeValidSecretManagerTestCaseCustom(badSecretKV),
|
||||||
makeValidSecretManagerTestCaseCustom(badSecretCert),
|
makeValidSecretManagerTestCaseCustom(badSecretCert),
|
||||||
|
makeValidSecretManagerTestCaseCustom(importedCertNoPvtKey),
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretPublicCert),
|
makeValidSecretManagerTestCaseCustom(setSecretPublicCert),
|
||||||
makeValidSecretManagerTestCaseCustom(badSecretPublicCert),
|
makeValidSecretManagerTestCaseCustom(badSecretPublicCert),
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretPrivateCert),
|
makeValidSecretManagerTestCaseCustom(setSecretPrivateCert),
|
||||||
|
@ -500,16 +517,16 @@ func TestIBMSecretManagerGetSecret(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sm := providerIBM{}
|
sm := providerIBM{}
|
||||||
for k, v := range successCases {
|
for _, v := range successCases {
|
||||||
t.Run(v.name, func(t *testing.T) {
|
t.Run(v.name, func(t *testing.T) {
|
||||||
sm.IBMClient = v.mockClient
|
sm.IBMClient = v.mockClient
|
||||||
sm.cache = NewCache(10, 1*time.Minute)
|
sm.cache = NewCache(10, 1*time.Minute)
|
||||||
out, err := sm.GetSecret(context.Background(), *v.ref)
|
out, err := sm.GetSecret(context.Background(), *v.ref)
|
||||||
if !ErrorContains(err, v.expectError) {
|
if !ErrorContains(err, v.expectError) {
|
||||||
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
|
t.Errorf("unexpected error:\n%s, expected:\n'%s'", err.Error(), v.expectError)
|
||||||
}
|
}
|
||||||
if string(out) != v.expectedSecret {
|
if string(out) != v.expectedSecret {
|
||||||
t.Errorf("[%d] unexpected secret: expected %s, got %s", k, v.expectedSecret, string(out))
|
t.Errorf("unexpected secret: expected:\n%s\ngot:\n%s", v.expectedSecret, string(out))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -779,6 +796,29 @@ func TestGetSecretMap(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// good case: imported_cert without a private_key
|
||||||
|
setimportedCertWithNoPvtKey := func(smtc *secretManagerTestCase) {
|
||||||
|
secret := &sm.ImportedCertificate{
|
||||||
|
CreatedBy: utilpointer.To("testCreatedBy"),
|
||||||
|
CreatedAt: &strfmt.DateTime{},
|
||||||
|
Downloaded: utilpointer.To(false),
|
||||||
|
Labels: []string{"abc", "def", "xyz"},
|
||||||
|
LocksTotal: utilpointer.To(int64(20)),
|
||||||
|
Certificate: utilpointer.To(secretCertificate),
|
||||||
|
Intermediate: utilpointer.To(secretIntermediate),
|
||||||
|
}
|
||||||
|
smtc.name = "good case: imported_cert without private key"
|
||||||
|
smtc.apiInput.ID = utilpointer.To(secretUUID)
|
||||||
|
smtc.apiOutput = secret
|
||||||
|
smtc.ref.Key = "imported_cert/" + secretUUID
|
||||||
|
|
||||||
|
smtc.expectedData = map[string][]byte{
|
||||||
|
"certificate": []byte(secretCertificate),
|
||||||
|
"intermediate": []byte(secretIntermediate),
|
||||||
|
"private_key": []byte(""),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// good case: public_cert with metadata
|
// good case: public_cert with metadata
|
||||||
setPublicCertWithMetadata := func(smtc *secretManagerTestCase) {
|
setPublicCertWithMetadata := func(smtc *secretManagerTestCase) {
|
||||||
secret := &sm.PublicCertificate{
|
secret := &sm.PublicCertificate{
|
||||||
|
@ -992,6 +1032,7 @@ func TestGetSecretMap(t *testing.T) {
|
||||||
makeValidSecretManagerTestCaseCustom(badSecretKVWithUnknownProperty),
|
makeValidSecretManagerTestCaseCustom(badSecretKVWithUnknownProperty),
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretPublicCert),
|
makeValidSecretManagerTestCaseCustom(setSecretPublicCert),
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretPrivateCert),
|
makeValidSecretManagerTestCaseCustom(setSecretPrivateCert),
|
||||||
|
makeValidSecretManagerTestCaseCustom(setimportedCertWithNoPvtKey),
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretIamWithMetadata),
|
makeValidSecretManagerTestCaseCustom(setSecretIamWithMetadata),
|
||||||
makeValidSecretManagerTestCaseCustom(setArbitraryWithMetadata),
|
makeValidSecretManagerTestCaseCustom(setArbitraryWithMetadata),
|
||||||
makeValidSecretManagerTestCaseCustom(setSecretUserPassWithMetadata),
|
makeValidSecretManagerTestCaseCustom(setSecretUserPassWithMetadata),
|
||||||
|
@ -1003,15 +1044,15 @@ func TestGetSecretMap(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
sm := providerIBM{}
|
sm := providerIBM{}
|
||||||
for k, v := range successCases {
|
for _, v := range successCases {
|
||||||
t.Run(v.name, func(t *testing.T) {
|
t.Run(v.name, func(t *testing.T) {
|
||||||
sm.IBMClient = v.mockClient
|
sm.IBMClient = v.mockClient
|
||||||
out, err := sm.GetSecretMap(context.Background(), *v.ref)
|
out, err := sm.GetSecretMap(context.Background(), *v.ref)
|
||||||
if !ErrorContains(err, v.expectError) {
|
if !ErrorContains(err, v.expectError) {
|
||||||
t.Errorf(" unexpected error: %s, expected: '%s'", err.Error(), v.expectError)
|
t.Errorf("unexpected error: %s, expected: '%s'", err.Error(), v.expectError)
|
||||||
}
|
}
|
||||||
if err == nil && !reflect.DeepEqual(out, v.expectedData) {
|
if err == nil && !reflect.DeepEqual(out, v.expectedData) {
|
||||||
t.Errorf("[%d] unexpected secret data: expected %+v, got %v", k, v.expectedData, out)
|
t.Errorf("unexpected secret data: expected:\n%+v\ngot:\n%+v", v.expectedData, out)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue