如何附加到 jinja2 中的列表以获取 ansible
how to append to a list in jinja2 for ansible
下面是我写的用于ansible的jinja2模板。
{% set port = 1234 %}
{% set server_ip = [] %}
{% for ip in host_ip %}
{% do server_ip.append({{ ip }}:{{ port }}) %}
{% endfor %}
{% server_ip|join(', ') %}
下面是我想要的输出:
devices = 192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234
但是当我 运行 ansible 剧本时,它会抛出如下错误:
"AnsibleError: teme templating string: Encountered unknown tag 'do'. Jinja was looking for th: 'endfor' or 'else'
任何帮助将不胜感激..
试试下面的代码:
{% set port = '1234' %}
{% set server_ip = [] %}
{% for ip in host_ip %}
{{ server_ip.append( ip+":"+port ) }}
{% endfor %}
{{ server_ip|join(',') }}
您将获得:
192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234
对我有用:
- set_fact:
devices: >-
{% for ip in host_ip %}{{ ip }}:1234{% if not loop.last %},{% endif %}{% endfor %}
如果您仍想使用 do
,请添加
jinja2_extensions = jinja2.ext.do
到您的 ansible 配置文件并更改
{% do server_ip.append({{ ip }}:{{ port }}) %}` to `{% do server_ip.append({ip:port}) %}`
我不喜欢任何答案,他们觉得太老套了(不得不担心输出 None
,或使用其他技术的虚假空白),但我认为我找到了一个可行的解决方案出色地。我从 this answer on a related question 中获得灵感并意识到您可以为同一个变量多次调用 set
并且似乎不会受到任何惩罚。
它仍然是一个 tad hacky,因为我不认为它打算像这样工作(话又说回来,Jinja 中的几个设计决策让我摸不着头脑,所以谁知道)。
{% set server_ip = server_ip.append({{ ip }}:{{ port }}) %}
有趣的是,虽然该值确实附加到 server_ip
,但该附加的 return 值(我们现在非常清楚是 None
)并没有分配回server_ip
在 LHS 上。这让我发现声明的 LHS 端似乎是空操作。
所以你也可以这样做并且附加工作:
{% set tmp = server_ip.append({{ ip }}:{{ port }}) %}
然而,如果您打印 tmp
,则什么也没有显示。去图吧。
为了避免使用 {{ server_ip.append( ip+":"+port ) }}
打印出 None
(只花了 20 分钟调试这个),如果你不想使用误导性的 {% set _ = server_ip.append( ip+":"+port ) %}
,你可以回到 Python 基础并执行以下操作:
# Remember that [1, 2] + [3] = [1, 2, 3]
{% set server_ip = server_ip + [ip+":"+port] %}
在 99.9% 的情况下,这将完成工作。但是,在您使用 非常 大列表的特殊情况下,在内存使用方面可能会有一个小的性能下降:在上面的示例中,[1, 2] + [3] = [1, 2, 3]
,[=15] =] 和 [1, 2, 3]
(初始列表和修改后的列表)将在内存中短暂共存,这与不在内存中创建其他对象的 append
方法相反。
map()
和 regex
的在线解决方案:
{{ ["1.1.1.1","2.2.2.2"]|map('regex_replace', '(.+)', "\1:1234")|join(', ') }}
map('regex_replace', '(.+)', "\1:1234")
将 :1234
添加到传递的数组 ["1.1.1.1","2.2.2.2"]
中的任何非空字符串 (.+)
。结果:
1.1.1.1:1234, 2.2.2.2:1234
下面是我写的用于ansible的jinja2模板。
{% set port = 1234 %}
{% set server_ip = [] %}
{% for ip in host_ip %}
{% do server_ip.append({{ ip }}:{{ port }}) %}
{% endfor %}
{% server_ip|join(', ') %}
下面是我想要的输出:
devices = 192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234
但是当我 运行 ansible 剧本时,它会抛出如下错误:
"AnsibleError: teme templating string: Encountered unknown tag 'do'. Jinja was looking for th: 'endfor' or 'else'
任何帮助将不胜感激..
试试下面的代码:
{% set port = '1234' %}
{% set server_ip = [] %}
{% for ip in host_ip %}
{{ server_ip.append( ip+":"+port ) }}
{% endfor %}
{{ server_ip|join(',') }}
您将获得:
192.168.56.14:1234,192.168.56.13:1234,192.168.56.10:1234
对我有用:
- set_fact:
devices: >-
{% for ip in host_ip %}{{ ip }}:1234{% if not loop.last %},{% endif %}{% endfor %}
如果您仍想使用 do
,请添加
jinja2_extensions = jinja2.ext.do
到您的 ansible 配置文件并更改
{% do server_ip.append({{ ip }}:{{ port }}) %}` to `{% do server_ip.append({ip:port}) %}`
我不喜欢任何答案,他们觉得太老套了(不得不担心输出 None
,或使用其他技术的虚假空白),但我认为我找到了一个可行的解决方案出色地。我从 this answer on a related question 中获得灵感并意识到您可以为同一个变量多次调用 set
并且似乎不会受到任何惩罚。
它仍然是一个 tad hacky,因为我不认为它打算像这样工作(话又说回来,Jinja 中的几个设计决策让我摸不着头脑,所以谁知道)。
{% set server_ip = server_ip.append({{ ip }}:{{ port }}) %}
有趣的是,虽然该值确实附加到 server_ip
,但该附加的 return 值(我们现在非常清楚是 None
)并没有分配回server_ip
在 LHS 上。这让我发现声明的 LHS 端似乎是空操作。
所以你也可以这样做并且附加工作:
{% set tmp = server_ip.append({{ ip }}:{{ port }}) %}
然而,如果您打印 tmp
,则什么也没有显示。去图吧。
为了避免使用 {{ server_ip.append( ip+":"+port ) }}
打印出 None
(只花了 20 分钟调试这个),如果你不想使用误导性的 {% set _ = server_ip.append( ip+":"+port ) %}
,你可以回到 Python 基础并执行以下操作:
# Remember that [1, 2] + [3] = [1, 2, 3]
{% set server_ip = server_ip + [ip+":"+port] %}
在 99.9% 的情况下,这将完成工作。但是,在您使用 非常 大列表的特殊情况下,在内存使用方面可能会有一个小的性能下降:在上面的示例中,[1, 2] + [3] = [1, 2, 3]
,[=15] =] 和 [1, 2, 3]
(初始列表和修改后的列表)将在内存中短暂共存,这与不在内存中创建其他对象的 append
方法相反。
map()
和 regex
的在线解决方案:
{{ ["1.1.1.1","2.2.2.2"]|map('regex_replace', '(.+)', "\1:1234")|join(', ') }}
map('regex_replace', '(.+)', "\1:1234")
将 :1234
添加到传递的数组 ["1.1.1.1","2.2.2.2"]
中的任何非空字符串 (.+)
。结果:
1.1.1.1:1234, 2.2.2.2:1234