15 votes

Ansible itère un dictionnaire avec des listes

J'ai la variable suivante chargée via include_vars :

access:
    username-foo:
      - path: /
        permissions: rwX
        recursive: true

    username-bar:
      - path: /
        permissions: rX

      - path: /css
        permissions: rwX
        recursive: true

      - path: /data
        permissions: rX

      - path: /data/reviews.yml
        permissions: rw

      - path: /js
        permissions: rX

      - path: /js/*.js
        permissions: rw

Je veux transmettre ces informations à la shell afin de définir les permissions appropriées.

J'ai essayé certaines techniques d'ici : http://docs.ansible.com/playbooks_loops.html mais n'a pas réussi à trouver une solution efficace.

Est-il possible d'itérer cette structure ? Si non, comment la restructurer pour qu'elle fonctionne ? Est-il possible de le faire sans enfreindre la règle DRY (par exemple, inclure le nom d'utilisateur dans chaque enregistrement) ?

21voto

isherwood Points 107

Tout d'abord, vous pouvez envisager d'utiliser la fonction file module plutôt que shell . Il est moins sujet à l'échec, et ostensiblement idempotent. Cependant, cela peut poser des problèmes lorsqu'on mélange des répertoires, des fichiers et des goujons de fichiers. YMMV.

Pour ce qui est du cœur de la question, je configurerais vos variables comme suit :

users:
  - username: bar
    directories:
      - path: /data
        permissions: rX
      - path: /js
        permissions: rX
  - username: foo
    directories:
      - path: /
        permissions: rwX

La pièce ressemblerait alors à ceci :

- name: Change mod/own
  shell: chown {{ item.0.username }} {{ item.1.path }};chmod u+{{ item.1.permissions }} {{ item.1.path }
  with_subelements:
    - users
    - directories

0 votes

Excellente idée ! Merci de votre attention ! Ça marche du tonnerre. BTW J'utilise shell car j'ai besoin de faire de l'ACL récursif et cela n'est pas supporté par le module acl module.

0 votes

Une logique solide. On dirait que shell est votre meilleur atout pour les ACL et la récursivité.

0 votes

BTW est-il possible d'ignorer une clé de hachage manquante comme recursive dans mon exemple ? Lorsque j'essaie d'y accéder et qu'il est manquant, Ansible arrête l'exécution du playbook et lève une exception. Je préfère ne pas ajouter recursive: false à chaque enregistrement.

7voto

Egidijus Points 109

Voici un bon exemple de sortie que vous pouvez essayer vous-même. Créez un nouveau playbook appelé iteration_loop.yml :

---

- name: Change mod/own
  hosts: all
  tasks:
  - name: show me the iterations
    debug: msg={{ item.0.username }} {{ item.1.path }} then {{ item.1.permissions }} {{ item.1.path }}
    with_subelements:
      - users
      - directories
  vars:
    users:
      - username: bar
        directories:
          - path: /data
            permissions: rX
          - path: /js
            permissions: rX
      - username: foo
        directories:
          - path: /
            permissions: rwX

Ensuite, exécutez le playbook comme ceci : ansible-playbook -i '172.16.222.131,' iteration_loop.yml

et la sortie devrait vous donner la façon dont les éléments sont accessibles :

PLAY [Change mod/own] ********************************************************* 

GATHERING FACTS *************************************************************** 
ok: [172.16.222.131]

TASK: [show me the iterations] ************************************************ 
ok: [172.16.222.131] => (item=({'username': 'bar'}, {'path': '/data', 'permissions': 'rX'})) => {
    "item": [
        {
            "username": "bar"
        }, 
        {
            "path": "/data", 
            "permissions": "rX"
        }
    ], 
    "msg": "bar"
}
ok: [172.16.222.131] => (item=({'username': 'bar'}, {'path': '/js', 'permissions': 'rX'})) => {
    "item": [
        {
            "username": "bar"
        }, 
        {
            "path": "/js", 
            "permissions": "rX"
        }
    ], 
    "msg": "bar"
}
ok: [172.16.222.131] => (item=({'username': 'foo'}, {'path': '/', 'permissions': 'rwX'})) => {
    "item": [
        {
            "username": "foo"
        }, 
        {
            "path": "/", 
            "permissions": "rwX"
        }
    ], 
    "msg": "foo"
}

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

2voto

Max Murphy Points 141

En supposant que dict={a:[1,2,3],b:[1,2]} et ainsi de suite :

- name: Flattened list
  set_fact:
    flattened: "{{ dict.values() | sum(start=[]) }}"

Maintenant flattened == [1,2,3,1,2]

0voto

user42826 Points 101

Je vais reformater vos variables au format ci-dessous :

access:
- username: foo
  directories:
    - path: /
      permissions: rwX
      recursive: true

- username: bar
  directories:
    - path: /
      permissions: rX
      recursive: false

    - path: /css
      permissions: rwX
      recursive: true

    - path: /data
      permissions: rX
      recursive: false

    - path: /data/reviews.yml
      permissions: rw
      recursive: false

    - path: /js
      permissions: rX
      recursive: false

    - path: /js/*.js
      permissions: rw
      recursive: false

et ensuite mon playbook comme ci-dessous :

tasks:
- name: Iterate the vars inside var4 when recursive
  debug: msg="username is {{ item.0.username }} and path is {{ item.1.path }} permission is {{ item.1.permissions }} and recursive"
  when: item.1.recursive
  ignore_errors: true
  with_subelements:
    - "{{ access }}"
    - directories
- name: Iterate the vars inside var4 when no recursive
  debug: msg="username is {{ item.0.username }} and path is {{ item.1.path }} permission is {{ item.1.permissions }}"
  when: not item.1.recursive
  ignore_errors: true
  with_subelements:
    - "{{ access }}"
    - directories

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X