Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add map merge functionality #1500

Merged
merged 5 commits into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions docs/templating-language.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,8 @@ provides the following functions:
- [in](#in)
- [loop](#loop)
- [join](#join)
- [mergeMap](#mergemap)
- [mergeMapWithOverride](#mergemapwithoverride)
- [trimSpace](#trimspace)
- [parseBool](#parsebool)
- [parseFloat](#parsefloat)
Expand Down Expand Up @@ -1223,6 +1225,28 @@ Takes the given list of strings as a pipe and joins them on the provided string:
{{ $items | join "," }}
```

### `mergeMap`

Takes the result from [`explode`](#explode) and an exploded argument then merges it both maps. The argument's source will not be overridden by piped map.

```golang
{{ $base := tree "base" | explode }}
{{ $overrides := tree "overrides" | explode | mergeMap $base}}
{{ with $overrides }}
{{ .a.b.c }}{{ end }}
```

### `mergeMapWithOverride`

Takes the result from [`explode`](#explode) and an exploded argument then merges it both maps. The argument's source will be overridden by piped map.

```golang
{{ $base := tree "base" | explode }}
{{ $overrides := tree "overrides" | explode | mergeMapWithOverride $base}}
{{ with $overrides }}
{{ .a.b.c }}{{ end }}
```

### `trimSpace`

Takes the provided input and trims all whitespace, tabs and newlines:
Expand Down
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ require (
github.com/hashicorp/logutils v1.0.0
github.com/hashicorp/serf v0.9.4 // indirect
github.com/hashicorp/vault/api v1.0.5-0.20190730042357-746c0b111519
github.com/imdario/mergo v0.3.12
github.com/mattn/go-colorable v0.1.7 // indirect
github.com/mattn/go-shellwords v1.0.12
github.com/mitchellh/go-homedir v1.1.0
github.com/mitchellh/hashstructure v1.0.0
github.com/mitchellh/mapstructure v1.3.3
Expand Down
9 changes: 2 additions & 7 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@ github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDk
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/eikenb/go-shellwords v1.0.12-0.20210603231637-cbc54604f068 h1:y0DBnMgUmMeM+y1h7R2Hv0IZNiAcK5FAjNbRbbJNe3A=
github.com/eikenb/go-shellwords v1.0.12-0.20210603231637-cbc54604f068/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
github.com/fatih/color v1.9.0 h1:8xPHl4/q1VyqGIPif1F+1V3Y3lSmrq01EabUW3CoW5s=
github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU=
Expand Down Expand Up @@ -124,6 +122,8 @@ github.com/hashicorp/vault/sdk v0.1.14-0.20190730042320-0dc007d98cc8 h1:fLUoZ8cI
github.com/hashicorp/vault/sdk v0.1.14-0.20190730042320-0dc007d98cc8/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvhkWnjtSYCaS2M=
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w=
Expand All @@ -146,10 +146,6 @@ github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcME
github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE=
github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY=
github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
github.com/mattn/go-shellwords v1.0.10 h1:Y7Xqm8piKOO3v10Thp7Z36h4FYFjt5xB//6XvOrs2Gw=
github.com/mattn/go-shellwords v1.0.10/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/mattn/go-shellwords v1.0.12 h1:M2zGm7EW6UQJvDeQxo4T51eKPurbeFbe8WtebGE2xrk=
github.com/mattn/go-shellwords v1.0.12/go.mod h1:EZzvwXDESEeg03EKmM+RmDnNOPKG4lLtQsUlTZDWQ8Y=
github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/miekg/dns v1.1.26 h1:gPxPSwALAeHJSjarOs00QjVdV9QoBvc1D2ujQUr5BzU=
Expand Down Expand Up @@ -248,7 +244,6 @@ golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e h1:vcxGaoTs7kV8m5Np9uUNQin4BrLOthgV7252N8V+FwY=
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
Expand Down
14 changes: 14 additions & 0 deletions template/funcs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import (
dep "github.com/hashicorp/consul-template/dependency"
"github.com/hashicorp/consul/api"
socktmpl "github.com/hashicorp/go-sockaddr/template"
"github.com/imdario/mergo"
"github.com/pkg/errors"
yaml "gopkg.in/yaml.v2"
)
Expand Down Expand Up @@ -739,6 +740,19 @@ func containsSomeFunc(retTrue, invert bool) func([]interface{}, interface{}) (bo
}
}

// mergeMap is used to merge two maps
func mergeMap(dstMap map[string]interface{}, srcMap map[string]interface{}, args ...func(*mergo.Config)) (map[string]interface{}, error) {
if err := mergo.Map(&dstMap, srcMap, args...); err != nil {
return nil, err
}
return dstMap, nil
}

// mergeMapWithOverride is used to merge two maps with dstMap overriding vaules in srcMap
func mergeMapWithOverride(dstMap map[string]interface{}, srcMap map[string]interface{}) (map[string]interface{}, error) {
return mergeMap(dstMap, srcMap, mergo.WithOverride)
}

// explode is used to expand a list of keypairs into a deeply-nested hash.
func explode(pairs []*dep.KeyPair) (map[string]interface{}, error) {
m := make(map[string]interface{})
Expand Down
2 changes: 2 additions & 0 deletions template/template.go
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,8 @@ func funcMap(i *funcMapInput) template.FuncMap {
"executeTemplate": executeTemplateFunc(i.t),
"explode": explode,
"explodeMap": explodeMap,
"mergeMap": mergeMap,
"mergeMapWithOverride": mergeMapWithOverride,
"in": in,
"indent": indent,
"loop": loop,
Expand Down
46 changes: 46 additions & 0 deletions template/template_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1191,6 +1191,52 @@ func TestTemplate_Execute(t *testing.T) {
"bar",
false,
},
{
"helper_mergeMap",
&NewTemplateInput{
Contents: `{{ $base := "{\"voo\":{\"bar\":\"v\"}}" | parseJSON}}{{ $role := tree "list" | explode | mergeMap $base}}{{ range $k, $v := $role }}{{ $k }}{{ $v }}{{ end }}`,
},
&ExecuteInput{
Brain: func() *Brain {
b := NewBrain()
d, err := dep.NewKVListQuery("list")
if err != nil {
t.Fatal(err)
}
b.Remember(d, []*dep.KeyPair{
&dep.KeyPair{Key: "", Value: ""},
&dep.KeyPair{Key: "foo/bar", Value: "a"},
&dep.KeyPair{Key: "zip/zap", Value: "b"},
})
return b
}(),
},
"foomap[bar:a]voomap[bar:v]zipmap[zap:b]",
false,
},
{
"helper_mergeMapWithOverride",
&NewTemplateInput{
Contents: `{{ $base := "{\"zip\":{\"zap\":\"t\"},\"voo\":{\"bar\":\"v\"}}" | parseJSON}}{{ $role := tree "list" | explode | mergeMapWithOverride $base}}{{ range $k, $v := $role }}{{ $k }}{{ $v }}{{ end }}`,
},
&ExecuteInput{
Brain: func() *Brain {
b := NewBrain()
d, err := dep.NewKVListQuery("list")
if err != nil {
t.Fatal(err)
}
b.Remember(d, []*dep.KeyPair{
&dep.KeyPair{Key: "", Value: ""},
&dep.KeyPair{Key: "foo/bar", Value: "a"},
&dep.KeyPair{Key: "zip/zap", Value: "b"},
})
return b
}(),
},
"foomap[bar:a]voomap[bar:v]zipmap[zap:b]",
false,
},
{
"helper_explode",
&NewTemplateInput{
Expand Down