Spec-Zone.ru › Ansible 2.4

Практическое руководство по разработке модулей Ansible для Windows

В этом разделе мы рассмотрим разработку, тестирование и отладку модуля Ansible для Windows.

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

Что охватывается в этом разделе:

  • Практическое руководство по разработке модулей Ansible для Windows
  • Настройка среды Windows
  • Разработка нового модуля Windows
  • Тестирование модуля Windows с помощью playbook
  • Отладка в Windows
  • Единое тестирование в Windows
  • Интеграционное тестирование в Windows
  • Поддержка коммуникаций и разработки в Windows

Настройка среды Windows

TODO: Добавить больше информации о том, как использовать Vagrant для настройки хоста Windows.

Разработка нового модуля Windows

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

  • Код модуля находится в файлах Powershell (.ps1), а документация — в файлах Python (.py) с тем же именем
  • Избегайте использования Write-Host/Debug/Verbose/Error в модуле и добавьте то, что должно быть возвращено, в переменную $result
  • При обработке исключений используйте Fail-Json -obj $result -message "exception message here"
  • Большинство новых модулей требуют режима проверки и интеграционных тестов перед включением в основной код Ansible
  • Избегайте использования try/catch для обработки больших блоков кода, а используйте их для отдельных вызовов, чтобы сообщение об ошибке было более информативным
  • При использовании try/catch старайтесь обрабатывать конкретные исключения
  • Избегайте использования PSCustomObjects, если это не требуется
  • Ищите общие функции в ./lib/ansible/module_utils/powershell/ и используйте код оттуда вместо дублирования работы. Их можно импортировать, добавив строку #Requires -Module *, где * — имя файла для импорта, и они будут автоматически включены в код модуля, отправленный целевому устройству Windows при запуске через Ansible
  • Убедитесь, что код работает под Powershell v3 и выше на Windows Server 2008 и выше; если требуются более новые версии Powershell или ОС, убедитесь, что документация чётко это отражает
  • Ansible запускает модули в режиме strictmode версии 2.0. Убедитесь, что вы тестируете с включённым strictmode, поместив Set-StrictMode -Version 2.0 в начало вашего скрипта разработки
  • Если возможно, отдавайте предпочтение встроенным командлетам Powershell по сравнению с вызовами исполняемых файлов
  • Если вы добавляете объект в $result, убедитесь, что все завершающие слэши удалены или экранированы, так как ConvertTo-Json не сможет их преобразовать
  • Используйте полные имена командлетов вместо псевдонимов, например, Remove-Item вместо rm
  • Используйте именованные параметры с командлетами, например, Remove-Item -Path C:\temp вместо Remove-Item C:\temp

Ниже приведён шаблон очень простого модуля Powershell:

#!powershell
# This file is part of Ansible

# GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt)

#Requires -Module Ansible.ModuleUtils.Legacy.psm1

$ErrorActionPreference = 'Stop'

$params = Parse-Args -arguments $args -supports_check_mode $true
$check_mode = Get-AnsibleParam -obj $params -name "_ansible_check_mode" -type "bool" -default $false
$diff_mode = Get-AnsibleParam -obj $params -name "_ansible_diff" -type "bool" -default $false

# these are your module parameters, there are various types which can be
# used to format your parameters. You can also set mandatory parameters
# with -failifempty, set defaults with -default and set choices with
# -validateset.
$string = Get-AnsibleParam -obj $params -name "string" -type "str" -failifempty $true
$bool = Get-AnsibleParam -obj $params -name "bool" -type "bool" -default $false
$int = Get-AnsibleParam -obj $params -name "int" -type "int"
$path = Get-AnsibleParam -obj $params -name "path" -type "path"
$list = Get-AnsibleParam -obj $params -name "list" -type "list"
$choices = Get-AnsibleParam -obj $params -name "choices" -type "str" -default "present" -validateset "absent","present"

$result = @{
    changed = $false
}

if ($diff_mode) {
    $result.diff = @{}
}

# code goes here

# you can add/set new result objects with
$result.changed = $true
$result.new_result = "Hi"

Exit-Json -obj $result

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

Иногда в Windows существуют несколько способов выполнения задачи; вот порядок их предпочтения при написании модулей:

  • Встроенные командлеты Powershell, например, Remove-Item -Path C:\temp -Recurse
  • Классы .NET, например, [System.IO.Path]::GetRandomFileName()
  • Объекты WMI через командлет New-CimInstance
  • Объекты COM через командлет New-Object -ComObject
  • Вызовы нативных исполняемых файлов, например, Secedit.exe

Тестирование модуля Windows с помощью playbook

Для тестирования модуля можно использовать playbook Ansible.

  • Создайте playbook в любом каталоге touch testmodule.yml
  • Создайте файл инвентаризации в том же каталоге touch hosts
  • Заполните файл инвентаризации переменными, необходимыми для подключения к хосту(ам) Windows.
  • Добавьте следующее в новый файл playbook:

    ---
    - name: test out windows module
      hosts: windows
      tasks:
      - name: test out module
        win_module:
          name: test name
    
  • Запустите playbook ansible-playbook -i hosts testmodule.yml

Это может быть довольно высоким уровнем и полезно для просмотра того, как Ansible работает с новым модулем от начала до конца: но есть лучшие способы протестировать модуль, как показано ниже.

Отладка в Windows

Отладка модуля в настоящее время возможна только на хосте Windows. Это очень полезно при разработке нового модуля или поиске ошибок. Ниже приведены шаги по настройке.

  • Скопируйте скрипт модуля на сервер Windows
  • Скопируйте ./lib/ansible/module_utils/powershell/Ansible.ModuleUtils.Legacy.psm1 в ту же папку, что и скрипт выше
  • Чтобы предотвратить выход скрипта из редактора при успешном выполнении, в Ansible.ModuleUtils.Legacy.psm1 внутри функции Exit-Json замените две последние строки функции на:

    ConvertTo-Json -InputObject $obj -Depth 99
    
  • Чтобы предотвратить выход скрипта из редактора при неудачном выполнении, в Ansible.ModuleUtils.Legacy.psm1 внутри функции Fail-Json замените две последние строки функции на:

    Write-Error -Message (ConvertTo-Json -InputObject $obj -Depth 99)
    
  • Добавьте следующее в начало скрипта модуля, который был скопирован на сервер:

    ### start setup code
    $complex_args = @{
        "_ansible_check_mode" = $false
        "_ansible_diff" = $false
        "path" = "C:\temp"
        "state" = "present"
    }
    
    Import-Module -Name .\Ansible.ModuleUtils.Legacy.psm1
    ### end setup code
    

Вы можете добавить дополнительные аргументы в $complex_args по мере необходимости модуля. Теперь модуль можно запустить на хосте Windows либо напрямую через Powershell, либо через IDE.

Для отладки скрипта Powershell можно использовать различные IDE, две из самых популярных:

  • Powershell ISE
  • Visual Studio Code

Для просмотра аргументов, передаваемых Ansible модулю, выполните следующие действия.

  • Добавьте префикс ANSIBLE_KEEP_REMOTE_FILES=1 к команде Ansible, чтобы Ansible сохранял файлы exec на сервере
  • Войдите на сервер Windows с тем же пользователем, от имени которого Ansible запустил модуль
  • Перейдите в %TEMP%\.., там должна быть папка, начинающаяся с ansible-tmp-
  • Внутри этой папки откройте Powershell-скрипт для модуля
  • В этом скрипте есть сырой JSON-скрипт в $json_raw, содержащий аргументы модуля в module_args
  • Эти аргументы можно вручную назначить переменной $complex_args, определённой в вашем отладочном скрипте

Единое тестирование в Windows

В настоящее время нет механизма для запуска модулей unit-тестов Powershell в Ansible CI. Работа над внедрением этой возможности в будущем.

Интеграционное тестирование в Windows

Интеграционные тесты модулей Ansible обычно пишутся как роли Ansible. Тестовые роли находятся в ./test/integration/targets. Сначала необходимо настроить тестовую среду и конфигурировать инвентаризацию Ansible для подключения к ней. В этом примере мы настраиваем тестовую инвентаризацию для подключения к двум хостам и запускаем интеграционные тесты для win_stat.

  • Создайте копию ./test/integration/inventory.winrm.template и просто назовите её inventory.winrm
  • Заполните записи в [windows] и задайте необходимые переменные для подключения к хосту
  • Чтобы запустить интеграционные тесты, выполните ansible-test windows-integration win_stat - можете заменить win_stat на роль, которую хотите протестировать

Это запустит все тесты, которые в данный момент определены для этой роли. Уровень подробности можно настроить с помощью аргумента -v так же, как и с ansible-playbook.

При разработке тестов для нового модуля рекомендуется протестировать сценарий в режиме проверки и 2 раза без режима проверки. Это гарантирует, что режим проверки не вносит изменений, но сообщает о них, а также, что повторное выполнение является идемпотентным и не сообщает о изменениях. Ниже приведен пример того, как это можно сделать:

- name: remove a file (check mode)
  win_file:
    path: C:\temp
    state: absent
  register: remove_file_check
  check_mode: yes

- name: get result of remove a file (check mode)
  win_command: powershell.exe "if (Test-Path -Path 'C:\temp') { 'true' } else { 'false' }"
  register: remove_file_actual_check

- name: assert remove a file (check mode)
  assert:
    that:
    - remove_file_check|changed
    - remove_file_actual_check.stdout == 'true\r\n'

- name: remove a file
  win_file:
    path: C:\temp
    state: absent
  register: remove_file

- name: get result of remove a file
  win_command: powershell.exe "if (Test-Path -Path 'C:\temp') { 'true' } else { 'false' }"
  register: remove_file_actual

- name: assert remove a file
  assert:
    that:
    - remove_file|changed
    - remove_file_actual.stdout == 'false\r\n'

- name: remove a file (idempotent)
  win_file:
    path: C:\temp
    state: absent
  register: remove_file_again

- name: assert remove a file (idempotent)
  assert:
    that:
    - not remove_file_again|changed

Поддержка коммуникаций и разработки в Windows

Присоединяйтесь к каналу IRC #ansible-devel или #ansible-windows на freenode для обсуждений разработки Ansible для Windows.

Для вопросов и обсуждений, связанных с использованием продукта Ansible, используйте канал #ansible.

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

Spec-Zone.ru

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