Skip to content

Commit

Permalink
Addition of .json as variable file format type.
Browse files Browse the repository at this point in the history
Variable files can now be written in json using the .json file
extension and format. Documentation has also been updated to show
example.

Closes #208
  • Loading branch information
jrasell committed Jul 6, 2018
1 parent 749536e commit 914c8d5
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 24 deletions.
2 changes: 1 addition & 1 deletion command/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ General Options:
-var-file=<file>
Used in conjunction with the -job-file will deploy a templated job to your
Nomad cluster. You can repeat this flag multiple times to supply multiple var-files.
[default: levant.(yaml|yml|tf)]
[default: levant.(json|yaml|yml|tf)]
`
return strings.TrimSpace(helpText)
}
Expand Down
2 changes: 1 addition & 1 deletion command/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ General Options:
-var-file=<file>
The variables file to render the template with. You can repeat this flag multiple
times to supply multiple var-files. [default: levant.(yaml|yml|tf)]
times to supply multiple var-files. [default: levant.(json|yaml|yml|tf)]
`
return strings.TrimSpace(helpText)
}
Expand Down
88 changes: 66 additions & 22 deletions docs/templates.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,54 +4,98 @@ Alongside enhanced deployments of Nomad jobs; Levant provides templating functio

### Template Substitution

Levant currently supports `.tf`, `.yaml` and `.yml` file extensions for the declaration of template variables and uses opening and closing double squared brackets `[[ ]]` within the templated job file. This is to ensure there is no clash with existing Nomad interpolation which uses the standard `{{ }}` notation.
Levant currently supports `.json`, `.tf`, `.yaml`, and `.yml` file extensions for the declaration of template variables and uses opening and closing double squared brackets `[[ ]]` within the templated job file. This is to ensure there is no clash with existing Nomad interpolation which uses the standard `{{ }}` notation.

Example Job Template:
#### JSON

JSON as well as YML provide the most flexible variable file format. It allows for descriptive and well organised jobs and variables file as shown below.

Example job template:
```hcl
resources {
cpu = [[.resources.cpu]]
memory = [[.resources.memory]]
network {
mbits = [[.resources.network.mbits]]
}
}
```

Example variable file:
```json
{
"resources":{
"cpu":250,
"memory":512,
"network":{
"mbits":10
}
}
}
```

#### Terraform

Terraform (.tf) is probably the most inflexible of the variable file formats but does provide an easy to follow, descriptive manner in which to work. It may also be advantageous to use this format if you use Terraform for infrastructure as code thus allow you to use a consistant file format.

Example job template:
```hcl
resources {
cpu = [[.cpu]]
memory = [[.memory]]
cpu = [[.resources_cpu]]
memory = [[.resources_memory]]
network {
mbits = [[.mbits]]
mbits = [[.resources_network_mbits]]
}
}
```

`.tf` variables file:
Example variable file:
```hcl
variable "cpu" {
default = 250
variable "resources_cpu" {
description = "the CPU in MHz to allocate to the task group"
type = "string"
default = 250
}
variable "memory" {
default = 512
variable "resources_memory" {
description = "the memory in MB to allocate to the task group"
type = "string"
default = 512
}
variable "mbits" {
default = 10
variable "resources_network_mbits" {
description = "the network bandwidth in MBits to allocate"
type = "string"
default = 10
}
```

`.yaml` or `.yml` variables file:
```yaml
cpu: 250
memory: 512
mbits: 10
```
#### YAML

Render:
Example job template:
```hcl
resources {
cpu = 250
memory = 512
cpu = [[.resources.cpu]]
memory = [[.resources.memory]]
network {
mbits = 10
mbits = [[.resources.network.mbits]]
}
}
```

Example variable file:
```yaml
---
resources:
cpu: 250
memory: 512
network:
mbits: 10
```

### Template Functions

Levant's template rendering supports a number of functions which provide flexibility when deploying jobs. As with the variable substitution, it uses opening and closing double squared brackets `[[ ]]` as not to conflict with Nomad's templating standard. Levant parses job files using the [Go Template library](https://golang.org/pkg/text/template/) which makes available the features of that library as well as the functions described below.
Expand Down
4 changes: 4 additions & 0 deletions helper/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func GetDefaultVarFile() (varFile string) {
log.Debug().Msg("helper/files: using default var-file `levant.yml`")
return "levant.yml"
}
if _, err := os.Stat("levant.json"); !os.IsNotExist(err) {
log.Debug().Msg("helper/files: using default var-file `levant.json`")
return "levant.json"
}
if _, err := os.Stat("levant.tf"); !os.IsNotExist(err) {
log.Debug().Msg("helper/files: using default var-file `levant.tf`")
return "levant.tf"
Expand Down
18 changes: 18 additions & 0 deletions template/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package template

import (
"bytes"
"encoding/json"
"fmt"
"io/ioutil"
"path"
Expand Down Expand Up @@ -70,6 +71,8 @@ func RenderTemplate(templateFile string, variableFiles []string, addr string, fl
variables, err = t.parseTFVars(variableFile)
case yamlVarExtension, ymlVarExtension:
variables, err = t.parseYAMLVars(variableFile)
case jsonVarExtension:
variables, err = t.parseJSONVars(variableFile)
default:
err = fmt.Errorf("variables file extension %v not supported", ext)
}
Expand Down Expand Up @@ -98,6 +101,21 @@ func RenderTemplate(templateFile string, variableFiles []string, addr string, fl
return
}

func (t *tmpl) parseJSONVars(variableFile string) (variables map[string]interface{}, err error) {

jsonFile, err := ioutil.ReadFile(variableFile)
if err != nil {
return
}

variables = make(map[string]interface{})
if err = json.Unmarshal(jsonFile, &variables); err != nil {
return
}

return variables, nil
}

func (t *tmpl) parseTFVars(variableFile string) (variables map[string]interface{}, err error) {

c := &config.Config{}
Expand Down
1 change: 1 addition & 0 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ type tmpl struct {
}

const (
jsonVarExtension = ".json"
terraformVarExtension = ".tf"
yamlVarExtension = ".yaml"
ymlVarExtension = ".yml"
Expand Down

0 comments on commit 914c8d5

Please sign in to comment.