Je cherche des conseils. Le code suivant crée une liste dynamique que je pourrai ensuite utiliser dans un modèle.
Ceci est une copie du code de test que j'ai constitué - pour le rôle réel, je viens d'ajouter la variable admins | regex_replace dans le modèle j2.
---
- 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') }}`
Cela me donne ce qui suit:
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
Alors… j'ai ce dont j'ai besoin, mais est-ce que j'y vais de la bonne façon?
La version d'Ansible est la version 2.0.2.0 fonctionnant sous Centos 7.2.
Merci d'avance.
Edit: Le filtre résultant a fini par ressembler à ceci:
- 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 }}
Après avoir ajouté un autre paramètre au yaml:
state: absent
Ringo a été laissé de côté, comme souhaité.
Les filtres opéreront sur des listes, donc avec with_items est vraiment une perte de temps, et les regex sont assez obtus pour ce que vous faites. Voulez-vous vraiment une chaîne séparée par des virgules ou voulez-vous simplement une liste des noms d'utilisateur extraits de la liste admin_accounts
?
Si vous voulez juste la liste, pourquoi pas:
set_fact:
admin_usernames: "{{ admin_accounts | map(attribute='name') | list }}"
... et si vous voulez vraiment que la liste séparée par des virgules soit une chaîne plate, ajoutez simplement un filtre de jointure:
set_fact:
admin_usernames: "{{ admin_accounts | map(attribute='name') | join(', ') }}"
Si votre cible ultime est un modèle, cependant, je suggérerais de le faire dans le modèle, car cela semble plutôt lié au formatage par rapport à la logique (sauf si vous ne faites que simplifier à des fins de débordement de pile) ...
Quand il est nécessaire d’ajouter un préfixe et un suffixe (et en faisant tout une liste), regardez:
set_fact:
extended_etcd_endpoints_list: "{{ groups['etcd'] | map('extract', hostvars, ['ansible_default_ipv4','address']) | map('regex_replace', '^(.*)$','https://\\1:2379') | list }}"
What is does: prend la liste de toutes les machines du groupe etcd, extrait l'adresse ipv4, ajoute un préfixe 'https: //' et un suffixe ': 2379'. À la fin, tout est transformé en liste.