【问题标题】:Using jinja variable as an argument in salt function used in a jinja for loop在 jinja for 循环中使用的 salt 函数中使用 jinja 变量作为参数
【发布时间】:2017-01-19 04:52:32
【问题描述】:

我已经搜索了很多,但我的新手阻止我找到有效的解决方案! 这是我的问题(不是那么复杂,或者我认为):

我的支柱数据:

server_access:
  ops: 
    - salt-dev
  ps:
    - client-salt.example.com
  rd:
  ops_trainees:

然后是我的 jinja 模板摘录:

{% set ldap_search_filter_additionnal = [] %}
{% for group in ['ops','ps','rd','ops_trainees'] %}
{% for servers in salt['pillar.get']('server_access:{{ group }}', {}) %}
{% if grains['fqdn'] == servers %}
{% set ldap_search_filter_additionnal = ldap_search_filter_additionnal.append('(isMemberOf="cn={{ group }},ou=test,dc=example,dc=com")') %}
{% endif %}
{% endfor %}
{% endfor %}

我希望循环遍历前 4 个值,然后是第二个(嵌套)循环,将这 4 个值中的每一个用作 salt 函数的参数,然后如果它与 fqdn 匹配,则添加一些 ldap 搜索过滤器等等...

但似乎不可能在 salt 函数调用中使用 jinja 变量,是吗?

如果不是,您专家建议如何获得预期的行为?

奖励:当 if 语句不正确时,您能确认 jinja 循环不会“中断”吗?

谢谢

UPDATE_1

在@Christophe Drevet-Droguet 的第一个命题之后: 我试过了,但我不能让它工作,或者至少满足我的需要,但我确实找到了一些“有点”工作的东西,除非我只让它对第一个元素起作用,尝试如下:

{%- set ldap_search_filter_additionnal = [] -%} 
{%- for server_group, server_name in pillar['server_access'].iteritems() -%} 
{%- if grains['fqdn'] == server_name[0] -%} 
{%- set testo = '(isMemberOf=\"cn='+server_group+',ou=interne,dc=example,dc=com\")' -%} 
{%- set ldap_search_filter_additionnal = ldap_search_filter_additionnal.append(testo) -%} 
{%- endif -%} 
{% endfor %}

我知道我只匹配(使用 if 语句)第一个元素,因为“server_name[0]”的“[0]”,到目前为止我不能做得更好,所以如果你有另一个改进请按我的需要工作:)

UPDATE_2:

好的,我终于得到了我一直在争取的行为,但是代码有点尴尬,所以如果有人有让它更优雅的提示,请把它扔在那里!

以下答案中的工作解决方案。

【问题讨论】:

    标签: for-loop jinja2 salt-stack


    【解决方案1】:

    首先,您不能使用 {{ group }} 语法,因为您已经在 jinja 表达式中。所以你必须使用这个语法:'server_access:' + group

    其次,由于您的支柱数据包含服务器列表,因此我将提供一个空列表 [] 作为默认值,这样无论支柱中是否存在列表,表达式的工作方式都相同。

    {% for servers in salt['pillar.get']('server_access:' + group, []) %}
    

    Jinja 通常不会因虚假陈述而中断。但是,如果变量不是您期望的类型,它很容易中断。因此[] 默认值。

    作为奖励:为了在字典上轻松迭代,我使用以下语法:

    {% for key, value in dict %}
    

    【讨论】:

    • 非常感谢 Christophe 的回答,我终于成功了,请参阅已接受的答案。
    【解决方案2】:

    工作解决方案:

    {%- set ldap_search_filter_additionnal = [] -%}
    {%- for serverGroup, serverName in pillar.get('server_access', {}).iteritems() -%}
    {%- for serverNameFull in serverName -%}
    {%- if serverNameFull == grains['fqdn'] -%}
    {%- set testo = '(isMemberOf=\"cn='+serverGroup+',ou=interne,dc=eloquant,dc=com\")' -%}
    {%- set ldap_search_filter_additionnal = ldap_search_filter_additionnal.append(testo) -%}
    {%- endif -%}
    {% endfor %}
    {% endfor %}
    

    第二个嵌套循环拯救了我,但是如果我很久以前就想到了这个解决方案,我无法接受,但现在我的头正在燃烧我需要一些可以正常工作的东西,请改进这段代码,我通常会去对于干净、整洁和优雅的代码,需要这方面的帮助!

    【讨论】:

    • 如果您只是将serverName 替换为serverList 并将serverNameFull 替换为serverName,应该更容易理解您的代码。问题是每个组的支柱中都有一个服务器列表,而不是服务器名称。如果您只需要一台服务器,则不应使用列表,而应使用简单的值,并且不需要第二个循环。
    • 感谢 Christophe,您对我的变量名说的太对了!我实际上需要多个服务器,这就是我使用列表的原因,每个组中只有一个服务器用于我的测试(我同意这不是很聪明),但我确实在每个组中有多个服务器......非常感谢你的洞察力
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-05-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-23
    • 2019-04-19
    • 2020-08-26
    相关资源
    最近更新 更多