2017-02-10 2 views
5

sagen ich das WörterbuchWie wird dieses Wörterbuch in Ansible durchlaufen?

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

und jetzt habe ich möchte nur eine Schleife über jedes Element (Schlüssel) und dann über jedes Element im Schlüssel (Wert). Ich habe diese

- name: Loop over the dictionary 
    debug: msg="Key={{ item.key }} value={{ item.value }}" 
    with_dict: "{{ war_files }}" 

Und ich dies. Es ist natürlich richtig, aber ist NICHT was ich will.

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']" 
} 

Ich möchte eine Ausgabe erhalten, die

"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 sagt, wie kann ich eine Aufgabe zu iteriert über das Wörterbuch zu schreiben, so dass es durch jede Taste geht, und dann werden die Elemente innerhalb jeder Taste? Im Wesentlichen habe ich ein verschachteltes Array und möchte darüber iterieren?

Antwort

4

Nun, ich konnte nicht eine sehr einfache Möglichkeit, es zu tun, aber finden, mit einem wenig jinja2, können wir etwas von dieser Art erreichen:

/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 }}" 

Und wenn das Textbuch ausgeführt wird :

/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

Thank you! Hier mag ich Chef über Ansible, wo ich einfach Ruby schreiben kann, um über eine Datenstruktur zu iterieren. Im Wesentlichen haben Sie das hier mit Python gemacht, aber diese Syntax ist einfach hässlich. –

+1

@ChrisF Ich schrieb Jinja2, nicht Python. –

+0

Aber ja, ich stimme dir zu. Marionette und Chef haben deswegen einen Vorteil gegenüber Ansible. –

0

Jetzt ansible ermöglicht diese

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