webentwicklung-frage-antwort-db.com.de

Richtige Methode zum Erstellen dynamischer Listen in Ansible

Ich suche Rat. Ich habe den folgenden Code, der eine Liste dynamisch erstellt, die ich später in einer Vorlage verwenden kann.

Dies ist eine Kopie des Testcodes, den ich zusammengestellt habe. Für die eigentliche Rolle habe ich der j2-Vorlage die Variable admins | regex_replace hinzugefü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 bekomme, was ich brauche, aber gehe ich es richtig an?

Ansible Version ist 2.0.2.0 und läuft unter Centos 7.2.

Danke im Voraus.


Bearbeiten: Der resultierende Filter sah dann so aus:

  - 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 dem yaml ein weiterer Parameter hinzugefügt wurde:

state: absent

Ringo wurde wie gewünscht weggelassen.

6
Rowley

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

Wenn Sie nur die Liste möchten, warum nicht:

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

... und wenn Sie die durch Kommas getrennte Liste wirklich als flache Zeichenfolge haben möchten, fügen Sie einfach einen Join-Filter hinzu:

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

Wenn Ihr ultimatives Ziel jedoch eine Vorlage ist, würde ich vorschlagen, dies innerhalb der Vorlage zu tun, da dies im Gegensatz zu logikbezogen ziemlich formatierungsbezogen aussieht (es sei denn, Sie vereinfachen nur für Stapelüberlaufzwecke) ...

7
nitzmahone

Wenn Präfix und Suffix hinzugefügt werden müssen (und alles zu einer Liste gemacht werden muss), schauen Sie sich Folgendes an:

  set_fact:
    extended_etcd_endpoints_list: "{{ groups['etcd'] | map('extract', hostvars, ['ansible_default_ipv4','address']) | map('regex_replace', '^(.*)$','https://\\1:2379') | list  }}"

Was ist: Nimmt die Liste aller Maschinen in der Gruppe etcd, extrahiert die IPv4-Adresse, fügt das Präfix 'https: //' und das Suffix ': 2379' hinzu. Am Ende wird alles in eine Liste umgewandelt.

1
ReSearchIT Eng