如何在 jinja2 语句中调用 salt 函数时使用 jinja2 变量作为参数

How to use a jinja2 variable as an arg in a call to salt function inside a jinja2 statement

这就是我正在做的事情。

  1. 我正在遍历支柱键值并分配给变量 shopt_option
  2. 如果字符串 'shopt_' 在变量 shopt_option 的值中,它运行一个嵌套的 if 语句
  3. 然后在 jinja2 封装的语句中,我需要设置一个变量来等于调用 salt 函数的输出。
  4. 该盐函数的参数之一也需要是循环中的变量。
  5. 我已经尝试了 2 小时的不同方法来编写此内容,我将在下面粘贴的内容当然是错误的语法,但有助于说明我想做什么,因为我知道在您执行的 jinja2 语句中引用变量时不要将其封装在双 curly 大括号中。
  6. 然而,作为括号内的 arg 似乎搞砸了使用 jinja2 变量的任何方式。
  7. 当往下看时,这是需要修复的行,我也愿意用其他方式来写它

    {% set shopt_option_value = salt['pillar.get']('user_management:bash_configurations:global:bashrc:{{ shopt_option }}') %}
    

Whosebug 上有一张票,他们将一个变量嵌套在一个接近的变量中,但在调用 salt 函数时不起作用。 Whosebug url 是

这是循环:

{# Loop through all global shopt option key names and set values accordingly #}
{% for shopt_option in salt['pillar.keys']('user_management:bash_configurations:global:bashrc') %}
  {% if 'shopt_' in shopt_option %}
    {% set shopt_option_value = salt['pillar.get']('user_management:bash_configurations:global:bashrc:{{ shopt_option }}') %}
    {% if shopt_option_value == 'True' %}
  shopt -s {{ shopt_option|replace("shopt_","") }}
    {% elif shopt_option_value == 'False' %}
  shopt -u {{ shopt_option|replace("shopt_","") }}
    {% elif shopt_option_value == 'default' %}
      # {{ shopt_option|replace("shopt_","") }} OS Default implied
    {% endif %}
      shopt_option_value is {{ shopt_option_value }} for debugging this
  {% endif %}
{% endfor %}

这是支柱 yaml 数据结构片段:

user_management:
  bash_configurations:
    global:
      bashrc:
        system_reserved_uid: 199
        system_reserved_umask: '077'
        non_system_reserved_umask: '077'
        shopt_autocd: default
        shopt_cdable_vars: default
        shopt_cdspell: False
        shopt_checkhash: default

我找到了一种更好的方法来遍历支柱键名称和/或值。

解决方案:

{%- for shopt_option_key in pillar['user_management']['bash_configurations']['global']['bashrc'] %}

似乎是另一种说法:

原尝试:

{% for shopt_option in salt['pillar.keys']('user_management:bash_configurations:global:bashrc') %}

然而,在 jinja2 语句中,以这种方式,文字值使用单引号而不带引号,正如您所期望的那样,它引用了 jinja2 变量的值。

有很多其他方法可以解决这个问题,我在看,这只是其中一种方法,可能不是最优雅的,所以我认为这是一个很好的解决方案(不是我发现的最糟糕的,也不是最糟糕的最好)。

这是最终的解决方案:

{#- Loop through all global shopt option key names and set values accordingly #}
{%- for shopt_option_key in pillar['user_management']['bash_configurations']['global']['bashrc'] %}
  {%- set shopt_option_value = pillar['user_management']['bash_configurations']['global']['bashrc'][shopt_option_key] %}
  {%- if 'shopt_' in shopt_option_key %}
    {%- if shopt_option_value %}
      shopt -s {{ shopt_option_key|replace("shopt_","") }}
    {%- elif shopt_option_value == False %}
      shopt -u {{ shopt_option_key|replace("shopt_","") }}
    {%- elif shopt_option_value == 'default' %}
      # {{ shopt_option_key|replace("shopt_","") }} OS Default implied
    {%- endif %}
  {%- endif %}
{%- endfor %}

这里有一些额外的改进说明:

  1. 这里的减号,{%- 修剪了前导白色 space 所以我不会在创建的文件中有空行
  2. 在 jinja2 中,如果键的值设置为布尔值,则不能在 'True' 或 'False' 比较前后使用引号,因为它将比较的值视为字符串,我不得不删除引号以将其视为 Boolean