diff --git a/README.md b/README.md index 02a38af..24009cc 100644 --- a/README.md +++ b/README.md @@ -731,7 +731,7 @@ Fetch values from Kubernetes secrets: - `ref+k8s://NAMESPACE/SECRET_NAME/KEY[?kubeConfigPath=&kubeContext=]` Authentication to the Kubernetes cluster is done by referencing the local kubeconfig file. -The path to the kubeconfig can be specified as a URI parameter, read from the `KUBECONFIG` environment variable or the provider with attempt to read `$HOME/.kube/config`. +The path to the kubeconfig can be specified as a URI parameter, read from the `KUBECONFIG` environment variable or the provider will attempt to read `$HOME/.kube/config`. The Kubernetes context can be specified as a URI parameteter. Environment variables: @@ -792,7 +792,7 @@ That's not the business of vals. Instead, use vals solely for composing sets of values that are then input to another templating engine or data manipulation language like Jsonnet and CUE. -Note though, `vals` dose have support for simple string interpolation like usage. See [Expression Syntax](#expression-syntax) for more information. +Note though, `vals` does have support for simple string interpolation like usage. See [Expression Syntax](#expression-syntax) for more information. ### Merge diff --git a/pkg/providers/k8s/k8s.go b/pkg/providers/k8s/k8s.go index cfcd27d..d588cf3 100644 --- a/pkg/providers/k8s/k8s.go +++ b/pkg/providers/k8s/k8s.go @@ -21,21 +21,21 @@ type provider struct { KubeContext string } -func New(l *log.Logger, cfg api.StaticConfig) *provider { +func New(l *log.Logger, cfg api.StaticConfig) (*provider, error) { p := &provider{ log: l, } kubeConfig, err := getKubeConfig(cfg) if err != nil { - fmt.Printf("An error occurred getting the Kubeconfig path: %s\n", err) - return p + fmt.Printf("Unable to get a valid Kubeconfig path: %s\n", err) + return nil, err } p.KubeConfigPath = kubeConfig p.KubeContext = getKubeContext(cfg) - return p + return p, nil } func getKubeConfig(cfg api.StaticConfig) (string, error) { @@ -79,13 +79,13 @@ func (p *provider) GetString(path string) (string, error) { secretName := splits[1] key := splits[2] - if p.KubeConfigPath == "" { - return "", fmt.Errorf("No Kubeconfig path was found") + secretData, err := getSecret(namespace, secretName, p.KubeConfigPath, p.KubeContext, context.Background()) + if err != nil { + return "", fmt.Errorf("Unable to get secret %s/%s: %s", namespace, secretName, err) } - secretData, err := getSecret(namespace, secretName, p.KubeConfigPath, p.KubeContext, context.Background()) secret, exists := secretData[key] - if err != nil || !exists { + if !exists { return "", fmt.Errorf("Key %s does not exist in %s/%s", key, namespace, secretName) } diff --git a/pkg/stringmapprovider/stringmapprovider.go b/pkg/stringmapprovider/stringmapprovider.go index d0923a6..28e2a39 100644 --- a/pkg/stringmapprovider/stringmapprovider.go +++ b/pkg/stringmapprovider/stringmapprovider.go @@ -45,7 +45,7 @@ func New(l *log.Logger, provider api.StaticConfig) (api.LazyLoadedStringMapProvi case "gkms": return gkms.New(l, provider), nil case "k8s": - return k8s.New(l, provider), nil + return k8s.New(l, provider) } return nil, fmt.Errorf("failed initializing string-map provider from config: %v", provider) diff --git a/pkg/stringprovider/stringprovider.go b/pkg/stringprovider/stringprovider.go index 8a0a35b..cb8e0af 100644 --- a/pkg/stringprovider/stringprovider.go +++ b/pkg/stringprovider/stringprovider.go @@ -66,7 +66,7 @@ func New(l *log.Logger, provider api.StaticConfig) (api.LazyLoadedStringProvider case "gkms": return gkms.New(l, provider), nil case "k8s": - return k8s.New(l, provider), nil + return k8s.New(l, provider) } return nil, fmt.Errorf("failed initializing string provider from config: %v", provider) diff --git a/vals.go b/vals.go index c5b4f2d..8d48df2 100644 --- a/vals.go +++ b/vals.go @@ -251,8 +251,7 @@ func (r *Runtime) prepare() (*expansion.ExpandRegexMatch, error) { p := gkms.New(r.logger, conf) return p, nil case ProviderK8s: - p := k8s.New(r.logger, conf) - return p, nil + return k8s.New(r.logger, conf) } return nil, fmt.Errorf("no provider registered for scheme %q", scheme) } diff --git a/vals_k8s_test.go b/vals_k8s_test.go new file mode 100644 index 0000000..60b7ea0 --- /dev/null +++ b/vals_k8s_test.go @@ -0,0 +1,69 @@ +package vals + +import ( + "fmt" + "os" + "testing" + + "github.com/google/go-cmp/cmp" +) + +func TestValues_k8s(t *testing.T) { + // Setup: + // create a local Kubernetes cluster using minikube: + // minikube start + // create a namespace: + // kubectl create namespace test-namespace + // create a secret: + // kubectl create secret generic mysecret -n test-namespace --from-literal=key=p4ssw0rd + + type testcase struct { + template map[string]interface{} + expected map[string]interface{} + } + + namespace := "test-namespace" + key := "key" + homeDir, _ := os.UserHomeDir() + + testcases := []testcase{ + { + template: map[string]interface{}{ + "test_key": fmt.Sprintf("secretref+k8s://%s/%s/%s", namespace, "mysecret", key), + }, + expected: map[string]interface{}{ + "test_key": "p4ssw0rd", + }, + }, + { + template: map[string]interface{}{ + "test_key": fmt.Sprintf("secretref+k8s://%s/%s/%s?kubeContext=minikube", namespace, "mysecret", key), + }, + expected: map[string]interface{}{ + "test_key": "p4ssw0rd", + }, + }, + { + template: map[string]interface{}{ + "test_key": fmt.Sprintf("secretref+k8s://%s/%s/%s?kubeContext=minikube&kubeConfigPath=%s/.kube/config", namespace, "mysecret", key, homeDir), + }, + expected: map[string]interface{}{ + "test_key": "p4ssw0rd", + }, + }, + } + + for i := range testcases { + tc := testcases[i] + t.Run(fmt.Sprintf("%d", i), func(t *testing.T) { + vals, err := Eval(tc.template) + if err != nil { + t.Fatalf("%v", err) + } + diff := cmp.Diff(tc.expected, vals) + if diff != "" { + t.Errorf("unexpected diff: %s", diff) + } + }) + } +}