2016-04-27 128 views
0

我有一個YAML文件,其中包含我想在Ansible模板中使用的變量。該文件是這樣的:模板中的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

的服務器關鍵並不適用於所有的網站存在,所以你需要或者跳過循環時,它的不確定,或使用空的默認列表,如:

{% for server in site['servers'] | default([]) %} 
{{ server['hostname'] }} 
{% endfor %} 
+0

感謝,馬特。模板我最終在對它的值進行任何操作之前先檢查「servers」鍵,這是一個字典列表。我的模板很長,但至少現在我明白了數據結構! – geary

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