我有一个YAML文件,其中包含我想在Ansible模板中使用的变量。该文件如下所示:
---
config:
version: "4.0"
description: "Global configuration"
sites:
- name: "Site J"
description: "Ficititious Site J"
servers:
- hostname: server1
- hostname: server2
- hostname: server3
- name: "Site K"
description: "Ficititious Site K"
- name: "Site L"
description: "Ficititious Site L"
我试图引用服务器,但是,在我的生活中无法弄清楚Jinja2模板中的语法。这是我目前的模板:
{{ config | to_nice_json }}
{% for site in config['sites'] %}
{{ site['name'] }}
{{ site['description'] }}
{% endfor %}
输出是:
{
"description": "Global configuration",
"sites": [
{
"description": "Ficititious Site J",
"name": "Site J",
"servers": [
{
"hostname": "server1"
},
{
"hostname": "server2"
},
{
"hostname": "server3"
}
]
},
{
"description": "Ficititious Site K",
"name": "Site K"
},
{
"description": "Ficititious Site L",
"name": "Site L"
}
],
"version": "4.0"
}
Site J
Ficititious Site J
Site K
Ficititious Site K
Site L
Ficititious Site L
我的问题是访问"服务器下的数据:"在现有的网站循环中。嵌套循环最明显的语法:
{% for server in site['servers'] %}
{{ server['hostname'] }}
{% endfor %}
不起作用。我得到这个Ansible错误:
fatal: [localhost] => {'msg': "AnsibleUndefinedVariable: One or more undefined variables: 'dict' object has no attribute 'servers'", 'failed': True}
在每个站点下循环浏览YAML文件中的服务器的正确语法是什么?我尝试了很多变化,似乎找不到合适的变体。
答案 0 :(得分:0)
所有站点中都不存在服务器密钥,因此您需要在未定义时跳过循环,或使用空的默认列表,例如:
{% for server in site['servers'] | default([]) %}
{{ server['hostname'] }}
{% endfor %}
答案 1 :(得分:0)
已经工作了几个小时。试图理解嵌套的字典和列表,以及作为列表的字典键,并取得了一些成功。对于没有Python经验的人来说,在Jinja2中使用复杂的嵌套结构可能很困难。无论如何,这就是我想出的一个模板,它实现了我所追求的目标。该模板包含大量代码,以帮助我理解所涉及的结构。这对我来说是一次学习经历。我觉得这可以用更少的代码完成,但这是我能做的最好的。如果任何人都能看到缩短或改进模板的方法,那就太棒了。
{#
Top-level "config" element contains a dictionary
#}
{%- for config_key,config_value in config.iteritems() -%}
{%- if config_key == "sites" -%}
{%- set sites_list = config_value -%}
{#
Under config, "sites" is a list.
#}
{%- for site_dict in sites_list -%}
{#
Each element of the sites list is a dictionary
#}
{%- for site_key,site_value in site_dict.iteritems() -%}
{#
The dictionary with key="servers" has a list as its value
#}
{%- if site_key == "servers" -%}
{%- set servers_list = site_value -%}
{%- for server_dict in servers_list -%}
{#
Each list value is a dictionary
#}
{%- for server_key,server_value in server_dict.iteritems() -%}
{#
Looking for values where the key is "hostname"
#}
{%- if server_key == "hostname" -%}
{{ server_value }}
{% endif %}
{%- endfor -%}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
{%- endfor -%}
{%- endif -%}
{%- endfor -%}
使用此输入文件:
---
config:
version: "4.0"
description: "Global configuration"
sites:
- name: "Site J"
description: "Ficititious Site J"
servers:
- hostname: server1
- hostname: server2
- hostname: server3
- name: "Site K"
description: "Ficititious Site K"
- name: "Site L"
description: "Ficititious Site L"
模板生成此输出:
server1
server2
server3