Ansible вложенный цикл и фильтр jinja2 - PullRequest
0 голосов
/ 17 мая 2019

Мне нужно перечислить несколько каталогов в моем проекте, у меня есть такое дерево:

.
└── path
    └── to
        ├── aa
        │   └── x9999
        ├── bb
        │   ├── x9997
        │   └── x9998
        ├── cc
        └── dd

Я сделал это задание в своей пьесе, чтобы найти каталоги:

---
- name: 'test of find'
  hosts: localhost
  vars:
    loopVar:
      - 'aa'
      - 'bb'
      - 'cc'
      - 'dd'
  tasks:
    - name: 'find'
      find:
        path: '/path/to/{{item}}'
        file_type: directory
        patterns: '[^_]*[a-z]+[0-9]{4}[a-z]*$'
        use_regex: yes
      register: list
      loop: '{{loopVar}}'

и результат:

{
    "list": {
        "results": [
            {
                "files": [
                    {
                        "path": "/path/to/aa/x9999"
                    }
                ],
                "item": "aa",
                "matched": 1
            },
            {
                "files":  [
                    {
                        "path": "/path/to/bb/x9997"
                    },
                    {
                        "path": "/path/to/bb/x9998"
                    }
                ],

                "item": "bb",
                "matched": 2
            },
            {
                "files": [],
                "item": "cc",
                "matched": 0
            },
            {
                "files": [],
                "item": "dd",
                "matched": 0
            }
        ]
    }
}

Я хочу вызвать include_role с этим массивом, но я не могу сделать это таким образом, потому что мне нужно иметь var на том же уровне, что и path. Я хочу работать над своим результатом, чтобы иметь такой вид значения:

{ "final": [
    { "path": "/path/to/aa/x9999", "var": "aa" },
    { "path": "/path/to/bb/x9998", "var": "bb" },
    { "path": "/path/to/bb/x9997", "var": "bb" }
  ]
}

Я много чего пробую с set_fact , но я не нахожу, как делать такую ​​работу. Большое спасибо за вашу помощь: -)

Ответы [ 2 ]

1 голос
/ 17 мая 2019

Игра ниже

- find:
    paths: "/path/to/{{ item }}"
    file_type: directory
    recurse: yes
  register: list
  loop: [ aa, bb, cc, dd]
- set_fact:
    pre_final: "{{ list.results|json_query('[].{path: files[].path,
                                                var: item}') }}"
- set_fact:
    final: "{{ final|default([]) + [{'var': item.0.var,
                                     'path': item.1}] }}"
  loop: "{{ lookup('subelements', pre_final, 'path') }}"
- debug:
    var: final

дает (сокращенно):

"final": [
    {
        "path": "/path/to/aa/x9999", 
        "var": "aa"
    }, 
    {
        "path": "/path/to/bb/x9997", 
        "var": "bb"
    }, 
    {
        "path": "/path/to/bb/x9998", 
        "var": "bb"
    }
]
0 голосов
/ 24 мая 2019

Я нашел способ сделать это.Это не мило, но это работает.Я должен использовать модуль include_tasks и заданный json_query:

playbook.yml

---
- name: 'test of find'
  hosts: localhost
  vars:
    loopVar:
      - 'aa'
      - 'bb'
      - 'cc'
      - 'dd'
  tasks:
    - name: 'find'
      find:
        path: '/path/to/{{item}}'
        file_type: directory
        patterns: '[^_]*[a-z]+[0-9]{4}[a-z]*$'
        use_regex: yes
      register: list
      loop: '{{loopVar}}'

    - set_fact:
        all: '{{ list.results|json_query("[].{path: files[].path, var: item, matched: matched}") }}'

    - include_tasks: 'inner.yml'
      vars:
        paths: '{{item.path}}'
        var: '{{item.var}}'
      loop: '{{all}}'
      when: 'item.matched != 0'

    - debug:
        var: final

inner.yaml

---
- set_fact:
    final: '{{ final|default([]) + [{ "path": path|basename, "var": var }] }}'
  loop: '{{paths}}'
  loop_control:
    loop_var: path

Результат:

[root@xxxx path]# ansible-playbook playbook.yml

PLAY [test of find] *********************************************************************************************************************************************************************************************************************

TASK [Gathering Facts] ******************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [find] *****************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=aa)
ok: [localhost] => (item=bb)
ok: [localhost] => (item=cc)
ok: [localhost] => (item=dd)

TASK [set_fact] *************************************************************************************************************************************************************************************************************************
ok: [localhost]

TASK [include_tasks] ********************************************************************************************************************************************************************************************************************
skipping: [localhost] => (item={'var': u'cc', 'path': [], 'matched': 0})
skipping: [localhost] => (item={'var': u'dd', 'path': [], 'matched': 0})
included: /mnt/hgfs/Documents/inner.yml for localhost => (item={'var': u'aa', 'path': [u'/path/to/aa/x9999'], 'matched': 1})
included: /mnt/hgfs/Documents/inner.yml for localhost => (item={'var': u'bb', 'path': [u'/path/to/bb/x9997', u'/path/to/bb/x9998'], 'matched': 2})

TASK [set_fact] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=/path/to/aa/x9999)

TASK [set_fact] *************************************************************************************************************************************************************************************************************************
ok: [localhost] => (item=/path/to/bb/x9997)
ok: [localhost] => (item=/path/to/bb/x9998)

TASK [debug] ****************************************************************************************************************************************************************************************************************************
ok: [localhost] => {
    "final": [
        {
            "path": "x9999",
            "var": "aa"
        },
        {
            "path": "x9997",
            "var": "bb"
        },
        {
            "path": "x9998",
            "var": "bb"
        }
    ]
}

PLAY RECAP ******************************************************************************************************************************************************************************************************************************
localhost                  : ok=8    changed=0    unreachable=0    failed=0

Я не нахожу способ сделать это без использования внешнего плейбука.Если кто-то найдет способ, я с удовольствием его изучу: -)

Спасибо большое.

...