# /usr/bin/env python
# -*- coding:utf-8 -*-
# Author  : wuyifei
# Data    : 10/10/18 10:18 AM
# FileName: ansible_api.py

import json
import datetime
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.plugins.callback import CallbackBase
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager

class PlaybookResultsCallback(CallbackBase):
    def __init__(self,*args,**kwargs):
        super(PlaybookResultsCallback,self).__init__(*args,**kwargs)
        self.task_ok = {}
        self.task_unreachable = {}
        self.task_failed = {}
        self.task_skipped = {}
        self.task_stats = {}

    def v2_runner_on_unreachable(self, result):
        self.task_unreachable[result._host.get_name()] = result

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

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

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

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

class ResultsCallback(CallbackBase):
    def __init__(self,*args,**kwargs):
        super(ResultsCallback,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


class Runner(object):
    def __init__(self,sources,*args,**kwargs):
        self.loader = DataLoader()
        self.results_callback = ResultsCallback()
        self.Playbook_results_callback = PlaybookResultsCallback()
        self.sources = sources # sources=['/etc/ansible/hosts'] or '172.17.0.2,172.17.0.3'
        self.inventory = InventoryManager(loader=self.loader,sources=self.sources)

        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        # 扩展加入变量用户名,密码
        self.variable_manager.extra_vars = {"ansible_user": "root", "ansible_ssh_pass": "Password1",
                                            "server_date":'"%s"'%datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        self.passwords = None
        self.results_raw = {}

        Options = namedtuple('Options',
                     ['connection',
                      'remote_user',
                      'ask_sudo_pass',
                      'verbosity',
                      'ack_pass',
                      'module_path',
                      'forks',
                      'become',
                      'become_method',
                      'become_user',
                      'check',
                      'listhosts',
                      'listtasks',
                      'listtags',
                      'syntax',
                      'sudo_user',
                      'sudo',
                      'diff'])
        # 初始化需要的对象
        self.options = Options(connection='smart',
                       remote_user=None,
                       ack_pass=None,
                       sudo_user=None,
                       forks=5,
                       sudo=None,
                       ask_sudo_pass=False,
                       verbosity=5,
                       module_path=None,
                       become=None,
                       become_method=None,
                       become_user=None,
                       check=False,
                       diff=False,
                       listhosts=None,
                       listtasks=None,
                       listtags=None,
                       syntax=None)

    def run_ad_hoc(self):
        play_source = dict(
            name="Ansible Play ad-hoc",
            hosts='all',
            gather_facts='no',
            tasks=[
                dict(action=dict(module='shell', args='hostname'), register='shell_out'),
                dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
            ]
        )
        play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)

        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
                stdout_callback=self.results_callback,
            )
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

        ##定义字典用于接收或者处理结果
    def get_adhoc_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.results_callback.host_ok.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['success'][hostvisiable] = result._result

        for host, result in self.results_callback.host_failed.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['failed'][hostvisiable] = result._result

        for host, result in self.results_callback.host_unreachable.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['unreachable'][hostvisiable] = result._result
        return json.dumps(self.results_raw,indent=4)

    def run_playbook(self,extra_vars=None):
        if extra_vars: self.variable_manager.extra_vars = extra_vars
        playbook = PlaybookExecutor(playbooks=['/home/wuyifei/ops_pro/ops_server/utils/playbooks/client_update.yml'],
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    options=self.options,
                                    passwords=self.passwords)

        playbook._tqm._stdout_callback = self.Playbook_results_callback
        results = playbook.run()


    def get_playbook_result(self):
        ##定义字典用于接收或者处理结果
        self.result_raw = {'success': {}, 'failed': {}, 'unreachable': {}, 'skipped': {}, 'status': {}}

        # 循环打印这个结果，success，failed，unreachable需要每个都定义一个
        for host, result in self.Playbook_results_callback.task_ok.items():
            self.result_raw['success'][host] = result._result

        for host, result in self.Playbook_results_callback.task_failed.items():
            self.result_raw['failed'][host] = result._result

        for host, result in self.Playbook_results_callback.task_unreachable.items():
            self.result_raw['unreachable'][host] = result._result

        for host, result in self.Playbook_results_callback.task_skipped.items():
            self.result_raw['skipped'][host] = result._result

        for host, result in self.Playbook_results_callback.task_stats.items():
            self.result_raw['status'][host] = result._result

        return json.dumps(self.result_raw,indent=4)

if __name__ == "__main__":
    c = Runner('10.0.4.193,'
               #'10.0.25.52,10.0.25.53,10.0.25.51,10.0.25.55'
)   # ['/etc/ansible/hosts'] or '172.17.0.2,172.17.0.3'
    # c.run_ad_hoc()
    c.run_playbook()
    # print (c.get_adhoc_result())
    print (c.get_playbook_result())
    '''
    {
        "success": {
            "172_17_0_2": {
                "msg": "docker_server30",
                "_ansible_verbose_always": true,
                "_ansible_no_log": false,
                "changed": false
            },
            "172_17_0_3": {
                "msg": "docker_server29",
                "_ansible_verbose_always": true,
                "_ansible_no_log": false,
                "changed": false
            }
        },
        "unreachable": {},
        "failed": {}
    } 
    '''

    '''
    {
        "success": {
            "172.17.0.2": {
                "stderr": "",
                "stderr_lines": [],
                "start": "2018-10-11 06:25:25.227928",
                "cmd": "hostname",
                "end": "2018-10-11 06:25:25.248382",
                "_ansible_parsed": true,
                "stdout": "docker_server30",
                "delta": "0:00:00.020454",
                "changed": true,
                "_ansible_no_log": false,
                "rc": 0,
                "stdout_lines": [
                    "docker_server30"
                ],
                "invocation": {
                    "module_args": {
                        "warn": true,
                        "_raw_params": "hostname",
                        "chdir": null,
                        "_uses_shell": true,
                        "argv": null,
                        "removes": null,
                        "stdin": null,
                        "executable": null,
                        "creates": null
                    }
                }
            },
            "172.17.0.3": {
                "stderr": "",
                "stderr_lines": [],
                "start": "2018-10-11 06:25:25.232889",
                "cmd": "hostname",
                "end": "2018-10-11 06:25:25.252864",
                "_ansible_parsed": true,
                "stdout": "docker_server29",
                "delta": "0:00:00.019975",
                "changed": true,
                "_ansible_no_log": false,
                "rc": 0,
                "stdout_lines": [
                    "docker_server29"
                ],
                "invocation": {
                    "module_args": {
                        "warn": true,
                        "_raw_params": "hostname",
                        "chdir": null,
                        "_uses_shell": true,
                        "argv": null,
                        "removes": null,
                        "stdin": null,
                        "executable": null,
                        "creates": null
                    }
                }
            }
        },
        "status": {},
        "unreachable": {},
        "skipped": {},
        "failed": {}
    }
    '''
213da7a3a435f372285d79c08a062ee25217c4d2
<mask token>


class ResultsCallback(CallbackBase):

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


class Runner(object):

    def __init__(self, sources, *args, **kwargs):
        self.loader = DataLoader()
        self.results_callback = ResultsCallback()
        self.Playbook_results_callback = PlaybookResultsCallback()
        self.sources = sources
        self.inventory = InventoryManager(loader=self.loader, sources=self.
            sources)
        self.variable_manager = VariableManager(loader=self.loader,
            inventory=self.inventory)
        self.variable_manager.extra_vars = {'ansible_user': 'root',
            'ansible_ssh_pass': 'Password1', 'server_date': '"%s"' %
            datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        self.passwords = None
        self.results_raw = {}
        Options = namedtuple('Options', ['connection', 'remote_user',
            'ask_sudo_pass', 'verbosity', 'ack_pass', 'module_path',
            'forks', 'become', 'become_method', 'become_user', 'check',
            'listhosts', 'listtasks', 'listtags', 'syntax', 'sudo_user',
            'sudo', 'diff'])
        self.options = Options(connection='smart', remote_user=None,
            ack_pass=None, sudo_user=None, forks=5, sudo=None,
            ask_sudo_pass=False, verbosity=5, module_path=None, become=None,
            become_method=None, become_user=None, check=False, diff=False,
            listhosts=None, listtasks=None, listtags=None, syntax=None)

    def run_ad_hoc(self):
        play_source = dict(name='Ansible Play ad-hoc', hosts='all',
            gather_facts='no', tasks=[dict(action=dict(module='shell', args
            ='hostname'), register='shell_out'), dict(action=dict(module=
            'debug', args=dict(msg='{{shell_out.stdout}}')))])
        play = Play().load(play_source, variable_manager=self.
            variable_manager, loader=self.loader)
        tqm = None
        try:
            tqm = TaskQueueManager(inventory=self.inventory,
                variable_manager=self.variable_manager, loader=self.loader,
                options=self.options, passwords=self.passwords,
                stdout_callback=self.results_callback)
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def get_adhoc_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.results_callback.host_ok.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['success'][hostvisiable] = result._result
        for host, result in self.results_callback.host_failed.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['failed'][hostvisiable] = result._result
        for host, result in self.results_callback.host_unreachable.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['unreachable'][hostvisiable] = result._result
        return json.dumps(self.results_raw, indent=4)

    def run_playbook(self, extra_vars=None):
        if extra_vars:
            self.variable_manager.extra_vars = extra_vars
        playbook = PlaybookExecutor(playbooks=[
            '/home/wuyifei/ops_pro/ops_server/utils/playbooks/client_update.yml'
            ], inventory=self.inventory, variable_manager=self.
            variable_manager, loader=self.loader, options=self.options,
            passwords=self.passwords)
        playbook._tqm._stdout_callback = self.Playbook_results_callback
        results = playbook.run()

    def get_playbook_result(self):
        self.result_raw = {'success': {}, 'failed': {}, 'unreachable': {},
            'skipped': {}, 'status': {}}
        for host, result in self.Playbook_results_callback.task_ok.items():
            self.result_raw['success'][host] = result._result
        for host, result in self.Playbook_results_callback.task_failed.items():
            self.result_raw['failed'][host] = result._result
        for host, result in self.Playbook_results_callback.task_unreachable.items(
            ):
            self.result_raw['unreachable'][host] = result._result
        for host, result in self.Playbook_results_callback.task_skipped.items(
            ):
            self.result_raw['skipped'][host] = result._result
        for host, result in self.Playbook_results_callback.task_stats.items():
            self.result_raw['status'][host] = result._result
        return json.dumps(self.result_raw, indent=4)


<mask token>

<mask token>


class PlaybookResultsCallback(CallbackBase):
    <mask token>
    <mask token>

    def v2_runner_on_ok(self, result, *args, **kwargs):
        self.task_ok[result._host.get_name()] = result
    <mask token>

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

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


class ResultsCallback(CallbackBase):

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


class Runner(object):

    def __init__(self, sources, *args, **kwargs):
        self.loader = DataLoader()
        self.results_callback = ResultsCallback()
        self.Playbook_results_callback = PlaybookResultsCallback()
        self.sources = sources
        self.inventory = InventoryManager(loader=self.loader, sources=self.
            sources)
        self.variable_manager = VariableManager(loader=self.loader,
            inventory=self.inventory)
        self.variable_manager.extra_vars = {'ansible_user': 'root',
            'ansible_ssh_pass': 'Password1', 'server_date': '"%s"' %
            datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        self.passwords = None
        self.results_raw = {}
        Options = namedtuple('Options', ['connection', 'remote_user',
            'ask_sudo_pass', 'verbosity', 'ack_pass', 'module_path',
            'forks', 'become', 'become_method', 'become_user', 'check',
            'listhosts', 'listtasks', 'listtags', 'syntax', 'sudo_user',
            'sudo', 'diff'])
        self.options = Options(connection='smart', remote_user=None,
            ack_pass=None, sudo_user=None, forks=5, sudo=None,
            ask_sudo_pass=False, verbosity=5, module_path=None, become=None,
            become_method=None, become_user=None, check=False, diff=False,
            listhosts=None, listtasks=None, listtags=None, syntax=None)

    def run_ad_hoc(self):
        play_source = dict(name='Ansible Play ad-hoc', hosts='all',
            gather_facts='no', tasks=[dict(action=dict(module='shell', args
            ='hostname'), register='shell_out'), dict(action=dict(module=
            'debug', args=dict(msg='{{shell_out.stdout}}')))])
        play = Play().load(play_source, variable_manager=self.
            variable_manager, loader=self.loader)
        tqm = None
        try:
            tqm = TaskQueueManager(inventory=self.inventory,
                variable_manager=self.variable_manager, loader=self.loader,
                options=self.options, passwords=self.passwords,
                stdout_callback=self.results_callback)
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def get_adhoc_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.results_callback.host_ok.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['success'][hostvisiable] = result._result
        for host, result in self.results_callback.host_failed.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['failed'][hostvisiable] = result._result
        for host, result in self.results_callback.host_unreachable.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['unreachable'][hostvisiable] = result._result
        return json.dumps(self.results_raw, indent=4)

    def run_playbook(self, extra_vars=None):
        if extra_vars:
            self.variable_manager.extra_vars = extra_vars
        playbook = PlaybookExecutor(playbooks=[
            '/home/wuyifei/ops_pro/ops_server/utils/playbooks/client_update.yml'
            ], inventory=self.inventory, variable_manager=self.
            variable_manager, loader=self.loader, options=self.options,
            passwords=self.passwords)
        playbook._tqm._stdout_callback = self.Playbook_results_callback
        results = playbook.run()

    def get_playbook_result(self):
        self.result_raw = {'success': {}, 'failed': {}, 'unreachable': {},
            'skipped': {}, 'status': {}}
        for host, result in self.Playbook_results_callback.task_ok.items():
            self.result_raw['success'][host] = result._result
        for host, result in self.Playbook_results_callback.task_failed.items():
            self.result_raw['failed'][host] = result._result
        for host, result in self.Playbook_results_callback.task_unreachable.items(
            ):
            self.result_raw['unreachable'][host] = result._result
        for host, result in self.Playbook_results_callback.task_skipped.items(
            ):
            self.result_raw['skipped'][host] = result._result
        for host, result in self.Playbook_results_callback.task_stats.items():
            self.result_raw['status'][host] = result._result
        return json.dumps(self.result_raw, indent=4)


<mask token>

<mask token>


class PlaybookResultsCallback(CallbackBase):

    def __init__(self, *args, **kwargs):
        super(PlaybookResultsCallback, self).__init__(*args, **kwargs)
        self.task_ok = {}
        self.task_unreachable = {}
        self.task_failed = {}
        self.task_skipped = {}
        self.task_stats = {}
    <mask token>

    def v2_runner_on_ok(self, result, *args, **kwargs):
        self.task_ok[result._host.get_name()] = result
    <mask token>

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

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


class ResultsCallback(CallbackBase):

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


class Runner(object):

    def __init__(self, sources, *args, **kwargs):
        self.loader = DataLoader()
        self.results_callback = ResultsCallback()
        self.Playbook_results_callback = PlaybookResultsCallback()
        self.sources = sources
        self.inventory = InventoryManager(loader=self.loader, sources=self.
            sources)
        self.variable_manager = VariableManager(loader=self.loader,
            inventory=self.inventory)
        self.variable_manager.extra_vars = {'ansible_user': 'root',
            'ansible_ssh_pass': 'Password1', 'server_date': '"%s"' %
            datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        self.passwords = None
        self.results_raw = {}
        Options = namedtuple('Options', ['connection', 'remote_user',
            'ask_sudo_pass', 'verbosity', 'ack_pass', 'module_path',
            'forks', 'become', 'become_method', 'become_user', 'check',
            'listhosts', 'listtasks', 'listtags', 'syntax', 'sudo_user',
            'sudo', 'diff'])
        self.options = Options(connection='smart', remote_user=None,
            ack_pass=None, sudo_user=None, forks=5, sudo=None,
            ask_sudo_pass=False, verbosity=5, module_path=None, become=None,
            become_method=None, become_user=None, check=False, diff=False,
            listhosts=None, listtasks=None, listtags=None, syntax=None)

    def run_ad_hoc(self):
        play_source = dict(name='Ansible Play ad-hoc', hosts='all',
            gather_facts='no', tasks=[dict(action=dict(module='shell', args
            ='hostname'), register='shell_out'), dict(action=dict(module=
            'debug', args=dict(msg='{{shell_out.stdout}}')))])
        play = Play().load(play_source, variable_manager=self.
            variable_manager, loader=self.loader)
        tqm = None
        try:
            tqm = TaskQueueManager(inventory=self.inventory,
                variable_manager=self.variable_manager, loader=self.loader,
                options=self.options, passwords=self.passwords,
                stdout_callback=self.results_callback)
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def get_adhoc_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.results_callback.host_ok.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['success'][hostvisiable] = result._result
        for host, result in self.results_callback.host_failed.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['failed'][hostvisiable] = result._result
        for host, result in self.results_callback.host_unreachable.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['unreachable'][hostvisiable] = result._result
        return json.dumps(self.results_raw, indent=4)

    def run_playbook(self, extra_vars=None):
        if extra_vars:
            self.variable_manager.extra_vars = extra_vars
        playbook = PlaybookExecutor(playbooks=[
            '/home/wuyifei/ops_pro/ops_server/utils/playbooks/client_update.yml'
            ], inventory=self.inventory, variable_manager=self.
            variable_manager, loader=self.loader, options=self.options,
            passwords=self.passwords)
        playbook._tqm._stdout_callback = self.Playbook_results_callback
        results = playbook.run()

    def get_playbook_result(self):
        self.result_raw = {'success': {}, 'failed': {}, 'unreachable': {},
            'skipped': {}, 'status': {}}
        for host, result in self.Playbook_results_callback.task_ok.items():
            self.result_raw['success'][host] = result._result
        for host, result in self.Playbook_results_callback.task_failed.items():
            self.result_raw['failed'][host] = result._result
        for host, result in self.Playbook_results_callback.task_unreachable.items(
            ):
            self.result_raw['unreachable'][host] = result._result
        for host, result in self.Playbook_results_callback.task_skipped.items(
            ):
            self.result_raw['skipped'][host] = result._result
        for host, result in self.Playbook_results_callback.task_stats.items():
            self.result_raw['status'][host] = result._result
        return json.dumps(self.result_raw, indent=4)


<mask token>

<mask token>


class PlaybookResultsCallback(CallbackBase):

    def __init__(self, *args, **kwargs):
        super(PlaybookResultsCallback, self).__init__(*args, **kwargs)
        self.task_ok = {}
        self.task_unreachable = {}
        self.task_failed = {}
        self.task_skipped = {}
        self.task_stats = {}

    def v2_runner_on_unreachable(self, result):
        self.task_unreachable[result._host.get_name()] = result

    def v2_runner_on_ok(self, result, *args, **kwargs):
        self.task_ok[result._host.get_name()] = result
    <mask token>

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

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


class ResultsCallback(CallbackBase):

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


class Runner(object):

    def __init__(self, sources, *args, **kwargs):
        self.loader = DataLoader()
        self.results_callback = ResultsCallback()
        self.Playbook_results_callback = PlaybookResultsCallback()
        self.sources = sources
        self.inventory = InventoryManager(loader=self.loader, sources=self.
            sources)
        self.variable_manager = VariableManager(loader=self.loader,
            inventory=self.inventory)
        self.variable_manager.extra_vars = {'ansible_user': 'root',
            'ansible_ssh_pass': 'Password1', 'server_date': '"%s"' %
            datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        self.passwords = None
        self.results_raw = {}
        Options = namedtuple('Options', ['connection', 'remote_user',
            'ask_sudo_pass', 'verbosity', 'ack_pass', 'module_path',
            'forks', 'become', 'become_method', 'become_user', 'check',
            'listhosts', 'listtasks', 'listtags', 'syntax', 'sudo_user',
            'sudo', 'diff'])
        self.options = Options(connection='smart', remote_user=None,
            ack_pass=None, sudo_user=None, forks=5, sudo=None,
            ask_sudo_pass=False, verbosity=5, module_path=None, become=None,
            become_method=None, become_user=None, check=False, diff=False,
            listhosts=None, listtasks=None, listtags=None, syntax=None)

    def run_ad_hoc(self):
        play_source = dict(name='Ansible Play ad-hoc', hosts='all',
            gather_facts='no', tasks=[dict(action=dict(module='shell', args
            ='hostname'), register='shell_out'), dict(action=dict(module=
            'debug', args=dict(msg='{{shell_out.stdout}}')))])
        play = Play().load(play_source, variable_manager=self.
            variable_manager, loader=self.loader)
        tqm = None
        try:
            tqm = TaskQueueManager(inventory=self.inventory,
                variable_manager=self.variable_manager, loader=self.loader,
                options=self.options, passwords=self.passwords,
                stdout_callback=self.results_callback)
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

    def get_adhoc_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.results_callback.host_ok.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['success'][hostvisiable] = result._result
        for host, result in self.results_callback.host_failed.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['failed'][hostvisiable] = result._result
        for host, result in self.results_callback.host_unreachable.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['unreachable'][hostvisiable] = result._result
        return json.dumps(self.results_raw, indent=4)

    def run_playbook(self, extra_vars=None):
        if extra_vars:
            self.variable_manager.extra_vars = extra_vars
        playbook = PlaybookExecutor(playbooks=[
            '/home/wuyifei/ops_pro/ops_server/utils/playbooks/client_update.yml'
            ], inventory=self.inventory, variable_manager=self.
            variable_manager, loader=self.loader, options=self.options,
            passwords=self.passwords)
        playbook._tqm._stdout_callback = self.Playbook_results_callback
        results = playbook.run()

    def get_playbook_result(self):
        self.result_raw = {'success': {}, 'failed': {}, 'unreachable': {},
            'skipped': {}, 'status': {}}
        for host, result in self.Playbook_results_callback.task_ok.items():
            self.result_raw['success'][host] = result._result
        for host, result in self.Playbook_results_callback.task_failed.items():
            self.result_raw['failed'][host] = result._result
        for host, result in self.Playbook_results_callback.task_unreachable.items(
            ):
            self.result_raw['unreachable'][host] = result._result
        for host, result in self.Playbook_results_callback.task_skipped.items(
            ):
            self.result_raw['skipped'][host] = result._result
        for host, result in self.Playbook_results_callback.task_stats.items():
            self.result_raw['status'][host] = result._result
        return json.dumps(self.result_raw, indent=4)


<mask token>

# /usr/bin/env python
# -*- coding:utf-8 -*-
# Author  : wuyifei
# Data    : 10/10/18 10:18 AM
# FileName: ansible_api.py

import json
import datetime
from collections import namedtuple
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.plugins.callback import CallbackBase
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager

class PlaybookResultsCallback(CallbackBase):
    def __init__(self,*args,**kwargs):
        super(PlaybookResultsCallback,self).__init__(*args,**kwargs)
        self.task_ok = {}
        self.task_unreachable = {}
        self.task_failed = {}
        self.task_skipped = {}
        self.task_stats = {}

    def v2_runner_on_unreachable(self, result):
        self.task_unreachable[result._host.get_name()] = result

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

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

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

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

class ResultsCallback(CallbackBase):
    def __init__(self,*args,**kwargs):
        super(ResultsCallback,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


class Runner(object):
    def __init__(self,sources,*args,**kwargs):
        self.loader = DataLoader()
        self.results_callback = ResultsCallback()
        self.Playbook_results_callback = PlaybookResultsCallback()
        self.sources = sources # sources=['/etc/ansible/hosts'] or '172.17.0.2,172.17.0.3'
        self.inventory = InventoryManager(loader=self.loader,sources=self.sources)

        self.variable_manager = VariableManager(loader=self.loader, inventory=self.inventory)
        # 扩展加入变量用户名,密码
        self.variable_manager.extra_vars = {"ansible_user": "root", "ansible_ssh_pass": "Password1",
                                            "server_date":'"%s"'%datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}
        self.passwords = None
        self.results_raw = {}

        Options = namedtuple('Options',
                     ['connection',
                      'remote_user',
                      'ask_sudo_pass',
                      'verbosity',
                      'ack_pass',
                      'module_path',
                      'forks',
                      'become',
                      'become_method',
                      'become_user',
                      'check',
                      'listhosts',
                      'listtasks',
                      'listtags',
                      'syntax',
                      'sudo_user',
                      'sudo',
                      'diff'])
        # 初始化需要的对象
        self.options = Options(connection='smart',
                       remote_user=None,
                       ack_pass=None,
                       sudo_user=None,
                       forks=5,
                       sudo=None,
                       ask_sudo_pass=False,
                       verbosity=5,
                       module_path=None,
                       become=None,
                       become_method=None,
                       become_user=None,
                       check=False,
                       diff=False,
                       listhosts=None,
                       listtasks=None,
                       listtags=None,
                       syntax=None)

    def run_ad_hoc(self):
        play_source = dict(
            name="Ansible Play ad-hoc",
            hosts='all',
            gather_facts='no',
            tasks=[
                dict(action=dict(module='shell', args='hostname'), register='shell_out'),
                dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
            ]
        )
        play = Play().load(play_source, variable_manager=self.variable_manager, loader=self.loader)

        tqm = None
        try:
            tqm = TaskQueueManager(
                inventory=self.inventory,
                variable_manager=self.variable_manager,
                loader=self.loader,
                options=self.options,
                passwords=self.passwords,
                stdout_callback=self.results_callback,
            )
            result = tqm.run(play)
        finally:
            if tqm is not None:
                tqm.cleanup()

        ##定义字典用于接收或者处理结果
    def get_adhoc_result(self):
        self.results_raw = {'success': {}, 'failed': {}, 'unreachable': {}}
        for host, result in self.results_callback.host_ok.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['success'][hostvisiable] = result._result

        for host, result in self.results_callback.host_failed.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['failed'][hostvisiable] = result._result

        for host, result in self.results_callback.host_unreachable.items():
            hostvisiable = host.replace('.', '_')
            self.results_raw['unreachable'][hostvisiable] = result._result
        return json.dumps(self.results_raw,indent=4)

    def run_playbook(self,extra_vars=None):
        if extra_vars: self.variable_manager.extra_vars = extra_vars
        playbook = PlaybookExecutor(playbooks=['/home/wuyifei/ops_pro/ops_server/utils/playbooks/client_update.yml'],
                                    inventory=self.inventory,
                                    variable_manager=self.variable_manager,
                                    loader=self.loader,
                                    options=self.options,
                                    passwords=self.passwords)

        playbook._tqm._stdout_callback = self.Playbook_results_callback
        results = playbook.run()


    def get_playbook_result(self):
        ##定义字典用于接收或者处理结果
        self.result_raw = {'success': {}, 'failed': {}, 'unreachable': {}, 'skipped': {}, 'status': {}}

        # 循环打印这个结果，success，failed，unreachable需要每个都定义一个
        for host, result in self.Playbook_results_callback.task_ok.items():
            self.result_raw['success'][host] = result._result

        for host, result in self.Playbook_results_callback.task_failed.items():
            self.result_raw['failed'][host] = result._result

        for host, result in self.Playbook_results_callback.task_unreachable.items():
            self.result_raw['unreachable'][host] = result._result

        for host, result in self.Playbook_results_callback.task_skipped.items():
            self.result_raw['skipped'][host] = result._result

        for host, result in self.Playbook_results_callback.task_stats.items():
            self.result_raw['status'][host] = result._result

        return json.dumps(self.result_raw,indent=4)

if __name__ == "__main__":
    c = Runner('10.0.4.193,'
               #'10.0.25.52,10.0.25.53,10.0.25.51,10.0.25.55'
)   # ['/etc/ansible/hosts'] or '172.17.0.2,172.17.0.3'
    # c.run_ad_hoc()
    c.run_playbook()
    # print (c.get_adhoc_result())
    print (c.get_playbook_result())
    '''
    {
        "success": {
            "172_17_0_2": {
                "msg": "docker_server30",
                "_ansible_verbose_always": true,
                "_ansible_no_log": false,
                "changed": false
            },
            "172_17_0_3": {
                "msg": "docker_server29",
                "_ansible_verbose_always": true,
                "_ansible_no_log": false,
                "changed": false
            }
        },
        "unreachable": {},
        "failed": {}
    } 
    '''

    '''
    {
        "success": {
            "172.17.0.2": {
                "stderr": "",
                "stderr_lines": [],
                "start": "2018-10-11 06:25:25.227928",
                "cmd": "hostname",
                "end": "2018-10-11 06:25:25.248382",
                "_ansible_parsed": true,
                "stdout": "docker_server30",
                "delta": "0:00:00.020454",
                "changed": true,
                "_ansible_no_log": false,
                "rc": 0,
                "stdout_lines": [
                    "docker_server30"
                ],
                "invocation": {
                    "module_args": {
                        "warn": true,
                        "_raw_params": "hostname",
                        "chdir": null,
                        "_uses_shell": true,
                        "argv": null,
                        "removes": null,
                        "stdin": null,
                        "executable": null,
                        "creates": null
                    }
                }
            },
            "172.17.0.3": {
                "stderr": "",
                "stderr_lines": [],
                "start": "2018-10-11 06:25:25.232889",
                "cmd": "hostname",
                "end": "2018-10-11 06:25:25.252864",
                "_ansible_parsed": true,
                "stdout": "docker_server29",
                "delta": "0:00:00.019975",
                "changed": true,
                "_ansible_no_log": false,
                "rc": 0,
                "stdout_lines": [
                    "docker_server29"
                ],
                "invocation": {
                    "module_args": {
                        "warn": true,
                        "_raw_params": "hostname",
                        "chdir": null,
                        "_uses_shell": true,
                        "argv": null,
                        "removes": null,
                        "stdin": null,
                        "executable": null,
                        "creates": null
                    }
                }
            }
        },
        "status": {},
        "unreachable": {},
        "skipped": {},
        "failed": {}
    }
    '''