Назад | Перейти на главную страницу

Ansible перебирает словарь со списками

У меня загружена следующая переменная через 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

Я хочу передать эту информацию в shell команда, чтобы установить соответствующие разрешения.

Я пробовал некоторые техники отсюда: http://docs.ansible.com/playbooks_loops.html но не смог найти рабочего решения.

Можно ли повторить эту структуру? Если нет, как мне реструктурировать его, чтобы он работал? Можно ли сделать это, не нарушая правила DRY (например, включать имя пользователя в каждую запись)?

Во-первых, вы можете рассмотреть возможность использования file модуль, скорее, чем shell. Он менее подвержен ошибкам и якобы идемпотентен. Однако это может вызвать проблемы со смешиванием каталогов, файлов и файловых глобусов. YMMV.

Что касается сути вопроса, я бы настроил ваши переменные так:

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

Тогда спектакль будет выглядеть так:

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

Это хороший пример вывода, который вы можете попробовать сами. Создайте новую книгу под названием 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

Затем запустите playbook следующим образом: ansible-playbook -i '172.16.222.131,' iteration_loop.yml

и вывод должен показать вам, как осуществляется доступ к элементам:

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   

При условии, что dict={a:[1,2,3],b:[1,2]} и так далее:

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

Сейчас flattened == [1,2,3,1,2]

Я переформатирую ваши вары в следующий формат:

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

а затем мою пьесу, как показано ниже:

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