Trying to use the Python modules to integrate in my deployment scripts. MODULE FAILURE

Hi,
I have been using ansible for a while with the yml’s and love the simplicity of the tool.
Now, I have used a snippet of a script to try run various ansible tasks on a host via Python.

Would one of you be able to point me in the right direction to get the script working? I copied it off another site and adjusted. Ultimatly, I would like to send it some VARS instead.
If you have a better way of running the script, it would be great also as I feel this is much longer then asking python to run the ansible executable…
Thanks
D

I believe the SSH works well as when I run the script :

$ ansible -i “192.168.47.157,” all -m ping -become --connection=ssh --user=bobvilla --ask-become-pass
SUDO password:
192.168.47.157 | SUCCESS => {
“changed”: false,
“ping”: “pong”
}

When I run my script, it throws this error…

$ ./runner.py
UP ***********
FAILED *******
192.168.47.183 >>> MODULE FAILURE
192.168.47.157 >>> MODULE FAILURE
DOWN *********

Here are a few details on my env.

$ python --version
Python 2.7.12
$ python3 --version
Python 3.5.2
$ ansible --version
ansible 2.4.3.0
config file = None
configured module search path = [‘/home/dave/.ansible/plugins/modules’, ‘/usr/share/ansible/plugins/modules’]
ansible python module location = /usr/local/lib/python3.5/dist-packages/ansible
executable location = /usr/local/bin/ansible
python version = 3.5.2 (default, Nov 23 2017, 16:37:01) [GCC 5.4.0 20160609]

Script Bellow.

#!/usr/bin/env python3
# -- coding: utf-8 --

from collections import namedtuple
from ansible.executor.task_queue_manager import TaskQueueManager
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

# Create a callback object so we can capture the output
class ResultsCollector(CallbackBase):

def init(self, *args, **kwargs):
super(ResultsCollector, 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

def v2_runner_on_ok(self, result, *args, **kwargs):
self.host_ok[result._host.get_name()] = result

def v2_runner_on_failed(self, result, *args, **kwargs):
self.host_failed[result._host.get_name()] = result

def main():
host_list = [‘192.168.47.157’,‘192.168.47.183’]
Options = namedtuple(‘Options’, [‘connection’,
‘module_path’,
‘forks’,
‘remote_user’,
#‘private_key_file’,
#‘ssh_common_args’,
#‘ssh_extra_args’,
#‘sftp_extra_args’,
#‘scp_extra_args’,
‘ansible_user’,
‘become’,
‘become_method’,
‘become_user’,
‘become_pass’,
‘verbosity’,
‘check’,
‘diff’])
# required for
# https://github.com/ansible/ansible/blob/devel/lib/ansible/inventory/manager.py#L204
sources = ‘,’.join(host_list)
if len(host_list) == 1:
sources += ‘,’

# initialize needed objects
loader = DataLoader()
options = Options(connection=‘ssh’,
#module_path=‘/usr/local/lib/python3.5/dist-packages/ansible/modules’,
module_path=‘’,
forks=100,
remote_user=‘bobvilla’,
#private_key_file=None,
#ssh_common_args=None,
#ssh_extra_args=None,
#sftp_extra_args=None,
#scp_extra_args=None,
ansible_user=‘nikita’,
become=‘yes’,
become_method=‘sudo’,
become_user=‘root’,
become_pass=‘password’,
verbosity=3,
check=False,
diff=False)

passwords = dict()

# create inventory and pass to var manager
inventory = InventoryManager(loader=loader, sources=sources)
variable_manager = VariableManager(loader=loader, inventory=inventory)

# create play with tasks
play_source = dict(
name=“Ansible Play”,
hosts=host_list,
gather_facts=‘yes’,
#tasks=[dict(action=dict(module=‘command’, args=dict(cmd=‘tail -10 /var/log/syslog’)))]
tasks=[dict(action=dict(module=‘ping’))]
)
play = Play().load(play_source, variable_manager=variable_manager, loader=loader)

# actually run it
tqm = None
callback = ResultsCollector()
try:
tqm = TaskQueueManager(
inventory=inventory,
variable_manager=variable_manager,
loader=loader,
options=options,
passwords=passwords,
)
tqm._stdout_callback = callback
result = tqm.run(play)
finally:
if tqm is not None:
tqm.cleanup()

print(“UP ***********”)
for host, result in callback.host_ok.items():
print(‘{0} >>> {1}’.format(host, result._result[‘stdout’]))

print(“FAILED *******”)
for host, result in callback.host_failed.items():
print(‘{0} >>> {1}’.format(host, result._result[‘msg’]))

print(“DOWN *********”)
for host, result in callback.host_unreachable.items():
print(‘{0} >>> {1}’.format(host, result._result[‘msg’]))

if name == ‘main’:
main()

Well, I answered my own question on the train. Hope this silly mistake can help someone else later.

become_user=‘root’, > become_user=‘bobvilla’,

On the other hand, I believe i found a slight bug.
When I run ping test, I get this error.

./runner.py
UP ***********
Traceback (most recent call last):
File “./runner.py”, line 133, in
main()
File “./runner.py”, line 122, in main
print(‘{0} >>> {1}’.format(host, result._result[‘stdout’]))
KeyError: ‘stdout’

I guess stdout doesn’t exist on the ping function.
As for the other functions like ‘command’, it works just fine and outputs the information.

Cheers.
D