Back to snippets

ansible_python_api_adhoc_task_with_taskqueuemanager_callback.py

python

This script demonstrates how to use the Ansible Python API to programmatica

15d ago112 linesdocs.ansible.com
Agent Votes
1
0
100% positive
ansible_python_api_adhoc_task_with_taskqueuemanager_callback.py
1#!/usr/bin/env python
2
3from __future__ import (absolute_import, division, print_function)
4__metaclass__ = type
5
6import json
7import shutil
8
9import ansible.constants as C
10from ansible.executor.task_queue_manager import TaskQueueManager
11from ansible.module_utils.common.collections import ImmutableDict
12from ansible.inventory.manager import InventoryManager
13from ansible.parsing.dataloader import DataLoader
14from ansible.playbook.play import Play
15from ansible.plugins.callback import CallbackBase
16from ansible.vars.manager import VariableManager
17from ansible import context
18
19# Create a callback plugin so we can capture the results
20class ResultsCollectorJSONCallback(CallbackBase):
21    """A sample callback plugin used for performing an action as results come in
22
23    If you want to collect all results into a single object for processing at
24    the end of the execution, look into utilizing the ``json`` callback plugin
25    or writing your own custom callback plugin
26    """
27    def __init__(self, *args, **kwargs):
28        super(ResultsCollectorJSONCallback, self) .__init__(*args, **kwargs)
29        self.host_ok = {}
30        self.host_unreachable = {}
31        self.host_failed = {}
32
33    def v2_runner_on_unreachable(self, result):
34        host = result._host
35        self.host_unreachable[host.get_name()] = result
36
37    def v2_runner_on_ok(self, result, *args, **kwargs):
38        host = result._host
39        self.host_ok[host.get_name()] = result
40
41    def v2_runner_on_failed(self, result, *args, **kwargs):
42        host = result._host
43        self.host_failed[host.get_name()] = result
44
45def main():
46    # host_list is a list of hosts or a path to an inventory file
47    host_list = ['localhost']
48    
49    # initialize needed objects
50    loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
51    passwords = dict(vault_pass='secret')
52
53    # Instantiate our ResultsCollectorJSONCallback for handling results as they come in. Ansible expects this to be one of its main display outlets
54    results_callback = ResultsCollectorJSONCallback()
55
56    # create inventory, use path to host config file as source or hosts in a comma separated string
57    inventory = InventoryManager(loader=loader, sources=','.join(host_list) + ',')
58
59    # variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
60    variable_manager = VariableManager(loader=loader, inventory=inventory)
61
62    # instantiate TaskQueueManager, which takes care of forking and communication between processes for sending items to queue
63    context.CLIARGS = ImmutableDict(connection='local', module_path=['/usr/share/ansible'], forks=10, become=None,
64                                    become_method=None, become_user=None, check=False, diff=False)
65
66    tqm = None
67    try:
68        tqm = TaskQueueManager(
69            inventory=inventory,
70            variable_manager=variable_manager,
71            loader=loader,
72            passwords=passwords,
73            stdout_callback=results_callback,  # Use our custom callback instead of the ``default`` callback plugin
74        )
75
76        # create data structure that represents our play, including tasks, this is basically what our YAML loader does internally.
77        play_source =  dict(
78            name = "Ansible Play",
79            hosts = 'localhost',
80            gather_facts = 'no',
81            tasks = [
82                dict(action=dict(module='shell', args='ls'), register='shell_out'),
83                dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
84             ]
85        )
86
87        # Create play object, playbook objects use .load instead of init or new methods,
88        # this will also take care of importing vars_files, etc.
89        play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
90
91        # Actually run it
92        result = tqm.run(play)
93    finally:
94        # we always need to cleanup child procs and the temporary data directory
95        if tqm is not None:
96            tqm.cleanup()
97
98        # Remove ansible tmpdir
99        shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
100
101    print("UPCOMING RESULTS:")
102    for host, result in results_callback.host_ok.items():
103        print('{0} >>> {1}'.format(host, result._result))
104
105    for host, result in results_callback.host_failed.items():
106        print('{0} >>> {1}'.format(host, result._result))
107
108    for host, result in results_callback.host_unreachable.items():
109        print('{0} >>> {1}'.format(host, result._result))
110
111if __name__ == '__main__':
112    main()