Как включить файлы один за другим, используя ключ словаря в ansible? - PullRequest
0 голосов
/ 01 ноября 2019

Я пытаюсь вызвать тестовые примеры один за другим из ansible. Каждый тестовый пример записывается в файл yml.

---
- hosts: localhost
  tasks:

  - set_fact:
      k8s_tests: 
        san-1.yml: "Scale replica to 1"
        san-2.yml: "Scale replica to 2"

  - name: display local tests
    debug: var=k8s_tests

  - include: "{{ k8s_test_item }}"
    vars:
      local_test: "{{ k8s_test_item }}"
    with_items: "{{ k8s_tests }}"
    loop_control:
      loop_var: k8s_test_item

Когда я его выполняю, порядок файлов неверный. Включение должно выполняться в порядке san-1.yml, а затем san-2.yml, но это было наоборот.

TASK [include] *********************************************************************************
included: /root/oc310/jenkinsrun/containers/K8S/san-2.yml for localhost
included: /root/oc310/jenkinsrun/containers/K8S/san-1.yml for localhost

Поэтому я добавил dictsort для сортировки словаря.

- include: "{{ k8s_test_item }}"
    vars:
      local_test: "{{ k8s_test_item }}"
    with_items: "{{ k8s_tests | dictsort }}"
    loop_control:
      loop_var: k8s_test_item 

, но он пытается включить ключ и значение и завершается неудачей.

TASK [include] *********************************************************************************
included: /root/oc310/jenkinsrun/containers/K8S/san-1.yml for localhost
fatal: [localhost]: FAILED! => {"reason": "Could not find or access '/root/oc310/jenkinsrun/containers/K8S/Scale replica to 1' on the Ansible Controller."}
included: /root/oc310/jenkinsrun/containers/K8S/san-2.yml for localhost
fatal: [localhost]: FAILED! => {"reason": "Could not find or access '/root/oc310/jenkinsrun/containers/K8S/Scale replica to 2' on the Ansible Controller."}

Значения 'Scale replica to 1' и 'Scale replica to 2' не являются файлами, и онине должны быть включены. Я попытался отсортировать по ключу, но все равно он пытается включить на основе значения и не удается.

- include: "{{ k8s_test_item }}"
    vars:
      local_test: "{{ k8s_test_item }}"
    with_items: "{{ k8s_tests | dictsort(false,'key') }}"
    loop_control:
      loop_var: k8s_test_item

ниже тот же вывод

TASK [include] *********************************************************************************
included: /root/oc310/jenkinsrun/containers/K8S/san-1.yml for localhost
fatal: [localhost]: FAILED! => {"reason": "Could not find or access '/root/oc310/jenkinsrun/containers/K8S/Scale replica to 1' on the Ansible Controller."}
included: /root/oc310/jenkinsrun/containers/K8S/san-2.yml for localhost
fatal: [localhost]: FAILED! => {"reason": "Could not find or access '/root/oc310/jenkinsrun/containers/K8S/Scale replica to 2' on the Ansible Controller."}

Мне нужно включить файл взаказать по одному. Как этого добиться?

1 Ответ

1 голос
/ 01 ноября 2019

Вот решение, обеспечивающее правильную сортировку имен файлов. Вам необходимо:

  • Преобразовать словарь в список с фильтром dict2items
  • Извлечь только атрибут key для каждого элемента в спискес map фильтром
  • sort результирующий список

Ниже приведена реализация с отладкой для отображения каждого описанногошаги.

Примечания:

  • Мне пришлось изменить порядок в объявлении var, чтобы получить тот же начальный результат, что и у вас, и получить успешную демонстрацию
  • loopэто новое ключевое слово для определения циклов и здесь эквивалентно with_list. См. документация петли
---
- name: Looping demo
  hosts: localhost
  gather_facts: false

  vars:
    k8s_tests:
      san-2.yml: "Scale replica to 2"
      san-1.yml: "Scale replica to 1"

  tasks:
    - name: Show initial var
      debug:
        var: k8s_tests

    - name: Show transforming dict to list
      debug:
        msg: "{{ k8s_tests | dict2items }}"

    - name: Show attribute extraction
      debug:
        msg: "{{ k8s_tests | dict2items | map(attribute='key') | list }}"

    - name: Show final sorted result
      debug:
        msg: "{{ k8s_tests | dict2items | map(attribute='key') | sort }}"

    - name: Actually looping over the data
      debug:
        var: item
      loop: "{{ k8s_tests | dict2items | map(attribute='key') | sort }}"
...