3

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? ).

A. Zakharov
  • 33
  • 1
  • 3
  • I faced a similar issue, and ended up creating a [custom look-up plugin](https://stackoverflow.com/a/72770110/1333025), which processes facts and makes them available as its output. – Petr Jun 27 '22 at 09:54

1 Answers1

3

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:
Konstantin Suvorov
  • 65,183
  • 9
  • 162
  • 193
  • Thank you so much for you example @Konstantin , but could you help me with how to use correctly this example ?I've been trying to use it like : ` x = ActionModule() module.exit_json(changed=False, meta=module.params, msg=x)` and getting error : ` x = ActionModule()\nTypeError: __init__() takes exactly 7 arguments (1 given)\n", "module_stdout": "", "msg": "MODULE FAILURE", "rc": 1 ` Or please show some documentation where i can find examples with this Class. I am really sorry for this question , but i am a newbie in python (and ansible as well). Thank you in advance. – A. Zakharov Jul 14 '17 at 10:15
  • Updated my answer with module example. – Konstantin Suvorov Jul 14 '17 at 10:31
  • Thank you so much @Konstantin it's working ! You saved my day – A. Zakharov Jul 14 '17 at 10:42