Support driver config fields being set to nil (#5391)

To pick up https://github.com/hashicorp/hcl2/pull/90
This commit is contained in:
Mahmood Ali
2019-03-05 21:47:06 -05:00
committed by GitHub
parent d8323724ef
commit 32623ce3ee
5 changed files with 125 additions and 7 deletions

View File

@@ -56,6 +56,33 @@ func TestConfig_ParseJSON(t *testing.T) {
Devices: []DockerDevice{},
},
},
{
name: "nil values for 'volumes' field are safe",
input: `{"Config": {"image": "bash:3", "volumes": null}}`,
expected: TaskConfig{
Image: "bash:3",
Mounts: []DockerMount{},
Devices: []DockerDevice{},
},
},
{
name: "nil values for 'args' field are safe",
input: `{"Config": {"image": "bash:3", "args": null}}`,
expected: TaskConfig{
Image: "bash:3",
Mounts: []DockerMount{},
Devices: []DockerDevice{},
},
},
{
name: "nil values for string fields are safe",
input: `{"Config": {"image": "bash:3", "command": null}}`,
expected: TaskConfig{
Image: "bash:3",
Mounts: []DockerMount{},
Devices: []DockerDevice{},
},
},
}
for _, c := range cases {

View File

@@ -8,6 +8,7 @@ import (
"github.com/hashicorp/nomad/helper/pluginutils/hclspecutils"
"github.com/hashicorp/nomad/helper/pluginutils/hclutils"
"github.com/hashicorp/nomad/plugins/drivers"
"github.com/hashicorp/nomad/plugins/shared/hclspec"
"github.com/kr/pretty"
"github.com/stretchr/testify/require"
"github.com/zclconf/go-cty/cty"
@@ -377,3 +378,83 @@ func TestParseHclInterface_Hcl(t *testing.T) {
})
}
}
func TestParseNullFields(t *testing.T) {
spec := hclspec.NewObject(map[string]*hclspec.Spec{
"array_field": hclspec.NewAttr("array_field", "list(string)", false),
"string_field": hclspec.NewAttr("string_field", "string", false),
"boolean_field": hclspec.NewAttr("boolean_field", "bool", false),
"number_field": hclspec.NewAttr("number_field", "number", false),
"block_field": hclspec.NewBlock("block_field", false, hclspec.NewObject((map[string]*hclspec.Spec{
"f": hclspec.NewAttr("f", "string", true),
}))),
"block_list_field": hclspec.NewBlockList("block_list_field", hclspec.NewObject((map[string]*hclspec.Spec{
"f": hclspec.NewAttr("f", "string", true),
}))),
})
type Sub struct {
F string `codec:"f"`
}
type TaskConfig struct {
Array []string `codec:"array_field"`
String string `codec:"string_field"`
Boolean bool `codec:"boolean_field"`
Number int64 `codec:"number_field"`
Block Sub `codec:"block_field"`
BlockList []Sub `codec:"block_list_field"`
}
cases := []struct {
name string
json string
expected TaskConfig
}{
{
"omitted fields",
`{"Config": {}}`,
TaskConfig{BlockList: []Sub{}},
},
{
"explicitly nil",
`{"Config": {
"array_field": null,
"string_field": null,
"boolean_field": null,
"number_field": null,
"block_field": null,
"block_list_field": null}}`,
TaskConfig{BlockList: []Sub{}},
},
{
// for sanity checking that the fields are actually set
"explicitly set to not null",
`{"Config": {
"array_field": ["a"],
"string_field": "a",
"boolean_field": true,
"number_field": 5,
"block_field": [{"f": "a"}],
"block_list_field": [{"f": "a"}, {"f": "b"}]}}`,
TaskConfig{
Array: []string{"a"},
String: "a",
Boolean: true,
Number: 5,
Block: Sub{"a"},
BlockList: []Sub{{"a"}, {"b"}},
},
},
}
parser := hclutils.NewConfigParser(spec)
for _, c := range cases {
t.Run(c.name, func(t *testing.T) {
var tc TaskConfig
parser.ParseJson(t, c.json, &tc)
require.EqualValues(t, c.expected, tc)
})
}
}

View File

@@ -1242,7 +1242,13 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) {
panic("parseObjectCons called without peeker pointing to open brace")
}
if forKeyword.TokenMatches(p.Peek()) {
// We must temporarily stop looking at newlines here while we check for
// a "for" keyword, since for expressions are _not_ newline-sensitive,
// even though object constructors are.
p.PushIncludeNewlines(false)
isFor := forKeyword.TokenMatches(p.Peek())
p.PopIncludeNewlines()
if isFor {
return p.finishParsingForExpr(open)
}
@@ -1377,6 +1383,8 @@ func (p *parser) parseObjectCons() (Expression, hcl.Diagnostics) {
}
func (p *parser) finishParsingForExpr(open Token) (Expression, hcl.Diagnostics) {
p.PushIncludeNewlines(false)
defer p.PopIncludeNewlines()
introducer := p.Read()
if !forKeyword.TokenMatches(introducer) {
// Should never happen if callers are behaving

View File

@@ -499,6 +499,8 @@ func (e *expression) Value(ctx *hcl.EvalContext) (cty.Value, hcl.Diagnostics) {
return cty.DynamicVal, diags
}
return cty.ObjectVal(attrs), diags
case *nullVal:
return cty.NullVal(cty.DynamicPseudoType), nil
default:
// Default to DynamicVal so that ASTs containing invalid nodes can
// still be partially-evaluated.

12
vendor/vendor.json vendored
View File

@@ -213,12 +213,12 @@
{"path":"github.com/hashicorp/hcl/json/parser","checksumSHA1":"138aCV5n8n7tkGYMsMVQQnnLq+0=","revision":"6e968a3fcdcbab092f5307fd0d85479d5af1e4dc","revisionTime":"2016-11-01T18:00:25Z"},
{"path":"github.com/hashicorp/hcl/json/scanner","checksumSHA1":"YdvFsNOMSWMLnY6fcliWQa0O5Fw=","revision":"6e968a3fcdcbab092f5307fd0d85479d5af1e4dc","revisionTime":"2016-11-01T18:00:25Z"},
{"path":"github.com/hashicorp/hcl/json/token","checksumSHA1":"fNlXQCQEnb+B3k5UDL/r15xtSJY=","revision":"6e968a3fcdcbab092f5307fd0d85479d5af1e4dc","revisionTime":"2016-11-01T18:00:25Z"},
{"path":"github.com/hashicorp/hcl2/gohcl","checksumSHA1":"RFEjfMQWPAVILXE2PhL6wDW8Zg4=","revision":"fb2bc46cdbe36e247dac0c7dc185b34eaeb54c21","revisionTime":"2019-02-14T11:58:25Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcl","checksumSHA1":"bUO4KS1yjAWa6miewgbUUsxYVfo=","revision":"fb2bc46cdbe36e247dac0c7dc185b34eaeb54c21","revisionTime":"2019-02-14T11:58:25Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcl/hclsyntax","checksumSHA1":"mIcAvc+sEAQO5kIWuLVqnvXEU6Y=","revision":"fb2bc46cdbe36e247dac0c7dc185b34eaeb54c21","revisionTime":"2019-02-14T11:58:25Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcl/json","checksumSHA1":"56M/avlLyKDeMb0D8RqKcK2kja8=","revision":"fb2bc46cdbe36e247dac0c7dc185b34eaeb54c21","revisionTime":"2019-02-14T11:58:25Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcldec","checksumSHA1":"6JRj4T/iQxIe/CoKXHDjPuupmL8=","revision":"fb2bc46cdbe36e247dac0c7dc185b34eaeb54c21","revisionTime":"2019-02-14T11:58:25Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hclwrite","checksumSHA1":"DQLzlvDUtHL1DkYDZrMx2vfKJUg=","revision":"fb2bc46cdbe36e247dac0c7dc185b34eaeb54c21","revisionTime":"2019-02-14T11:58:25Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/gohcl","checksumSHA1":"RFEjfMQWPAVILXE2PhL6wDW8Zg4=","revision":"fdf8e232b64f68d5335fa1be449b0160dadacdb5","revisionTime":"2019-03-05T17:45:54Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcl","checksumSHA1":"bUO4KS1yjAWa6miewgbUUsxYVfo=","revision":"fdf8e232b64f68d5335fa1be449b0160dadacdb5","revisionTime":"2019-03-05T17:45:54Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcl/hclsyntax","checksumSHA1":"uMWQk/2xJyIqL6ILq83VYVxkuY8=","revision":"fdf8e232b64f68d5335fa1be449b0160dadacdb5","revisionTime":"2019-03-05T17:45:54Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcl/json","checksumSHA1":"Vagtn0ywFboMp7br/xvzeuNUFNc=","revision":"fdf8e232b64f68d5335fa1be449b0160dadacdb5","revisionTime":"2019-03-05T17:45:54Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hcldec","checksumSHA1":"6JRj4T/iQxIe/CoKXHDjPuupmL8=","revision":"fdf8e232b64f68d5335fa1be449b0160dadacdb5","revisionTime":"2019-03-05T17:45:54Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/hcl2/hclwrite","checksumSHA1":"DQLzlvDUtHL1DkYDZrMx2vfKJUg=","revision":"fdf8e232b64f68d5335fa1be449b0160dadacdb5","revisionTime":"2019-03-05T17:45:54Z","version":"master","versionExact":"master"},
{"path":"github.com/hashicorp/logutils","checksumSHA1":"vt+P9D2yWDO3gdvdgCzwqunlhxU=","revision":"0dc08b1671f34c4250ce212759ebd880f743d883"},
{"path":"github.com/hashicorp/memberlist","checksumSHA1":"yAu2gPVXIh28yJ2If5gZPrf04kU=","revision":"1a62499c21db33d57691001d5e08a71ec857b18f","revisionTime":"2019-01-03T22:22:36Z"},
{"path":"github.com/hashicorp/net-rpc-msgpackrpc","checksumSHA1":"qnlqWJYV81ENr61SZk9c65R1mDo=","revision":"a14192a58a694c123d8fe5481d4a4727d6ae82f3"},