Skip to content

Commit

Permalink
refactor: switch per string template substitution
Browse files Browse the repository at this point in the history
  • Loading branch information
rajiteh authored and Raj Perera committed Feb 19, 2022
1 parent d5d2cae commit ddb4e5e
Show file tree
Hide file tree
Showing 3 changed files with 57 additions and 19 deletions.
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ require (
github.com/stretchr/testify v1.7.0
go.mozilla.org/sops/v3 v3.6.1
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
helm.sh/helm/v3 v3.5.1
k8s.io/api v0.21.3
k8s.io/apimachinery v0.21.3
Expand Down
70 changes: 54 additions & 16 deletions pkg/target/target.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@ import (
"k8s.io/apimachinery/pkg/util/sets"

"github.com/Masterminds/sprig/v3"
goyaml "gopkg.in/yaml.v3"
)

var (
Expand Down Expand Up @@ -544,28 +543,67 @@ func tplFuncMap() template.FuncMap {
}

func processTemplateValues(valuesMap map[string]interface{}, templateContext map[string]interface{}) (map[string]interface{}, error) {
var tplResult bytes.Buffer

valuesMapStr, err := goyaml.Marshal(valuesMap)
tplFn := template.New("values").Funcs(tplFuncMap()).Option("missingkey=error")
tplResult, err := templateSubstitutions(valuesMap, templateContext, tplFn)
if err != nil {
return nil, err
}

tpl, err := template.New("values").Funcs(tplFuncMap()).Option("missingkey=error").Parse(string(valuesMapStr))
if err != nil {
return nil, err
compiledYaml, ok := tplResult.(map[string]interface{})
if !ok {
return nil, fmt.Errorf("templated result was expected to be map[string]interface{}, got %T", tplResult)
}

if err := tpl.Execute(&tplResult, templateContext); err != nil {
return nil, err
}
return compiledYaml, nil
}

var compiledYaml map[string]interface{}
if err := goyaml.Unmarshal(tplResult.Bytes(), &compiledYaml); err != nil {
return nil, err
}
func templateSubstitutions(src interface{}, templateContext map[string]interface{}, tplFn *template.Template) (interface{}, error) {
switch tplVal := src.(type) {
case string:
tpl, err := tplFn.Parse(tplVal)
if err != nil {
return nil, err
}

return compiledYaml, nil
var tplBytes bytes.Buffer
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("failed to process template substitution for strung '%s': [%v]", tplVal, err)
}
}()
err = tpl.Execute(&tplBytes, templateContext)
if err != nil {
return nil, fmt.Errorf("failed to process template substitution for string '%s': [%v]", tplVal, err)
}
return tplBytes.String(), nil
case map[string]interface{}:
newMap := make(map[string]interface{})
for key, val := range tplVal {
processedKey, err := templateSubstitutions(key, templateContext, tplFn)
if err != nil {
return nil, err
}
keyAsString, ok := processedKey.(string)
if !ok {
return nil, fmt.Errorf("expected a string to be returned, but instead got [%T]", processedKey)
}
if newMap[keyAsString], err = templateSubstitutions(val, templateContext, tplFn); err != nil {
return nil, err
}
}
return newMap, nil
case []interface{}:
newSlice := make([]interface{}, len(tplVal))
for i, v := range tplVal {
newVal, err := templateSubstitutions(v, templateContext, tplFn)
if err != nil {
return nil, err
}
newSlice[i] = newVal
}
return newSlice, nil
default:
return tplVal, nil
}
}

func processLabelValues(valuesMap map[string]interface{}, clusterLabels map[string]string) error {
Expand Down
4 changes: 2 additions & 2 deletions pkg/target/target_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ helm:
fromAnnotation: "{{ .ClusterAnnotations.testAnnotation }}"
clusterNamespace: "{{ .ClusterNamespace }}"
fleetClusterName: "{{ .ClusterName }}"
reallyLongClusterName: kubernets.io/cluster/{{ index .ClusterLabels "really-long-label-name-with-many-characters-in-it" }}
reallyLongClusterName: kubernets.io/cluster/{{ index .ClusterLabels "really-long-label-name-with-many-many-characters-in-it" }}
customStruct:
- name: "{{ .Values.topLevel }}"
key1: value1
Expand Down Expand Up @@ -153,7 +153,7 @@ func TestProcessTemplateValues(t *testing.T) {
clusterLabels := map[string]string{
"name": "local",
"envType": "dev",
"really-long-label-name-with-many-characters-in-it": "foobar",
"really-long-label-name-with-many-many-characters-in-it": "foobar",
}

clusterAnnotations := map[string]string{
Expand Down

0 comments on commit ddb4e5e

Please sign in to comment.