mirror of
https://github.com/rancher/os.git
synced 2025-07-13 06:34:04 +00:00
Merge pull request #882 from joshwget/unmarshal-args-as-yaml
Use yaml.Unmarshal to handle config arguments
This commit is contained in:
commit
5d15d3aa2c
@ -153,6 +153,52 @@ func TestFilterDottedKeys(t *testing.T) {
|
|||||||
assert.Equal(expectedRest, rest)
|
assert.Equal(expectedRest, rest)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestUnmarshalOrReturnString(t *testing.T) {
|
||||||
|
assert := require.New(t)
|
||||||
|
|
||||||
|
assert.Equal("ab", unmarshalOrReturnString("ab"))
|
||||||
|
assert.Equal("a\nb", unmarshalOrReturnString("a\nb"))
|
||||||
|
assert.Equal("a\n", unmarshalOrReturnString("a\n"))
|
||||||
|
assert.Equal("\nb", unmarshalOrReturnString("\nb"))
|
||||||
|
assert.Equal("a,b", unmarshalOrReturnString("a,b"))
|
||||||
|
assert.Equal("a,", unmarshalOrReturnString("a,"))
|
||||||
|
assert.Equal(",b", unmarshalOrReturnString(",b"))
|
||||||
|
|
||||||
|
assert.Equal(int64(10), unmarshalOrReturnString("10"))
|
||||||
|
assert.Equal(true, unmarshalOrReturnString("true"))
|
||||||
|
assert.Equal(false, unmarshalOrReturnString("false"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a"}, unmarshalOrReturnString("[a]"))
|
||||||
|
assert.Equal([]interface{}{"a"}, unmarshalOrReturnString("[\"a\"]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a,"}, unmarshalOrReturnString("[\"a,\"]"))
|
||||||
|
assert.Equal([]interface{}{" a, "}, unmarshalOrReturnString("[\" a, \"]"))
|
||||||
|
assert.Equal([]interface{}{",a"}, unmarshalOrReturnString("[\",a\"]"))
|
||||||
|
assert.Equal([]interface{}{" ,a "}, unmarshalOrReturnString("[\" ,a \"]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a\n"}, unmarshalOrReturnString("[\"a\n\"]"))
|
||||||
|
assert.Equal([]interface{}{" a\n "}, unmarshalOrReturnString("[\" a\n \"]"))
|
||||||
|
assert.Equal([]interface{}{"\na"}, unmarshalOrReturnString("[\"\na\"]"))
|
||||||
|
assert.Equal([]interface{}{" \na "}, unmarshalOrReturnString("[\" \na \"]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a", "b"}, unmarshalOrReturnString("[a,b]"))
|
||||||
|
assert.Equal([]interface{}{"a", "b"}, unmarshalOrReturnString("[\"a\",\"b\"]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a,", "b"}, unmarshalOrReturnString("[\"a,\",b]"))
|
||||||
|
assert.Equal([]interface{}{"a", ",b"}, unmarshalOrReturnString("[a,\",b\"]"))
|
||||||
|
assert.Equal([]interface{}{" a, ", " ,b "}, unmarshalOrReturnString("[\" a, \",\" ,b \"]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a\n", "b"}, unmarshalOrReturnString("[\"a\n\",b]"))
|
||||||
|
assert.Equal([]interface{}{"a", "\nb"}, unmarshalOrReturnString("[a,\"\nb\"]"))
|
||||||
|
assert.Equal([]interface{}{" a\n ", " \nb "}, unmarshalOrReturnString("[\" a\n \",\" \nb \"]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a", int64(10)}, unmarshalOrReturnString("[a,10]"))
|
||||||
|
assert.Equal([]interface{}{int64(10), "a"}, unmarshalOrReturnString("[10,a]"))
|
||||||
|
|
||||||
|
assert.Equal([]interface{}{"a", true}, unmarshalOrReturnString("[a,true]"))
|
||||||
|
assert.Equal([]interface{}{false, "a"}, unmarshalOrReturnString("[false,a]"))
|
||||||
|
}
|
||||||
|
|
||||||
func TestParseCmdline(t *testing.T) {
|
func TestParseCmdline(t *testing.T) {
|
||||||
assert := require.New(t)
|
assert := require.New(t)
|
||||||
|
|
||||||
@ -161,18 +207,20 @@ func TestParseCmdline(t *testing.T) {
|
|||||||
"rescue": true,
|
"rescue": true,
|
||||||
"key1": "value1",
|
"key1": "value1",
|
||||||
"key2": "value2",
|
"key2": "value2",
|
||||||
"keyArray": []interface{}{"1", "2"},
|
"keyArray": []interface{}{int64(1), int64(2)},
|
||||||
"obj1": map[interface{}]interface{}{
|
"obj1": map[interface{}]interface{}{
|
||||||
"key3": "3value",
|
"key3": "3value",
|
||||||
"obj2": map[interface{}]interface{}{
|
"obj2": map[interface{}]interface{}{
|
||||||
"key4": true,
|
"key4": true,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
"key5": 5,
|
"key5": int64(5),
|
||||||
|
"key6": "a,b",
|
||||||
|
"key7": "a\nb",
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
actual := parseCmdline("a b rancher.rescue rancher.keyArray=[1,2] rancher.key1=value1 c rancher.key2=value2 rancher.obj1.key3=3value rancher.obj1.obj2.key4 rancher.key5=5")
|
actual := parseCmdline("a b rancher.rescue rancher.keyArray=[1,2] 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(expected, actual)
|
assert.Equal(expected, actual)
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,9 @@ package config
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
log "github.com/Sirupsen/logrus"
|
log "github.com/Sirupsen/logrus"
|
||||||
|
yaml "github.com/cloudfoundry-incubator/candiedyaml"
|
||||||
|
|
||||||
"github.com/rancher/os/util"
|
"github.com/rancher/os/util"
|
||||||
"regexp"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -87,7 +86,7 @@ func getOrSetVal(args string, data map[interface{}]interface{}, value interface{
|
|||||||
// Reached end, set the value
|
// Reached end, set the value
|
||||||
if last && value != nil {
|
if last && value != nil {
|
||||||
if s, ok := value.(string); ok {
|
if s, ok := value.(string); ok {
|
||||||
value = DummyMarshall(s)
|
value = unmarshalOrReturnString(s)
|
||||||
}
|
}
|
||||||
|
|
||||||
t[part] = value
|
t[part] = value
|
||||||
@ -121,28 +120,36 @@ func getOrSetVal(args string, data map[interface{}]interface{}, value interface{
|
|||||||
return "", tData
|
return "", tData
|
||||||
}
|
}
|
||||||
|
|
||||||
func DummyMarshall(value string) interface{} {
|
// YAML parsers will remove newlines, but we'd like to keep those
|
||||||
if strings.HasPrefix(value, "[") && strings.HasSuffix(value, "]") {
|
// replace newlines with magicString, and then undo after unmarshaling
|
||||||
result := []interface{}{}
|
var magicString = "9XsJcx6dR5EERYCC"
|
||||||
for _, i := range strings.Split(value[1:len(value)-1], ",") {
|
|
||||||
result = append(result, strings.TrimSpace(i))
|
func reverseReplacement(result interface{}) interface{} {
|
||||||
|
switch val := result.(type) {
|
||||||
|
case map[interface{}]interface{}:
|
||||||
|
for k, v := range val {
|
||||||
|
val[k] = reverseReplacement(v)
|
||||||
}
|
}
|
||||||
|
return val
|
||||||
|
case []interface{}:
|
||||||
|
for i, item := range val {
|
||||||
|
val[i] = reverseReplacement(item)
|
||||||
|
}
|
||||||
|
return val
|
||||||
|
case string:
|
||||||
|
return strings.Replace(val, magicString, "\n", -1)
|
||||||
|
}
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
if value == "true" {
|
func unmarshalOrReturnString(value string) (result interface{}) {
|
||||||
return true
|
value = strings.Replace(value, "\n", magicString, -1)
|
||||||
} else if value == "false" {
|
if err := yaml.Unmarshal([]byte(value), &result); err != nil {
|
||||||
return false
|
result = value
|
||||||
} else if ok, _ := regexp.MatchString("^[0-9]+$", value); ok {
|
|
||||||
i, err := strconv.Atoi(value)
|
|
||||||
if err != nil {
|
|
||||||
panic(err)
|
|
||||||
}
|
}
|
||||||
return i
|
result = reverseReplacement(result)
|
||||||
}
|
return
|
||||||
|
|
||||||
return value
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseCmdline(cmdLine string) map[interface{}]interface{} {
|
func parseCmdline(cmdLine string) map[interface{}]interface{} {
|
||||||
@ -167,7 +174,7 @@ outer:
|
|||||||
keys := strings.Split(kv[0], ".")
|
keys := strings.Split(kv[0], ".")
|
||||||
for i, key := range keys {
|
for i, key := range keys {
|
||||||
if i == len(keys)-1 {
|
if i == len(keys)-1 {
|
||||||
current[key] = DummyMarshall(value)
|
current[key] = unmarshalOrReturnString(value)
|
||||||
} else {
|
} else {
|
||||||
if obj, ok := current[key]; ok {
|
if obj, ok := current[key]; ok {
|
||||||
if newCurrent, ok := obj.(map[interface{}]interface{}); ok {
|
if newCurrent, ok := obj.(map[interface{}]interface{}); ok {
|
||||||
|
Loading…
Reference in New Issue
Block a user