Skip to content

Commit

Permalink
command: add render command
Browse files Browse the repository at this point in the history
allows testing how the template will be rendered
  • Loading branch information
Peter McAtominey committed Oct 10, 2017
1 parent d156de5 commit fd95da4
Show file tree
Hide file tree
Showing 6 changed files with 130 additions and 17 deletions.
16 changes: 16 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,22 @@ Full example:
levant deploy -log-level=debug -address=nomad.devoops -var-file=var.yaml -var 'var=test' example.nomad
```

### Command: `render`

`render` allows rendering of a Nomad job template without deploying, useful when testing or debugging. An example render command would look like `levant render -out job.nomad job.nomad.tpl`, options:

* **-var-file** (string: "") The variables file to render the template with.

* **-output** (string: "") The path to write the rendered template to. The template will be rendered to stdout if this is not set.

Like `deploy`, the `render` command also supports passing variables individually on the command line. Multiple vars can be passed in the format of `-var 'key=value'`. Variables passed via the command line take precedence over the same variable declared within a passed variable file.

Full example:

```
levant render -var-file=var.yaml -var 'var=test' render example.nomad
```

### Command: `version`

The `version` command displays build information about the running binary, including the release version.
2 changes: 1 addition & 1 deletion command/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func (c *DeployCommand) Run(args []string) int {

logging.SetLevel(log)

job, err = levant.RenderTemplate(args[0], variables, &c.Meta.flagVars)
job, err = levant.RenderJob(args[0], variables, &c.Meta.flagVars)
if err != nil {
c.UI.Error(fmt.Sprintf("[ERROR] levant/command: %v", err))
return 1
Expand Down
90 changes: 90 additions & 0 deletions command/render.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
package command

import (
"bytes"
"fmt"
"os"
"strings"

"github.com/jrasell/levant/levant"
)

// RenderCommand is the command implementation that allows users to render a
// Nomad job template based on passed templates and variables.
type RenderCommand struct {
args []string
Meta
}

// Help provides the help information for the template command.
func (c *RenderCommand) Help() string {
helpText := `
Usage: levant render [options] TEMPLATE
Render a Nomad job template, useful for debugging.
General Options:
-out=<file>
Specify the path to write the rendered template out to, if a file exists at
the specified path it will be truncated before rendering. The template will be
rendered to stdout if this is not set.
-var-file=<file>
The variables file to render the template with.
`
return strings.TrimSpace(helpText)
}

// Synopsis is provides a brief summary of the template command.
func (c *RenderCommand) Synopsis() string {
return "Render a Nomad job from a template"
}

// Run triggers a run of the Levant template functions.
func (c *RenderCommand) Run(args []string) int {

var variables, outPath string
var err error
var tpl *bytes.Buffer

flags := c.Meta.FlagSet("render", FlagSetVars)
flags.Usage = func() { c.UI.Output(c.Help()) }

flags.StringVar(&variables, "var-file", "", "")
flags.StringVar(&outPath, "out", "", "")

if err = flags.Parse(args); err != nil {
return 1
}

args = flags.Args()

if len(args) != 1 {
c.UI.Error(c.Help())
return 1
}

tpl, err = levant.RenderTemplate(args[0], variables, &c.Meta.flagVars)
if err != nil {
c.UI.Error(fmt.Sprintf("[ERROR] levant/command: %v", err))
return 1
}

out := os.Stdout
if outPath != "" {
out, err = os.Create(outPath)
if err != nil {
c.UI.Error(fmt.Sprintf("[ERROR] levant/command: %v", err))
return 1
}
}

_, err = tpl.WriteTo(out)
if err != nil {
c.UI.Error(fmt.Sprintf("[ERROR] levant/command: %v", err))
return 1
}

return 0
}
5 changes: 5 additions & 0 deletions commands.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ func Commands(metaPtr *command.Meta) map[string]cli.CommandFactory {
Meta: meta,
}, nil
},
"render": func() (cli.Command, error) {
return &command.RenderCommand{
Meta: meta,
}, nil
},
"version": func() (cli.Command, error) {
ver := version.Version
rel := version.VersionPrerelease
Expand Down
22 changes: 12 additions & 10 deletions levant/templater.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,20 @@ const (
ymlVarExtension = ".yml"
)

func RenderJob(templateFile, variableFile string, flagVars *map[string]string) (job *nomad.Job, err error) {
var tpl *bytes.Buffer
tpl, err = RenderTemplate(templateFile, variableFile, flagVars)
if err != nil {
return
}

job, err = jobspec.Parse(tpl)
return
}

// RenderTemplate is the main entry point to render the template based on the
// passed variables file.
func RenderTemplate(templateFile, variableFile string, flagVars *map[string]string) (job *nomad.Job, err error) {

var tpl *bytes.Buffer
func RenderTemplate(templateFile, variableFile string, flagVars *map[string]string) (tpl *bytes.Buffer, err error) {
ext := path.Ext(variableFile)

src, err := ioutil.ReadFile(templateFile)
Expand All @@ -43,9 +52,7 @@ func RenderTemplate(templateFile, variableFile string, flagVars *map[string]stri
tpl, err = renderYAMLVarsTemplate(string(src), variableFile, flagVars)
case "":
if len(*flagVars) == 0 {
logging.Debug("levant/template: no variables file or var flags, skipping templating")
tpl = bytes.NewBuffer(src)
break
}

logging.Debug("levant/templater: variable file not passed, using any passed CLI variables")
Expand All @@ -54,11 +61,6 @@ func RenderTemplate(templateFile, variableFile string, flagVars *map[string]stri
err = fmt.Errorf("variables file extension %v not supported", ext)
}

if err != nil {
return
}

job, err = jobspec.Parse(tpl)
return
}

Expand Down
12 changes: 6 additions & 6 deletions levant/templater_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ func TestTemplater_RenderTemplate(t *testing.T) {
fVars := make(map[string]string)

// Test basic TF template render.
job, err = RenderTemplate("test-fixtures/single_templated.nomad", "test-fixtures/test.tf", &fVars)
job, err = RenderJob("test-fixtures/single_templated.nomad", "test-fixtures/test.tf", &fVars)
if err != nil {
t.Fatal(err)
}
Expand All @@ -30,7 +30,7 @@ func TestTemplater_RenderTemplate(t *testing.T) {
}

// Test basic YAML template render.
job, err = RenderTemplate("test-fixtures/single_templated.nomad", "test-fixtures/test.yaml", &fVars)
job, err = RenderJob("test-fixtures/single_templated.nomad", "test-fixtures/test.yaml", &fVars)
if err != nil {
t.Fatal(err)
}
Expand All @@ -39,7 +39,7 @@ func TestTemplater_RenderTemplate(t *testing.T) {
}

// Test empty var-args and empty variable file render.
job, err = RenderTemplate("test-fixtures/none_templated.nomad", "", &fVars)
job, err = RenderJob("test-fixtures/none_templated.nomad", "", &fVars)
if err != nil {
t.Fatal(err)
}
Expand All @@ -49,7 +49,7 @@ func TestTemplater_RenderTemplate(t *testing.T) {

// Test var-args only render.
fVars["job_name"] = testJobName
job, err = RenderTemplate("test-fixtures/single_templated.nomad", "", &fVars)
job, err = RenderJob("test-fixtures/single_templated.nomad", "", &fVars)
if err != nil {
t.Fatal(err)
}
Expand All @@ -60,7 +60,7 @@ func TestTemplater_RenderTemplate(t *testing.T) {
// Test var-args and variables file render.
delete(fVars, "job_name")
fVars["datacentre"] = testDCName
job, err = RenderTemplate("test-fixtures/multi_templated.nomad", "test-fixtures/test.yaml", &fVars)
job, err = RenderJob("test-fixtures/multi_templated.nomad", "test-fixtures/test.yaml", &fVars)
if err != nil {
t.Fatal(err)
}
Expand All @@ -73,7 +73,7 @@ func TestTemplater_RenderTemplate(t *testing.T) {

// Test var-args only render.
fVars["job_name"] = testJobName
job, err = RenderTemplate("test-fixtures/missing_var.nomad", "", &fVars)
_, err = RenderTemplate("test-fixtures/missing_var.nomad", "", &fVars)
if err == nil {
t.Fatal("expected err to not be nil")
}
Expand Down

0 comments on commit fd95da4

Please sign in to comment.