Skip to content

Commit

Permalink
add support for dot notation in variables
Browse files Browse the repository at this point in the history
Example: -v docker_tls.ca=... -v docker_tls.private_key=...
Signed-off-by: Tyler Schultz <[email protected]>
  • Loading branch information
cppforlife authored and tylerschultz committed Jul 7, 2017
1 parent 35373bb commit 06eede2
Show file tree
Hide file tree
Showing 4 changed files with 100 additions and 18 deletions.
34 changes: 18 additions & 16 deletions cmd/var_flags.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,20 +18,32 @@ type VarFlags struct {
func (f VarFlags) AsVariables() boshtpl.Variables {
var firstToUse []boshtpl.Variables

firstToUse = append(firstToUse, f.kvsAsVars())
staticVars := boshtpl.StaticVariables{}

for i, _ := range f.VarFiles {
firstToUse = append(firstToUse, f.VarFiles[len(f.VarFiles)-i-1].Vars)
for i, _ := range f.VarsEnvs {
for k, v := range f.VarsEnvs[i].Vars {
staticVars[k] = v
}
}

for i, _ := range f.VarsFiles {
firstToUse = append(firstToUse, f.VarsFiles[len(f.VarsFiles)-i-1].Vars)
for k, v := range f.VarsFiles[i].Vars {
staticVars[k] = v
}
}

for i, _ := range f.VarsEnvs {
firstToUse = append(firstToUse, f.VarsEnvs[len(f.VarsEnvs)-i-1].Vars)
for i, _ := range f.VarFiles {
for k, v := range f.VarFiles[i].Vars {
staticVars[k] = v
}
}

for _, kv := range f.VarKVs {
staticVars[kv.Name] = kv.Value
}

firstToUse = append(firstToUse, staticVars)

store := &f.VarsFSStore

if f.VarsFSStore.IsSet() {
Expand All @@ -46,13 +58,3 @@ func (f VarFlags) AsVariables() boshtpl.Variables {

return vars
}

func (f VarFlags) kvsAsVars() boshtpl.Variables {
vars := boshtpl.StaticVariables{}

for _, kv := range f.VarKVs {
vars[kv.Name] = kv.Value
}

return vars
}
38 changes: 36 additions & 2 deletions director/template/static_vars.go
Original file line number Diff line number Diff line change
@@ -1,20 +1,54 @@
package template

import (
"strings"
)

type StaticVariables map[string]interface{}

var _ Variables = StaticVariables{}

func (v StaticVariables) Get(varDef VariableDefinition) (interface{}, bool, error) {
val, found := v[varDef.Name]
val, found := v.processed()[varDef.Name]
return val, found, nil
}

func (v StaticVariables) List() ([]VariableDefinition, error) {
var defs []VariableDefinition

for name, _ := range v {
for name, _ := range v.processed() {
defs = append(defs, VariableDefinition{Name: name})
}

return defs, nil
}

func (v StaticVariables) processed() map[string]interface{} {
processed := map[interface{}]interface{}{}

for name, val := range v {
pieces := strings.Split(name, ".")
if len(pieces) == 1 {
processed[name] = val
} else {
mapRef := processed

for _, p := range pieces[0 : len(pieces)-1] {
if _, found := processed[p]; !found {
mapRef[p] = map[interface{}]interface{}{}
}
mapRef = mapRef[p].(map[interface{}]interface{})
}

mapRef[pieces[len(pieces)-1]] = val
}
}

processedTyped := map[string]interface{}{}

for k, v := range processed {
processedTyped[k.(string)] = v
}

return processedTyped
}
26 changes: 26 additions & 0 deletions director/template/static_vars_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ var _ = Describe("StaticVariables", func() {
Expect(found).To(BeFalse())
Expect(err).ToNot(HaveOccurred())
})

It("recognizes keys that use dot notation for subvalues", func() {
a := StaticVariables{"a.subkey": "foo", "a.subkey2": "foo2"}

val, found, err := a.Get(VariableDefinition{Name: "a"})
Expect(val).To(Equal(map[interface{}]interface{}{"subkey": "foo", "subkey2": "foo2"}))
Expect(found).To(BeTrue())
Expect(err).ToNot(HaveOccurred())

a = StaticVariables{"a.subkey.subsubkey": "foo", "a.subkey2": "foo2"}

val, found, err = a.Get(VariableDefinition{Name: "a"})
Expect(val).To(Equal(map[interface{}]interface{}{
"subkey": map[interface{}]interface{}{"subsubkey": "foo"},
"subkey2": "foo2",
}))
Expect(found).To(BeTrue())
Expect(err).ToNot(HaveOccurred())

a = StaticVariables{"a.subkey": "foo"}

val, found, err = a.Get(VariableDefinition{Name: "a.subkey"})
Expect(val).To(BeNil())
Expect(found).To(BeFalse())
Expect(err).ToNot(HaveOccurred())
})
})

Describe("List", func() {
Expand Down
20 changes: 20 additions & 0 deletions integration/interpolate_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,26 @@ var _ = Describe("interpolate command", func() {
Expect(ui.Blocks).To(Equal([]string{"file: val\n"}))
})

It("interpolates manifest with variables provided piece by piece via dot notation", func() {
err := fs.WriteFileString("/template", "file: ((key))\nfile2: ((key.subkey2))\n")
Expect(err).ToNot(HaveOccurred())

err = fs.WriteFileString("/file-val", "file-val-content")
Expect(err).ToNot(HaveOccurred())

cmd, err := cmdFactory.New([]string{
"interpolate", "/template",
"-v", "key.subkey=val",
"-v", "key.subkey2=val2",
"--var-file", "key.subkey3=/file-val",
})
Expect(err).ToNot(HaveOccurred())

err = cmd.Execute()
Expect(err).ToNot(HaveOccurred())
Expect(ui.Blocks).To(Equal([]string{"file:\n subkey: val\n subkey2: val2\n subkey3: file-val-content\nfile2: val2\n"}))
})

It("returns portion of the template when --path flag is provided", func() {
err := fs.WriteFileString("/file", "file: ((key))")
Expect(err).ToNot(HaveOccurred())
Expand Down

0 comments on commit 06eede2

Please sign in to comment.