Skip to content

Commit

Permalink
Add support to render template from string
Browse files Browse the repository at this point in the history
Signed-off-by: Ivan Kolodiazhnyi <[email protected]>
  • Loading branch information
e0ne committed Dec 30, 2024
1 parent eb2fa5f commit 0a5260b
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 22 deletions.
40 changes: 25 additions & 15 deletions pkg/render/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ func RenderDir(manifestDir string, d *RenderData) ([]*unstructured.Unstructured,
return nil
}

objs, err := RenderTemplate(path, d)
objs, err := RenderFileTemplate(path, d)
if err != nil {
return err
}
Expand All @@ -77,10 +77,14 @@ func RenderDir(manifestDir string, d *RenderData) ([]*unstructured.Unstructured,
return out, nil
}

// RenderTemplate reads, renders, and attempts to parse a yaml or
func RenderTemplate(template string, d *RenderData) (*bytes.Buffer, error) {
return renderTemplate(template, d)
}

// RenderFileTemplate reads, renders, and attempts to parse a yaml or
// json file representing one or more k8s api objects
func RenderTemplate(path string, d *RenderData) ([]*unstructured.Unstructured, error) {
rendered, err := renderTemplate(path, d)
func RenderFileTemplate(path string, d *RenderData) ([]*unstructured.Unstructured, error) {
rendered, err := renderFileTemplate(path, d)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -112,8 +116,9 @@ func RenderTemplate(path string, d *RenderData) ([]*unstructured.Unstructured, e
return out, nil
}

func renderTemplate(path string, d *RenderData) (*bytes.Buffer, error) {
tmpl := template.New(path).Option("missingkey=error")
func renderTemplate(rawTemplate string, d *RenderData) (*bytes.Buffer, error) {

tmpl := template.New("template").Option("missingkey=error")
if d.Funcs != nil {
tmpl.Funcs(d.Funcs)
}
Expand All @@ -122,23 +127,28 @@ func renderTemplate(path string, d *RenderData) (*bytes.Buffer, error) {
tmpl.Funcs(template.FuncMap{"getOr": getOr, "isSet": isSet})
tmpl.Funcs(sprig.TxtFuncMap())

source, err := os.ReadFile(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to read manifest %s", path)
}

if _, err := tmpl.Parse(string(source)); err != nil {
return nil, errors.Wrapf(err, "failed to parse manifest %s as template", path)
if _, err := tmpl.Parse(rawTemplate); err != nil {
return nil, errors.Wrapf(err, "failed to parse manifest %s as template", rawTemplate)
}

rendered := bytes.Buffer{}
if err := tmpl.Execute(&rendered, d.Data); err != nil {
return nil, errors.Wrapf(err, "failed to render manifest %s", path)
return nil, errors.Wrapf(err, "failed to render manifest %s", rawTemplate)
}

return &rendered, nil
}

func renderFileTemplate(path string, d *RenderData) (*bytes.Buffer, error) {

source, err := os.ReadFile(path)
if err != nil {
return nil, errors.Wrapf(err, "failed to read manifest %s", path)
}

return renderTemplate(string(source[:]), d)
}

func formateDeviceList(devs []DeviceInfo) string {
out := ""
for _, dev := range devs {
Expand Down Expand Up @@ -232,7 +242,7 @@ func filterTemplates(toFilter map[string]string, path string, d *RenderData) err
}

// Render the template file
renderedData, err := renderTemplate(path, d)
renderedData, err := renderFileTemplate(path, d)
if err != nil {
return err
}
Expand Down
14 changes: 7 additions & 7 deletions pkg/render/render_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ func TestRenderSimple(t *testing.T) {

d := MakeRenderData()

o1, err := RenderTemplate("testdata/manifests/simple.yaml", &d)
o1, err := RenderFileTemplate("testdata/manifests/simple.yaml", &d)
g.Expect(err).NotTo(HaveOccurred())

g.Expect(o1).To(HaveLen(1))
Expand All @@ -36,7 +36,7 @@ func TestRenderSimple(t *testing.T) {
g.Expect(o1[0].MarshalJSON()).To(MatchJSON(expected))

// test that json parses the same
o2, err := RenderTemplate("testdata/manifests/simple.json", &d)
o2, err := RenderFileTemplate("testdata/manifests/simple.json", &d)
g.Expect(err).NotTo(HaveOccurred())
g.Expect(o2).To(Equal(o1))
}
Expand All @@ -47,7 +47,7 @@ func TestRenderMultiple(t *testing.T) {
p := "testdata/manifests/multiple.yaml"
d := MakeRenderData()

o, err := RenderTemplate(p, &d)
o, err := RenderFileTemplate(p, &d)
g.Expect(err).NotTo(HaveOccurred())

g.Expect(o).To(HaveLen(3))
Expand All @@ -64,19 +64,19 @@ func TestTemplate(t *testing.T) {

// Test that missing variables are detected
d := MakeRenderData()
_, err := RenderTemplate(p, &d)
_, err := RenderFileTemplate(p, &d)
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(HaveSuffix(`function "fname" not defined`))

// Set expected function (but not variable)
d.Funcs["fname"] = func(s string) string { return "test-" + s }
_, err = RenderTemplate(p, &d)
_, err = RenderFileTemplate(p, &d)
g.Expect(err).To(HaveOccurred())
g.Expect(err.Error()).To(HaveSuffix(`has no entry for key "Namespace"`))

// now we can render
d.Data["Namespace"] = "myns"
o, err := RenderTemplate(p, &d)
o, err := RenderFileTemplate(p, &d)
g.Expect(err).NotTo(HaveOccurred())

g.Expect(o[0].GetName()).To(Equal("test-podname"))
Expand All @@ -95,7 +95,7 @@ func TestTemplateWithEmptyObject(t *testing.T) {

d := MakeRenderData()
d.Data["Enable"] = true
o, err := RenderTemplate(p, &d)
o, err := RenderFileTemplate(p, &d)
g.Expect(err).NotTo(HaveOccurred())

g.Expect(len(o)).To(Equal(2))
Expand Down

0 comments on commit 0a5260b

Please sign in to comment.