9

我不明白如何最好地参数化 Jsonnet 文件,以便我可以从 bash 和另一个 Jsonnet 文件调用同一个文件。

假设我有一个名为 template.jsonnet 的简单模板:

{
  // Required arguments
  name:: error "'name' must be specified",
  port:: error "'port' must be specified",

  ...,
}

我可以很容易地将其合并到另一个 Jsonnet 文件中,并提供其所需的参数值:

{
  local template = = import "./template.jsonnet";

  template + {
    name:: "service",
    port:: 8080,
}

我正在努力确定我可以template.jsonnet从 bash 调用以获得相同结果的预期方式。

我可以使用--ext-str,但这似乎需要std.extVar(x)

一个 GitHub问题表明它--tla-code可能是 std.extVar() 的替代品,但我不明白如何使用它来满足我的需要。

一个后续问题是:如何为参数执行此操作这是一个数组:

{
  local template = = import "./template.jsonnet";

  template + {
    name:: "service",
    port:: [8080,8081,8082],
}
4

1 回答 1

17

最直接的方法是使用一些内联的jsonnet:

jsonnet -e '(import "template.jsonnet") + { name: "service", port: 8080 }'

为了更容易进行参数化,您可以使用 extVars 或顶级参数 (TLA)。

jsonnet -e 'function(name, port) (import "template.jsonnet") + { name: name, port: port }' --tla-str name="blah" --tla-code port='[8080, 8081]'

或者

jsonnet -e '(import "template.jsonnet") + { name: std.extVar("name"), port: std.extVar("port") }' --ext-str name="blah" --ext-code port='[8080, 8081]'

更好的方法是使 template.jsonnet 成为一个函数并使用--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.
  }

然后在另一个 jsonnet 文件中,您可以按如下方式使用它:

local template = import "./template.jsonnet";
{

  filled_template: template(
    name="service",
    port=8080 // or port=[8080,8081,8082]
  )
}

您可以使用 shell 中的模板,如下所示:

jsonnet --tla-code name='"some name"' --tla-code port=8080 template.jsonnet

请注意名称如何需要引号(没有外部'它们将由 shell 解释)。那是因为您可以将任何 jsonnet 代码传递给任何类型的tla-code.

如果要逐字传递字符串,可以使用--tla-str

jsonnet --tla-str name="some name" --tla-code port=8080 template.jsonnet

另一方面,您可以将数组(或对象,或任何 jsonnet 代码)传递给--tla-code

jsonnet --tla-code name='"some name"' --tla-code port='[8080, 8081, 8082]' template.jsonnet

或者,如果您不想更改您的template.jsonnet,您可以使用包装文件来提供我描述的接口:

模板函数.jsonnet:

local template = import "./template.jsonnet";
function(name, port) template + {
  name: name,
  port: port
}
于 2018-01-24T06:20:32.313 回答