Jsonnet
Categories:
Jsonnet is a configuration language for building JSON. It provides capabilities for defining functions, pulling in external data, and other useful features to create dynamic JSON configuration files.
Format
Jsonnet looks very similar to JSON:
{
person1: {
name: 'Alice',
welcome: 'Hello ' + self.name + '!',
},
person2: self.person1 { name: 'Bob' },
}
{
"person1": {
"name": "Alice",
"welcome": "Hello Alice!"
},
"person2": {
"name": "Bob",
"welcome": "Hello Bob!"
}
}
You can learn more about the formatting for Jsonnet on the Jsonnet website: https://jsonnet.org/.
Key Concepts
Standard Library
Jsonnet ships with a number of standard functions. You can read about them here: https://jsonnet.org/ref/stdlib.html.
Importing Jsonnet
Jsonnet can import other jsonnet files (typically with the file extension “.libsonnet”). These files can contain functions, other JSON data, and even other imports:
local func = import 'func.libsonnet';
{
person1: {
name: 'Alice',
welcome: 'Hello ' + self.name + '!',
},
person2: func('Bob'),
}
function(name)
{
name: name,
welcome: 'Hello ' + self.name + '!',
}
Immutable
Jsonnet values are immutable. You cannot change them, you must define a new value. Here is how to handle common scenarios where you might want to change something:
local object1 = {
hello: 'world'
}
object1 + {
hello: 'person'
}
local something = if true then 'else' else 'other';
Native Functions
Jsonnet can be extended with custom functions via Native Functions. These functions are non-standard and are supported only within the current Jsonnet implementation. Any of these functions can be disabled using the jsonnet
configuration.
get(object=null, filter, default=null, prefix='') any
This function is similar to std.get
, except it uses jq filtering instead oa field, and it caches the return value for future get
functions. The key is <prefix>:<field>
, so prefix
should be set if field
may be duplicated.
Due to the way filtering works, the default
value will be returned if the filter doesn’t match anything or if the found value is null
. If you want this function to return null
, keep the default set to null
.
local get() = std.native('get')(object=null, field, default=null, prefix='');
get(object={
a: 'b',
}, field='a', default='a', prefix='b')
getArch() string
This function returns the current architecture based on GOARCH.
local getArch() = std.native('getArch')();
getArch()
getConfig() object
This function returns the current configuration for the application as a Jsonnet object.
local getConfig() = std.native('getConfig')();
config()
getCmd(command, fallback=null, cache=false) string
This function executes a command as the current user and returns the stdout of it. Any errors will cause rendering to fail, unless a fallback is provided.
This function is disabled by default. Set jsonnet.disableGetCmd
to false
to enable it.
local getCmd(command, fallback=null) = std.native('getCmd')(command, fallback);
getCmd('ls -al mydir/', 'mydir')
getEnv(key, fallback=null, cache=false) string
This function returns the string value of the environment variable. If the environment variable is not defined or does not exist, it returns an empty string or a fallback value if provided.
local getEnv(key) = std.native('getEnv')(key);
getEnv('PWD')
getFile(path, fallback=null, cache=false) string
This function returns the string value of a path
(local or http/https via GET). The results are cached for repeat lookups within the current render cycle. For HTTP or HTTPS paths, you can set headers for your request using a #
, the header as a k:v
, and deliminiated by a newline \r\n
, e.g. getEnv('https://example.com/api#myHeader:myValue\r\nmyOtherHeader:myOtherValue'
.
In addition to adding headers, a few “special headers” can be set that will change the underlying client transport:
clientSkipVerify
Disable TLS verification (:
is optional).
If the path is unreachable, an error will be thrown and rendering will halt. You can optionally provide a fallback value to prevent this, this value will be returned instead on failure.
Using this function with URLs is disabled by default. Set jsonnet.disableGetFileHTTP
to false
to enable it.
local getFile(path, fallback=null) = std.native('getFile')(path, fallback);
getFile('~/.bashrc', 'fallback')
getOS () string
This function returns the current architecture based on GOOS.
local getOS() = std.native('getOS')();
getOS()
getPath() string
This function returns the string value of the full directory path containing the target jsonnet file. This value may be an empty string if the exact value cannot be determined.
local getPath() = std.native('getPath')();
getPath()
getRecord(type, name, fallback=null) []string
This function returns a list of sorted string values of a DNS record with type
and name
. The results are cached for repeat lookups within the current render cycle. The currently supported values for type
are a
, aaaa
, cname
, and txt
.
This function is disabled by default. Set jsonnet.disableGetRecord
to false
to enable it.
local getRecord(type, name, fallback=null) = std.native('getRecord')(type, name, fallback);
getRecord('a', 'candid.dev', 'fallback')
randStr(length) string
This function returns a random string of length length
. Will panic if it cannot generate a cryptographically secure value.
local randStr(length) = std.native('randStr')(length);
randStr(10)
regexMatch(regex, string) bool
This function returns a bool if string
matches regex
. Will throw an error if regex
is invalid/doesn’t compile.
local regexMatch(regex, string) = std.native('regexMatch')(regex, string);
regexMatch('^hello world$', 'hello world')
render(string) object
This function renders string
using Jsonnet.
std.native('render')(|||
local regexMatch(regex, string) = std.native('regexMatch')(regex, string);
regexMatch('^hello world$', 'hello world')
|||)
Best Practices
Always Wrap Your Ifs
if
s can be wrapped with parenthesis in Jsonnet or not wrapped. By keeping if
s always wrapped, it makes it easier to understand where they end:
local noWrap = if 'this' then 'that' else 'that' + 'yep'
local withWrap = (if 'this' then 'that' else 'that') + 'yep'
Formatting
“Proper” Jsonnet format/linting recommends:
- Single quotes for strings
- Two spaces, no tabs