Skip to content

Commit

Permalink
Add the possibility to template playbooks (close #103)
Browse files Browse the repository at this point in the history
  • Loading branch information
dannymc129 authored and mhadam committed Jul 5, 2018
1 parent 5e416bb commit d3b7eda
Show file tree
Hide file tree
Showing 6 changed files with 73 additions and 10 deletions.
18 changes: 18 additions & 0 deletions integration/resources/good-postgres-with-template.yml
@@ -0,0 +1,18 @@
:targets:
- :name: "My Postgres database 1"
:type: postgres
:host: {{.host}}
:database: sql_runner_tests_1
:port: 5432
:username: {{.username}}
:password: {{.password}}
:ssl: false # SSL disabled by default
:variables:
:test_schema: sql_runner_tests
:timeFormat: "2006_01_02"
:steps:
- :name: Create schema and table
:queries:
- :name: Create schema and table
:file: postgres-sql/good/1.sql
:template: true
6 changes: 4 additions & 2 deletions sql_runner/consul_provider.go
Expand Up @@ -15,12 +15,14 @@ package main
type ConsulPlaybookProvider struct {
consulAddress string
consulKey string
variables map[string]string
}

func NewConsulPlaybookProvider(consulAddress, consulKey string) *ConsulPlaybookProvider {
func NewConsulPlaybookProvider(consulAddress, consulKey string, variables map[string]string) *ConsulPlaybookProvider {
return &ConsulPlaybookProvider{
consulAddress: consulAddress,
consulKey: consulKey,
variables: variables,
}
}

Expand All @@ -30,6 +32,6 @@ func (p ConsulPlaybookProvider) GetPlaybook() (*Playbook, error) {
return nil, err
}

playbook, pbErr := parsePlaybookYaml(lines)
playbook, pbErr := parsePlaybookYaml(lines, p.variables)
return &playbook, pbErr
}
4 changes: 2 additions & 2 deletions sql_runner/main.go
Expand Up @@ -154,9 +154,9 @@ func processFlags() Options {
// based on flags passed in
func PlaybookProviderFromOptions(options Options) (PlaybookProvider, error) {
if options.consul != "" {
return NewConsulPlaybookProvider(options.consul, options.playbook), nil
return NewConsulPlaybookProvider(options.consul, options.playbook, options.variables), nil
} else if options.playbook != "" {
return NewYAMLFilePlaybookProvider(options.playbook), nil
return NewYAMLFilePlaybookProvider(options.playbook, options.variables), nil
} else {
return nil, errors.New("Cannot determine provider for playbook")
}
Expand Down
6 changes: 4 additions & 2 deletions sql_runner/yaml_provider.go
Expand Up @@ -14,11 +14,13 @@ package main

type YAMLFilePlaybookProvider struct {
playbookPath string
variables map[string]string
}

func NewYAMLFilePlaybookProvider(playbookPath string) *YAMLFilePlaybookProvider {
func NewYAMLFilePlaybookProvider(playbookPath string, variables map[string]string) *YAMLFilePlaybookProvider {
return &YAMLFilePlaybookProvider{
playbookPath: playbookPath,
variables: variables,
}
}

Expand All @@ -28,6 +30,6 @@ func (p YAMLFilePlaybookProvider) GetPlaybook() (*Playbook, error) {
return nil, err
}

playbook, pbErr := parsePlaybookYaml(lines)
playbook, pbErr := parsePlaybookYaml(lines, p.variables)
return &playbook, pbErr
}
24 changes: 22 additions & 2 deletions sql_runner/yaml_utils.go
Expand Up @@ -17,6 +17,7 @@ import (
"gopkg.in/yaml.v1"
"regexp"
"strings"
"text/template"
)

var (
Expand All @@ -26,13 +27,18 @@ var (

// Parses a playbook.yml to return the targets
// to execute against and the steps to execute
func parsePlaybookYaml(playbookBytes []byte) (Playbook, error) {
func parsePlaybookYaml(playbookBytes []byte, variables map[string]string) (Playbook, error) {
// Define and initialize the Playbook struct
var playbook Playbook = NewPlaybook()

// Clean up the YAML
cleaned := cleanYaml(playbookBytes)
err := yaml.Unmarshal(cleaned, &playbook)

// Run the yaml through the template engine
str, err := fillPlaybookTemplate(string(cleaned[:]), variables)

// Unmarshal the yaml into the playbook
err = yaml.Unmarshal([]byte(str), &playbook)

return playbook, err
}
Expand All @@ -51,3 +57,17 @@ func cleanYaml(rawYaml []byte) []byte {
}
return buffer.Bytes()
}

func fillPlaybookTemplate(playbookStr string, variables map[string]string) (string, error) {
t, err := template.New("playbook").Parse(playbookStr)
if err != nil {
return "", err
}

var filled bytes.Buffer
if err := t.Execute(&filled, variables); err != nil {
return "", err
}

return filled.String(), err
}
25 changes: 23 additions & 2 deletions sql_runner/yaml_utils_test.go
Expand Up @@ -20,7 +20,7 @@ import (
func TestParsePlaybookYaml(t *testing.T) {
assert := assert.New(t)

playbook, err := parsePlaybookYaml(nil)
playbook, err := parsePlaybookYaml(nil, nil)
assert.Nil(err)
assert.NotNil(playbook)
assert.Equal(0, len(playbook.Targets))
Expand All @@ -30,7 +30,7 @@ func TestParsePlaybookYaml(t *testing.T) {
assert.Nil(err1)
assert.NotNil(playbookBytes)

playbook, err = parsePlaybookYaml(playbookBytes)
playbook, err = parsePlaybookYaml(playbookBytes, nil)
assert.Nil(err)
assert.NotNil(playbook)
assert.Equal(2, len(playbook.Targets))
Expand All @@ -51,3 +51,24 @@ func TestCleanYaml(t *testing.T) {
cleanYamlStr = string(cleanYaml(nil))
assert.Equal("\n", cleanYamlStr)
}

func TestTemplateYaml(t *testing.T) {
assert := assert.New(t)

playbookBytes, err1 := loadLocalFile("../integration/resources/good-postgres-with-template.yml")
assert.Nil(err1)

var m map[string]string = make(map[string]string)

m["password"] = "qwerty123"
m["username"] = "animoto"
m["host"] = "theinternetz"

playbook, err := parsePlaybookYaml(playbookBytes, CLIVariables(m))

assert.Nil(err)

assert.Equal("qwerty123", playbook.Targets[0].Password)
assert.Equal("animoto", playbook.Targets[0].Username)
assert.Equal("theinternetz", playbook.Targets[0].Host)
}

0 comments on commit d3b7eda

Please sign in to comment.