diff --git a/workflow/template_validator.go b/workflow/template_validator.go index c8d8ba1b7..864706b39 100644 --- a/workflow/template_validator.go +++ b/workflow/template_validator.go @@ -4,8 +4,8 @@ import ( "bytes" "encoding/json" "fmt" - "html/template" "io/ioutil" + "text/template" "github.com/docker/distribution/reference" "github.com/pkg/errors" @@ -68,7 +68,7 @@ func RenderTemplate(templateID, templateData string, devices []byte) (string, er return "", err } - t := template.New("workflow-template") + t := template.New("workflow-template").Option("missingkey=error") _, err = t.Parse(string(templateData)) if err != nil { err = errors.Wrapf(err, errTemplateParsing, templateID) diff --git a/workflow/template_validator_test.go b/workflow/template_validator_test.go index bbd9af171..c371f86bb 100644 --- a/workflow/template_validator_test.go +++ b/workflow/template_validator_test.go @@ -6,7 +6,7 @@ import ( "strings" "testing" - "github.com/google/uuid" + "github.com/google/go-cmp/cmp" "github.com/stretchr/testify/assert" ) @@ -233,34 +233,84 @@ func TestValidateTemplate(t *testing.T) { func TestRenderTemplate(t *testing.T) { tests := []struct { - name string - hwAddress []byte - expectedError func(t *testing.T, err error) + name string + hwAddress []byte + templateID string + templateData string + expectedError func(t *testing.T, err error) + expectedTemplate string }{ { - name: "valid-hardware-address", - hwAddress: []byte("{\"device_1\":\"08:00:27:00:00:01\"}"), + name: "valid-hardware-address", + hwAddress: []byte("{\"device_1\":\"08:00:27:00:00:01\"}"), + templateID: "49748301-d0d9-4ee9-84df-b64e6e1ef3dd", + templateData: validTemplate, + expectedTemplate: ` +version: "0.1" +name: hello_world_workflow +global_timeout: 600 +tasks: + - name: "hello world" + worker: "08:00:27:00:00:01" + actions: + - name: "hello_world" + image: hello-world + timeout: 60 +`, }, { - name: "invalid-hardware-address", - hwAddress: []byte("{\"invalid_device\":\"08:00:27:00:00:01\"}"), + name: "invalid-hardware-address", + templateData: validTemplate, + hwAddress: []byte("{\"invalid_device\":\"08:00:27:00:00:01\"}"), expectedError: func(t *testing.T, err error) { if err == nil { t.Error("expected error, got nil") } - if !strings.Contains(err.Error(), "invalid hardware address: {\"invalid_device\":\"08:00:27:00:00:01\"}") { - t.Errorf("\nexpected err: %s\ngot: %s", "invalid hardware address: {\"invalid_device\":\"08:00:27:00:00:01\"}", err) + if !strings.Contains(err.Error(), `executing "workflow-template" at <.device_1>: map has no entry for key "device_1"`) { + t.Errorf("\nexpected err: %s\ngot: %s", `executing "workflow-template" at <.device_1>: map has no entry for key "device_1"`, err) } }, }, + { + name: "template with << should not be escaped in any way", + hwAddress: []byte("{\"device_1\":\"08:00:27:00:00:01\"}"), + templateID: "98788301-d0d9-4ee9-84df-b64e6e1ef1cc", + templateData: ` +version: "0.1" +name: hello_world_workflow +global_timeout: 600 +tasks: + - name: "hello world<<" + worker: "{{.device_1}}" + actions: + - name: "hello_world" + image: hello-world + timeout: 60 +`, + expectedTemplate: ` +version: "0.1" +name: hello_world_workflow +global_timeout: 600 +tasks: + - name: "hello world<<" + worker: "08:00:27:00:00:01" + actions: + - name: "hello_world" + image: hello-world + timeout: 60 +`, + }, } - templateID := uuid.New().String() for _, test := range tests { t.Run(test.name, func(t *testing.T) { - _, err := RenderTemplate(templateID, validTemplate, test.hwAddress) - if err != nil { + temp, err := RenderTemplate(test.templateID, test.templateData, test.hwAddress) + if test.expectedError != nil { test.expectedError(t, err) + return + } + if diff := cmp.Diff(test.expectedTemplate, temp); diff != "" { + t.Error(diff) } }) }