provisioner/chef-solo: deeploy nested JSON works properly
This commit is contained in:
parent
3ac246d611
commit
8fc46aaa82
|
@ -52,6 +52,7 @@ BUG FIXES:
|
|||
Windows [GH-963]
|
||||
* provisioner/ansible: set cwd to staging directory [GH-1016]
|
||||
* provisioners/chef-client: Don't chown directory with Ubuntu. [GH-939]
|
||||
* provisioners/chef-solo: Deeply nested JSON works properly. [GH-1076]
|
||||
* provisioners/shell: Env var values can have equal signs. [GH-1045]
|
||||
* provisioners/shell: chmod the uploaded script file to 0777. [GH-994]
|
||||
* post-processor/docker-push: Allow repositories with ports. [GH-923]
|
||||
|
|
|
@ -203,6 +203,17 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
}
|
||||
}
|
||||
|
||||
jsonValid := true
|
||||
for k, v := range p.config.Json {
|
||||
p.config.Json[k], err = p.deepJsonFix(k, v)
|
||||
if err != nil {
|
||||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Error processing JSON: %s", err))
|
||||
jsonValid = false
|
||||
}
|
||||
}
|
||||
|
||||
if jsonValid {
|
||||
// Process the user variables within the JSON and set the JSON.
|
||||
// Do this early so that we can validate and show errors.
|
||||
p.config.Json, err = p.processJsonUserVars()
|
||||
|
@ -210,6 +221,7 @@ func (p *Provisioner) Prepare(raws ...interface{}) error {
|
|||
errs = packer.MultiErrorAppend(
|
||||
errs, fmt.Errorf("Error processing user variables in JSON: %s", err))
|
||||
}
|
||||
}
|
||||
|
||||
if errs != nil && len(errs.Errors) > 0 {
|
||||
return errs
|
||||
|
@ -470,6 +482,57 @@ func (p *Provisioner) installChef(ui packer.Ui, comm packer.Communicator) error
|
|||
return nil
|
||||
}
|
||||
|
||||
func (p *Provisioner) deepJsonFix(key string, current interface{}) (interface{}, error) {
|
||||
if current == nil {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
switch c := current.(type) {
|
||||
case []interface{}:
|
||||
val := make([]interface{}, len(c))
|
||||
for i, v := range c {
|
||||
var err error
|
||||
val[i], err = p.deepJsonFix(fmt.Sprintf("%s[%d]", key, i), v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return val, nil
|
||||
case bool:
|
||||
return c, nil
|
||||
case int:
|
||||
return c, nil
|
||||
case uint:
|
||||
return c, nil
|
||||
case float32:
|
||||
return c, nil
|
||||
case float64:
|
||||
return c, nil
|
||||
case map[interface{}]interface{}:
|
||||
val := make(map[string]interface{})
|
||||
for k, v := range c {
|
||||
ks, ok := k.(string)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("%s: key is not string", key)
|
||||
}
|
||||
|
||||
var err error
|
||||
val[ks], err = p.deepJsonFix(
|
||||
fmt.Sprintf("%s.%s", key, ks), v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return val, nil
|
||||
case string:
|
||||
return c, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown type for key: '%s'", key)
|
||||
}
|
||||
}
|
||||
|
||||
func (p *Provisioner) processJsonUserVars() (map[string]interface{}, error) {
|
||||
jsonBytes, err := json.Marshal(p.config.Json)
|
||||
if err != nil {
|
||||
|
|
|
@ -262,3 +262,33 @@ func TestProvisionerPrepare_json(t *testing.T) {
|
|||
t.Fatalf("bad: %#v", p.config.Json)
|
||||
}
|
||||
}
|
||||
|
||||
func TestProvisionerPrepare_jsonNested(t *testing.T) {
|
||||
config := testConfig()
|
||||
config["json"] = map[string]interface{}{
|
||||
"foo": map[interface{}]interface{}{
|
||||
"bar": "baz",
|
||||
},
|
||||
|
||||
"bar": []interface{}{
|
||||
"foo",
|
||||
|
||||
map[interface{}]interface{}{
|
||||
"bar": "baz",
|
||||
},
|
||||
},
|
||||
|
||||
"bFalse": false,
|
||||
"bTrue": true,
|
||||
"bNil": nil,
|
||||
|
||||
"bInt": 1,
|
||||
"bFloat": 4.5,
|
||||
}
|
||||
|
||||
var p Provisioner
|
||||
err := p.Prepare(config)
|
||||
if err != nil {
|
||||
t.Fatalf("err: %s", err)
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue