2016-06-07 7 views
1

Ich suche Rat. Ich habe den folgenden Code, der dynamisch eine Liste erstellt, die ich später in einer Vorlage verwenden kann.Richtiger Weg, um dynamische Listen in Ansible zu erstellen

Dies ist eine Kopie des Testcodes, den ich zusammengestellt habe - für die eigentliche Rolle habe ich gerade die Variable admins | regex_replace in die j2-Vorlage eingefügt.

--- 

    - hosts: localhost 
    gather_facts: false 

    vars: 
     # define empty admins var first so ansible doesn't complain 
     admins: 

     admin_accounts: 
     - name: john 
     uid: 1000 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 
     - name: paul 
     uid: 1001 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 
     - name: george 
     uid: 1002 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 
     - name: ringo 
     uid: 1003 
     group: sysadmin 
     shell: /bin/bash 
     comment: "Unix Administrator" 

    tasks: 

     - name: build array of admin user names 
     set_fact: admins="{{ admins}} {{ item.name }}" 
     with_items: "{{ admin_accounts }}" 

     # print out the fact piping through two jinja2 filters 
     # careful with word wrapping 
     - debug: msg={{ admins | regex_replace('\s+',', ') | regex_replace`(',\s(.*)','\\1') }}` 

Das gibt mir folgendes:

PLAY [localhost] *************************************************************** 

TASK [build array of admin user names] ***************************************** 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'john', u'uid': 1000}) 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'paul', u'uid': 1001}) 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'george', u'uid': 1002}) 
ok: [localhost] => (item={u'comment': u'Unix Administrator', u'shell': u'/bin/bash', u'group': u'sysadmin', u'name': u'ringo', u'uid': 1003}) 

TASK [debug] ******************************************************************* 
ok: [localhost] => { 
    "msg": "john, paul, george, ringo" 
} 

PLAY RECAP ********************************************************************* 
localhost     : ok=2 changed=0 unreachable=0 failed=0 

Also ... ich bekommen, was ich brauche, aber bin ich es der richtige Weg zu gehen?

Ansible Version ist 2.0.2.0 auf Centos 7.2 ausgeführt.

Vielen Dank im Voraus.


Edit: Der resultierende Filter endete wie folgt aussehen:

- name: build list of admin user names 
    set_fact: 
     admin_list: "{{ admin_accounts | selectattr('state', 'equalto', 'present') | map(attribute='name') | join(', ') }}" 
    - debug: msg={{ admin_list }} 

Nachdem andere Parameter yaml hinzugefügt:

state: absent 

Ringo weggelassen wurde, wie gewünscht.

Antwort

2

Filter funktionieren auf Listen, so dass die with_items wirklich verschwenderisch sind, und das Regex-Zeug ist ziemlich stumpf für das, was Sie tun. Möchten Sie wirklich eine durch Kommas getrennte Zeichenfolge oder möchten Sie nur eine Liste der Benutzernamen, die aus der admin_accounts Liste extrahiert wurden?

Wenn Sie nur die Liste, warum nicht:

set_fact: 
    admin_usernames: "{{ admin_accounts | map(attribute='name') | list }}" 

... und wenn Sie wirklich die durch Kommata getrennte Liste als flache Zeichenfolge wollen, fügen Sie einfach ein Verknüpfungsfilter:

set_fact: 
    admin_usernames: "{{ admin_accounts | map(attribute='name') | join(', ') }}" 

Wenn Ihr ultimatives Ziel eine Vorlage ist, würde ich vorschlagen, dies innerhalb der Vorlage zu tun, da diese im Gegensatz zur Logik ziemlich formatierungsbezogen aussieht (es sei denn, Sie vereinfachen einfach die Stapelüberlauf-Funktion) ...

+0

Exac tally was ich nicht wusste ich suchte, danke so sehr! Das Codebeispiel wurde für den Post erstellt, Sie haben richtigerweise angenommen, dass dies für eine Vorlage war, aber ich hatte keine Ahnung, wie ich die Formatierung erhalten könnte, die ich in j2 benötigte. Vielen Dank, sehr geschätzt! – Rowley

+0

Entschuldigen Sie die Frage, aber gibt es einen Filter, der es mir erlauben würde, bedingt zu mappen? Ich verweise auf einen json, der zum Erstellen von Benutzerkonten verwendet wird und das "state" -Attribut verwendet, um Account-Aliase für sudoers herauszufinden. Verwenden Sie with_items und wenn Sie zusammen den gewünschten Effekt erzielen. Ich kann in den Ansible-Filtern nicht sehen, wie ich das machen könnte, ohne meinen eigenen Filter zu schreiben. Ich bin gerade ein bisschen davon entfernt ... – Rowley

+0

Habe gerade eine gute Seite auf Filtern gefunden [hier] (http://jinja.pocoo.org/docs/dev/templates/#builtin-filters) und habe selectattr und entdeckt ablehnen Leider sieht es so aus, als ob meine aktuelle Version von ansible jinja2.7, nicht 2.8 verwendet, daher bekomme ich "keinen Test namens 'equalto'. – Rowley

Verwandte Themen