Как вызвать параметризованный Jsonnet из bash?

Я не могу понять, как лучше всего параметризовать файл 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],
}

1 ответ

Решение

Самый прямой способ - использовать встроенный 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]
  )
}

И вы можете использовать шаблон из оболочки следующим образом:

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

Обратите внимание, что кавычки необходимы для имени (без внешнего ' они будут интерпретированы оболочкой). Это потому, что вы можете передать любой код 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 Вы можете использовать файл-обертку для предоставления интерфейса, который я описал:

template_func.jsonnet:

local template = import "./template.jsonnet";
function(name, port) template + {
  name: name,
  port: port
}
Другие вопросы по тегам