【问题标题】:use ansible_facts in module code在模块代码中使用 ansible_facts
【发布时间】:2017-07-13 07:58:52
【问题描述】:

我正在尝试创建自己的 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? (甚至有可能吗?)。

【问题讨论】:

    标签: python ansible ansible-facts


    【解决方案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:
    

    【讨论】:

    • 非常感谢你的例子@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 的新手(也是 ansible ). 提前谢谢你。
    • 用模块示例更新了我的答案。
    • 非常感谢@Konstantin,它正在工作!你拯救了我的一天
    猜你喜欢
    • 2020-05-31
    • 1970-01-01
    • 1970-01-01
    • 2020-07-22
    • 2012-08-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-13
    相关资源
    最近更新 更多