ansible python api 2.0使用

简介:

 最近想利用python来调用anbile来实现一些功能,发现ansible的api已经升级到了2.0,使用上比以前复杂了许多。

 这里我参考了官方文档的例子,做了一些整改,写了一个python调用ansible的函数,执行过程中输出执行结果。函数返回执行结果,便于筛选和存储所需的数据:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# vim exec_ansible.py
from ansible.inventory.manager  import  InventoryManager
from ansible.playbook.play  import  Play
from ansible.executor.task_queue_manager  import  TaskQueueManager
from ansible.plugins.callback  import  CallbackBase
 
class ResultCallback(CallbackBase):
     "" "A sample callback plugin used  for  performing an action as results come  in
 
     If you want to collect all results into a single object  for  processing at
     the end of the execution,  look  into utilizing the ``json`` callback plugin
     or writing your own custom callback plugin
     "" "
     def v2_runner_on_ok(self, result, **kwargs):
         "" "Print a json representation of the result
         This method could store the result  in  an instance attribute  for  retrieval later
         "" "
         global exec_result
         host = result._host
         self.data = json.dumps({host.name: result._result}, indent=4)
         exec_result = dict(exec_result,**json.loads(self.data))
 
 
def exec_ansible(module,args,host):               
     Options = namedtuple( 'Options' , [ 'connection' 'module_path' 'forks' 'become' 'become_method' 'become_user' 'check' 'diff' ])
     # initialize needed objects
     loader = DataLoader()
     options = Options(connection= 'ssh' , module_path= '/usr/local/lib/python3.6/site-packages/ansible-2.4.1.0-py3.6.egg/ansible/modules/' , forks=100, become=None, become_method=None, become_user=None, check=False, diff =False)
     passwords = dict(vault_pass= 'secret' )
 
     # Instantiate our ResultCallback for handling results as they come in
     results_callback = ResultCallback()
 
     # create inventory and pass to var manager
     inventory = InventoryManager(loader=loader, sources=[ '/etc/ansible/hosts' ])
     variable_manager = VariableManager(loader=loader, inventory=inventory)
 
     # create play with tasks
     play_source =  dict(
             name =  "Ansible Play" ,
             hosts = host,
             gather_facts =  'no' ,
             tasks = [
                 dict(action=dict(module=module, args=args), register= 'shell_out' ),
              ]
         )
     play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
 
     # actually run it
     tqm = None
     global exec_result
     try:
         tqm = TaskQueueManager(
                   inventory=inventory,
                   variable_manager=variable_manager,
                   loader=loader,
                   options=options,
                   passwords=passwords,
                   stdout_callback=results_callback,   # Use our custom callback instead of the ``default`` callback plugin
               )
         result = tqm.run(play)
     finally:
         if  tqm is not None:
             tqm.cleanup()
         return  exec_result


调用例子:

  我本地ansible的hosts文件如下:

1
2
3
4
# more /etc/ansible/hosts
[testserver]
192.168.52.128
192.168.52.135

  调用如下:

  先调用testserver一组主机批量执行date命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
>>> from exec_ansible  import  exec_ansible                             
>>> test1 = exec_ansible(module= 'shell' ,args= 'date' ,host= 'testserver' )
{
     "192.168.52.135" : {
         "warnings" : [],
         "stderr" "" ,
         "delta" "0:00:00.003688" ,
         "_ansible_no_log" false ,
         "stdout" "Sat Nov  5 18:54:17 CST 2016" ,
         "cmd" "date" ,
         "_ansible_parsed" true ,
         "rc" : 0,
         "invocation" : {
             "module_args" : {
                 "removes" : null,
                 "executable" : null,
                 "creates" : null,
                 "chdir" : null,
                 "warn" true ,
                 "_raw_params" "date" ,
                 "_uses_shell" true
             },
             "module_name" "command"
         },
         "start" "2016-11-05 18:54:17.563525" ,
         "changed" true ,
         "end" "2016-11-05 18:54:17.567213" ,
         "stdout_lines" : [
             "Sat Nov  5 18:54:17 CST 2016"
         ]
     }
}
{
     "192.168.52.128" : {
         "warnings" : [],
         "stderr" "" ,
         "delta" "0:00:00.003244" ,
         "_ansible_no_log" false ,
         "stdout" "Sat Nov  5 21:48:38 CST 2016" ,
         "cmd" "date" ,
         "_ansible_parsed" true ,
         "rc" : 0,
         "invocation" : {
             "module_args" : {
                 "removes" : null,
                 "executable" : null,
                 "creates" : null,
                 "chdir" : null,
                 "warn" true ,
                 "_raw_params" "date" ,
                 "_uses_shell" true
             },
             "module_name" "command"
         },
         "start" "2016-11-05 21:48:38.252785" ,
         "changed" true ,
         "end" "2016-11-05 21:48:38.256029" ,
         "stdout_lines" : [
             "Sat Nov  5 21:48:38 CST 2016"
         ]
     }
}

  

 指定单台执行命令:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
>>> test2 = exec_ansible(module= 'shell' ,args= 'free -m' ,host= '192.168.52.128' )
{
     "192.168.52.128" : {
         "warnings" : [],
         "changed" true ,
         "invocation" : {
             "module_args" : {
                 "_raw_params" "free -m" ,
                 "executable" : null,
                 "chdir" : null,
                 "creates" : null,
                 "removes" : null,
                 "_uses_shell" true ,
                 "warn" true
             },
             "module_name" "command"
         },
         "rc" : 0,
         "start" "2016-11-05 21:53:10.738545" ,
         "_ansible_parsed" true ,
         "delta" "0:00:00.002871" ,
         "stdout_lines" : [
             "             total       used       free     shared    buffers     cached" ,
             "Mem:          1869       1786         83          3        312        512" ,
             "-/+ buffers/cache:        961        908 " ,
             "Swap:         4047          3       4044 "
         ],
         "stderr" "" ,
         "end" "2016-11-05 21:53:10.741416" ,
         "cmd" "free -m" ,
         "_ansible_no_log" false ,
         "stdout" "             total       used       free     shared    buffers     cached\nMem:          1869       1786         83          3        312        512\n-/+ buffers/cache:        961        908 \nSwap:         4047          3       4044 "
     }
}

 这里可以从输出中取到输出结果:

1
2
3
4
5
>>> stdout = test2[ "192.168.52.128" ][ "stdout" ]
              total       used        free      shared    buffers     cached
Mem:          1869       1756        112          2        314        490
-/+ buffers /cache :        951        917 
Swap:         4047          4       4043


 我写的脚本有个bug,就是当指定一组主机批量执行的时候,返回的函数中,存储内容的只剩下最后执行命令的那台主机的相关信息,做不到把所有的主机的执行信息存储,希望有大神可以解决这个问题,并不吝赐教!!(已解决,参考更改过的exec_ansible脚本)



-------后续更新---------------

注:

      新版本的api相关模块已经修改,故使用方法上也需要整改,本文档的例子已更新api的使用,如上的exec_ansible脚本。


-----bug解决----

     另外,我在脚本中新增了全局空字典参数exec_result={},分别在class ResultCallback和函数exec_result中进行全局函数声明,用以存储执行过程中所产生的stdout输出,以解决之前脚本的bug(返回函数中,存储内容的只剩下最后执行命令的那台主机的相关信息,做不到把所有的主机的执行信息存储)。

      只需在python主体重定义exec_result = {}这个空字典,即可实现。


使用如下:

1
2
3
4
exec_result  =  {}
=  exec_ansible( "shell" , "free -m" , "test" )
print (a)
{ '192.168.204.128' : { 'changed' True 'end' '2017-11-07 15:16:08.970746' 'stdout' '             t









本文转自 icenycmh 51CTO博客,原文链接:http://blog.51cto.com/icenycmh/1870642,如需转载请自行联系原作者
目录
相关文章
|
4天前
|
机器学习/深度学习 设计模式 API
Python 高级编程与实战:构建 RESTful API
本文深入探讨了使用 Python 构建 RESTful API 的方法,涵盖 Flask、Django REST Framework 和 FastAPI 三个主流框架。通过实战项目示例,详细讲解了如何处理 GET、POST 请求,并返回相应数据。学习这些技术将帮助你掌握构建高效、可靠的 Web API。
|
5天前
|
存储 监控 API
1688平台API接口实战:Python实现店铺全量商品数据抓取
本文介绍如何使用Python通过1688开放平台的API接口自动化抓取店铺所有商品数据。首先,开发者需在1688开放平台完成注册并获取App Key和App Secret,申请“商品信息查询”权限。接着,利用`alibaba.trade.product.search4trade`接口,构建请求参数、生成MD5签名,并通过分页机制获取全量商品数据。文中详细解析了响应结构、存储优化及常见问题处理方法,还提供了竞品监控、库存预警等应用场景示例和完整代码。
|
7天前
|
机器学习/深度学习 开发框架 API
Python 高级编程与实战:深入理解 Web 开发与 API 设计
在前几篇文章中,我们探讨了 Python 的基础语法、面向对象编程、函数式编程、元编程、性能优化、调试技巧以及数据科学和机器学习。本文将深入探讨 Python 在 Web 开发和 API 设计中的应用,并通过实战项目帮助你掌握这些技术。
|
8天前
|
JSON API 数据格式
Python 请求微店商品详情数据 API 接口
微店开放平台允许开发者通过API获取商品详情数据。使用Python请求微店商品详情API的主要步骤包括:1. 注册并申请API权限,获得app_key和app_secret;2. 确定API接口地址与请求参数,如商品ID;3. 生成签名确保请求安全合法;4. 使用requests库发送HTTP请求获取数据;5. 处理返回的JSON格式响应数据。开发时需严格遵循微店API文档要求。
|
13天前
|
数据采集 供应链 API
实战指南:通过1688开放平台API获取商品详情数据(附Python代码及避坑指南)
1688作为国内最大的B2B供应链平台,其API为企业提供合法合规的JSON数据源,直接获取批发价、SKU库存等核心数据。相比爬虫方案,官方API避免了反爬严格、数据缺失和法律风险等问题。企业接入1688商品API需完成资质认证、创建应用、签名机制解析及调用接口四步。应用场景包括智能采购系统、供应商评估模型和跨境选品分析。提供高频问题解决方案及安全合规实践,确保数据安全与合法使用。立即访问1688开放平台,解锁B2B数据宝藏!
|
1月前
|
JSON 数据可视化 API
Python 中调用 DeepSeek-R1 API的方法介绍,图文教程
本教程详细介绍了如何使用 Python 调用 DeepSeek 的 R1 大模型 API,适合编程新手。首先登录 DeepSeek 控制台获取 API Key,安装 Python 和 requests 库后,编写基础调用代码并运行。文末包含常见问题解答和更简单的可视化调用方法,建议收藏备用。 原文链接:[如何使用 Python 调用 DeepSeek-R1 API?](https://apifox.com/apiskills/how-to-call-the-deepseek-r1-api-using-python/)
|
2月前
|
数据采集 JavaScript 前端开发
京东商品详情 API 接口指南(Python 篇)
本简介介绍如何使用Python抓取京东商品详情数据。首先,需搭建开发环境并安装必要的库(如requests、BeautifulSoup和lxml),了解京东反爬虫机制,确定商品ID获取方式。通过发送HTTP请求并解析HTML,可提取价格、优惠券、视频链接等信息。此方法适用于电商数据分析、竞品分析、购物助手及内容创作等场景,帮助用户做出更明智的购买决策,优化营销策略。
|
2月前
|
数据采集 供应链 API
Python爬虫与1688图片搜索API接口:深度解析与显著收益
在电子商务领域,数据是驱动业务决策的核心。阿里巴巴旗下的1688平台作为全球领先的B2B市场,提供了丰富的API接口,特别是图片搜索API(`item_search_img`),允许开发者通过上传图片搜索相似商品。本文介绍如何结合Python爬虫技术高效利用该接口,提升搜索效率和用户体验,助力企业实现自动化商品搜索、库存管理优化、竞品监控与定价策略调整等,显著提高运营效率和市场竞争力。
115 3
|
3月前
|
JavaScript API C#
【Azure Developer】Python代码调用Graph API将外部用户添加到组,结果无效,也无错误信息
根据Graph API文档,在单个请求中将多个成员添加到组时,Python代码示例中的`members@odata.bind`被错误写为`members@odata_bind`,导致用户未成功添加。
61 10
|
3月前
|
数据采集 JSON API
如何利用Python爬虫淘宝商品详情高级版(item_get_pro)API接口及返回值解析说明
本文介绍了如何利用Python爬虫技术调用淘宝商品详情高级版API接口(item_get_pro),获取商品的详细信息,包括标题、价格、销量等。文章涵盖了环境准备、API权限申请、请求构建和返回值解析等内容,强调了数据获取的合规性和安全性。

推荐镜像

更多