从 jinja2 for 循环动态创建变量名的问题

Issue creating a variable name dynamically from jinja2 for loop

我正在尝试创建一组模板,其中包含基于特定列表和字典动态创建的名称及其内容。

导致问题的部分代码如下。

{% for tenant in object_list %}
{%- set name = 'object_t' + tenant + 'rules' %}
{{name}}:
    - permit ip any {{ tenant_public_ip['object_t' + tenant | string +'_pub'['Subnets'][0] }}
{% endfor %}

# combine acls
complete_acls:
  - name: DEFAULT_ACL
    rules: {{'"{{ default_rules }}"'}}

  {% for tenant in object_list %}
  {% set item= 'object_t' + tenant + 'rules' %}
  - name: Tenant_{{tenant}}_ACCESS-VLANS
    rules: {{"{{item}}"}}
  {% endfor %} 

出现错误:模板化字符串时出现模板错误:预期标记“,”,出现“{”。

正在解析的参数:

object_list: [1, 2, 3, 4, 5]
 
tenant_public_ip: {u''object_t5_pub'': {u''Subnets'': [u''8.51.14.124/28''], u''Vlan_id'': u''5010''}, u''object_t2_pub'': {u''Subnets'': [u''8.51.14.128/28''], u''Vlan_id'': u''2010''}, u''object_t4_pub'': {u''Subnets'': [u''8.51.14.176/28''], u''Vlan_id'': u''4100''}, u''object_t1_pub'': {u''Subnets'': [u''8.51.14.160/28''], u''Vlan_id'': u''1100''}, u''object_t3_pub'': {u''Subnets'': [u''8.51.14.144/28''], u''Vlan_id'': u''3100''}} '

我是 Jinja2 模板的新手,我做错了什么?

我 运行 在第一个问题之后遇到的另一个问题是在像上面那样添加几个模块后组合底部的所有规则。

我得到的规则是 'item' 变量名称拆分为字母 - “o、b、j、e、c、t”,而不是收集之前创建的存储在“object_t_1rules" 例如。我可以通过直接使用创建它们时使用的特定名称而不是使用 for 循环来单独访问它们。我知道 Jinja2 不允许嵌套变量访问。我还能如何在这里实现我想要的?

您的 template/code 中有多个错误,准确地说是以下几行:

{%- set name = 'object_t' + tenant + 'rules' %}
  - permit ip any {{ tenant_public_ip[ip_{{tenant}}_pub][Subnets][0] }}

首先,tenant 是一个整数,您试图将它放在两个字符串之间。 Jinja 比 vanilla Python 更不宽容,所以你需要一个过滤器:

{%- set name = 'object_t' + tenant | string + 'rules' %}

其次,Subnets应该是一个字符串;但是,您正在尝试访问一个名为 Subnets 的对象(因为缺少撇号):

  - permit ip any {{ tenant_public_ip[ip_{{tenant}}_pub]['Subnets'][0] }}

第三,你不需要 {{}} 环绕 tenant:

  - permit ip any {{ tenant_public_ip[ip_tenant_pub]['Subnets'][0] }}

最后,您的 tenant_public_ip 示例字典不包含任何名为 ip_<integer>_pub 的键,仅包含 object_t<integer>_pub。为了让您的代码按预期工作,请将您的字典修改为:

tenant_public_ip: {'ip_1_pub': {'Subnets': ...}, ...}

或将您的模板修改为:

  - permit ip any {{ tenant_public_ip['object_t' + tenant | string + '_pub']['Subnets'][0] }}

就我个人而言,我会选择前者(修改模板)。