use ansible_facts in module code

↘锁芯ラ 提交于 2019-12-18 09:37:03

问题


I am trying to create my own ansible module (which will update cmdb) and i am looking how to use ansible_facts in module code ?

example of my module script is :

#!/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()

What variable i should use to call ansible_facts in module script? (And is it even possible? ).


回答1:


I doubt this is possible from inside module itself, because they are executed in the context of remote machine with predefined parameters.

But you can wrap your module with action plugin (that is executed in local context), collect required data from available variables and pass them as parameters to your module.

Like this (./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)

In this case if your module expect mem_size parameter it will be set to ansible_memtotal_mb's value with action plugin.

Module example (./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()

Test playbook:

---
- hosts: all
  tasks:
    - a_test:


来源:https://stackoverflow.com/questions/45074728/use-ansible-facts-in-module-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!