Skip to content

Commit

Permalink
feat(tmpl): fails when key does not exist (#916)
Browse files Browse the repository at this point in the history
The templates used in Feature SDK are not intended (at least right now) to provide conditional rendering like in Helm. Thus we should fail fast if the Feature's underlying map does not provide the key referred to in a template. 

This is achieved by passing the parsing option (missingkey=error) to built-in Golang templating.

> [!NOTE]
> This works out of the box with `struct`s but we should also fail when dealing with `map`s.
  • Loading branch information
bartoszmajsak authored Mar 13, 2024
1 parent 623285e commit e87c2a5
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 3 deletions.
5 changes: 4 additions & 1 deletion pkg/feature/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,10 @@ func (t *templateManifest) Process(data any) ([]*unstructured.Unstructured, erro
return nil, fmt.Errorf("failed to create file: %w", err)
}

tmpl, err := template.New(t.name).Funcs(template.FuncMap{"ReplaceChar": ReplaceChar}).Parse(string(content))
tmpl, err := template.New(t.name).
Option("missingkey=error").
Funcs(template.FuncMap{"ReplaceChar": ReplaceChar}).
Parse(string(content))
if err != nil {
return nil, fmt.Errorf("failed to parse template: %w", err)
}
Expand Down
21 changes: 19 additions & 2 deletions pkg/feature/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,7 @@ data:
})

Describe("Templated Manifest Processing", func() {
BeforeEach(func() {
resourceYaml := `
resourceYaml := `
apiVersion: v1
kind: ConfigMap
metadata:
Expand All @@ -85,11 +84,29 @@ metadata:
data:
key: Data
`

BeforeEach(func() {
path = "path/to/template.yaml"
err := afero.WriteFile(inMemFS.Afs, path, []byte(resourceYaml), 0644)
Expect(err).ToNot(HaveOccurred())
})

It("should fail when template refers to non existing key", func() {
// given
pathToBrokenTpl := filepath.Join("broken", path)
Expect(afero.WriteFile(inMemFS.Afs, pathToBrokenTpl, []byte(resourceYaml+"\n {{ .NotExistingKey }}"), 0644)).To(Succeed())
data := map[string]string{
"TargetNamespace": "template-ns",
}
manifest := feature.CreateTemplateManifestFrom(inMemFS, pathToBrokenTpl)

// when
_, err := manifest.Process(data)

// then
Expect(err).Should(MatchError(ContainSubstring("at <.NotExistingKey>: map has no entry for key")))
})

It("should substitute target namespace in the templated manifest", func() {
// given
data := feature.Spec{
Expand Down

0 comments on commit e87c2a5

Please sign in to comment.