พูดซ้ำพจนานุกรมที่มีรายการ


15

ฉันโหลดตัวแปรต่อไปนี้ผ่าน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 (เช่นรวมชื่อผู้ใช้ไว้ในทุก ๆ บันทึก)?

คำตอบ:


21

ปิดแรกคุณอาจต้องการที่จะต้องพิจารณาโดยใช้fileโมดูลshellมากกว่า มันล้มเหลวน้อยลงง่ายและ idempotent อย่างเห็นได้ชัด อย่างไรก็ตามนั่นอาจทำให้คุณมีปัญหาเกี่ยวกับการผสมไดเรกทอรีไฟล์และไฟล์ globs 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

ความคิดที่ดี! ขอบคุณ! ทำงานเหมือนจับใจ BTW ฉันกำลังใช้shellโมดูลเพราะฉันต้องทำ ACL แบบเรียกซ้ำและไม่ได้รับการสนับสนุนจากaclโมดูล
Slava Fomin II

ตรรกะที่มั่นคง ดูเหมือนว่าshellเป็นทางออกที่ดีที่สุดของคุณด้วย ACL และการเรียกซ้ำ
Christopher Karel

BTW เป็นไปได้ไหมที่จะเพิกเฉยต่อคีย์แฮชที่หายไปอย่างrecursiveในตัวอย่างของฉัน เมื่อฉันพยายามที่จะเข้าถึงมันและมันหายไป Ansible จะหยุดการดำเนินการของ playbook และโยนข้อยกเว้น ฉันไม่ต้องการเพิ่มrecursive: falseในทุกระเบียน
Slava Fomin II

1
{{ some_variable | default() }}ผมคิดว่าไวยากรณ์เริ่มต้นควรทำงาน: ดังนั้นในกรณีนี้: {{ item.1.recursive | default(false) }}
Christopher Karel

งานจะเปลี่ยนแปลงอย่างไรหากคีย์ "ไดเรกทอรี" เป็นเพียงรายการแทนที่จะเป็นพจนานุกรมด้วย?
Chris F

7

นี่เป็นตัวอย่างผลลัพธ์ที่ดีที่คุณสามารถลองได้ สร้าง playbook ใหม่ชื่อ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   

1

สมมติว่าdict={a:[1,2,3],b:[1,2]}เป็นต้น:

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

ตอนนี้ flattened == [1,2,3,1,2]


0

ฉันจะฟอร์แมต vars ของคุณเป็นรูปแบบด้านล่าง:

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

แล้ว playbook ของฉันดังนี้:

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
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.