mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
Feat/allow keeper to work with complex types (#3016)
* update dependencies (#3005) Signed-off-by: External Secrets Operator <ExternalSecretsOperator@users.noreply.github.com> Co-authored-by: External Secrets Operator <ExternalSecretsOperator@users.noreply.github.com> Co-authored-by: Moritz Johner <moolen@users.noreply.github.com> Signed-off-by: Pedro Parra Ortega <parraortega.pedro@gmail.com> * feat: allow keeper to work with complex types Signed-off-by: Pedro Parra Ortega <parraortega.pedro@gmail.com> --------- Signed-off-by: External Secrets Operator <ExternalSecretsOperator@users.noreply.github.com> Signed-off-by: Pedro Parra Ortega <parraortega.pedro@gmail.com> Co-authored-by: eso-service-account-app[bot] <85832941+eso-service-account-app[bot]@users.noreply.github.com> Co-authored-by: External Secrets Operator <ExternalSecretsOperator@users.noreply.github.com> Co-authored-by: Moritz Johner <moolen@users.noreply.github.com>
This commit is contained in:
parent
559c773792
commit
ba8cf6bde5
4 changed files with 55 additions and 16 deletions
|
@ -56,8 +56,10 @@ Be sure the `keepersecurity` provider is listed in the `Kind=SecretStore`
|
|||
* Files: Record's file's Name
|
||||
* `find.tags` are not supported at this time.
|
||||
|
||||
**NOTE:** For complex [types](https://docs.keeper.io/secrets-manager/secrets-manager/about/field-record-types), like name, phone, bankAccount, which does not match with a single string value, external secrets will return the complete json string. Use the json template functions to decode.
|
||||
|
||||
### Creating external secret
|
||||
To create a kubernetes secret from the GCP Secret Manager secret a `Kind=ExternalSecret` is needed.
|
||||
To create a kubernetes secret from Keeper Secret Manager secret a `Kind=ExternalSecret` is needed.
|
||||
|
||||
```yaml
|
||||
{% include 'keepersecurity-external-secret.yaml' %}
|
||||
|
|
|
@ -70,4 +70,24 @@ spec:
|
|||
remoteRef:
|
||||
key: OqPt3Vd37My7G8rTb-8Q
|
||||
property: password
|
||||
---
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
refreshInterval: 1h # rate SecretManager pulls KeeperSrucity
|
||||
secretStoreRef:
|
||||
kind: SecretStore
|
||||
name: example # name of the SecretStore (or kind specified)
|
||||
target:
|
||||
name: secret-to-be-created # name of the k8s Secret to be created
|
||||
creationPolicy: Owner
|
||||
template:
|
||||
engineVersion: v2
|
||||
data:
|
||||
username: "{{ (fromJson .name).first }} {{ (fromJson .name).middle }} {{ (fromJson .name).last }}" # decode json string into vars
|
||||
dataFrom:
|
||||
- extract:
|
||||
key: OqPt3Vd37My7G8rTb-8Q # ID of the Keeper Record
|
||||
{% endraw %}
|
||||
|
|
|
@ -71,14 +71,14 @@ type SecurityClient interface {
|
|||
}
|
||||
|
||||
type Field struct {
|
||||
Type string `json:"type"`
|
||||
Value []string `json:"value"`
|
||||
Type string `json:"type"`
|
||||
Value []interface{} `json:"value"`
|
||||
}
|
||||
|
||||
type CustomField struct {
|
||||
Type string `json:"type"`
|
||||
Label string `json:"label"`
|
||||
Value []string `json:"value"`
|
||||
Type string `json:"type"`
|
||||
Label string `json:"label"`
|
||||
Value []interface{} `json:"value"`
|
||||
}
|
||||
|
||||
type File struct {
|
||||
|
@ -401,10 +401,25 @@ func (s *Secret) getItems(ref esv1beta1.ExternalSecretDataRemoteRef) (map[string
|
|||
return secretData, nil
|
||||
}
|
||||
|
||||
func getFieldValue(value []interface{}) []byte {
|
||||
if len(value) < 1 {
|
||||
return []byte{}
|
||||
} else if len(value) == 1 {
|
||||
res, _ := json.Marshal(value[0])
|
||||
if str, ok := value[0].(string); ok {
|
||||
res = []byte(str)
|
||||
}
|
||||
return res
|
||||
} else {
|
||||
res, _ := json.Marshal(value)
|
||||
return res
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Secret) getField(key string) ([]byte, error) {
|
||||
for _, field := range s.Fields {
|
||||
if field.Type == key && field.Type != keeperSecurityFileRef && field.Type != keeperSecurityMfa && len(field.Value) > 0 {
|
||||
return []byte(field.Value[0]), nil
|
||||
return getFieldValue(field.Value), nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,7 +430,7 @@ func (s *Secret) getFields() map[string][]byte {
|
|||
secretData := make(map[string][]byte)
|
||||
for _, field := range s.Fields {
|
||||
if len(field.Value) > 0 {
|
||||
secretData[field.Type] = []byte(field.Value[0])
|
||||
secretData[field.Type] = getFieldValue(field.Value)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -425,7 +440,7 @@ func (s *Secret) getFields() map[string][]byte {
|
|||
func (s *Secret) getCustomField(key string) ([]byte, error) {
|
||||
for _, field := range s.Custom {
|
||||
if field.Label == key && len(field.Value) > 0 {
|
||||
return []byte(field.Value[0]), nil
|
||||
return getFieldValue(field.Value), nil
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -436,7 +451,7 @@ func (s *Secret) getCustomFields() map[string][]byte {
|
|||
secretData := make(map[string][]byte)
|
||||
for _, field := range s.Custom {
|
||||
if len(field.Value) > 0 {
|
||||
secretData[field.Label] = []byte(field.Value[0])
|
||||
secretData[field.Label] = getFieldValue(field.Value)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -33,14 +33,15 @@ const (
|
|||
folderID = "a8ekf031k"
|
||||
validExistingRecord = "record0/login"
|
||||
invalidRecord = "record5/login"
|
||||
outputRecord0 = "{\"title\":\"record0\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":null,\"files\":null}"
|
||||
outputRecord1 = "{\"title\":\"record1\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":null,\"files\":null}"
|
||||
outputRecord2 = "{\"title\":\"record2\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":null,\"files\":null}"
|
||||
outputRecord0 = "{\"title\":\"record0\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":[{\"type\":\"host\",\"label\":\"host0\",\"value\":[{\"hostName\":\"mysql\",\"port\":\"3306\"}]}],\"files\":null}"
|
||||
outputRecord1 = "{\"title\":\"record1\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":[{\"type\":\"host\",\"label\":\"host1\",\"value\":[{\"hostName\":\"mysql\",\"port\":\"3306\"}]}],\"files\":null}"
|
||||
outputRecord2 = "{\"title\":\"record2\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":[{\"type\":\"host\",\"label\":\"host2\",\"value\":[{\"hostName\":\"mysql\",\"port\":\"3306\"}]}],\"files\":null}"
|
||||
record0 = "record0"
|
||||
record1 = "record1"
|
||||
record2 = "record2"
|
||||
LoginKey = "login"
|
||||
PasswordKey = "password"
|
||||
HostKeyFormat = "host%d"
|
||||
RecordNameFormat = "record%d"
|
||||
)
|
||||
|
||||
|
@ -412,8 +413,9 @@ func TestClientGetSecretMap(t *testing.T) {
|
|||
},
|
||||
},
|
||||
want: map[string][]byte{
|
||||
LoginKey: []byte("foo"),
|
||||
PasswordKey: []byte("bar"),
|
||||
LoginKey: []byte("foo"),
|
||||
PasswordKey: []byte("bar"),
|
||||
fmt.Sprintf(HostKeyFormat, 0): []byte("{\"hostName\":\"mysql\",\"port\":\"3306\"}"),
|
||||
},
|
||||
wantErr: false,
|
||||
},
|
||||
|
@ -650,7 +652,7 @@ func generateRecords() []*ksm.Record {
|
|||
},
|
||||
}
|
||||
}
|
||||
sec := fmt.Sprintf("{\"title\":\"record%d\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}]}", i)
|
||||
sec := fmt.Sprintf("{\"title\":\"record%d\",\"type\":\"login\",\"fields\":[{\"type\":\"login\",\"value\":[\"foo\"]},{\"type\":\"password\",\"value\":[\"bar\"]}],\"custom\":[{\"type\":\"host\",\"label\":\"host%d\",\"value\":[{\"hostName\":\"mysql\",\"port\":\"3306\"}]}]}", i, i)
|
||||
record.SetTitle(fmt.Sprintf(RecordNameFormat, i))
|
||||
record.SetStandardFieldValue(LoginKey, "foo")
|
||||
record.SetStandardFieldValue(PasswordKey, "bar")
|
||||
|
|
Loading…
Reference in a new issue