mirror of
https://github.com/external-secrets/external-secrets.git
synced 2024-12-14 11:57:59 +00:00
Add tweaks for secretsManager GetSecret tests
For readability and scalability, create a struct with default test case values, then use anonymous function "tweaks" with only the changes from default to test on.
This commit is contained in:
parent
8bd306cc01
commit
73fd040965
1 changed files with 137 additions and 169 deletions
|
@ -37,179 +37,147 @@ func TestConstructor(t *testing.T) {
|
|||
assert.NotNil(t, c.client)
|
||||
}
|
||||
|
||||
type secretsManagerTestCase struct {
|
||||
fakeClient *fakesm.Client
|
||||
apiInput *awssm.GetSecretValueInput
|
||||
apiOutput *awssm.GetSecretValueOutput
|
||||
ref *esv1alpha1.ExternalSecretDataRemoteRef
|
||||
apiErr error
|
||||
expectError string
|
||||
expectedSecret string
|
||||
}
|
||||
|
||||
func makeValidSecretsManagerTestCase() *secretsManagerTestCase {
|
||||
smtc := secretsManagerTestCase{
|
||||
fakeClient: &fakesm.Client{},
|
||||
apiInput: makeValidAPIInput(),
|
||||
ref: makeValidRef(),
|
||||
apiOutput: makeValidAPIOutput(),
|
||||
apiErr: nil,
|
||||
expectError: "",
|
||||
expectedSecret: "",
|
||||
}
|
||||
smtc.fakeClient.WithValue(smtc.apiInput, smtc.apiOutput, smtc.apiErr)
|
||||
return &smtc
|
||||
}
|
||||
|
||||
func makeValidRef() *esv1alpha1.ExternalSecretDataRemoteRef {
|
||||
return &esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Version: "AWSCURRENT",
|
||||
}
|
||||
}
|
||||
|
||||
func makeValidAPIInput() *awssm.GetSecretValueInput {
|
||||
return &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
}
|
||||
}
|
||||
|
||||
func makeValidAPIOutput() *awssm.GetSecretValueOutput {
|
||||
return &awssm.GetSecretValueOutput{
|
||||
SecretString: aws.String(""),
|
||||
}
|
||||
}
|
||||
|
||||
func makeValidSecretsManagerTestCaseCustom(tweaks ...func(smtc *secretsManagerTestCase)) *secretsManagerTestCase {
|
||||
smtc := makeValidSecretsManagerTestCase()
|
||||
for _, fn := range tweaks {
|
||||
fn(smtc)
|
||||
}
|
||||
smtc.fakeClient.WithValue(smtc.apiInput, smtc.apiOutput, smtc.apiErr)
|
||||
return smtc
|
||||
}
|
||||
|
||||
// test the sm<->aws interface
|
||||
// make sure correct values are passed and errors are handled accordingly.
|
||||
func TestGetSecret(t *testing.T) {
|
||||
fake := &fakesm.Client{}
|
||||
p := &SecretsManager{
|
||||
client: fake,
|
||||
func TestSecretsManagerGetSecret(t *testing.T) {
|
||||
// good case: default version is set
|
||||
// key is passed in, output is sent back
|
||||
setSecretString := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretString = aws.String("testtesttest")
|
||||
smtc.expectedSecret = "testtesttest"
|
||||
}
|
||||
for i, row := range []struct {
|
||||
apiInput *awssm.GetSecretValueInput
|
||||
apiOutput *awssm.GetSecretValueOutput
|
||||
rr esv1alpha1.ExternalSecretDataRemoteRef
|
||||
apiErr error
|
||||
expectError string
|
||||
expectedSecret string
|
||||
}{
|
||||
{
|
||||
// good case: default version is set
|
||||
// key is passed in, output is sent back
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: aws.String("RRRRR"),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "",
|
||||
expectedSecret: "RRRRR",
|
||||
},
|
||||
{
|
||||
// good case: extract property
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Property: "/shmoo",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: aws.String(`{"/shmoo": "bang"}`),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "",
|
||||
expectedSecret: "bang",
|
||||
},
|
||||
{
|
||||
// bad case: missing property
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Property: "INVALPROP",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: aws.String(`{"/shmoo": "bang"}`),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "key INVALPROP does not exist in secret",
|
||||
expectedSecret: "",
|
||||
},
|
||||
{
|
||||
// bad case: extract property failure due to invalid json
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Property: "INVALPROP",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: aws.String(`------`),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "key INVALPROP does not exist in secret",
|
||||
expectedSecret: "",
|
||||
},
|
||||
{
|
||||
// case: ssm.SecretString may be nil but binary is set
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: nil,
|
||||
SecretBinary: []byte("yesplease"),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "",
|
||||
expectedSecret: "yesplease",
|
||||
},
|
||||
{
|
||||
// case: both .SecretString and .SecretBinary is nil
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: nil,
|
||||
SecretBinary: nil,
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "no secret string nor binary for key",
|
||||
expectedSecret: "",
|
||||
},
|
||||
{
|
||||
// case: secretOut.SecretBinary JSON parsing
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/baz"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/baz",
|
||||
Property: "foobar.baz",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: nil,
|
||||
SecretBinary: []byte(`{"foobar":{"baz":"nestedval"}}`),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "",
|
||||
expectedSecret: "nestedval",
|
||||
},
|
||||
{
|
||||
// should pass version
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/foo/bar"),
|
||||
VersionStage: aws.String("1234"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/foo/bar",
|
||||
Version: "1234",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{
|
||||
SecretString: aws.String("FOOBA!"),
|
||||
},
|
||||
apiErr: nil,
|
||||
expectError: "",
|
||||
expectedSecret: "FOOBA!",
|
||||
},
|
||||
{
|
||||
// should return err
|
||||
apiInput: &awssm.GetSecretValueInput{
|
||||
SecretId: aws.String("/foo/bar"),
|
||||
VersionStage: aws.String("AWSCURRENT"),
|
||||
},
|
||||
rr: esv1alpha1.ExternalSecretDataRemoteRef{
|
||||
Key: "/foo/bar",
|
||||
},
|
||||
apiOutput: &awssm.GetSecretValueOutput{},
|
||||
apiErr: fmt.Errorf("oh no"),
|
||||
expectError: "oh no",
|
||||
},
|
||||
} {
|
||||
fake.WithValue(row.apiInput, row.apiOutput, row.apiErr)
|
||||
out, err := p.GetSecret(context.Background(), row.rr)
|
||||
if !ErrorContains(err, row.expectError) {
|
||||
t.Errorf("[%d] unexpected error: %s, expected: '%s'", i, err.Error(), row.expectError)
|
||||
|
||||
// good case: extract property
|
||||
// Testing that the property exists in the SecretString
|
||||
setRefPropertyExistsInKey := func(smtc *secretsManagerTestCase) {
|
||||
smtc.ref.Property = "/shmoo"
|
||||
smtc.apiOutput.SecretString = aws.String(`{"/shmoo": "bang"}`)
|
||||
smtc.expectedSecret = "bang"
|
||||
}
|
||||
|
||||
// bad case: missing property
|
||||
setRefMissingProperty := func(smtc *secretsManagerTestCase) {
|
||||
smtc.ref.Property = "INVALPROP"
|
||||
smtc.expectError = "key INVALPROP does not exist in secret"
|
||||
}
|
||||
|
||||
// bad case: extract property failure due to invalid json
|
||||
setRefMissingPropertyInvalidJSON := func(smtc *secretsManagerTestCase) {
|
||||
smtc.ref.Property = "INVALPROP"
|
||||
smtc.apiOutput.SecretString = aws.String(`------`)
|
||||
smtc.expectError = "key INVALPROP does not exist in secret"
|
||||
}
|
||||
|
||||
// good case: set .SecretString to nil but set binary with value
|
||||
setSecretBinaryNotSecretString := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretBinary = []byte("yesplease")
|
||||
// needs to be set as nil, empty quotes ("") is considered existing
|
||||
smtc.apiOutput.SecretString = nil
|
||||
smtc.expectedSecret = "yesplease"
|
||||
}
|
||||
|
||||
// bad case: both .SecretString and .SecretBinary are nil
|
||||
setSecretBinaryAndSecretStringToNil := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretBinary = nil
|
||||
smtc.apiOutput.SecretString = nil
|
||||
smtc.expectError = "no secret string nor binary for key"
|
||||
}
|
||||
// good case: secretOut.SecretBinary JSON parsing
|
||||
setNestedSecretValueJSONParsing := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiOutput.SecretString = nil
|
||||
smtc.apiOutput.SecretBinary = []byte(`{"foobar":{"baz":"nestedval"}}`)
|
||||
smtc.ref.Property = "foobar.baz"
|
||||
smtc.expectedSecret = "nestedval"
|
||||
}
|
||||
|
||||
// good case: custom version set
|
||||
setCustomVersion := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiInput.VersionStage = aws.String("1234")
|
||||
smtc.ref.Version = "1234"
|
||||
smtc.apiOutput.SecretString = aws.String("FOOBA!")
|
||||
smtc.expectedSecret = "FOOBA!"
|
||||
}
|
||||
// bad case: set apiErr
|
||||
setAPIErr := func(smtc *secretsManagerTestCase) {
|
||||
smtc.apiErr = fmt.Errorf("oh no")
|
||||
smtc.expectError = "oh no"
|
||||
}
|
||||
|
||||
successCases := []*secretsManagerTestCase{
|
||||
makeValidSecretsManagerTestCase(),
|
||||
makeValidSecretsManagerTestCaseCustom(setSecretString),
|
||||
makeValidSecretsManagerTestCaseCustom(setRefPropertyExistsInKey),
|
||||
makeValidSecretsManagerTestCaseCustom(setRefMissingProperty),
|
||||
makeValidSecretsManagerTestCaseCustom(setRefMissingPropertyInvalidJSON),
|
||||
makeValidSecretsManagerTestCaseCustom(setSecretBinaryNotSecretString),
|
||||
makeValidSecretsManagerTestCaseCustom(setSecretBinaryAndSecretStringToNil),
|
||||
makeValidSecretsManagerTestCaseCustom(setNestedSecretValueJSONParsing),
|
||||
makeValidSecretsManagerTestCaseCustom(setCustomVersion),
|
||||
makeValidSecretsManagerTestCaseCustom(setAPIErr),
|
||||
}
|
||||
|
||||
sm := SecretsManager{}
|
||||
for k, v := range successCases {
|
||||
sm.client = v.fakeClient
|
||||
out, err := sm.GetSecret(context.Background(), *v.ref)
|
||||
if !ErrorContains(err, v.expectError) {
|
||||
t.Errorf("[%d] unexpected error: %s, expected: '%s'", k, err.Error(), v.expectError)
|
||||
}
|
||||
if string(out) != row.expectedSecret {
|
||||
t.Errorf("[%d] unexpected secret: expected %s, got %s", i, row.expectedSecret, string(out))
|
||||
if string(out) != v.expectedSecret {
|
||||
t.Errorf("[%d] unexpected secret: expected %s, got %s", k, v.expectedSecret, string(out))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue