/* 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 ovh import ( "context" "fmt" "reflect" "testing" kclient "sigs.k8s.io/controller-runtime/pkg/client" esv1 "github.com/external-secrets/external-secrets/apis/externalsecrets/v1" "github.com/external-secrets/external-secrets/providers/v1/ovh/fake" ) func TestGetAllSecrets(t *testing.T) { path2 := "pattern2/test" slashPath := "pattern//slash" emptySecretPath := "empty" nilSecretPath := "nil" noMatchRegexp := "^noMatch.*$" invalidRegexp := "\\wa\\w([a]" testCases := map[string]struct { should map[string][]byte errshould string kube kclient.Client refFind esv1.ExternalSecretFind okmsClient fake.FakeOkmsClient }{ "Empty Secret Found": { errshould: fmt.Sprintf("failed to retrieve multiple secrets: failed to retrieve secret at path %q: secret version data is missing", emptySecretPath+"/empty-secret"), refFind: esv1.ExternalSecretFind{ Path: &emptySecretPath, }, }, "Nil Secret Found": { errshould: fmt.Sprintf("failed to retrieve multiple secrets: failed to retrieve secret at path %q: secret version data is missing", nilSecretPath+"/nil-secret"), refFind: esv1.ExternalSecretFind{ Path: &nilSecretPath, }, }, "Invalid Regex": { errshould: fmt.Sprintf("failed to retrieve multiple secrets: could not parse regex: error parsing regexp: missing closing ): `%s`", invalidRegexp), refFind: esv1.ExternalSecretFind{ Name: &esv1.FindName{ RegExp: invalidRegexp, }, }, }, "Empty Regex": { should: map[string][]byte{ "mysecret": []byte(`{"key1":"value1","key2":"value2"}`), "nested-secret": []byte(`{"users":{"alice":{"age":"23"},"baptist":{"age":"27"}}}`), "pattern2/test/test-secret": []byte("{\"key4\":\"value4\"}"), "pattern2/test/test.secret": []byte("{\"key5\":\"value5\"}"), "pattern2/secret": []byte("{\"key6\":\"value6\"}"), }, refFind: esv1.ExternalSecretFind{ Name: &esv1.FindName{ RegExp: "", }, }, }, "No Regexp Match": { refFind: esv1.ExternalSecretFind{ Name: &esv1.FindName{ RegExp: noMatchRegexp, }, }, should: map[string][]byte{}, }, "Regex pattern containing '.' or '-' only": { should: map[string][]byte{ "nested-secret": []byte(`{"users":{"alice":{"age":"23"},"baptist":{"age":"27"}}}`), "pattern2/test/test-secret": []byte("{\"key4\":\"value4\"}"), "pattern2/test/test.secret": []byte("{\"key5\":\"value5\"}"), }, refFind: esv1.ExternalSecretFind{ Name: &esv1.FindName{ RegExp: ".*[.-].*", }, }, }, "Path pattern2/test": { should: map[string][]byte{ "pattern2/test/test-secret": []byte("{\"key4\":\"value4\"}"), "pattern2/test/test.secret": []byte("{\"key5\":\"value5\"}"), }, refFind: esv1.ExternalSecretFind{ Path: &path2, }, }, "Path pattern//wrong": { should: map[string][]byte{ "/pattern2/test/testsecret": []byte("{\"key4\":\"value4\"}"), "pattern2/test/test//secret": []byte("{\"key5\":\"value5\"}"), }, refFind: esv1.ExternalSecretFind{ Path: &slashPath, }, errshould: "failed to retrieve multiple secrets: invalid path \"pattern//slash\": cannot start with a / or contain a //", }, "Secrets found without path": { should: map[string][]byte{ "mysecret": []byte(`{"key1":"value1","key2":"value2"}`), "nested-secret": []byte(`{"users":{"alice":{"age":"23"},"baptist":{"age":"27"}}}`), "pattern2/test/test-secret": []byte("{\"key4\":\"value4\"}"), "pattern2/test/test.secret": []byte("{\"key5\":\"value5\"}"), "pattern2/secret": []byte("{\"key6\":\"value6\"}"), }, refFind: esv1.ExternalSecretFind{ Path: nil, }, }, } ctx := context.Background() for name, testCase := range testCases { t.Run(name, func(t *testing.T) { cl := &ovhClient{ okmsClient: testCase.okmsClient, kube: testCase.kube, } secrets, err := cl.GetAllSecrets(ctx, testCase.refFind) if testCase.errshould != "" { if err == nil { t.Errorf("\nexpected value: %s\nactual value: \n\n", testCase.errshould) } else if err.Error() != testCase.errshould { t.Errorf("\nexpected value: %s\nactual value: %v\n\n", testCase.errshould, err) } return } else if err != nil { t.Errorf("\nunexpected error: %v\n\n", err) return } if !reflect.DeepEqual(testCase.should, secrets) { t.Errorf("\nexpected value: %v\nactual value: %v\n\n", convertByteMapToStringMap(testCase.should), convertByteMapToStringMap(secrets)) } }) } } func convertByteMapToStringMap(m map[string][]byte) map[string]string { newMap := make(map[string]string) for key, value := range m { newMap[key] = string(value) } return newMap }