Skip to content
Snippets Groups Projects
Unverified Commit 1f85d5dd authored by Angus Lees's avatar Angus Lees
Browse files

Add manifestJson and manifestYaml functions

jsonnet's `std.toString()` returns "compact" JSON.  Sometimes this is
not appropriate, particularly when generating large output that might
need to be viewed/debugged by a human.

This change implements manifestYaml and manifestJson functions, which
generate YAML and "pretty" JSON respectively.

A slight implementation wrinkle is that libjsonnet currently only
supports passing primitive (scalar) types to native functions, so
these arguments need to be JSON-serialised/unserialised across the
native function call boundary.
parent 86dc7ebd
No related branches found
No related tags found
No related merge requests found
......@@ -13,6 +13,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
// NB: libjsonnet native functions can only pass primitive types, so
// some functions json-encode the arg. These "*FromJson" functions
// will be replaced by regular native version when libjsonnet is able
// to support this. This file strives to hide this implementation
// detail.
{
// parseJson(data): parses the `data` string as a json document, and
// returns the resulting jsonnet object.
......@@ -24,6 +30,21 @@
// element.
parseYaml:: std.native("parseYaml"),
// manifestJson(value, indent): convert the jsonnet object `value`
// to a string encoded as "pretty" (multi-line) JSON, with each
// nesting level indented by `indent` spaces.
manifestJson(value, indent=4):: (
local f = std.native("manifestJsonFromJson");
f(std.toString(value), indent)
),
// manifestYaml(value): convert the jsonnet object `value` to a
// string encoded as a single YAML document.
manifestYaml(value):: (
local f = std.native("manifestYamlFromJson");
f(std.toString(value))
),
// escapeStringRegex(s): Quote the regex metacharacters found in s.
// The result is a regex that will match the original literal
// characters.
......
......@@ -27,16 +27,43 @@ baz: xyzzy
");
assert x == [[3, 4], {foo: "bar", baz: "xyzzy"}] : "got " + x;
local x = kubecfg.manifestJson({foo: "bar", baz: [3, 4]});
assert x == '{
"baz": [
3,
4
],
"foo": "bar"
}
' : "got " + x;
local x = kubecfg.manifestJson({foo: "bar", baz: [3, 4]}, indent=2);
assert x == '{
"baz": [
3,
4
],
"foo": "bar"
}
' : "got " + x;
local x = kubecfg.manifestYaml({foo: "bar", baz: [3, 4]});
assert x == "baz:
- 3
- 4
foo: bar
" : "got " + x;
local i = kubecfg.resolveImage("busybox");
assert i == "busybox:latest" : "got " + i;
assert kubecfg.regexMatch("o$", "foo");
local r1 = kubecfg.escapeStringRegex("f[o");
assert r1 == "f\\[o" : "got " + r1;
local r = kubecfg.escapeStringRegex("f[o");
assert r == "f\\[o" : "got " + r;
local r2 = kubecfg.regexSubst("e", "tree", "oll");
assert r2 == "trolloll" : "got " + r2;
local r = kubecfg.regexSubst("e", "tree", "oll");
assert r == "trolloll" : "got " + r;
// Kubecfg wants to see something that looks like a k8s object
{
......
......@@ -20,6 +20,9 @@ import (
"encoding/json"
"io"
"regexp"
"strings"
goyaml "github.com/ghodss/yaml"
jsonnet "github.com/strickyak/jsonnet_cgo"
"k8s.io/apimachinery/pkg/util/yaml"
......@@ -40,6 +43,11 @@ func resolveImage(resolver Resolver, image string) (string, error) {
// RegisterNativeFuncs adds kubecfg's native jsonnet functions to provided VM
func RegisterNativeFuncs(vm *jsonnet.VM, resolver Resolver) {
// NB: libjsonnet native functions can only pass primitive
// types, so some functions json-encode the arg. These
// "*FromJson" functions will be replaced by regular native
// version when libjsonnet is able to support this.
vm.NativeCallback("parseJson", []string{"json"}, func(data []byte) (res interface{}, err error) {
err = json.Unmarshal(data, &res)
return
......@@ -61,6 +69,25 @@ func RegisterNativeFuncs(vm *jsonnet.VM, resolver Resolver) {
return ret, nil
})
vm.NativeCallback("manifestJsonFromJson", []string{"json", "indent"}, func(data []byte, indent int) (string, error) {
data = bytes.TrimSpace(data)
buf := bytes.Buffer{}
if err := json.Indent(&buf, data, "", strings.Repeat(" ", indent)); err != nil {
return "", err
}
buf.WriteString("\n")
return buf.String(), nil
})
vm.NativeCallback("manifestYamlFromJson", []string{"json"}, func(data []byte) (string, error) {
var input interface{}
if err := json.Unmarshal(data, &input); err != nil {
return "", err
}
output, err := goyaml.Marshal(input)
return string(output), err
})
vm.NativeCallback("resolveImage", []string{"image"}, func(image string) (string, error) {
return resolveImage(resolver, image)
})
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment