mirror of
https://github.com/kemko/nomad.git
synced 2026-01-01 16:05:42 +03:00
Support driver config fields being set to nil (#5391)
To pick up https://github.com/hashicorp/hcl2/pull/90
This commit is contained in:
@@ -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 {
|
||||
|
||||
@@ -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)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
10
vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser.go
generated
vendored
10
vendor/github.com/hashicorp/hcl2/hcl/hclsyntax/parser.go
generated
vendored
@@ -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
|
||||
|
||||
2
vendor/github.com/hashicorp/hcl2/hcl/json/structure.go
generated
vendored
2
vendor/github.com/hashicorp/hcl2/hcl/json/structure.go
generated
vendored
@@ -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
12
vendor/vendor.json
vendored
@@ -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"},
|
||||
|
||||
Reference in New Issue
Block a user