использовать ansible_facts в коде модуля

Я пытаюсь создать свой собственный модуль ansible (который будет обновлять cmdb), и я ищу, как использовать ansible_facts в коде модуля?

пример моего скрипта модуля:

#!/usr/bin/python

from ansible.module_utils.basic import *

import json, ast

from servicenow import ServiceNow
from servicenow import Connection


def __get_server_info(table,server_name="", sys_id=""):
     if sys_id == "":
       return table.fetch_one({'name': server_name})

     if server_name == "":
       return table.fetch_one({'sys_id': sys_id})

def __update_cmdb_hwinfo(table, sys_id, server_name=""):
    return table.update({'sys_id': sys_id,{'hw_ram': 'Here for example i want to put ansible_facts about server ram size'})


def main():


    fields = {
       "snow_instance": {"required": True, "type": "str"},
       "snow_username": {"required": True, "type": "str"},
       "snow_password": {"required": True, "type": "str"},
       "server_name":   {"required": True, "type": "str" },
       "api_type":      {"default": "JSONv2", "type": "str"},
    }

    module = AnsibleModule(argument_spec=fields)
    snow_connection = Connection.Auth(username=module.params['snow_username'], password=module.params['snow_password'], instance=module.params['snow_instance'], api=module.params['api_typ
e'])
    server = ServiceNow.Base(snow_connection)
    server.__table__ = 'cmdb_ci_server_list.do'

    machine = __get_server_info(server, )
    ## Define connection object to ServiceNow instance
    module.exit_json(changed=False, meta=module.params, msg=machine)


if __name__ == '__main__':
    main()

Какую переменную я должен использовать для вызова ansible_facts в скрипте модуля? (И возможно ли это?).


person A. Zakharov    schedule 13.07.2017    source источник


Ответы (1)


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

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

Вот так (./action_plugins/a_test.py):

from ansible.plugins.action import ActionBase

class ActionModule(ActionBase):

    def run(self, tmp=None, task_vars=None):

        result = super(ActionModule, self).run(tmp, task_vars)

        module_args = self._task.args.copy()
        module_args['mem_size'] = self._templar._available_variables.get('ansible_memtotal_mb')

        return self._execute_module(module_args=module_args, task_vars=task_vars, tmp=tmp)

В этом случае, если ваш модуль ожидает параметр mem_size, он будет установлен на значение ansible_memtotal_mb с плагином действия.

Пример модуля (./library/a_test.py):

#!/usr/bin/python

def main():
    module = AnsibleModule(
        argument_spec = dict(
            mem_size=dict(required=False, default=None),
        ),
        supports_check_mode = False
    )

    module.exit_json(changed=False, mem_size=module.params['mem_size'])

from ansible.module_utils.basic import *
from ansible.module_utils.urls import *

main()

Тестовый плейбук:

---
- hosts: all
  tasks:
    - a_test:
person Konstantin Suvorov    schedule 13.07.2017
comment
Большое спасибо за ваш пример @Konstantin, но не могли бы вы помочь мне правильно использовать этот пример? Я пытался использовать его так: `x = ActionModule() module.exit_json(changed=False, meta=module .params, msg=x)` и получаю ошибку: `x = ActionModule()\nTypeError: __init__() принимает ровно 7 аргументов (1 указан)\n, module_stdout: , msg: MODULE FAILURE, rc: 1 ` Или, пожалуйста, покажите некоторая документация, где я могу найти примеры с этим классом. Мне очень жаль за этот вопрос, но я новичок в python (и в доступном). Заранее спасибо. - person A. Zakharov; 14.07.2017
comment
Обновлен мой ответ с примером модуля. - person Konstantin Suvorov; 14.07.2017
comment
Большое спасибо @Konstantin, все работает! Вы спасли мой день - person A. Zakharov; 14.07.2017