From fa4a8c4744777899a48b9a7338a1f492bda7d4de Mon Sep 17 00:00:00 2001 From: Peter McAtominey Date: Thu, 5 Oct 2017 15:54:23 +0100 Subject: [PATCH] templater: fail rendering if a variable is not set previously the default behaviour of text/template was used which would print the string "", this could lead to a situation where an job file appears valid but would fail to run --- levant/templater.go | 11 +++-- levant/templater_test.go | 11 +++++ levant/test-fixtures/missing_var.nomad | 56 ++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 levant/test-fixtures/missing_var.nomad diff --git a/levant/templater.go b/levant/templater.go index bf566e4b4..cd5a4d46c 100644 --- a/levant/templater.go +++ b/levant/templater.go @@ -85,7 +85,7 @@ func renderTFTemplte(src, variableFile string, flagVars *map[string]string) (tpl mergedVars := helper.VariableMerge(&variables, flagVars) // Setup the template file for rendering - t := template.New("jobTemplate").Delims("[[", "]]") + t := newTemplate() if t, err = t.Parse(src); err != nil { return @@ -117,7 +117,7 @@ func renderYAMLVarsTemplate(src, variableFile string, flagVars *map[string]strin mergedVars := helper.VariableMerge(&variables, flagVars) // Setup the template file for rendering - t := template.New("jobTemplate").Delims("[[", "]]") + t := newTemplate() if t, err = t.Parse(string(src)); err != nil { return } @@ -134,7 +134,7 @@ func readJobFile(src string, flagVars *map[string]string) (tpl *bytes.Buffer, er tpl = &bytes.Buffer{} // Setup the template file for rendering - t := template.New("jobTemplate").Delims("[[", "]]") + t := newTemplate() if t, err = t.Parse(src); err != nil { return } @@ -145,3 +145,8 @@ func readJobFile(src string, flagVars *map[string]string) (tpl *bytes.Buffer, er return tpl, nil } + +// newTemplate returns an empty template with default options set +func newTemplate() *template.Template { + return template.New("jobTemplate").Delims("[[", "]]").Option("missingkey=error") +} diff --git a/levant/templater_test.go b/levant/templater_test.go index 1780b3202..f076f5f2e 100644 --- a/levant/templater_test.go +++ b/levant/templater_test.go @@ -1,6 +1,7 @@ package levant import ( + "strings" "testing" nomad "github.com/hashicorp/nomad/api" @@ -69,4 +70,14 @@ func TestTemplater_RenderTemplate(t *testing.T) { if job.Datacenters[0] != testDCName { t.Fatalf("expected %s but got %v", testDCName, job.Datacenters[0]) } + + // Test var-args only render. + fVars["job_name"] = testJobName + job, err = RenderTemplate("test-fixtures/missing_var.nomad", "", &fVars) + if err == nil { + t.Fatal("expected err to not be nil") + } + if !strings.Contains(err.Error(), "binary_url") { + t.Fatal("expected err to mention missing var (binary_url)") + } } diff --git a/levant/test-fixtures/missing_var.nomad b/levant/test-fixtures/missing_var.nomad new file mode 100644 index 000000000..f07ba5a0a --- /dev/null +++ b/levant/test-fixtures/missing_var.nomad @@ -0,0 +1,56 @@ +job "[[.job_name]]" { + datacenters = ["dc1"] + type = "service" + update { + max_parallel = 1 + min_healthy_time = "10s" + healthy_deadline = "1m" + auto_revert = true + } + + group "cache" { + count = 1 + restart { + attempts = 10 + interval = "5m" + delay = "25s" + mode = "delay" + } + ephemeral_disk { + size = 300 + } + task "redis" { + artifact { + # .binary_url is not set + source = "[[ .binary_url ]]" + } + + driver = "docker" + config { + image = "redis:3.2" + port_map { + db = 6379 + } + } + resources { + cpu = 500 + memory = 256 + network { + mbits = 10 + port "db" {} + } + } + service { + name = "global-redis-check" + tags = ["global", "cache"] + port = "db" + check { + name = "alive" + type = "tcp" + interval = "10s" + timeout = "2s" + } + } + } + } +}