Skip to main content
 首页 » 编程设计

python之如何从 Ansible python playbook api 获取远程标准输出

2025年05月04日29grandyang

我知道我可以使用 Ansible 的 debug 模块打印标准数据,如下所示:

--- 
- hosts: all 
  tasks: 
  - name: list files under /root folder 
    command: ls /root 
    register: out 
 
  - name: stdout 
    debug: var=out.stdout_lines 

来自How to use Ansible 2.0 Python API to run a Playbook?的回答,我可以用 python 代码运行 Ansible 剧本。

所以问题是如何使用 Ansible python api 获取此剧本中变量 out 的内容?

请您参考如下方法:

这是我的答案,你应该做一个回调

# -*- coding: utf-8 -*- 
import json 
from ansible.parsing.dataloader import DataLoader 
from ansible.vars import VariableManager 
from ansible.inventory import Inventory 
from ansible.playbook.play import Play 
from ansible.executor.task_queue_manager import TaskQueueManager 
from ansible.executor.playbook_executor import PlaybookExecutor 
 
from ansible.plugins import callback_loader 
from ansible.plugins.callback import CallbackBase 
 
import os 
import logging 
 
 
loader = DataLoader() 
variable_manager = VariableManager() 
inventory = Inventory(loader=loader, variable_manager=variable_manager) 
variable_manager.set_inventory(inventory) 
 
#get result 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, ignore_errors=False): 
        name = result._host.get_name() 
        task = result._task.get_name() 
        ansible_log(result) 
        #self.host_unreachable[result._host.get_name()] = result 
        self.host_unreachable.append(dict(ip=name, task=task, result=result)) 
 
    def v2_runner_on_ok(self, result,  *args, **kwargs): 
        name = result._host.get_name() 
        task = result._task.get_name() 
        if task == "setup": 
            pass 
        elif "Info" in task: 
            self.host_ok.append(dict(ip=name, task=task, result=result)) 
        else: 
            ansible_log(result) 
            self.host_ok.append(dict(ip=name, task=task, result=result)) 
 
    def v2_runner_on_failed(self, result,   *args, **kwargs): 
        name = result._host.get_name() 
        task = result._task.get_name() 
        ansible_log(result) 
        self.host_failed.append(dict(ip=name, task=task, result=result)) 
 
class Options(object): 
    def __init__(self): 
        self.connection = "smart" 
        self.forks = 10 
        self.check = False 
        self.become = None 
        self.become_method = None 
        self.become_user=None 
    def __getattr__(self, name): 
        return None 
 
options = Options() 
 
 
def run_adhoc(ip,order): 
    variable_manager.extra_vars={"ansible_ssh_user":"root" , "ansible_ssh_pass":"passwd"} 
    play_source = {"name":"Ansible Ad-Hoc","hosts":"%s"%ip,"gather_facts":"no","tasks":[{"action":{"module":"command","args":"%s"%order}}]} 
#    play_source = {"name":"Ansible Ad-Hoc","hosts":"192.168.2.160","gather_facts":"no","tasks":[{"action":{"module":"command","args":"python ~/store.py del"}}]}    
    play = Play().load(play_source, variable_manager=variable_manager, loader=loader) 
    tqm = None 
    callback = ResultsCollector() 
 
    try: 
        tqm = TaskQueueManager( 
            inventory=inventory, 
            variable_manager=variable_manager, 
            loader=loader, 
            options=options, 
            passwords=None, 
            run_tree=False, 
        ) 
        tqm._stdout_callback = callback 
        result = tqm.run(play) 
        return callback 
 
    finally: 
        if tqm is not None: 
            tqm.cleanup() 
 
def run_playbook(books): 
    results_callback = callback_loader.get('json') 
    playbooks = [books] 
 
    variable_manager.extra_vars={"ansible_ssh_user":"root" , "ansible_ssh_pass":"passwd"} 
    callback = ResultsCollector() 
 
    pd = PlaybookExecutor( 
        playbooks=playbooks, 
        inventory=inventory, 
        variable_manager=variable_manager, 
        loader=loader, 
        options=options, 
        passwords=None, 
 
        ) 
    pd._tqm._stdout_callback = callback 
 
    try: 
        result = pd.run() 
        return callback 
 
    except Exception as e: 
        print e 
 
if __name__ == '__main__': 
    #run_playbook("yml/info/process.yml") 
 
    #run_adhoc("192.168.2.149", "ifconfig")