Reputation: 40296
I can't understand how to best to parameterize a Jsonnet file so that I may call the same file from bash and from another Jsonnet file.
Assuming I have a simple template called template.jsonnet:
{
// Required arguments
name:: error "'name' must be specified",
port:: error "'port' must be specified",
...,
}
I can readily incorporate this into another Jsonnet file and provide its required parameter values with:
{
local template = = import "./template.jsonnet";
template + {
name:: "service",
port:: 8080,
}
I'm struggling to determine the intended way that I could call template.jsonnet
from bash to achieve the same result.
I can use --ext-str
but this appears to require std.extVar(x)
A GitHub issue suggests that --tla-code
may be an alternative to std.extVar() but I don't understand how to use it for my needs.
A follow-up question is: how do do this for a parameter this is an array:
{
local template = = import "./template.jsonnet";
template + {
name:: "service",
port:: [8080,8081,8082],
}
Upvotes: 10
Views: 10087
Reputation: 2991
The most direct way is to use some inline jsonnet:
jsonnet -e '(import "template.jsonnet") + { name: "service", port: 8080 }'
For easier parametrization, you can use extVars or top-level-arguments (TLAs).
jsonnet -e 'function(name, port) (import "template.jsonnet") + { name: name, port: port }' --tla-str name="blah" --tla-code port='[8080, 8081]'
or
jsonnet -e '(import "template.jsonnet") + { name: std.extVar("name"), port: std.extVar("port") }' --ext-str name="blah" --ext-code port='[8080, 8081]'
A better way is to make template.jsonnet a function and use --tla-code
/ --tla-str
:
function(name, port) {
name:: name,
port:: port
// Sidenote: the fields are hidden here, because they use ::,
// use : to make them appear when the object is manifested.
// Sidenote 2: You can provide default argument values.
// For example function(name, port=8080) makes port optional.
}
Then in another jsonnet file you can use it as follows:
local template = import "./template.jsonnet";
{
filled_template: template(
name="service",
port=8080 // or port=[8080,8081,8082]
)
}
And you can use the template from shell as follows:
jsonnet --tla-code name='"some name"' --tla-code port=8080 template.jsonnet
Note how quotation marks are necessary for name (without outer '
they would be interpreted by shell). That's because you can pass any jsonnet code that evaluates to any type in tla-code
.
If you want to pass a string verbatim you can use --tla-str
:
jsonnet --tla-str name="some name" --tla-code port=8080 template.jsonnet
On the other hand you can pass an array (or an object, or any jsonnet code) to --tla-code
:
jsonnet --tla-code name='"some name"' --tla-code port='[8080, 8081, 8082]' template.jsonnet
Alternatively, if you don't want to change your template.jsonnet
you can use a wrapper file to provide the interface that I described:
template_func.jsonnet:
local template = import "./template.jsonnet";
function(name, port) template + {
name: name,
port: port
}
Upvotes: 21