【问题标题】:How to run a python append list inside jinja2 template如何在 jinja2 模板中运行 python 追加列表
【发布时间】:2019-09-03 12:30:41
【问题描述】:

我正在尝试在 Jinja2 中使用 python 执行 for 循环,该循环将创建并附加到一个列表 - 但是我认为我可能有语法问题,因为在本机 python 中似乎可以正常工作的代码在 Jinja2 模板中失败。我想要一些关于我可能做错了什么的帮助

在高层次上,代码将使用 aws gather fact 收集的子网列表,使用单独的 yaml 文件中提供的数字来确定要附加到单独列表中的子网数量,以便 for 循环运行,并且填充一个单独的 yaml 文件。

{% set subnets_to_use = [] %}
{% set number_of_subnets = {{ cluster.master }} %}  <-- #this value is set in another yaml file
{% set list = usable_kops_subnets %} <-- this has been set by gather facts seperately
{% set list_len = list | length %}
{% for i in range(number_of_subnets) %}
{{ subnets_to_use.append(list[(i)%list_len]) }} <-- #appears to fail here
{% endfor %}

{% for etcd_host_id in subnets_to_use[:cluster.master] %}
    - instanceGroup: master-{{ etcd_host_id.availability_zone }}-{{ loop.index }}
      name: {{ etcd_host_id.availability_zone }}-{{ loop.index }}
{% endfor %}

"msg": "AnsibleError: 模板化字符串时出现模板错误:预期标记 ':',得到 '}'

当我在 python 编译器中运行类似的 Python 代码时,代码似乎可以工作

例如:

x = 400
list = ["string1","str2","str3","str4"]
subnets_to_use = []
list_len = len(list)
for i in range(x):
       subnets_to_use.append(list[(i)%list_len])
print (subnets_to_use)

【问题讨论】:

  • 在将subnets_to_use 发送到模板之前,将所有元素附加到subnets_to_use
  • 感谢您的回答 - 您是否建议在模板之外进行设置?
  • 这是最自然的方法 - 在将所有需要的数据发送到模板之前创建它们。没有创建模板来替换 Python 的代码。
  • 在模板之外这样做有意义吗?
  • Python 的代码应该收集所有数据,然后使用模板显示数据。在模板中混合代码只会像在 PHP 中那样混乱。

标签: python ansible jinja2


【解决方案1】:

您的注意力似乎在错误的路线上。改变这一行

{% set number_of_subnets = {{ cluster.master }} %}

到这里

{% set number_of_subnets = cluster.master %}

然后它应该可以正常工作了。

【讨论】:

    【解决方案2】:

    我最终在 ansible 中使用了以下内容,而不是使用 python - 似乎有效。在这个实例中,clusters.node 被定义为 3,我有一个 aws 收集事实的子网。我想要创建 3 个实例组,它们都具有相同的子网。

    - name: setup of subnet variables on nodes
      hosts: localhost
      gather_facts: false
      vars:
        subnets: "{{usable_kops_subnets}}"
        subnet_length: "{{subnets | length }}"
        servers: "{{cluster.node}}"
        slist_nodes: []
      tasks:
      - name: slist_nodes setup
        set_fact:
           slist_nodes: '{{ slist_nodes + [subnets[(item|int + 0) % (subnet_length|int + 0)]] }}'
        loop: "{{range(0,servers|int,1)| list}}"
    

    然后我针对“slist_nodes”列表运行循环,例如

    {% for subnet in slist_nodes %}
    
    < code>
    
    {% endfor %}
    

    这将使用子网创建 3 个实例。

    【讨论】:

      猜你喜欢
      • 2017-07-17
      • 2013-01-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-05-09
      • 1970-01-01
      • 2014-02-13
      相关资源
      最近更新 更多