Ansible lặp lại một từ điển với danh sách


15

Tôi có biến sau đây nạp qua 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

Tôi muốn cung cấp thông tin này cho shelllệnh để đặt quyền thích hợp.

Tôi đã thử một số kỹ thuật từ đây: http://docs.ansible.com/playbooks_loops.html nhưng không thể đưa ra giải pháp làm việc.

Có thể lặp lại cấu trúc này? Nếu không, làm thế nào để tôi cấu trúc lại nó để làm cho nó hoạt động? Có thể làm điều này mà không vi phạm quy tắc DRY (ví dụ bao gồm tên người dùng vào mỗi bản ghi) không?

Câu trả lời:


21

Trước hết, bạn có thể muốn xem xét sử dụng filemô-đun , hơn là shell. Đó là ít dễ thất bại, và bề ngoài bình dị. Tuy nhiên, điều đó có thể cung cấp cho bạn một số vấn đề với việc trộn các thư mục, tệp và các tập tin. YMMV.

Đối với trọng tâm của câu hỏi, tôi sẽ thiết lập các biến của bạn như vậy:

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

Vở kịch sẽ như thế này:

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

Ý tưởng tuyệt vời! Cảm ơn! Hoạt động như một lá bùa. BTW Tôi đang sử dụng shellmô-đun vì tôi cần thực hiện ACL đệ quy và điều đó không được aclmô-đun hỗ trợ .
Slava Fomin II

Logic vững chắc. Có vẻ như shelllà đặt cược tốt nhất của bạn với ACL và đệ quy.
Christopher Karel

BTW có thể bỏ qua khóa băm bị thiếu như recursivetrong ví dụ của tôi không? Khi tôi cố gắng truy cập nó và nó bị thiếu, Ansible sẽ dừng việc thực thi Playbook và ném ngoại lệ. Tôi không muốn thêm recursive: falsevào mỗi hồ sơ.
Slava Fomin II

1
Tôi nghĩ cú pháp mặc định sẽ hoạt động : {{ some_variable | default() }}. Vì vậy, trong trường hợp này: {{ item.1.recursive | default(false) }}
Christopher Karel

Tác vụ sẽ thay đổi như thế nào nếu khóa "thư mục" chỉ là một danh sách thay vì từ điển?
Chris F

7

Đây là một ví dụ đầu ra tốt mà bạn có thể tự thử. Tạo một playbook mới gọi là 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

Sau đó chạy playbook như thế này: ansible-playbook -i '172.16.222.131,' iteration_loop.yml

và đầu ra sẽ cung cấp cho bạn cách các mục được truy cập:

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   

1

Giả sử dict={a:[1,2,3],b:[1,2]}như vậy và như vậy:

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

Hiện nay flattened == [1,2,3,1,2]


0

Tôi sẽ định dạng lại các vars của bạn theo định dạng dưới đây:

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

và sau đó là playbook của tôi như sau:

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
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.