在第二篇文章中虽然可以执行adhoc和playbook但是执行结果的输出并不是特别直观,虽然没有报错但是到底什么结果其实你是不知道的尤其是在执行adhoc的时候,这时候我们要利用callback来设置一下执行结果的输出。

执行adhoc

#!/usr/bin/env python
# -*- coding: utf-8 -*- from collections import namedtuple
# 核心类
# 用于读取YAML和JSON格式的文件
import sys
from ansible.parsing.dataloader import DataLoader
# 用于存储各类变量信息
from ansible.vars.manager import VariableManager
# 用于导入资产文件
from ansible.inventory.manager import InventoryManager
# 存储执行hosts的角色信息
from ansible.playbook.play import Play
# ansible底层用到的任务队列
from ansible.executor.task_queue_manager import TaskQueueManager
# 状态回调,各种成功失败的状态
from ansible.plugins.callback import CallbackBase class MyCallbackBase(CallbackBase):
"""
通过api调用ac-hoc的时候输出结果很多时候不是很明确或者说不是我们想要的结果,主要它还是输出到STDOUT,而且通常我们是在工程里面执行
这时候就需要后台的结果前端可以解析,正常的API调用输出前端很难解析。 对比之前的执行 adhoc()查看区别。
为了实现这个目的就需要重写CallbackBase类,需要重写下面三个方法
"""
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # python3中重载父类构造方法的方式,在Python2中写法会有区别。
self.host_ok = {}
self.host_unreachable = {}
self.host_failed = {} def v2_runner_on_unreachable(self, result):
"""
重写 unreachable 状态
:param result: 这是父类里面一个对象,这个对象可以获取执行任务信息
"""
self.host_unreachable[result._host.get_name()] = result def v2_runner_on_ok(self, result, *args, **kwargs):
"""
重写 ok 状态
:param result:
"""
self.host_ok[result._host.get_name()] = result def v2_runner_on_failed(self, result, *args, **kwargs):
"""
重写 failed 状态
:param result:
"""
self.host_failed[result._host.get_name()] = result def useMyCallbackBase():
"""
这里通过调用ad-hoc来使用自定义callback
:return:
"""
dl = DataLoader()
im = InventoryManager(loader=dl, sources=["hosts"])
vm = VariableManager(loader=dl, inventory=im)
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"
])
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)
play_source = dict(name="Ansible Play", # 任务名称
hosts="test", # 目标主机,可以填写具体主机也可以是主机组名称
gather_facts="no", # 是否收集配置信息 # tasks是具体执行的任务,列表形式,每个具体任务都是一个字典
tasks=[
dict(action=dict(module="shell", args="touch /tmp/bbb.txt", warn=False))
])
play = Play().load(play_source, variable_manager=vm, loader=dl) passwords = dict() # 这个可以为空,因为在hosts文件中 mycallback = MyCallbackBase() # 实例化自定义callback tqm = TaskQueueManager(
inventory=im,
variable_manager=vm,
loader=dl,
options=options,
passwords=passwords,
stdout_callback=mycallback # 配置使用自定义callback
)
tqm.run(play)
# print(mycallback.host_ok.items()) # 它会返回2个东西,一个主机一个是执行结果对象
# 定义数据结构
result_raw = {"success": {}, "failed": {}, "unreachable": {}}
# 如果成功那么 mycallback.host_ok.items() 才可以遍历,上面的任务肯定能成功所以我们就直接遍历这个
for host, result in mycallback.host_ok.items():
result_raw["success"][host] = result._result for host, result in mycallback.host_failed.items():
result_raw["failed"][host] = result._result for host, result in mycallback.host_unreachable.items():
result_raw["unreachable"][host] = result._result print(result_raw) def main():
useMyCallbackBase() if __name__ == "__main__":
try:
main()
finally:
sys.exit()

执行playbook

#!/usr/bin/env python
# -*- coding: utf-8 -*- import sys
from collections import namedtuple
# 核心类
# 用于读取YAML和JSON格式的文件
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 class MyPlaybookCallbackBase(CallbackBase):
"""
playbook的callback改写,格式化输出playbook执行结果
"""
CALLBACK_VERSION = 2.0 def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.task_ok = {}
self.task_unreachable = {}
self.task_failed = {}
self.task_skipped = {}
self.task_status = {} def v2_runner_on_unreachable(self, result):
"""
重写 unreachable 状态
:param result: 这是父类里面一个对象,这个对象可以获取执行任务信息
"""
self.task_unreachable[result._host.get_name()] = result def v2_runner_on_ok(self, result, *args, **kwargs):
"""
重写 ok 状态
:param result:
"""
self.task_ok[result._host.get_name()] = result def v2_runner_on_failed(self, result, *args, **kwargs):
"""
重写 failed 状态
:param result:
"""
self.task_failed[result._host.get_name()] = result def v2_runner_on_skipped(self, result):
self.task_skipped[result._host.get_name()] = result def v2_playbook_on_stats(self, stats):
hosts = sorted(stats.processed.keys())
for h in hosts:
t = stats.summarize(h)
self.task_status[h] = {
"ok": t["ok"],
"changed": t["changed"],
"unreachable": t["unreachable"],
"skipped": t["skipped"],
"failed": t["failed"]
} def usecallbackplaybook():
"""
调用 playbook
调用playboo大致和调用ad-hoc相同,只是真正调用的是使用PlaybookExecutor
:return:
"""
dl = DataLoader()
im = InventoryManager(loader=dl, sources=["hosts"])
vm = VariableManager(loader=dl, inventory=im)
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"
])
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)
passwords = dict() # 这个可以为空,因为在hosts文件中
#
try:
playbook = PlaybookExecutor(playbooks=["f1.yml"], inventory=im, variable_manager=vm, loader=dl, options=options, passwords=passwords)
callback = MyPlaybookCallbackBase()
playbook._tqm._stdout_callback = callback # 配置callback
playbook.run() # print(callback.task_ok.items())
result_raw = {"ok": {}, "failed": {}, "unreachable": {}, "skipped": {}, "status": {}}
for host, result in callback.task_ok.items():
result_raw["ok"][host] = result._result for host, result in callback.task_failed.items():
result_raw["failed"][host] = result._result for host, result in callback.task_unreachable.items():
result_raw["unreachable"][host] = result._result for host, result in callback.task_skipped.items():
result_raw["skipped"][host] = result._result for host, result in callback.task_status.items():
result_raw["status"][host] = result._result print(result_raw)
except Exception as err:
print(err) def main():
usecallbackplaybook() if __name__ == "__main__":
try:
main()
finally:
sys.exit()

Python调用ansible API系列(三)带有callback的执行adhoc和playbook的更多相关文章

  1. Python调用ansible API系列(五)综合使用

    如何把动态生成资产信息.执行playbook以及自定义结果结合起来用呢? #!/usr/bin/env python # -*- coding: utf-8 -*- """ ...

  2. Python调用ansible API系列(四)动态生成hosts文件

    方法一:通过最原始的操作文件的方式 #!/usr/bin/env python # -*- coding: utf-8 -*- """ 通过操作文件形式动态生成ansib ...

  3. Python调用ansible API系列(一)获取资产信息

    你想让ansible工作首先就需要设置资产信息,那么我们如何通过使用Python调取Ansible的API来获取资产信息呢? 要提前准备一个hosts文件 获取组或者主机 #!/usr/bin/env ...

  4. Python调用ansible API系列(二)执行adhoc和playbook

    执行adhoc #!/usr/bin/env python # -*- coding: utf-8 -*- import sys from collections import namedtuple ...

  5. Ansible Tower系列 三(使用tower执行一个任务)【转】

    创建playbook Tower playbook 项目默认存在 /var/lib/awx/projects/ su - awx cd projects/ mkdir ansible-for-devo ...

  6. python调用ansible api 2.0 运行playbook带callback返回

    # -*- coding:utf8 -*- ''' Created on 2017年1月13日 @author: qiancheng ''' import os import json from co ...

  7. 关于python调用zabbix api接口

    因公司业务需要,引进了自动化运维,所用到的监控平台为zbbix3.2,最近正在学习python,计划使用python调用zabbix api接口去做些事情,如生成报表,我想最基本的是要取得zabbix ...

  8. Redis总结(五)缓存雪崩和缓存穿透等问题 Web API系列(三)统一异常处理 C#总结(一)AutoResetEvent的使用介绍(用AutoResetEvent实现同步) C#总结(二)事件Event 介绍总结 C#总结(三)DataGridView增加全选列 Web API系列(二)接口安全和参数校验 RabbitMQ学习系列(六): RabbitMQ 高可用集群

    Redis总结(五)缓存雪崩和缓存穿透等问题   前面讲过一些redis 缓存的使用和数据持久化.感兴趣的朋友可以看看之前的文章,http://www.cnblogs.com/zhangweizhon ...

  9. 使用Python调用Flickr API抓取图片数据

    Flickr是雅虎旗下的图片分享网站,上面有全世界网友分享的大量精彩图片,被认为是专业的图片网站.其API也很友好,可以实现多种功能.这里我使用了Python调用其API获得了大量的照片数据.需要注意 ...

随机推荐

  1. Angular4.x通过路由守卫进行路由重定向,实现根据条件跳转到相应的页面

    需求: 最近在做一个网上商城的项目,技术用的是Angular4.x.有一个很常见的需求是:用户在点击"我的"按钮时读取cookie,如果有数据,则跳转到个人信息页面,否则跳转到注册 ...

  2. 爬虫之urllib.error模块

    error模块简介 我们在爬虫的时候发请求的时候难免出现错误,如访问不到服务器或者访问被禁止等等, 出错了之后urllib将错误信息封装成了一个模块对象中,这个模块就叫error模块 error的分类 ...

  3. UED团队规范设计参考及建议

    公司产品线逐渐增多,变动频繁且并行开发,常常需要设计与开发能够快速的做出响应.同时这类产品中有存在很多类似的页面以及组件,可以通过抽象得到一些稳定且高复用性的内容.通过模块化的解决方案,降低冗余的生产 ...

  4. 工作中常用的JS函数整理分享(欢迎大家补充)

    今年在渣X工作整理的常用JS函数 今年来了渣X工作,我所在这个部门分工很奇怪,CSS竟然有专门的人在搞,开发PHP的人员需要处理JS,以至于有时候开发起来不是那么得心应手,感觉把JS和CSS拆开就像是 ...

  5. WordPress调用特色图片地址源,去除特色图片img标签其他样式

    我们在制作WordPress主题时候想要给wordpress特色图片,这也是为了更加的美观,但是我们直接使用wordpress特色图片引用代码的时候却发现,出现下面的情况. wordpress特色图片 ...

  6. 微信小程序-获取经纬度

    微信小程序-获取经纬度 最近公司新功能 要求在外的市场人员 发送位置信息回来. 用的还是微信小程序开发.... 微信小程序 提供一个接口 getLocation 这个接口反回来的位置 相对实际位置 相 ...

  7. QT5:C++实现基于multimedia的音乐播放器(一)

    上一篇里简略的描述了一下播放器的实现,这一篇开始具体描述一下过程. 环境配置:Qt Creator 打开Qt Creator,创建一个new project,项目名称随你喜欢(我的是MusicPlay ...

  8. MySql中innodb存储引擎事务日志详解

    分析下MySql中innodb存储引擎是如何通过日志来实现事务的? Mysql会最大程度的使用缓存机制来提高数据库的访问效率,但是万一数据库发生断电,因为缓存的数据没有写入磁盘,导致缓存在内存中的数据 ...

  9. linux几种定时函数的使用

    Linux定时函数介绍: 在程序开发过程中,我们时不时要用到一些定时器,通常如果时间精度要求不高,可以使用sleep,uslepp函数让进程睡眠一段时间来实现定时, 前者单位为秒(s),后者为微妙(u ...

  10. HBuilder 插件开发(openinstall 集成)

    离线打包 如果要集成使用非基座包下的第三方 SDK,就必须使用离线打包.可以参考 官方文档 进行离线打包,如果嫌官方文档看不懂,可以查看 其他技术人员的教程 开发插件 编写 Android 原生代码 ...