diff --git a/changelog/fragments/helm-overrides-template.yaml b/changelog/fragments/helm-overrides-template.yaml new file mode 100644 index 00000000000..9a2cd4adee0 --- /dev/null +++ b/changelog/fragments/helm-overrides-template.yaml @@ -0,0 +1,6 @@ +# entries is a list of entries to include in +# release notes and/or the migration guide +entries: + - description: > + For helm-based operators, support go `text/template` expansion of override values + kind: addition diff --git a/go.mod b/go.mod index fafd3f49965..5a771785064 100644 --- a/go.mod +++ b/go.mod @@ -6,6 +6,7 @@ require ( github.com/blang/semver/v4 v4.0.0 github.com/fatih/structtag v1.1.0 github.com/go-logr/logr v0.4.0 + github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 github.com/iancoleman/strcase v0.0.0-20191112232945-16388991a334 github.com/kr/text v0.2.0 github.com/markbates/inflect v1.0.4 diff --git a/go.sum b/go.sum index 5e52c8fc55d..103a2751a6d 100644 --- a/go.sum +++ b/go.sum @@ -409,6 +409,7 @@ github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= +github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0 h1:p104kn46Q8WdvHunIJ9dAyjPVtrBPhSr3KT2yUst43I= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= github.com/gobuffalo/envy v1.6.5/go.mod h1:N+GkhhZ/93bGZc6ZKhJLP6+m+tCNPKwgSpH9kaifseQ= github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= diff --git a/internal/helm/watches/watches.go b/internal/helm/watches/watches.go index c02413abb32..5f2b7d617cc 100644 --- a/internal/helm/watches/watches.go +++ b/internal/helm/watches/watches.go @@ -15,12 +15,15 @@ package watches import ( + "bytes" "errors" "fmt" "io" "io/ioutil" "os" + "text/template" + sprig "github.com/go-task/slim-sprig" "helm.sh/helm/v3/pkg/chartutil" "k8s.io/apimachinery/pkg/runtime/schema" "sigs.k8s.io/yaml" @@ -110,21 +113,34 @@ func LoadReader(reader io.Reader) ([]Watch, error) { trueVal := true w.WatchDependentResources = &trueVal } - w.OverrideValues = expandOverrideEnvs(w.OverrideValues) + w.OverrideValues, err = expandOverrideValues(w.OverrideValues) + if err != nil { + return nil, fmt.Errorf("failed to expand override values: %v", err) + } watches[i] = w } return watches, nil } -func expandOverrideEnvs(in map[string]string) map[string]string { +func expandOverrideValues(in map[string]string) (map[string]string, error) { if in == nil { - return nil + return nil, nil } out := make(map[string]string) for k, v := range in { - out[k] = os.ExpandEnv(v) + envV := os.ExpandEnv(v) + + v := &bytes.Buffer{} + tmplV, err := template.New(k).Funcs(sprig.TxtFuncMap()).Parse(envV) + if err != nil { + return nil, fmt.Errorf("invalid template string %q: %v", envV, err) + } + if err := tmplV.Execute(v, nil); err != nil { + return nil, fmt.Errorf("failed to execute template %q: %v", envV, err) + } + out[k] = v.String() } - return out + return out, nil } func verifyGVK(gvk schema.GroupVersionKind) error { diff --git a/internal/helm/watches/watches_test.go b/internal/helm/watches/watches_test.go index cdea650c4ee..7f543f39105 100644 --- a/internal/helm/watches/watches_test.go +++ b/internal/helm/watches/watches_test.go @@ -55,7 +55,7 @@ func TestLoadReader(t *testing.T) { expectErr: false, }, { - name: "valid with override expansion", + name: "valid with override env expansion", data: `--- - group: mygroup version: v1alpha1 @@ -76,6 +76,48 @@ func TestLoadReader(t *testing.T) { }, expectErr: false, }, + { + name: "valid with override template expansion", + data: `--- +- group: mygroup + version: v1alpha1 + kind: MyKind + chart: ../../../internal/plugins/helm/v1/chartutil/testdata/test-chart + watchDependentResources: false + overrideValues: + repo: '{{ ("$MY_IMAGE" | split ":")._0 }}' + tag: '{{ ("$MY_IMAGE" | split ":")._1 }}' +`, + env: map[string]string{"MY_IMAGE": "quay.io/operator-framework/helm-operator:latest"}, + expectWatches: []Watch{ + { + GroupVersionKind: schema.GroupVersionKind{Group: "mygroup", Version: "v1alpha1", Kind: "MyKind"}, + ChartDir: "../../../internal/plugins/helm/v1/chartutil/testdata/test-chart", + WatchDependentResources: &falseVal, + OverrideValues: map[string]string{ + "repo": "quay.io/operator-framework/helm-operator", + "tag": "latest", + }, + }, + }, + expectErr: false, + }, + + { + name: "invalid with override template expansion", + data: `--- +- group: mygroup + version: v1alpha1 + kind: MyKind + chart: ../../../internal/plugins/helm/v1/chartutil/testdata/test-chart + watchDependentResources: false + overrideValues: + repo: '{{ ("$MY_IMAGE" | split ":")._0 }}' + tag: '{{ ("$MY_IMAGE" | split ":")._1' +`, + env: map[string]string{"MY_IMAGE": "quay.io/operator-framework/helm-operator:latest"}, + expectErr: true, + }, { name: "multiple gvk", data: `---