mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-15 17:51:01 +00:00
Add support for referencing secrets manager secrets by their VersionId
This commit is contained in:
parent
c532bac0be
commit
b004894b77
3 changed files with 78 additions and 7 deletions
|
@ -57,4 +57,54 @@ This is an example on how you would look up nested keys in the above json object
|
|||
{% include 'aws-sm-external-secret.yaml' %}
|
||||
```
|
||||
|
||||
### Secret Versions
|
||||
|
||||
SecretsManager creates a new version of a secret every time it is updated. The secret version can be reference in two ways, the `VersionStage` and the `VersionId`. The `VersionId` is a unique uuid which is generated every time the secret changes. This id is immutable and will always refer to the same secret data. The `VersionStage` is an alias to a `VersionId`, and can refer to different secret data as the secret is updated. By default, SecretsManager will add the version stages `AWSCURRENT` and `AWSPREVIOUS` to every secret, but other stages can be created via the [update-secret-version-stage](https://docs.aws.amazon.com/cli/latest/reference/secretsmanager/update-secret-version-stage.html) api.
|
||||
|
||||
The `version` field on the `remoteRef` of the ExternalSecret will normally consider the version to be a `VersionStage`, but if the field is prefixed with `uuid/`, then the version will be considered a `VersionId`.
|
||||
|
||||
So in this example, the operator will request the secret with `VersionStage` as `AWSPREVIOUS`:
|
||||
|
||||
``` yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: secretstore-sample
|
||||
kind: SecretStore
|
||||
target:
|
||||
name: secret-to-be-created
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: secret-key-to-be-managed
|
||||
remoteRef:
|
||||
key: "example/secret"
|
||||
version: "AWSPREVIOUS"
|
||||
```
|
||||
|
||||
While in this example, the operator will request the secret with `VersionId` as `abcd-1234`
|
||||
|
||||
``` yaml
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: example
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: secretstore-sample
|
||||
kind: SecretStore
|
||||
target:
|
||||
name: secret-to-be-created
|
||||
creationPolicy: Owner
|
||||
data:
|
||||
- secretKey: secret-key-to-be-managed
|
||||
remoteRef:
|
||||
key: "example/secret"
|
||||
version: "uuid/abcd-1234"
|
||||
```
|
||||
|
||||
--8<-- "snippets/provider-aws-access.md"
|
||||
|
|
|
@ -77,10 +77,21 @@ func (sm *SecretsManager) fetch(_ context.Context, ref esv1beta1.ExternalSecretD
|
|||
log.Info("found secret in cache", "key", ref.Key, "version", ver)
|
||||
return secretOut, nil
|
||||
}
|
||||
secretOut, err := sm.client.GetSecretValue(&awssm.GetSecretValueInput{
|
||||
SecretId: &ref.Key,
|
||||
VersionStage: &ver,
|
||||
})
|
||||
|
||||
var getSecretValueInput *awssm.GetSecretValueInput
|
||||
if strings.HasPrefix(ver, "uuid/") {
|
||||
versionID := strings.TrimPrefix(ver, "uuid/")
|
||||
getSecretValueInput = &awssm.GetSecretValueInput{
|
||||
SecretId: &ref.Key,
|
||||
VersionId: &versionID,
|
||||
}
|
||||
} else {
|
||||
getSecretValueInput = &awssm.GetSecretValueInput{
|
||||
SecretId: &ref.Key,
|
||||
VersionStage: &ver,
|
||||
}
|
||||
}
|
||||
secretOut, err := sm.client.GetSecretValue(getSecretValueInput)
|
||||
var nf *awssm.ResourceNotFoundException
|
||||
if errors.As(err, &nf) {
|
||||
return nil, esv1beta1.NoSecretErr
|
||||
|
|
|
@ -155,14 +155,23 @@ func TestSecretsManagerGetSecret(t *testing.T) {
|
|||
smtc.expectedSecret = "nestedval"
|
||||
}
|
||||
|
||||
// good case: custom version set
|
||||
setCustomVersion := func(smtc *secretsManagerTestCase) {
|
||||
// good case: custom version stage set
|
||||
setCustomVersionStage := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiInput.VersionStage = aws.String("1234")
|
||||
smtc.remoteRef.Version = "1234"
|
||||
smtc.apiOutput.SecretString = aws.String("FOOBA!")
|
||||
smtc.expectedSecret = "FOOBA!"
|
||||
}
|
||||
|
||||
// good case: custom version id set
|
||||
setCustomVersionID := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiInput.VersionStage = nil
|
||||
smtc.apiInput.VersionId = aws.String("1234-5678")
|
||||
smtc.remoteRef.Version = "uuid/1234-5678"
|
||||
smtc.apiOutput.SecretString = aws.String("myvalue")
|
||||
smtc.expectedSecret = "myvalue"
|
||||
}
|
||||
|
||||
successCases := []*secretsManagerTestCase{
|
||||
makeValidSecretsManagerTestCase(),
|
||||
makeValidSecretsManagerTestCaseCustom(setSecretString),
|
||||
|
@ -173,7 +182,8 @@ func TestSecretsManagerGetSecret(t *testing.T) {
|
|||
makeValidSecretsManagerTestCaseCustom(setSecretBinaryAndSecretStringToNil),
|
||||
makeValidSecretsManagerTestCaseCustom(setNestedSecretValueJSONParsing),
|
||||
makeValidSecretsManagerTestCaseCustom(setSecretValueWithDot),
|
||||
makeValidSecretsManagerTestCaseCustom(setCustomVersion),
|
||||
makeValidSecretsManagerTestCaseCustom(setCustomVersionStage),
|
||||
makeValidSecretsManagerTestCaseCustom(setCustomVersionID),
|
||||
makeValidSecretsManagerTestCaseCustom(setAPIErr),
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue