Ansible 循环遍历列表来构建文件夹结构

问题描述 投票:0回答:2

我得到了以下列表:

vars:

  - sftp_users:

    - name: user1

      authorized: [user1.pub]

      append: True

      home: /cdrstorage/sftp/user1

      sftp_directories:

      - folder1

      - folder2

    - name: user2

      authorized: [user2.pub]

      append: True

      home: /cdrstorage/sftp/user2

      sftp_directories:

      - folder3

  - sftp_subdirectories:

    - source

    - processed

    - rejected

我想为每个用户生成以下结构及其“sftp_directories”和一些常见的“sftp_subdirectories”,如下所示

/cdrstorage/sftp/user1/folder1/source

/cdrstorage/sftp/user1/folder1/processed

/cdrstorage/sftp/user1/folder1/rejected

/cdrstorage/sftp/user1/folder2/source

/cdrstorage/sftp/user1/folder2/processed

/cdrstorage/sftp/user1/folder2/rejected

/cdrstorage/sftp/user2/folder3/source

/cdrstorage/sftp/user2/folder3/processed

/cdrstorage/sftp/user2/folder3/rejected

我怎样才能做到最好。

谢谢!

我已经尝试过 with_nested 和 with_subelements 。无法实现。

list loops ansible path structure
2个回答
1
投票

下面的金贾

  sublist: |
    {% filter from_yaml %}
    {% for user in sftp_users %}
    {% for dir in user.sftp_directories %}
    {% for subdir in sftp_subdirectories %}
    - {{ user.home }}/{{ dir }}/{{ subdir }}
    {% endfor %}
    {% endfor %}
    {% endfor %}
    {% endfilter %}

将创建列表

  sublist:
  - /cdrstorage/sftp/user1/folder1/source
  - /cdrstorage/sftp/user1/folder1/processed
  - /cdrstorage/sftp/user1/folder1/rejected
  - /cdrstorage/sftp/user1/folder2/source
  - /cdrstorage/sftp/user1/folder2/processed
  - /cdrstorage/sftp/user1/folder2/rejected
  - /cdrstorage/sftp/user2/folder3/source
  - /cdrstorage/sftp/user2/folder3/processed
  - /cdrstorage/sftp/user2/folder3/rejected

如果你想迭代结构,请组合列表

  subdirs: "{{ sftp_users|
               map(attribute='sftp_directories')|
               map('product', sftp_subdirectories)|
               map('map', 'join', '/')|
               map('community.general.dict_kv', 'subdirs') }}"
  sftp_subdirs: "{{ sftp_users|zip(subdirs)|map('combine') }}"

给予

  sftp_subdirs:
  - append: true
    authorized:
    - user1.pub
    home: /cdrstorage/sftp/user1
    name: user1
    sftp_directories:
    - folder1
    - folder2
    subdirs:
    - folder1/source
    - folder1/processed
    - folder1/rejected
    - folder2/source
    - folder2/processed
    - folder2/rejected
  - append: true
    authorized:
    - user2.pub
    home: /cdrstorage/sftp/user2
    name: user2
    sftp_directories:
    - folder3
    subdirs:
    - folder3/source
    - folder3/processed
    - folder3/rejected

现在,您可以使用子元素迭代列表

    - debug:
        msg: "{{ item.0.home }}/{{ item.1 }}"
      loop: "{{ sftp_subdirs|subelements('subdirs') }}"
      loop_control:
        label: "{{ item.0.name }}"

给出(删节)

  msg: /cdrstorage/sftp/user1/folder1/source
  msg: /cdrstorage/sftp/user1/folder1/processed
  msg: /cdrstorage/sftp/user1/folder1/rejected
  msg: /cdrstorage/sftp/user1/folder2/source
  msg: /cdrstorage/sftp/user1/folder2/processed
  msg: /cdrstorage/sftp/user1/folder2/rejected
  msg: /cdrstorage/sftp/user2/folder3/source
  msg: /cdrstorage/sftp/user2/folder3/processed
  msg: /cdrstorage/sftp/user2/folder3/rejected

用于测试的完整剧本示例

- hosts: localhost

  vars:

    sftp_users:
      - append: true
        authorized: [user1.pub]
        home: /cdrstorage/sftp/user1
        name: user1
        sftp_directories: [folder1, folder2]
      - append: true
        authorized: [user2.pub]
        home: /cdrstorage/sftp/user2
        name: user2
        sftp_directories: [folder3]
    sftp_subdirectories: [source, processed, rejected]

    subdirs: "{{ sftp_users|
                 map(attribute='sftp_directories')|
                 map('product', sftp_subdirectories)|
                 map('map', 'join', '/')|
                 map('community.general.dict_kv', 'subdirs') }}"
    sftp_subdirs: "{{ sftp_users|zip(subdirs)|map('combine') }}"
    sublist: |
      {% filter from_yaml %}
      {% for user in sftp_users %}
      {% for dir in user.sftp_directories %}
      {% for subdir in sftp_subdirectories %}
      - {{ user.home }}/{{ dir }}/{{ subdir }}
      {% endfor %}
      {% endfor %}
      {% endfor %}
      {% endfilter %}

  tasks:

    - debug:
        var: subdirs
    - debug:
        var: sublist
    - debug:
        var: sftp_subdirs

    - debug:
        msg: "{{ item.0.home }}/{{ item.1 }}"
      loop: "{{ sftp_subdirs|subelements('subdirs') }}"
      loop_control:
        label: "{{ item.0.name }}"
      tags: loop

1
投票

欢迎来到SO。下次写完请不要停下来

I have tried it with with_nested and with_subelements. Couldnt achieve it
。给出您编写的实际代码、它给出的结果以及您期望的结果。换句话说,提供一个最小的可重现示例。这可以帮助每个人更好地理解您的问题,并提供一些证据表明您已经诚实地尝试解决您的问题(请参阅SO 用户需要付出多少努力)。谢谢


有很多方法可以实现您的要求。下面的剧本有点牵强,但仅使用 ansible 即可给出您期望的结果,而不需要补充

set_facts
和循环。

---
- hosts: localhost
  gather_facts: false
  vars:
    sftp_users:
      - name: user1
        authorized: [user1.pub]
        append: True
        home: /cdrstorage/sftp/user1
        sftp_directories:
          - folder1
          - folder2
      - name: user2
        authorized: [user2.pub]
        append: True
        home: /cdrstorage/sftp/user2
        sftp_directories:
          - folder3
    sftp_subdirectories:
      - source
      - processed
      - rejected

    _homes: "{{ ['home: '] | product(sftp_users | map(attribute='home')) | map('join') | map('from_yaml') }}"
    _dirs: "{{ ['subdirs: '] 
      | product(
        sftp_users | map(attribute='sftp_directories')
        | map('product', sftp_subdirectories) | map('map', 'join', '/')
      )
      | map('join') | map('from_yaml') }}"

    _all_info: "{{ _homes | zip(_dirs) | map('combine') | subelements('subdirs') }}"

  tasks:
    - name: Example task
      ansible.builtin.debug:
        msg: "I would create {{ item.0.home }}/{{ item.1 }}"
      loop: "{{ _all_info }}"

这给出了(您可以调试中间变量来研究解决方案):

PLAY [localhost] ***********************************************************************************************************************************************************************************************************************

TASK [Example task] ********************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user1', 'subdirs': ['folder1/source', 'folder1/processed', 'folder1/rejected', 'folder2/source', 'folder2/processed', 'folder2/rejected']}, 'folder1/source']) => {
    "msg": "I would create /cdrstorage/sftp/user1/folder1/source"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user1', 'subdirs': ['folder1/source', 'folder1/processed', 'folder1/rejected', 'folder2/source', 'folder2/processed', 'folder2/rejected']}, 'folder1/processed']) => {
    "msg": "I would create /cdrstorage/sftp/user1/folder1/processed"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user1', 'subdirs': ['folder1/source', 'folder1/processed', 'folder1/rejected', 'folder2/source', 'folder2/processed', 'folder2/rejected']}, 'folder1/rejected']) => {
    "msg": "I would create /cdrstorage/sftp/user1/folder1/rejected"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user1', 'subdirs': ['folder1/source', 'folder1/processed', 'folder1/rejected', 'folder2/source', 'folder2/processed', 'folder2/rejected']}, 'folder2/source']) => {
    "msg": "I would create /cdrstorage/sftp/user1/folder2/source"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user1', 'subdirs': ['folder1/source', 'folder1/processed', 'folder1/rejected', 'folder2/source', 'folder2/processed', 'folder2/rejected']}, 'folder2/processed']) => {
    "msg": "I would create /cdrstorage/sftp/user1/folder2/processed"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user1', 'subdirs': ['folder1/source', 'folder1/processed', 'folder1/rejected', 'folder2/source', 'folder2/processed', 'folder2/rejected']}, 'folder2/rejected']) => {
    "msg": "I would create /cdrstorage/sftp/user1/folder2/rejected"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user2', 'subdirs': ['folder3/source', 'folder3/processed', 'folder3/rejected']}, 'folder3/source']) => {
    "msg": "I would create /cdrstorage/sftp/user2/folder3/source"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user2', 'subdirs': ['folder3/source', 'folder3/processed', 'folder3/rejected']}, 'folder3/processed']) => {
    "msg": "I would create /cdrstorage/sftp/user2/folder3/processed"
}
ok: [localhost] => (item=[{'home': '/cdrstorage/sftp/user2', 'subdirs': ['folder3/source', 'folder3/processed', 'folder3/rejected']}, 'folder3/rejected']) => {
    "msg": "I would create /cdrstorage/sftp/user2/folder3/rejected"
}

PLAY RECAP *****************************************************************************************************************************************************************************************************************************
localhost                  : ok=1    changed=0    unreachable=0    failed=0    skipped=0    rescued=0    ignored=0   
© www.soinside.com 2019 - 2024. All rights reserved.