diff --git a/config/config_test.go b/config/config_test.go index 588bc320..22739664 100644 --- a/config/config_test.go +++ b/config/config_test.go @@ -1,9 +1,10 @@ package config import ( - yaml "github.com/cloudfoundry-incubator/candiedyaml" "testing" + yaml "github.com/cloudfoundry-incubator/candiedyaml" + "github.com/rancher/os/util" "github.com/stretchr/testify/require" ) @@ -102,28 +103,60 @@ func TestUnmarshalOrReturnString(t *testing.T) { func TestParseCmdline(t *testing.T) { assert := require.New(t) - expected := map[interface{}]interface{}{ + assert.Equal(map[interface{}]interface{}{ "rancher": map[interface{}]interface{}{ - "rescue": true, - "key1": "value1", - "key2": "value2", - "keyArray": []interface{}{int64(1), int64(2)}, - "strArray": []interface{}{"url:http://192.168.1.100/cloud-config"}, - "obj1": map[interface{}]interface{}{ - "key3": "3value", - "obj2": map[interface{}]interface{}{ - "key4": true, - }, - }, - "key5": int64(5), - "key6": "a,b", - "key7": "a\nb", + "key1": "value1", + "key2": "value2", }, - } + }, parseCmdline("a b rancher.key1=value1 c rancher.key2=value2")) - actual := parseCmdline("a b rancher.rescue rancher.keyArray=[1,2] rancher.strArray=[\"url:http://192.168.1.100/cloud-config\"] rancher.key1=value1 c rancher.key2=value2 rancher.obj1.key3=3value rancher.obj1.obj2.key4 rancher.key5=5 rancher.key6=a,b rancher.key7=a\nb") + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "key": "a,b", + }, + }, parseCmdline("rancher.key=a,b")) - assert.Equal(expected, actual) + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "key": "a\nb", + }, + }, parseCmdline("rancher.key=a\nb")) + + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "key": "a:b", + }, + }, parseCmdline("rancher.key=a:b")) + + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "key": int64(5), + }, + }, parseCmdline("rancher.key=5")) + + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "rescue": true, + }, + }, parseCmdline("rancher.rescue")) + + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "keyArray": []interface{}{int64(1), int64(2)}, + }, + }, parseCmdline("rancher.keyArray=[1,2]")) + + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "strArray": []interface{}{"url:http://192.168.1.100/cloud-config"}, + }, + }, parseCmdline("rancher.strArray=[\"url:http://192.168.1.100/cloud-config\"]")) + + assert.Equal(map[interface{}]interface{}{ + "rancher": map[interface{}]interface{}{ + "strArray": []interface{}{"url:http://192.168.1.100/cloud-config"}, + }, + }, parseCmdline("rancher.strArray=[url:http://192.168.1.100/cloud-config]")) } func TestGet(t *testing.T) { diff --git a/config/data_funcs.go b/config/data_funcs.go index 5156d8a8..3eb87e69 100644 --- a/config/data_funcs.go +++ b/config/data_funcs.go @@ -116,9 +116,12 @@ func getOrSetVal(args string, data map[interface{}]interface{}, value interface{ return "", tData } -// YAML parsers will remove newlines, but we'd like to keep those -// replace newlines with magicString, and then undo after unmarshaling -var magicString = "9XsJcx6dR5EERYCC" +// Replace newlines and colons with random strings +// This is done to avoid YAML treating these as special characters +var ( + newlineMagicString = "9XsJcx6dR5EERYCC" + colonMagicString = "V0Rc21pIVknMm2rr" +) func reverseReplacement(result interface{}) interface{} { switch val := result.(type) { @@ -133,14 +136,17 @@ func reverseReplacement(result interface{}) interface{} { } return val case string: - return strings.Replace(val, magicString, "\n", -1) + val = strings.Replace(val, newlineMagicString, "\n", -1) + val = strings.Replace(val, colonMagicString, ":", -1) + return val } return result } func unmarshalOrReturnString(value string) (result interface{}) { - value = strings.Replace(value, "\n", magicString, -1) + value = strings.Replace(value, "\n", newlineMagicString, -1) + value = strings.Replace(value, ":", colonMagicString, -1) if err := yaml.Unmarshal([]byte(value), &result); err != nil { result = value }