Spec-Zone.ru › Ansible

Разработка модулей сетевых ресурсов

  • Изучение модулей сетевых и защитных ресурсов
  • Разработка модулей сетевых и защитных ресурсов

    • Изучение модели и конструктора модулей ресурсов
    • Доступ к конструктору модулей ресурсов
    • Создание модели
    • Создание каркаса коллекции из модели ресурса
  • Примеры

    • Структура каталога коллекции
    • Структура каталога роли
    • Использование коллекции
    • Использование роли
  • Структура и рабочий процесс модуля ресурса
  • Выполнение ansible-test sanity и tox для модулей ресурсов
  • Тестирование модулей ресурсов

    • Интеграционные тесты модулей ресурсов
    • Требования к тестам на единицу
  • Пример: Тестирование на единицу модулей ресурсов Ansible для сетей

    • Использование эмуляторов для тестирования модулей ресурсов Ansible для сетей
    • Моделирование данных устройства

Изучение модулей сетевых и защитных ресурсов

Сетевые и защитные устройства разделяют конфигурацию на разделы (например, интерфейсы, VLANы и так далее), которые применяются к сети или службе безопасности. Модули ресурсов Ansible используют это для того, чтобы пользователи могли настраивать подразделы или ресурсы в конфигурации устройства. Модули ресурсов обеспечивают согласованный опыт работы с различными сетевыми и защитными устройствами. Например, модуль сетевого ресурса может обновлять только конфигурацию определённой части сетевых интерфейсов, VLANов, ACL и т. д. для сетевого устройства. Модуль ресурса:

  1. Извлекает часть конфигурации (сбор фактов), например, конфигурацию интерфейсов.
  2. Преобразует полученную конфигурацию в пары «ключ-значение».
  3. Размещает эти пары «ключ-значение» в внутреннем независимом структурированном формате данных.

Теперь, когда данные конфигурации нормализованы, пользователь может обновить и изменить данные, а затем использовать модуль ресурса для отправки данных конфигурации обратно на устройство. Это приводит к полному обновлению конфигурации без необходимости ручного парсинга, обработки данных и управления моделью данных.

Модуль ресурса имеет два ключевых элемента верхнего уровня - config и state:

  • config определяет модель данных конфигурации ресурса как пары «ключ-значение». Тип опции config может быть dict или list of dict в зависимости от управляемого ресурса. То есть, если устройство имеет одну глобальную конфигурацию, она должна быть типа dict (например, глобальная конфигурация LLDP). Если устройство имеет несколько экземпляров конфигурации, она должна быть типа list с каждым элементом в списке типа dict (например, конфигурация интерфейсов).
  • state определяет действие, которое модуль ресурса выполняет на целевом устройстве.

state для нового модуля ресурса должен поддерживать следующие значения (по мере необходимости для устройств, которые их поддерживают):

merged

Ansible объединяет конфигурацию на устройстве с предоставленной конфигурацией в задаче.

replaced

Ansible заменяет подсекцию конфигурации на устройстве подсекцией предоставленной конфигурации в задаче.

overridden

Ansible перезаписывает подсекцию конфигурации на устройстве предоставленной конфигурацией в задаче. Используйте с осторожностью, так как вы можете удалить доступ к устройству (например, перезаписав конфигурацию интерфейса управления).

deleted

Ansible удаляет подсекцию конфигурации на устройстве и восстанавливает любые значения по умолчанию.

gathered

Ansible отображает подробности ресурса, собранные с сетевого устройства, и доступные с ключом gathered в результате.

rendered

Ansible преобразует предоставленную конфигурацию в задаче в собственный формат устройства (например, Cisco IOS CLI). Ansible возвращает эту преобразованную конфигурацию в ключе rendered в результате. Обратите внимание, что это состояние не взаимодействует с сетевым устройством и может использоваться автономно.

parsed

Ansible анализирует конфигурацию из опции running_configuration в структурированные данные Ansible в ключе parsed в результате. Обратите внимание, что это не собирает конфигурацию с сетевого устройства, поэтому это состояние может использоваться автономно.

Модули в поддерживаемых Ansible коллекциях должны поддерживать эти значения состояния. Если вы разрабатываете модуль только с состояниями «present» и «absent», вы можете отправить его в коллекцию сообщества.

Примечание

Состояния rendered, gathered, и parsed не производят никаких изменений на устройстве.

См. также

Подробный обзор модулей ресурсов VLAN для автоматизации сетей

Пошаговое руководство по реализации значений состояния для VLANов.

Разработка модулей ресурсов сети и безопасности

Команда инженеров Ansible обеспечивает единообразный дизайн модулей и шаблонов кода в поддерживаемых Ansible коллекциях для ресурсов и платформ, чтобы обеспечить независимость от поставщика и создавать качественный код. Рекомендуется использовать построитель модулей ресурсов для разработки модуля ресурса.

Процесс разработки модуля ресурса в общих чертах:

  1. Создайте и поделитесь дизайн модели ресурса в репозитории моделей модулей ресурсов в виде PR для проверки.
  2. Скачайте последнюю версию построителя модулей ресурсов.
  3. Запустите resource module builder для создания каркаса коллекции из вашей утвержденной модели ресурса.
  4. Напишите код для реализации вашего модуля ресурса.
  5. Разработайте интеграционные и модульные тесты для проверки вашего модуля ресурса.
  6. Создайте PR в соответствующую коллекцию, в которую вы хотите добавить свой новый модуль ресурса. Обратитесь к Вклад в поддерживаемые Ansible коллекции за подробной информацией о определении правильной коллекции для вашего модуля.

Понимание модели и построителя модулей ресурсов

Построитель модулей ресурсов — это Ansible Playbook, который помогает разработчикам создавать и поддерживать модуль Ansible ресурса. Он использует модель как единственный источник правды для модуля. Эта модель представляет собой yaml файл, который используется для раздела ДОКУМЕНТАЦИЯ модуля и спецификации аргументов.

Построитель модулей ресурсов обладает следующими возможностями:

  • Использует определенную модель для создания структуры каталогов модуля ресурса и начальных файлов классов.
  • Создает либо роль Ansible, либо коллекцию.
  • Последующее использование построителя модулей ресурсов заменит только спецификацию модуля arspec и файл, содержащий строку документации модуля.
  • Позволяет хранить сложные примеры вместе с моделью в одном каталоге.
  • Поддерживает модель как единственный источник правды для модуля и использует построитель модулей ресурсов для обновления исходных файлов по мере необходимости.
  • Создаёт рабочие примеры модулей для <network_os>_<resource> и <network_os>_facts.

Доступ к построителю модулей ресурсов

Для доступа к построителю модулей ресурсов:

  1. клонируйте репозиторий GitHub:
git clone https://github.com/ansible-network/resource_module_builder.git
  1. Установите необходимые зависимости:
pip install -r requirements.txt

Создание модели

Вы должны создать модель для вашего нового ресурса. Модель является единственным источником истины как для argspec, так и для строки документации, обеспечивая их синхронизацию. После утверждения вашей модели вы можете использовать построитель модулей ресурсов для генерации трёх элементов на основе модели:

  • Каркас для нового модуля
  • Argspec для нового модуля
  • Строка документации для нового модуля

Для любых последующих изменений функциональности сначала обновите модель, а затем используйте построитель модулей ресурсов для обновления argspec и строки документации модуля.

Например, построитель моделей ресурсов включает пример myos_interfaces.yml в каталоге models, как показано ниже:

---
GENERATOR_VERSION: '1.0'

NETWORK_OS: myos
RESOURCE: interfaces
COPYRIGHT: Copyright 2019 Red Hat
LICENSE: gpl-3.0.txt

DOCUMENTATION: |
  module: myos_interfaces
  version_added: 1.0.0
  short_description: 'Manages <xxxx> attributes of <network_os> <resource>'
  description: 'Manages <xxxx> attributes of <network_os> <resource>.'
  author: Ansible Network Engineer
 notes:
    - 'Tested against <network_os> <version>'
  options:
    config:
      description: The provided configuration
      type: list
      elements: dict
      suboptions:
        name:
          type: str
          description: The name of the <resource>
        some_string:
          type: str
          description:
          - The some_string_01
          choices:
          - choice_a
          - choice_b
          - choice_c
          default: choice_a
        some_bool:
          description:
          - The some_bool.
          type: bool
        some_int:
          description:
          - The some_int.
          type: int
          version_added: '1.1.0'
        some_dict:
          type: dict
          description:
          - The some_dict.
          suboptions:
            property_01:
              description:
              - The property_01
              type: str
    state:
      description:
      - The state of the configuration after module completion.
      type: str
      choices:
      - merged
      - replaced
      - overridden
      - deleted
      default: merged
EXAMPLES:
  - deleted_example_01.txt
  - merged_example_01.txt
  - overridden_example_01.txt
  - replaced_example_01.txt

Обратите внимание, что вы должны включить примеры для каждого из состояний, которые поддерживает ресурс. Построитель модулей ресурсов также включает их в пример модели.

Поделитесь этой моделью в виде PR для проверки в репозитории моделей модулей ресурсов. Вы также можете найти больше примеров моделей в этом месте.

Создание каркаса коллекции из модели ресурса

Для использования построителя модулей ресурсов для создания каркаса коллекции из вашей утверждённой модели ресурса:

ansible-playbook -e rm_dest=<destination for modules and module utils> \
                 -e structure=collection \
                 -e collection_org=<collection_org> \
                 -e collection_name=<collection_name> \
                 -e model=<model> \
                 site.yml

Где параметры следующие:

  • rm_dest: Каталог, в котором построитель модулей ресурсов размещает файлы и каталоги для модуля ресурса и модулей фактов.
  • structure: Тип структуры каталогов (роль или коллекция)

    • role: Создать структуру каталогов роли.
    • collection: Создать структуру каталогов коллекции.
  • collection_org: Организация коллекции, необходимая при structure=collection.
  • collection_name: Название коллекции, необходимое при structure=collection.
  • model: Путь к файлу модели.

Для использования построителя модулей ресурсов для создания каркаса роли:

ansible-playbook -e rm_dest=<destination for modules and module utils> \
                 -e structure=role \
                 -e model=<model> \
                 site.yml

Примеры

Структура каталогов коллекции

Этот пример демонстрирует структуру каталогов для следующих:

  • network_os: myos
  • resource: interfaces
ansible-playbook -e rm_dest=~/github/rm_example \
                 -e structure=collection \
                 -e collection_org=cidrblock \
                 -e collection_name=my_collection \
                 -e model=models/myos/interfaces/myos_interfaces.yml \
                 site.yml
├── docs
├── LICENSE.txt
├── playbooks
├── plugins
|   ├── action
|   ├── filter
|   ├── inventory
|   ├── modules
|   |   ├── __init__.py
|   |   ├── myos_facts.py
|   |   └──  myos_interfaces.py
|   └──  module_utils
|       ├── __init__.py
|       └──  network
|           ├── __init__.py
|           └──  myos
|               ├── argspec
|               |   ├── facts
|               |   |   ├── facts.py
|               |   |   └──  __init__.py
|               |   ├── __init__.py
|               |   └──  interfaces
|               |       ├── __init__.py
|               |       └──  interfaces.py
|               ├── config
|               |   ├── __init__.py
|               |   └──  interfaces
|               |       ├── __init__.py
|               |       └──  interfaces.py
|               ├── facts
|               |   ├── facts.py
|               |   ├── __init__.py
|               |   └──  interfaces
|               |       ├── __init__.py
|               |       └──  interfaces.py
|               ├── __init__.py
|               └──  utils
|                   ├── __init__.py
|                   └──  utils.py
├── README.md
└──  roles

Структура каталогов роли

Этот пример отображает структуру каталогов роли для следующих:

  • network_os: myos
  • resource: interfaces
ansible-playbook -e rm_dest=~/github/rm_example/roles/my_role \
                 -e structure=role \
                 -e model=models/myos/interfaces/myos_interfaces.yml \
                 site.yml
roles
└── my_role
    ├── library
    │   ├── __init__.py
    │   ├── myos_facts.py
    │   └── myos_interfaces.py
    ├── LICENSE.txt
    ├── module_utils
    │   ├── __init__.py
    │   └── network
    │       ├── __init__.py
    │       └── myos
    │           ├── argspec
    │           │   ├── facts
    │           │   │   ├── facts.py
    │           │   │   └── __init__.py
    │           │   ├── __init__.py
    │           │   └── interfaces
    │           │       ├── __init__.py
    │           │       └── interfaces.py
    │           ├── config
    │           │   ├── __init__.py
    │           │   └── interfaces
    │           │       ├── __init__.py
    │           │       └── interfaces.py
    │           ├── facts
    │           │   ├── facts.py
    │           │   ├── __init__.py
    │           │   └── interfaces
    │           │       ├── __init__.py
    │           │       └── interfaces.py
    │           ├── __init__.py
    │           └── utils
    │               ├── __init__.py
    │               └── utils.py
    └── README.md

Использование коллекции

Этот пример демонстрирует использование сгенерированной коллекции в playbook:

----
- hosts: myos101
  gather_facts: False
  tasks:
  - cidrblock.my_collection.myos_interfaces:
    register: result
  - debug:
      var: result
  - cidrblock.my_collection.myos_facts:
  - debug:
      var: ansible_network_resources

Использование роли

Этот пример демонстрирует использование сгенерированной роли в playbook:

- hosts: myos101
  gather_facts: False
  roles:
  - my_role

- hosts: myos101
  gather_facts: False
  tasks:
  - myos_interfaces:
    register: result
  - debug:
      var: result
  - myos_facts:
  - debug:
      var: ansible_network_resources

Структура и рабочий процесс модуля ресурса

Структура модуля ресурса включает следующие компоненты:

Модуль
  • library/<ansible_network_os>_<resource>.py.
  • Импортирует пакет ресурсов module_utils и вызывает API execute_module.
def main():
    result = <resource_package>(module).execute_module()
Спецификация аргументов модуля
  • module_utils/<ansible_network_os>/argspec/<resource>/.
  • Спецификация аргументов для ресурса.
Факты
  • module_utils/<ansible_network_os>/facts/<resource>/.
  • Заполнение фактов для ресурса.
  • Запись в module_utils/<ansible_network_os>/facts/facts.py для API get_facts для поддержания синхронизации модуля <ansible_network_os>_facts и собранных фактов для модуля ресурса для каждого подмножества.
  • Запись подмножества ресурса в список FACTS_RESOURCE_SUBSETS в module_utils/<ansible_network_os>/facts/facts.py для корректной работы сбора фактов.
Пакет модулей в module_utils
  • module_utils/<ansible_network_os>/<config>/<resource>/.
  • Реализует API execute_module для загрузки конфигурации на устройство и генерирует результат с ключами changed, commands, before и after.
  • Вызывает API get_facts для возвращения фактов конфигурации <resource> или возвращает разницу, если устройство поддерживает разницу onbox.
  • Сравнение собранных фактов и заданных значений ключей, если разница не поддерживается.
  • Генерация конечной конфигурации.
Утилиты
  • module_utils/<ansible_network_os>/utils.
  • Утилиты для платформы <ansible_network_os>.

Запуск ansible-test sanity и tox для модулей ресурсов

Вы должны запустить ansible-test sanity и tox -elinters из корневого каталога коллекции перед отправкой вашего PR в поддерживаемую Ansible коллекцию. CI выполнит оба и завершится ошибкой, если эти тесты завершатся неудачно. Обратитесь к Тестирование Ansible за подробностями о ansible-test sanity.

Для установки необходимых пакетов:

  1. Убедитесь, что у вас настроена действительная среда разработки Ansible. Обратитесь к Подготовка среды для разработки модулей Ansible за подробностями.
  2. Запустите pip install -r requirements.txt из корневого каталога коллекции.

Запуск tox -elinters:

  • Считывает tox.ini из корневого каталога коллекции и устанавливает необходимые зависимости (например, black и flake8).
  • Выполняет их с предопределёнными параметрами (например, длина строки и игнорирование).
  • Выполняет black в режиме проверки, чтобы показать, какие файлы будут отформатированы, без фактического форматирования.

Тестирование модулей ресурсов

Тесты основаны на роли, сгенерированной создателем модуля ресурсов. После внесения изменений в создатель модуля ресурсов, роль должна быть сгенерирована заново, а тесты изменены и запущены по мере необходимости. Чтобы сгенерировать роль после изменений:

rm -rf rmb_tests/roles/my_role
ansible-playbook -e rm_dest=./rmb_tests/roles/my_role \
                 -e structure=role \
                 -e model=models/myos/interfaces/myos_interfaces.yml \
                 site.yml

Интеграционные тесты модулей ресурсов

Требования к интеграционным тестам высокого уровня для новых модулей ресурсов таковы:

  1. Напишите тестовый случай для каждого состояния.
  2. Напишите дополнительные тестовые случаи для проверки поведения модуля, когда пустой config.yaml предоставлен.
  3. Добавьте тестовый случай обратного хода. Это включает операцию merge, за которой следует gather_facts, обновление merge с дополнительной конфигурацией, а затем возвращение к базовой конфигурации с использованием ранее собранных фактов с state установленным в значение overridden.
  4. В тех случаях, когда это применимо, утверждения должны проверяться после и перед dicts по отношению к жестко закодированному Источнику Истины.

Мы используем Zuul в качестве CI для запуска интеграционного теста.

  • Чтобы просмотреть отчет, щелкните Подробности в комментарии CI в PR
  • Чтобы просмотреть отчет о сбое, щелкните ansible/check и выберите не пройденный тест.
  • Чтобы просмотреть журналы во время выполнения теста, найдите свой номер PR на панели статуса Zuul.
  • Чтобы исправить локальный сбой статического теста, выполните tox -e black в корневой папке коллекции.

Чтобы просмотреть журналы выполнения Ansible и отлаживать сбои тестов:

  1. Щелкните не пройденную задачу, чтобы получить сводку, и щелкните Журналы для получения журнала.
  2. Щелкните консоль и прокрутите вниз, чтобы найти не пройденный тест.
  3. Щелкните > рядом с не пройденным тестом для получения полных подробностей.

Структура интеграционного теста

Каждый тестовый случай, как правило, должен следовать этому шаблону:

  • setup —> test —> assert —> test again (для идемпотентности) —> assert —> tear down (при необходимости) -> done. Это помогает предотвратить превращение тестовых playbooks в монолитные и трудно отлаживаемые.
  • Включайте имя для каждой задачи, которая не является утверждением. Вы можете добавлять имена к утверждениям также, но проще определить сломанную задачу в случае неудачного теста, если вы добавите имя для каждой задачи.
  • Файлы, содержащие тестовые случаи, должны заканчиваться на .yaml

Реализация

Для платформ, которые поддерживают connection: local и connection: network_cli используйте следующие рекомендации:

  • Называйте каталоги targets/ по имени модуля.
  • Файл main.yaml должен просто ссылаться на транспорт.

Следующий пример демонстрирует интеграционные тесты для модуля vyos.vyos.vyos_l3_interfaces в коллекции vyos.vyos:

test/integration/targets/vyos_l3_interfaces/tasks/main.yaml

---
- import_tasks: cli.yaml
  tags:
    - cli

test/integration/targets/vyos_l3_interfaces/tasks/cli.yaml

---
- name: collect all cli test cases
  find:
    paths: "{{ role_path }}/tests/cli"
    patterns: "{{ testcase }}.yaml"
  register: test_cases
  delegate_to: localhost

- name: set test_items
  set_fact: test_items="{{ test_cases.files | map(attribute='path') | list }}"

- name: run test cases (connection=network_cli)
  include_tasks:
     file: "{{ test_case_to_run }}"
  vars:
     ansible_connection: network_cli
  with_items: "{{ test_items }}"
  loop_control:
    loop_var: test_case_to_run

- name: run test case (connection=local)
  include_tasks:
     file: "{{ test_case_to_run }}"
  vars:
     ansible_connection: local
     ansible_become: false
  with_first_found: "{{ test_items }}"
  loop_control:
    loop_var: test_case_to_run

test/integration/targets/vyos_l3_interfaces/tests/cli/overridden.yaml

---
- debug:
 msg: START vyos_l3_interfaces merged integration tests on connection={{ ansible_connection
   }}

- import_tasks: _remove_config.yaml

- block:

 - import_tasks: _populate.yaml

 - name: Overrides all device configuration with provided configuration
   register: result
   vyos.vyos.vyos_l3_interfaces: &id001
     config:

       - name: eth0
         ipv4:

           - address: dhcp

       - name: eth1
         ipv4:

           - address: 192.0.2.15/24
     state: overridden

 - name: Assert that before dicts were correctly generated
   assert:
     that:
       - "{{ populate | symmetric_difference(result['before']) |length == 0 }}"

 - name: Assert that correct commands were generated
   assert:
     that:
       - "{{ overridden['commands'] | symmetric_difference(result['commands'])\
         \ |length == 0 }}"

 - name: Assert that after dicts were correctly generated
   assert:
     that:
       - "{{ overridden['after'] | symmetric_difference(result['after']) |length\
         \ == 0 }}"

 - name: Overrides all device configuration with provided configurations (IDEMPOTENT)
   register: result
   vyos.vyos.vyos_l3_interfaces: *id001

 - name: Assert that the previous task was idempotent
   assert:
     that:
       - result['changed'] == false

 - name: Assert that before dicts were correctly generated
   assert:
     that:
       - "{{ overridden['after'] | symmetric_difference(result['before']) |length\
         \ == 0 }}"
always:

 - import_tasks: _remove_config.yaml

Обнаружение тестовых ресурсов во время выполнения

Ваши тесты должны обнаруживать ресурсы (например, интерфейсы) во время выполнения, а не жестко их кодировать в тесте. Это позволяет тесту работать на различных системах.

Например:

- name: Collect interface list
  connection: ansible.netcommon.network_cli
  register: intout
  cisco.nxos.nxos_command:
    commands:
      - show interface brief | json

- set_fact:
    intdataraw: "{{ intout.stdout_lines[0]['TABLE_interface']['ROW_interface'] }}"

- set_fact:
    nxos_int1: '{{ intdataraw[1].interface }}'

- set_fact:
    nxos_int2: '{{ intdataraw[2].interface }}'

- set_fact:
    nxos_int3: '{{ intdataraw[3].interface }}'

Полный пример такого теста см. по адресу https://github.com/ansible-collections/cisco.nxos/blob/main/tests/integration/targets/prepare_nxos_tests/tasks/main.yml.

Запуск сетевых интеграционных тестов

Ansible использует Zuul для запуска набора интеграционных тестов для каждого PR, включая новые тесты, добавленные в этом PR. Для поиска и исправления проблем в сетевых модулях запустите сетевой интеграционный тест локально перед отправкой PR.

Сначала создайте файл инвентаризации, который указывает на ваши тестовые машины. Группа инвентаризации должна соответствовать имени платформы (например, eos, ios):

cd test/integration
cp inventory.network.template inventory.networking
${EDITOR:-vi} inventory.networking
# Add in machines for the platform(s) you wish to test

Чтобы запустить эти сетевые интеграционные тесты, используйте ansible-test network-integration --inventory </path/to/inventory> <tests_to_run>:

ansible-test network-integration  --inventory ~/myinventory -vvv vyos_facts
ansible-test network-integration  --inventory ~/myinventory -vvv vyos_.*

Чтобы запустить все сетевые тесты для конкретной платформы:

ansible-test network-integration --inventory  /path/to-collection-module/test/integration/inventory.networking vyos_.*

Этот пример будет выполняться против всех vyos модулей. Обратите внимание, что vyos_.* — это соответствие по регулярному выражению, а не шаблон bash — включайте . при модификации этого примера.

Чтобы запустить интеграционные тесты для определенного модуля:

ansible-test network-integration --inventory  /path/to-collection-module/test/integration/inventory.networking vyos_l3_interfaces

Чтобы запустить один тестовый случай для определенного модуля:

# Only run vyos_l3_interfaces/tests/cli/gathered.yaml
ansible-test network-integration --inventory  /path/to-collection-module/test/integration/inventory.networking vyos_l3_interfaces --testcase gathered

Чтобы запустить интеграционные тесты для определенного транспорта:

 # Only run nxapi test
ansible-test network-integration --inventory  /path/to-collection-module/test/integration/inventory.networking  --tags="nxapi" nxos_.*

# Skip any cli tests
 ansible-test network-integration --inventory  /path/to-collection-module/test/integration/inventory.networking  --skip-tags="cli" nxos_.*

См. test/integration/targets/nxos_bgp/tasks/main.yaml для способа реализации этого в тестах.

Для дополнительных параметров:

ansible-test network-integration --help

Если вам нужна дополнительная помощь или обратная связь, обратитесь к сообществу. Подробности см. в руководстве по общению Ansible.

Требования к модульным тестам

Требования к модульным тестам высокого уровня, которым должны следовать новые модули ресурсов:

  1. Напишите тестовые случаи для всех состояний со всеми возможными комбинациями значений конфигурации.
  2. Напишите тестовые случаи для проверки условий ошибок (отрицательные сценарии).
  3. Проверьте значение ключей changed и commands в каждом тестовом случае.

Мы запускаем все модульные тестовые случаи на нашем наборе тестов Zuul на последней версии Python, поддерживаемой нашей системой CI.

Используйте ту же процедуру, что и для интеграционных тестов, для просмотра отчетов и журналов модульных тестов Zuul.

См. тестирование модулей модулей для общих подробностей о модульных тестах.

Пример: Модульное тестирование Ansible сетевых модулей ресурсов

В этом разделе рассматривается пример разработки модульных тестов для модулей ресурсов Ansible.

См. Модульные тесты и Модульное тестирование модулей Ansible для общей документации по модульным тестам Ansible для модулей. Сначала ознакомьтесь с этими страницами, чтобы понять модульные тесты и почему и когда их следует использовать.

Использование эмуляторов для модульного тестирования сетевых модулей ресурсов Ansible

Мок-объекты могут быть очень полезными при создании модульных тестов для особых или сложных случаев, но они также могут привести к сложным и запутанным ситуациям программирования. Одно хорошее применение эмуляторов — моделирование API. Пакет mock поставляется с Ansible (используйте import units.compat.mock).

Вы можете смоделировать подключение к устройству и вывод от устройства следующим образом:

self.mock_get_config = patch( "ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.get_config"
)
self.get_config = self.mock_get_config.start()

self.mock_load_config = patch(
"ansible_collections.ansible.netcommon.plugins.module_utils.network.common.network.Config.load_config"
)
self.load_config = self.mock_load_config.start()

self.mock_get_resource_connection_config = patch(
"ansible_collections.ansible.netcommon.plugins.module_utils.network.common.cfg.base.get_resource_connection"
)
self.get_resource_connection_config = (self.mock_get_resource_connection_config.start())

self.mock_get_resource_connection_facts = patch(
"ansible_collections.ansible.netcommon.plugins.module_utils.network.common.facts.facts.get_resource_connection"
)
self.get_resource_connection_facts = (self.mock_get_resource_connection_facts.start())

self.mock_edit_config = patch(
"ansible_collections.arista.eos.plugins.module_utils.network.eos.providers.providers.CliProvider.edit_config"
)
self.edit_config = self.mock_edit_config.start()

self.mock_execute_show_command = patch(
"ansible_collections.arista.eos.plugins.module_utils.network.eos.facts.l2_interfaces.l2_interfaces.L2_interfacesFacts.get_device_data"
)
self.execute_show_command = self.mock_execute_show_command.start()

Файл фактов модуля теперь включает новый метод get_device_data. Вызовите get_device_data здесь, чтобы эмулировать вывод устройства.

Эмуляция данных устройства

Чтобы смоделировать получение результатов от устройств или предоставить другие сложные структуры данных, поступающие из внешних библиотек, вы можете использовать fixtures для чтения предварительно сгенерированных данных. Текстовые файлы для этих предварительно сгенерированных данных находятся в test/units/modules/network/PLATFORM/fixtures/. См., например, файл eos_l2_interfaces.cfg.

Загрузите данные с помощью метода load_fixture и установите эти данные в качестве возвращаемого значения метода get_device_data в файле фактов:

def load_fixtures(self, commands=None, transport='cli'):
    def load_from_file(*args, **kwargs):
        return load_fixture('eos_l2_interfaces_config.cfg')
    self.execute_show_command.side_effect = load_from_file

См. файл модульного теста test_eos_l2_interfaces для практического примера.

См. также

Модульные тесты

Подробное изучение разработки модульных тестов для модулей Ansible

Тестирование Ansible и коллекций

Запуск тестов локально, включая сборку и отчет о покрытии

Разработка модулей

Начало разработки модуля

© 2012–2018 Michael DeHaan
© 2018–2024 Red Hat, Inc.
Licensed under the GNU General Public License version 3.
https://docs.ansible.com/ansible/latest/network/dev_guide/developing_resource_modules_network.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API