2017-02-10 43 views
5

Say mam tego słownikaJak zapętlić ten słownik w Ansible?

war_files: 
    server1: 
    - file1.war 
    - file2.war 
    server2: 
    - file1.war 
    - file2.war 
    - file3.war 

i teraz po prostu chcę pętli na każdej pozycji (key), a następnie na każdej pozycji w kluczu (wartości). Zrobiłem to:

I rozumiem to. Jest to oczywiście poprawne, ale NIE jest to, czego chcę.

ok: [localhost] => (item={'value': [u'file1.war', u'file2.war'], 'key': u'server1'}) => { 
    "item": { 
     "key": "server1", 
     "value": [ 
      "file1.war", 
      "file2.war" 
     ] 
    }, 
    "msg": "Server=server1, WAR=[u'file1.war', u'file2.war']" 
} 
ok: [localhost] => (item={'value': [u'file1.war', u'file2.war', u'file3.war'], 'key': u'server2'}) => { 
    "item": { 
     "key": "server2", 
     "value": [ 
      "file1.war", 
      "file2.war", 
      "file3.war" 
     ] 
    }, 
    "msg": "Server=server2, WAR=[u'file1.war', u'file2.war', u'file3.war']" 
} 

Chcę uzyskać dane wyjściowe, które mówi

"msg": "Server=server1, WAR=file1.war" 
"msg": "Server=server1, WAR=file2.war" 
"msg": "Server=server2, WAR=file1.war" 
"msg": "Server=server2, WAR=file2.war" 
"msg": "Server=server2, WAR=file3.war" 

IOW, jak mogę napisać zadanie iteruje słownika więc przechodzi przez każdy klucz, a następnie elementy wewnątrz każdego klucza? W gruncie rzeczy mam zagnieżdżoną tablicę i chcę ją powtórzyć?

Odpowiedz

4

Cóż, nie mogłem znaleźć bardzo łatwy sposób to zrobić, jednak z odrobiną jinja2, możemy osiągnąć coś w tym rodzaju:

/tmp ❯❯❯ cat example.yml 
--- 
- hosts: 127.0.0.1 
    vars: 
    war_files: 
     server1: 
     - file1.war 
     - file2.war 
     server2: 
     - file1.war 
     - file2.war 
     - file3.war 
    tasks: 
    - set_fact: 
     war_files_list_of_dicts: | 
      {% set res = [] -%} 
      {% for key in war_files.keys() -%} 
      {% for value in war_files[key] -%} 
       {% set ignored = res.extend([{'Server': key, 'WAR':value}]) -%} 
      {%- endfor %} 
      {%- endfor %} 
      {{ res }} 

    - name: let's debug the crap out of this 
    debug: var=war_files_list_of_dicts 

    - name: Servers and their WARs!!! 
    debug: 
     msg: "Server={{ item.Server }}, WAR={{ item.WAR }}" 
    with_items: "{{ war_files_list_of_dicts }}" 

A kiedy PlayBook jest prowadzony :

/tmp ❯❯❯ ansible-playbook example.yml 
[WARNING]: provided hosts list is empty, only localhost is available 


PLAY [127.0.0.1] *************************************************************** 

TASK [setup] ******************************************************************* 
ok: [127.0.0.1] 

TASK [set_fact] **************************************************************** 
ok: [127.0.0.1] 

TASK [let's debug the crap out of this] **************************************** 
ok: [127.0.0.1] => { 
    "war_files_list_of_dicts": [ 
     { 
      "Server": "server1", 
      "WAR": "file1.war" 
     }, 
     { 
      "Server": "server1", 
      "WAR": "file2.war" 
     }, 
     { 
      "Server": "server2", 
      "WAR": "file1.war" 
     }, 
     { 
      "Server": "server2", 
      "WAR": "file2.war" 
     }, 
     { 
      "Server": "server2", 
      "WAR": "file3.war" 
     } 
    ] 
} 

TASK [Servers and their WARs!!!] *********************************************** 
ok: [127.0.0.1] => (item={'WAR': u'file1.war', 'Server': u'server1'}) => { 
    "item": { 
     "Server": "server1", 
     "WAR": "file1.war" 
    }, 
    "msg": "Server=server1, WAR=file1.war" 
} 
ok: [127.0.0.1] => (item={'WAR': u'file2.war', 'Server': u'server1'}) => { 
    "item": { 
     "Server": "server1", 
     "WAR": "file2.war" 
    }, 
    "msg": "Server=server1, WAR=file2.war" 
} 
ok: [127.0.0.1] => (item={'WAR': u'file1.war', 'Server': u'server2'}) => { 
    "item": { 
     "Server": "server2", 
     "WAR": "file1.war" 
    }, 
    "msg": "Server=server2, WAR=file1.war" 
} 
ok: [127.0.0.1] => (item={'WAR': u'file2.war', 'Server': u'server2'}) => { 
    "item": { 
     "Server": "server2", 
     "WAR": "file2.war" 
    }, 
    "msg": "Server=server2, WAR=file2.war" 
} 
ok: [127.0.0.1] => (item={'WAR': u'file3.war', 'Server': u'server2'}) => { 
    "item": { 
     "Server": "server2", 
     "WAR": "file3.war" 
    }, 
    "msg": "Server=server2, WAR=file3.war" 
} 

PLAY RECAP ********************************************************************* 
127.0.0.1     : ok=4 changed=0 unreachable=0 failed=0 
+0

Dziękujemy! To jest miejsce, w którym lubię Chef over Ansible, gdzie mogę napisać Ruby do iteracji nad strukturą danych. Zasadniczo to właśnie robiłeś z Pythonem, ale ta składnia jest po prostu brzydka. –

+1

@ChrisF Napisałem jinja2, a nie python. –

+0

Ale tak, zgadzam się z tobą. Marionetka i szef kuchni mają przewagę nad Ansible z tego powodu. –

0

teraz ansibl pozwala to

- name: add several users 
    user: 
    name: "{{ item.name }}" 
    state: present 
    groups: "{{ item.groups }}" 
    with_items: 
    - { name: 'testuser1', groups: 'wheel' } 
    - { name: 'testuser2', groups: 'root' }