Skip to content

Commit

Permalink
Merge pull request #210 from jrasell/f_gh_208
Browse files Browse the repository at this point in the history
Addition of .json as variable file format type.
  • Loading branch information
jrasell authored Jul 6, 2018
2 parents 749536e + d536a24 commit 8329c80
Show file tree
Hide file tree
Showing 7 changed files with 92 additions and 25 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ Levant is an open source templating and deployment tool for [HashiCorp Nomad](ht

* **Canary Auto Promotion**: In environments with advanced automation and alerting, automatic promotion of canary deployments may be desirable after a certain time threshold. Levant allows the user to specify a `canary-auto-promote` time period, which if reached with a healthy set of canaries, will automatically promote the deployment.

* **Multiple Variable File Formats**: Currently Levant supports `.tf`, `.yaml` and `.yml` file extensions for the declaration of template variables. *This is planned to increase in the near future.*
* **Multiple Variable File Formats**: Currently Levant supports `.json`, `.tf`, `.yaml`, and `.yml` file extensions for the declaration of template variables.

* **Auto Revert Checking**: In the event that a job deployment does not pass its healthy threshold and the job has auto-revert enabled; Levant will track the resulting rollback deployment so you can see the exact outcome of the deployment process.

Expand Down
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 8329c80

Please sign in to comment.