Вопрос или проблема
У меня есть локальная коллекция Ansible. Вот как выглядит моя структура папок:
/
|_ collections
| |_ ansible_collections
| |_ my # Пространство имен
| |_ tools # Коллекция
| |_ plugins
| |_ modules
| |_ my_module.py # Модуль
|_ my_playbook.yml
В my_playbook.yml
я вызываю модуль с помощью <namespace>.<collection>.<module>
, например: my.tools.my_module
.
Это работает нормально, но я хочу определить переиспользуемые классы/функции для обращения из my_module.py
. Куда мне положить эти другие библиотеки?
Я пробовал включить их в (например) plugins/modules/my_lib.py
, я пробовал в plugins/module_utils/my_lib.py
и т.д. В my_module.py
я пробовал импортировать разными способами:
from my.tools.module_utils.my_lib import my_func
from module_utils.my_lib import my_func
import sys, os
sys.path.append(os.path.abspath('../module_utils'))
from my_lib import my_func
Какой правильный способ этого достичь?
Ответ или решение
Чтобы импортировать функции Python из модуля в локальной коллекции Ansible, нужно учитывать определенные принципы структуры проектов и правила импорта в Python. Ваша структура каталогов выглядит следующим образом:
/
|_ collections
| |_ ansible_collections
| |_ my # Пространство имен
| |_ tools # Коллекция
| |_ plugins
| |_ modules
| |_ my_module.py # Модуль
|_ my_playbook.yml
Шаг 1: Создание библиотеки
Первым делом, вам нужно создать библиотеку функций или классов, которые вы хотите использовать в my_module.py
. Лучше всего разместить их в каталоге plugins/module_utils/
, потому что именно там предназначены вспомогательные модули, которые используют другие модули.
Теперь создайте файл my_lib.py
в каталоге plugins/module_utils/
:
collections/
└── ansible_collections/
└── my/
└── tools/
└── plugins/
├── modules/
│ └── my_module.py
└── module_utils/
└── my_lib.py
Шаг 2: Импортирование библиотеки
Теперь вам нужно импортировать функции из my_lib.py
в ваш модуль my_module.py
. Император my_lib
должен выглядеть следующим образом:
# my_module.py
from ansible.module_utils.my_lib import my_func
def main():
# Ваш код, использующий my_func
result = my_func()
# Логика вашей модуля, возврат результатов и т.д.
if __name__ == '__main__':
main()
Шаг 3: Пример функции
Чтобы проиллюстрировать, как это работает, создайте простую функцию в my_lib.py
:
# my_lib.py
def my_func():
return "Hello from my_lib!"
Шаг 4: Запуск вашего плейбука
Теперь, когда вы создали структуру и импортировали библиотеку, вы можете запустить свой плейбук my_playbook.yml
. Убедитесь, что ваш my_module.py
правильно определяет входные параметры и возвращает данные, как это предусмотрено. Вот пример простого плейбука:
# my_playbook.yml
- name: Test my_module
hosts: localhost
tasks:
- name: Run my_module
my.tools.my_module:
Завершение
Теперь вы успешно создали структуру для импортирования функций из библиотеки в модуль Ansible. Здесь важно помнить, что каталог module_utils
специально предназначен для общих утилит, которые могут использоваться во всех модулях вашей коллекции. При таком подходе ваш код будет структурированным, легко поддерживаемым и переиспользуемым.
Таким образом, следуя приведенному руководству, вы сможете эффективно импортировать функции и классы из библиотек в своих модулях Ansible, что приведет к лучшему управлению вашими ресурсами и более чистой архитектуре проекта.