From f001eba23e56907c31db71b7aacb8fc1ea43763b Mon Sep 17 00:00:00 2001 From: David Wilson Date: Wed, 14 Feb 2018 21:27:14 +0545 Subject: [PATCH] ansible: Merge module runner into helpers.py. --- examples/ansible_demo.py | 102 ------------------------------------- mitogen/ansible/helpers.py | 87 +++++++++++++++++++++++++++++++ 2 files changed, 87 insertions(+), 102 deletions(-) delete mode 100644 examples/ansible_demo.py diff --git a/examples/ansible_demo.py b/examples/ansible_demo.py deleted file mode 100644 index 50cf83d2..00000000 --- a/examples/ansible_demo.py +++ /dev/null @@ -1,102 +0,0 @@ -""" -Minimal demo of running an Ansible module via mitogen. -""" - -import json -import time - -import mitogen - -# Prevent accident import of an Ansible module from hanging on stdin read. -import ansible.module_utils.basic -ansible.module_utils.basic._ANSIBLE_ARGS = '{}' - - -class Exit(Exception): - """ - Raised when a module exits with success. - """ - def __init__(self, dct): - self.dct = dct - - -class ModuleError(Exception): - """ - Raised when a module voluntarily indicates failure via .fail_json(). - """ - def __init__(self, msg, dct): - Exception.__init__(self, msg) - self.dct = dct - - -def wtf_exit_json(self, **kwargs): - """ - Replace AnsibleModule.exit_json() with something that doesn't try to - suicide the process or JSON-encode the dictionary. Instead, cause Exit to - be raised, with a `dct` attribute containing the successful result - dictionary. - """ - self.add_path_info(kwargs) - kwargs.setdefault('changed', False) - kwargs.setdefault('invocation', { - 'module_args': self.params - }) - kwargs = ansible.module_utils.basic.remove_values(kwargs, self.no_log_values) - self.do_cleanup_files() - raise Exit(kwargs) - - -def wtf_fail_json(self, **kwargs): - """ - Replace AnsibleModule.fail_json() with something that raises ModuleError, - which includes a `dct` attribute. - """ - self.add_path_info(kwargs) - kwargs.setdefault('failed', True) - kwargs.setdefault('invocation', { - 'module_args': self.params - }) - kwargs = ansible.module_utils.basic.remove_values(kwargs, self.no_log_values) - self.do_cleanup_files() - raise ModuleError(kwargs.get('msg'), kwargs) - - -def run_module(module, raw_params=None, args=None): - """ - Set up the process environment in preparation for running an Ansible - module. The monkey-patches the Ansible libraries in various places to - prevent it from trying to kill the process on completion, and to prevent it - from reading sys.stdin. - """ - if args is None: - args = {} - if raw_params is not None: - args['_raw_params'] = raw_params - - ansible.module_utils.basic.AnsibleModule.exit_json = wtf_exit_json - ansible.module_utils.basic.AnsibleModule.fail_json = wtf_fail_json - ansible.module_utils.basic._ANSIBLE_ARGS = json.dumps({ - 'ANSIBLE_MODULE_ARGS': args - }) - - try: - mod = __import__(module, {}, {}, ['']) - # Ansible modules begin execution on import, because they're crap from - # hell. Thus the above __import__ will cause either Exit or - # ModuleError to be raised. If we reach the line below, the module did - # not execute and must already have been imported for a previous - # invocation, so we need to invoke main explicitly. - mod.main() - except Exit, e: - return e.dct - - -def main(router): - context = router.local() - print context.call(run_module, 'ansible.modules.system.setup') - for x in xrange(10): - print context.call(run_module, 'ansible.modules.commands.command', 'hostname') - -if __name__ == '__main__' and mitogen.is_master: - import mitogen.utils - mitogen.utils.run_with_router(main) diff --git a/mitogen/ansible/helpers.py b/mitogen/ansible/helpers.py index 0e976510..776de0ba 100644 --- a/mitogen/ansible/helpers.py +++ b/mitogen/ansible/helpers.py @@ -34,7 +34,94 @@ So here we define helpers in some sanely layered package where the entirety of Ansible won't be imported. """ +import json import subprocess +import time + +import mitogen + +# Prevent accidental import of an Ansible module from hanging on stdin read. +import ansible.module_utils.basic +ansible.module_utils.basic._ANSIBLE_ARGS = '{}' + + +class Exit(Exception): + """ + Raised when a module exits with success. + """ + def __init__(self, dct): + self.dct = dct + + +class ModuleError(Exception): + """ + Raised when a module voluntarily indicates failure via .fail_json(). + """ + def __init__(self, msg, dct): + Exception.__init__(self, msg) + self.dct = dct + + +def wtf_exit_json(self, **kwargs): + """ + Replace AnsibleModule.exit_json() with something that doesn't try to + suicide the process or JSON-encode the dictionary. Instead, cause Exit to + be raised, with a `dct` attribute containing the successful result + dictionary. + """ + self.add_path_info(kwargs) + kwargs.setdefault('changed', False) + kwargs.setdefault('invocation', { + 'module_args': self.params + }) + kwargs = ansible.module_utils.basic.remove_values(kwargs, self.no_log_values) + self.do_cleanup_files() + raise Exit(kwargs) + + +def wtf_fail_json(self, **kwargs): + """ + Replace AnsibleModule.fail_json() with something that raises ModuleError, + which includes a `dct` attribute. + """ + self.add_path_info(kwargs) + kwargs.setdefault('failed', True) + kwargs.setdefault('invocation', { + 'module_args': self.params + }) + kwargs = ansible.module_utils.basic.remove_values(kwargs, self.no_log_values) + self.do_cleanup_files() + raise ModuleError(kwargs.get('msg'), kwargs) + + +def run_module(module, raw_params=None, args=None): + """ + Set up the process environment in preparation for running an Ansible + module. The monkey-patches the Ansible libraries in various places to + prevent it from trying to kill the process on completion, and to prevent it + from reading sys.stdin. + """ + if args is None: + args = {} + if raw_params is not None: + args['_raw_params'] = raw_params + + ansible.module_utils.basic.AnsibleModule.exit_json = wtf_exit_json + ansible.module_utils.basic.AnsibleModule.fail_json = wtf_fail_json + ansible.module_utils.basic._ANSIBLE_ARGS = json.dumps({ + 'ANSIBLE_MODULE_ARGS': args + }) + + try: + mod = __import__(module, {}, {}, ['']) + # Ansible modules begin execution on import, because they're crap from + # hell. Thus the above __import__ will cause either Exit or + # ModuleError to be raised. If we reach the line below, the module did + # not execute and must already have been imported for a previous + # invocation, so we need to invoke main explicitly. + mod.main() + except Exit, e: + return e.dct def exec_command(cmd, in_data=None):