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

38 views
Skip to first unread message

David H

unread,
Feb 12, 2018, 4:20:02 PM2/12/18
to Ansible Project
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()


David H

unread,
Feb 12, 2018, 6:04:34 PM2/12/18
to Ansible Project
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 <module>
    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
Reply all
Reply to author
Forward
0 new messages