web-dev-qa-db-fra.com

Possibilité d'itérer 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 alimenter ces informations à la commande Shell afin de définir les autorisations appropriées.

J'ai essayé quelques techniques d'ici: http://docs.ansible.com/playbooks_loops.html mais je n'ai pas réussi à trouver une solution de travail.

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

15
Slava Fomin II

Tout d'abord, vous pouvez envisager d'utiliser le module file , plutôt que Shell. Il est moins sujet aux pannes et ostensiblement idempotent. Cependant, cela peut vous poser quelques problèmes avec le mélange des répertoires, des fichiers et des globes de fichiers. YMMV.

Quant au 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

Le jeu 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
21
Christopher Karel

Ceci est un bon exemple de sortie que vous pouvez essayer vous-même. Créez un nouveau livre de jeu 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

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

et la sortie devrait vous indiquer comment accéder aux éléments:

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   
7
Egidijus

En admettant que dict={a:[1,2,3],b:[1,2]} etc:

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

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

2
Max Murphy

Je vais reformater vos vars 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

puis 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
0
user42826