| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662 |
- /*
- Copyright © The ESO Authors
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
- https://www.apache.org/licenses/LICENSE-2.0
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
- */
- package beyondtrustworkloadcredentials
- import (
- "context"
- "encoding/json"
- "fmt"
- "path"
- "strings"
- "testing"
- "github.com/google/go-cmp/cmp"
- esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1"
- "github.com/external-secrets/external-secrets/providers/v1/beyondtrustworkloadcredentials/fake"
- btwcutil "github.com/external-secrets/external-secrets/providers/v1/beyondtrustworkloadcredentials/util"
- )
- const (
- validSecretName = "apikey"
- validFolderPath = "valid/folder/path"
- invalidSecretName = "INVALID_NAME"
- invalidFolderPath = "INVALID_PATH"
- )
- ///////////////////////
- // test case structs //
- ///////////////////////
- type beyondtrustworkloadcredentialsGetSecretTestCase struct {
- label string
- fakeBtsecretsClient *fake.BeyondtrustWorkloadCredentialsClient
- ctx context.Context
- name *string
- folderPath *string
- remoteRef esv1.ExternalSecretDataRemoteRef
- fakeBtsecretsResponse *btwcutil.KV
- fakeBtsecretsError *string
- expectedError *string
- expectedResponse []byte
- }
- type beyondtrustworkloadcredentialsGetAllSecretsTestCase struct {
- label string
- fakeBtsecretsClient *fake.BeyondtrustWorkloadCredentialsClient
- ctx context.Context
- name *string
- names []string
- folderPath *string
- remoteRef esv1.ExternalSecretFind
- fakeBtsecretsGetResponse *btwcutil.KV
- fakeBtsecretsGetResponses []btwcutil.KV
- fakeBtsecretsListResponse []btwcutil.KVListItem
- fakeBtsecretsGetError *string
- fakeBtsecretsListError *string
- expectedError *string
- expectedResponse map[string][]byte
- }
- ////////////
- // makers //
- ////////////
- // makeValidGetSecretTestCase creates a valid test case for GetSecret tests.
- func makeValidGetSecretTestCase() *beyondtrustworkloadcredentialsGetSecretTestCase {
- return &beyondtrustworkloadcredentialsGetSecretTestCase{
- fakeBtsecretsClient: &fake.BeyondtrustWorkloadCredentialsClient{},
- ctx: context.Background(),
- name: new(validSecretName),
- folderPath: new(validFolderPath),
- remoteRef: esv1.ExternalSecretDataRemoteRef{Key: validSecretName, Property: ""},
- }
- }
- // makeValidGetAllSecretsTestCase creates a valid test case for GetSecrets tests.
- func makeValidGetAllSecretsTestCase() *beyondtrustworkloadcredentialsGetAllSecretsTestCase {
- return &beyondtrustworkloadcredentialsGetAllSecretsTestCase{
- fakeBtsecretsClient: &fake.BeyondtrustWorkloadCredentialsClient{},
- ctx: context.Background(),
- name: new(validSecretName),
- folderPath: new(validFolderPath),
- remoteRef: esv1.ExternalSecretFind{},
- }
- }
- // makeValidGetSecretTestCaseWithValues injects values into the faked BeyondtrustWorkloadCredentialsClient for GetSecret tests.
- func makeValidGetSecretTestCaseWithValues(tweaks ...func(tc *beyondtrustworkloadcredentialsGetSecretTestCase)) *beyondtrustworkloadcredentialsGetSecretTestCase {
- vtc := makeValidGetSecretTestCase()
- for _, fn := range tweaks {
- fn(vtc)
- }
- vtc.fakeBtsecretsClient.WithValues(vtc.ctx, vtc.name, vtc.folderPath, vtc.fakeBtsecretsResponse, nil, vtc.fakeBtsecretsError, nil)
- return vtc
- }
- // makeValidGetAllSecretsTestCaseWithValues injects values into the faked BeyondtrustWorkloadCredentialsClient for GetSecrets tests.
- func makeValidGetAllSecretsTestCaseWithValues(tweaks ...func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase)) *beyondtrustworkloadcredentialsGetAllSecretsTestCase {
- vtc := makeValidGetAllSecretsTestCase()
- for _, fn := range tweaks {
- fn(vtc)
- }
- vtc.fakeBtsecretsClient.WithValues(vtc.ctx, vtc.name, vtc.folderPath, vtc.fakeBtsecretsGetResponse, vtc.fakeBtsecretsListResponse, vtc.fakeBtsecretsGetError, vtc.fakeBtsecretsListError)
- return vtc
- }
- // makeValidGetAllSecretsTestCaseWithMultiValues injects values with multiple GET responses into the faked BeyondtrustWorkloadCredentialsClient for GetSecrets tests.
- func makeValidGetAllSecretsTestCaseWithMultiValues(tweaks ...func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase)) *beyondtrustworkloadcredentialsGetAllSecretsTestCase {
- vtc := makeValidGetAllSecretsTestCase()
- for _, fn := range tweaks {
- fn(vtc)
- }
- vtc.fakeBtsecretsClient.WithMultiValues(vtc.ctx, vtc.names, vtc.folderPath, vtc.fakeBtsecretsGetResponses, vtc.fakeBtsecretsListResponse, vtc.fakeBtsecretsGetError, vtc.fakeBtsecretsListError)
- return vtc
- }
- ///////////
- // tests //
- ///////////
- func TestGetSecret(t *testing.T) {
- // happy paths
- validSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- Secret: map[string]any{"valid": "test"},
- }
- fakeKVBytes, err := json.Marshal(fakeKV.Secret)
- if err != nil {
- t.Errorf("failed to marshal fake KV: %#v, error: %q", fakeKV, err.Error())
- }
- tc.label = "GetSecret - Valid"
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedResponse = fakeKVBytes
- }
- validSecretProperty := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- propertyValue := "test"
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- Secret: map[string]any{"valid": propertyValue, "doNotInclude": "this"},
- }
- tc.label = "GetSecret - Valid Property"
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: validSecretName, Property: "valid"}
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedResponse = []byte(propertyValue)
- }
- // sad paths
- clientError := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- tc.label = "GetSecret - Client Error"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName}
- tc.fakeBtsecretsError = new("beyondtrustworkloadcredentials error")
- tc.expectedError = new("failed to get secret")
- }
- nilSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- }
- tc.label = "GetSecret - Nil Secret"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName}
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedError = new("secret value is nil")
- }
- invalidSecretProperty := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- Secret: map[string]any{"invalid": "test"},
- }
- ref := esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName, Property: "nonexistant"}
- tc.label = "GetSecret - Invalid Property"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = ref
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedError = new(fmt.Sprintf("property %s not found in secret", ref.Property))
- }
- invalidSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- Secret: map[string]any{"invalid": func() {}},
- }
- tc.label = "GetSecret - Invalid"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName}
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedError = new("failed to marshal secret")
- }
- testCases := []*beyondtrustworkloadcredentialsGetSecretTestCase{
- // happy paths
- makeValidGetSecretTestCaseWithValues(validSecret),
- makeValidGetSecretTestCaseWithValues(validSecretProperty),
- // sad paths
- makeValidGetSecretTestCaseWithValues(clientError),
- makeValidGetSecretTestCaseWithValues(nilSecret),
- makeValidGetSecretTestCaseWithValues(invalidSecretProperty),
- makeValidGetSecretTestCaseWithValues(invalidSecret),
- }
- c := Client{store: &esv1.BeyondtrustWorkloadCredentialsProvider{}}
- for i, tc := range testCases {
- t.Run(tc.label, func(t *testing.T) {
- c.beyondtrustWorkloadCredentialsClient = tc.fakeBtsecretsClient
- c.store.FolderPath = *tc.folderPath
- out, err := c.GetSecret(context.Background(), tc.remoteRef)
- // assert error
- if tc.expectedError == nil && err != nil {
- t.Errorf("[%d] unexpected error: expected nil, got %q", i, err.Error())
- }
- if tc.expectedError != nil && !ErrorContains(err, *tc.expectedError) {
- t.Errorf("[%d] unexpected error: expected %q, got %q", i, *tc.expectedError, err)
- }
- // assert response
- if tc.expectedResponse == nil && out != nil {
- t.Errorf("[%d] unexpected response: expected nil, got %#v", i, out)
- }
- if tc.expectedResponse != nil && !cmp.Equal(out, tc.expectedResponse) {
- t.Errorf("[%d] unexpected response: expected %#v, got %#v", i, tc.expectedResponse, out)
- }
- })
- }
- }
- func ErrorContains(out error, want string) bool {
- if out == nil {
- return want == ""
- }
- if want == "" {
- return false
- }
- return strings.Contains(out.Error(), want)
- }
- func TestGetAllSecrets(t *testing.T) {
- // happy paths
- validSecretKVs := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- Secret: map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
- }
- fakeListItem := btwcutil.KVListItem{
- Path: fakeKV.Path,
- }
- fakeKVBytes := map[string][]byte{
- fakeKV.Path + "/key1": []byte("val1"),
- fakeKV.Path + "/key2": []byte("val2"),
- fakeKV.Path + "/key3": []byte("val3"),
- }
- tc.label = "GetAllSecrets - Secret KVs - Valid"
- tc.remoteRef = esv1.ExternalSecretFind{Path: new(validFolderPath)}
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem}
- tc.fakeBtsecretsGetResponse = fakeKV
- tc.expectedResponse = fakeKVBytes
- }
- validNamedSecrets := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- findName := fmt.Sprintf("%s-include", validSecretName)
- fakeKV1 := btwcutil.KV{
- Path: fmt.Sprintf("%s/%s-fakeKV1", validFolderPath, findName),
- Secret: map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
- }
- fakeKV2 := btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- }
- fakeKV3 := btwcutil.KV{
- Path: fmt.Sprintf("%s/%s-fakeKV3", validFolderPath, findName),
- Secret: map[string]any{"key6": "val6"},
- }
- fakeListItem1 := btwcutil.KVListItem{
- Path: fakeKV1.Path,
- }
- fakeListItem2 := btwcutil.KVListItem{
- Path: fakeKV2.Path,
- }
- fakeListItem3 := btwcutil.KVListItem{
- Path: fakeKV3.Path,
- }
- fakeResponseBytes := map[string][]byte{
- fakeKV1.Path + "/key1": []byte("val1"),
- fakeKV1.Path + "/key2": []byte("val2"),
- fakeKV1.Path + "/key3": []byte("val3"),
- fakeKV3.Path + "/key6": []byte("val6"),
- }
- _, name1 := path.Split(fakeListItem1.Path)
- _, name3 := path.Split(fakeListItem3.Path)
- tc.label = "GetAllSecrets - Secret KVs - Valid Find RegExp"
- tc.names = []string{name1, name3}
- tc.remoteRef = esv1.ExternalSecretFind{Name: &esv1.FindName{RegExp: fmt.Sprintf("^%s.*", findName)}}
- tc.fakeBtsecretsGetResponses = []btwcutil.KV{fakeKV1, fakeKV3}
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem1, fakeListItem2, fakeListItem3}
- tc.expectedResponse = fakeResponseBytes
- }
- validAllSecrets := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- findPath := fmt.Sprintf("%s/%s-include", validFolderPath, validSecretName)
- fakeKV1 := btwcutil.KV{
- Path: fmt.Sprintf("%s-fakeKV1", findPath),
- Secret: map[string]any{"key1": "val1", "key2": "val2", "key3": "val3"},
- }
- fakeKV2 := btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- Secret: map[string]any{"key4": "val4", "key5": "val5"},
- }
- fakeKV3 := btwcutil.KV{
- Path: fmt.Sprintf("%s-fakeKV3", findPath),
- Secret: map[string]any{"key6": "val6"},
- }
- fakeListItem1 := btwcutil.KVListItem{
- Path: fmt.Sprintf("%s-fakeKV1", findPath),
- }
- fakeListItem2 := btwcutil.KVListItem{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- }
- fakeListItem3 := btwcutil.KVListItem{
- Path: fmt.Sprintf("%s-fakeKV3", findPath),
- }
- fakeResponseBytes := map[string][]byte{
- fakeKV1.Path + "/key1": []byte("val1"),
- fakeKV1.Path + "/key2": []byte("val2"),
- fakeKV1.Path + "/key3": []byte("val3"),
- fakeKV2.Path + "/key4": []byte("val4"),
- fakeKV2.Path + "/key5": []byte("val5"),
- fakeKV3.Path + "/key6": []byte("val6"),
- }
- _, name1 := path.Split(fakeListItem1.Path)
- _, name2 := path.Split(fakeListItem2.Path)
- _, name3 := path.Split(fakeListItem3.Path)
- tc.label = "GetAllSecrets - List Secrets - Valid"
- tc.names = []string{name1, name2, name3}
- tc.fakeBtsecretsGetResponses = []btwcutil.KV{fakeKV1, fakeKV2, fakeKV3}
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem1, fakeListItem2, fakeListItem3}
- tc.expectedResponse = fakeResponseBytes
- }
- // sad paths
- clientGetError := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- tc.label = "GetAllSecrets - Secret KVs - Client Error"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretFind{Path: new(invalidFolderPath)}
- tc.fakeBtsecretsListError = new("beyondtrustworkloadcredentials list error")
- tc.expectedError = new("failed to list secrets:")
- }
- nilSecret := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- }
- fakeListItem := btwcutil.KVListItem{
- Path: fakeKV.Path,
- }
- tc.label = "GetAllSecrets - Secret KVs - Nil Secret"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretFind{Path: new(invalidFolderPath)}
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem}
- tc.fakeBtsecretsGetResponse = fakeKV
- // Provider now returns NoSecretError when no results are found
- tc.expectedError = new("Secret does not exist")
- }
- invalidSecret := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- Secret: map[string]any{"invalid": func() {}},
- }
- fakeListItem := btwcutil.KVListItem{
- Path: fakeKV.Path,
- }
- tc.label = "GetAllSecrets - Secret KVs - Invalid Secret"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretFind{Path: new(invalidFolderPath)}
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{fakeListItem}
- tc.fakeBtsecretsGetResponse = fakeKV
- tc.expectedError = new("failed to marshal secret value for key")
- }
- clientListError := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- tc.label = "GetAllSecrets - List Secrets - Client Error"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.fakeBtsecretsListError = new("beyondtrustworkloadcredentials list error")
- tc.expectedError = new("failed to list secrets:")
- }
- invalidFindRegex := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- tc.label = "GetAllSecrets - List Secrets - Invalid Find RegExp"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretFind{Name: &esv1.FindName{RegExp: "[invalid-regex"}}
- tc.expectedError = new("invalid name regexp")
- }
- clientGetErrorInList := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- tc.label = "GetAllSecrets - List Secrets - Get KVs - Client Error"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{{}}
- tc.fakeBtsecretsGetError = new("beyondtrustworkloadcredentials get error in list")
- tc.expectedError = new("failed to get secret at path")
- }
- nilSecretInList := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- }
- tc.label = "GetAllSecrets - List Secrets - Get KVs - Nil Secret"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.fakeBtsecretsGetResponse = fakeKV
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{{Path: fakeKV.Path}}
- // In list mode, skip missing entries; when no results are found, return NoSecretError
- tc.expectedError = new("Secret does not exist")
- }
- invalidSecretInList := func(tc *beyondtrustworkloadcredentialsGetAllSecretsTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- Secret: map[string]any{"invalid": func() {}},
- }
- tc.label = "GetAllSecrets - List Secrets - Get KVs - Invalid"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.fakeBtsecretsGetResponse = fakeKV
- tc.fakeBtsecretsListResponse = []btwcutil.KVListItem{{Path: fakeKV.Path}}
- tc.expectedError = new("failed to marshal secret value for key")
- }
- testCases := []*beyondtrustworkloadcredentialsGetAllSecretsTestCase{
- // happy paths
- makeValidGetAllSecretsTestCaseWithValues(validSecretKVs),
- makeValidGetAllSecretsTestCaseWithMultiValues(validNamedSecrets),
- makeValidGetAllSecretsTestCaseWithMultiValues(validAllSecrets),
- // sad paths
- makeValidGetAllSecretsTestCaseWithValues(clientGetError),
- makeValidGetAllSecretsTestCaseWithValues(nilSecret),
- makeValidGetAllSecretsTestCaseWithValues(invalidSecret),
- makeValidGetAllSecretsTestCaseWithValues(clientListError),
- makeValidGetAllSecretsTestCaseWithValues(invalidFindRegex),
- makeValidGetAllSecretsTestCaseWithValues(clientGetErrorInList),
- makeValidGetAllSecretsTestCaseWithValues(nilSecretInList),
- makeValidGetAllSecretsTestCaseWithValues(invalidSecretInList),
- }
- c := Client{store: &esv1.BeyondtrustWorkloadCredentialsProvider{}}
- for i, tc := range testCases {
- t.Run(tc.label, func(t *testing.T) {
- c.beyondtrustWorkloadCredentialsClient = tc.fakeBtsecretsClient
- c.store.FolderPath = *tc.folderPath
- out, err := c.GetAllSecrets(context.Background(), tc.remoteRef)
- // assert error
- if tc.expectedError == nil && err != nil {
- t.Errorf("[%d] unexpected error: expected nil, got %q", i, err.Error())
- }
- if tc.expectedError != nil && !ErrorContains(err, *tc.expectedError) {
- t.Errorf("[%d] unexpected error: expected %q, got %q", i, *tc.expectedError, err)
- }
- // assert response
- if tc.expectedResponse == nil && out != nil {
- t.Errorf("[%d] unexpected response: expected nil, got %#v", i, out)
- }
- if tc.expectedResponse != nil && !cmp.Equal(out, tc.expectedResponse) {
- t.Errorf("[%d] unexpected response: expected %#v, got %#v", i, tc.expectedResponse, out)
- }
- })
- }
- }
- func TestGetSecretMap(t *testing.T) {
- // happy paths
- validSecretMap := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- Secret: map[string]any{"username": "admin", "password": "secret123", "port": 5432},
- }
- tc.label = "GetSecretMap - Valid"
- tc.fakeBtsecretsResponse = fakeKV
- // For GetSecretMap tests, we use a map comparison, not a single byte response
- // This test will use a custom comparison below
- }
- validSecretMapWithTypes := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", validFolderPath, validSecretName),
- Secret: map[string]any{
- "username": "admin",
- "config": map[string]string{"env": "prod", "region": "us-east-1"},
- },
- }
- tc.label = "GetSecretMap - Valid With Complex Types"
- tc.fakeBtsecretsResponse = fakeKV
- }
- // sad paths
- clientError := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- tc.label = "GetSecretMap - Client Error"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName}
- tc.fakeBtsecretsError = new("beyondtrustworkloadcredentials error")
- tc.expectedError = new("failed to get secret")
- }
- nilSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- }
- tc.label = "GetSecretMap - Nil Secret"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName}
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedError = new("secret value is nil")
- }
- invalidSecret := func(tc *beyondtrustworkloadcredentialsGetSecretTestCase) {
- fakeKV := &btwcutil.KV{
- Path: fmt.Sprintf("%s/%s", invalidFolderPath, invalidSecretName),
- Secret: map[string]any{
- "valid": "test",
- "invalid": func() {}, // Unmarshalable type
- },
- }
- tc.label = "GetSecretMap - Invalid"
- tc.name = new(invalidSecretName)
- tc.folderPath = new(invalidFolderPath)
- tc.remoteRef = esv1.ExternalSecretDataRemoteRef{Key: invalidSecretName}
- tc.fakeBtsecretsResponse = fakeKV
- tc.expectedError = new("failed to marshal secret value for key")
- }
- testCases := []*beyondtrustworkloadcredentialsGetSecretTestCase{
- // happy paths
- makeValidGetSecretTestCaseWithValues(validSecretMap),
- makeValidGetSecretTestCaseWithValues(validSecretMapWithTypes),
- // sad paths
- makeValidGetSecretTestCaseWithValues(clientError),
- makeValidGetSecretTestCaseWithValues(nilSecret),
- makeValidGetSecretTestCaseWithValues(invalidSecret),
- }
- c := Client{store: &esv1.BeyondtrustWorkloadCredentialsProvider{}}
- for i, tc := range testCases {
- t.Run(tc.label, func(t *testing.T) {
- c.beyondtrustWorkloadCredentialsClient = tc.fakeBtsecretsClient
- c.store.FolderPath = *tc.folderPath
- out, err := c.GetSecretMap(context.Background(), tc.remoteRef)
- // assert error
- if tc.expectedError == nil && err != nil {
- t.Errorf("[%d] unexpected error: expected nil, got %q", i, err.Error())
- }
- if tc.expectedError != nil && !ErrorContains(err, *tc.expectedError) {
- t.Errorf("[%d] unexpected error: expected %q, got %q", i, *tc.expectedError, err)
- }
- // For happy path tests with complex types, just verify no error and non-nil response
- if i < 2 && tc.expectedError == nil {
- if out == nil {
- t.Errorf("[%d] unexpected response: expected non-nil map, got nil", i)
- }
- if len(out) == 0 {
- t.Errorf("[%d] unexpected response: expected non-empty map, got empty", i)
- }
- }
- })
- }
- }
|