diff --git a/pkg/chartutil/files.go b/pkg/chartutil/files.go index 51df52f3c..516a83fd2 100644 --- a/pkg/chartutil/files.go +++ b/pkg/chartutil/files.go @@ -17,6 +17,7 @@ package chartutil import ( "encoding/base64" + "encoding/json" "path" "strings" @@ -189,3 +190,31 @@ func FromYaml(str string) map[string]interface{} { } return m } + +// ToJson takes an interface, marshals it to json, and returns a string. It will +// always return a string, even on marshal error (empty string). +// +// This is designed to be called from a template. +func ToJson(v interface{}) string { + data, err := json.Marshal(v) + if err != nil { + // Swallow errors inside of a template. + return "" + } + return string(data) +} + +// FromJson converts a YAML document into a map[string]interface{}. +// +// This is not a general-purpose JSON parser, and will not parse all valid +// YAML documents. Additionally, because its intended use is within templates +// it tolerates errors. It will insert the returned error message string into +// m["error"] in the returned map. +func FromJson(str string) map[string]interface{} { + m := map[string]interface{}{} + + if err := json.Unmarshal([]byte(str), &m); err != nil { + m["Error"] = err.Error() + } + return m +} diff --git a/pkg/chartutil/files_test.go b/pkg/chartutil/files_test.go index ae101201d..c522e0078 100644 --- a/pkg/chartutil/files_test.go +++ b/pkg/chartutil/files_test.go @@ -141,3 +141,52 @@ one: t.Fatal("Expected parser error") } } + +func TestToJson(t *testing.T) { + expect := `{"foo":"bar"}` + v := struct { + Foo string `json:"foo"` + }{ + Foo: "bar", + } + + if got := ToJson(v); got != expect { + t.Errorf("Expected %q, got %q", expect, got) + } +} + +func TestFromJson(t *testing.T) { + doc := `{ + "hello": "world", + "one": { + "two": "three" + } +} +` + dict := FromJson(doc) + if err, ok := dict["Error"]; ok { + t.Fatalf("Parse error: %s", err) + } + + if len(dict) != 2 { + t.Fatal("expected two elements.") + } + + world := dict["hello"] + if world.(string) != "world" { + t.Fatal("Expected the world. Is that too much to ask?") + } + + // This should fail because we don't currently support lists: + doc2 := ` +[ + "one", + "two", + "three" +] +` + dict = FromJson(doc2) + if _, ok := dict["Error"]; !ok { + t.Fatal("Expected parser error") + } +} diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 34d7ad79d..88a661865 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -72,6 +72,8 @@ func FuncMap() template.FuncMap { extra := template.FuncMap{ "toYaml": chartutil.ToYaml, "fromYaml": chartutil.FromYaml, + "toJson": chartutil.ToJson, + "fromJson": chartutil.FromJson, // This is a placeholder for the "include" function, which is // late-bound to a template. By declaring it here, we preserve the