@ -3,41 +3,58 @@
from __future__ import ( absolute_import , division , print_function )
__metaclass__ = type
import json
import shutil
import ansible . constants as C
from ansible . executor . task_queue_manager import TaskQueueManager
from ansible . module_utils . common . collections import ImmutableDict
from ansible . inventory . manager import InventoryManager
from ansible . parsing . dataloader import DataLoader
from ansible . playbook . play import Play
from ansible . plugins . callback import CallbackBase
from ansible . vars . manager import VariableManager
from ansible import context
from ansible . module_utils . common . collections import ImmutableDict
# Create a callback object so we can capture the output
class ResultsCollector ( CallbackBase ) :
# Create a callback plugin so we can capture the output
class ResultsCollectorJSONCallback ( CallbackBase ) :
""" A sample callback plugin used for performing an action as results come in.
If you want to collect all results into a single object for processing at
the end of the execution , look into utilizing the ` ` json ` ` callback plugin
or writing your own custom callback plugin .
"""
def __init__ ( self , * args , * * kwargs ) :
super ( ResultsCollector , self ) . __init__ ( * args , * * kwargs )
super ( ResultsCollector JSONCallback , self ) . __init__ ( * args , * * kwargs )
self . host_ok = { }
self . host_unreachable = { }
self . host_failed = { }
def v2_runner_on_unreachable ( self , result ) :
self . host_unreachable [ result . _host . get_name ( ) ] = result
host = result . _host
self . host_unreachable [ host . get_name ( ) ] = result
def v2_runner_on_ok ( self , result , * args , * * kwargs ) :
self . host_ok [ result . _host . get_name ( ) ] = result
""" Print a json representation of the result.
Also , store the result in an instance attribute for retrieval later
"""
host = result . _host
self . host_ok [ host . get_name ( ) ] = result
print ( json . dumps ( { host . name : result . _result } , indent = 4 ) )
def v2_runner_on_failed ( self , result , * args , * * kwargs ) :
self . host_failed [ result . _host . get_name ( ) ] = result
host = result . _host
self . host_failed [ host . get_name ( ) ] = result
def main ( ) :
host_list = [ ' localhost ' , ' www.example.com ' , ' www.google.com ' ]
# since the API is constructed for CLI it expects certain options to always be set in the context object
context . CLIARGS = ImmutableDict ( connection = ' smart ' , module_path = [ ' / usr/share/ansible' ] , forks = 10 , become = None ,
context . CLIARGS = ImmutableDict ( connection = ' smart ' , module_path = [ ' / to/mymodules' , ' / usr/share/ansible' ] , forks = 10 , become = None ,
become_method = None , become_user = None , check = False , diff = False )
# required for
# https://github.com/ansible/ansible/blob/devel/lib/ansible/inventory/manager.py#L204
sources = ' , ' . join ( host_list )
@ -45,20 +62,19 @@ def main():
sources + = ' , '
# initialize needed objects
loader = DataLoader ( )
passwords = dict ( )
loader = DataLoader ( ) # Takes care of finding and reading yaml, json and ini files
passwords = dict ( vault_pass = ' secret ' )
# Instantiate our ResultsCollector for handling results as
# they come in. Ansible expects this to be one of its main
# display outlets.
callback = ResultsCollector ( )
# Instantiate our ResultsCollectorJSONCallback for handling results as they come in. Ansible expects this to be one of its main display outlets
results_callback = ResultsCollectorJSONCallback ( )
# create inventory and pass to var manager
# create inventory, use path to host config file as source or hosts in a comma separated string
inventory = InventoryManager ( loader = loader , sources = sources )
# variable manager takes care of merging all the different sources to give you a unified view of variables available in each context
variable_manager = VariableManager ( loader = loader , inventory = inventory )
# Instantiate task queue manager, which takes care of forking
# and setting up all objects to iterate over host list and tasks.
# instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks
# IMPORTANT: This also adds library dirs paths to the module loader
# IMPORTANT: and so it must be initialized before calling `Play.load()`.
tqm = TaskQueueManager (
@ -66,37 +82,47 @@ def main():
variable_manager = variable_manager ,
loader = loader ,
passwords = passwords ,
stdout_callback = callback,
stdout_callback = results_ callback, # Use our custom callback instead of the ``default`` callback plugin, which prints to stdout
)
# create play with tasks
# create data structure that represents our play, including tasks, this is basically what our YAML loader does internally.
play_source = dict (
name = " Ansible Play " ,
hosts = host_list ,
gather_facts = ' no ' ,
tasks = [ dict ( action = dict ( module = ' command ' , args = dict ( cmd = ' /usr/bin/uptime ' ) ) ) ]
tasks = [
dict ( action = dict ( module = ' shell ' , args = ' ls ' ) , register = ' shell_out ' ) ,
dict ( action = dict ( module = ' debug ' , args = dict ( msg = ' {{ shell_out.stdout}} ' ) ) ) ,
dict ( action = dict ( module = ' command ' , args = dict ( cmd = ' /usr/bin/uptime ' ) ) ) ,
]
)
# Create play object, playbook objects use .load instead of init or new methods,
# this will also automatically create the task objects from the info provided in play_source
play = Play ( ) . load ( play_source , variable_manager = variable_manager , loader = loader )
# actually run it
# A ctually run it
try :
result = tqm . run ( play )
result = tqm . run ( play ) # most interesting data for a play is actually sent to the callback's methods
finally :
if tqm is not None :
tqm . cleanup ( )
# we always need to cleanup child procs and the structures we use to communicate with them
tqm . cleanup ( )
if loader :
loader . cleanup_all_tmp_files ( )
# Remove ansible tmpdir
shutil . rmtree ( C . DEFAULT_LOCAL_TMP , True )
print ( " UP *********** " )
for host , result in callback . host_ok . items ( ) :
for host , result in results_ callback. host_ok . items ( ) :
print ( ' {0} >>> {1} ' . format ( host , result . _result [ ' stdout ' ] ) )
print ( " FAILED ******* " )
for host , result in callback. host_failed . items ( ) :
for host , result in results_ callback. host_failed . items ( ) :
print ( ' {0} >>> {1} ' . format ( host , result . _result [ ' msg ' ] ) )
print ( " DOWN ********* " )
for host , result in callback. host_unreachable . items ( ) :
for host , result in results_ callback. host_unreachable . items ( ) :
print ( ' {0} >>> {1} ' . format ( host , result . _result [ ' msg ' ] ) )