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,如需转载请自行联系原作者
目录
相关文章
|
15天前
|
前端开发 API UED
Python后端与前端交互新纪元:AJAX、Fetch API联手,打造极致用户体验!
Python后端与前端交互新纪元:AJAX、Fetch API联手,打造极致用户体验!
53 2
|
3天前
|
存储 JSON API
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)
15 7
Python| 如何使用 DALL·E 和 OpenAI API 生成图像(1)
|
2天前
|
前端开发 API 开发者
深度剖析:AJAX、Fetch API如何成为Python后端开发者的最佳拍档!
深度剖析:AJAX、Fetch API如何成为Python后端开发者的最佳拍档!
14 4
|
2天前
|
前端开发 JavaScript API
惊呆了!学会AJAX与Fetch API,你的Python Web项目瞬间高大上!
在Web开发领域,AJAX与Fetch API是提升交互体验的关键技术。AJAX(Asynchronous JavaScript and XML)作为异步通信的先驱,通过XMLHttpRequest对象实现了局部页面更新,提升了应用流畅度。Fetch API则以更现代、简洁的方式处理HTTP请求,基于Promises提供了丰富的功能。当与Python Web框架(如Django、Flask)结合时,这两者能显著增强应用的响应速度和用户体验,使项目更加高效、高大上。
12 2
|
4天前
|
前端开发 API 开发者
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
从零到精通,AJAX与Fetch API让你的Python Web前后端交互无所不能!
15 3
|
3天前
|
API Python 容器
再探泛型 API,感受 Python 对象的设计哲学
再探泛型 API,感受 Python 对象的设计哲学
12 2
|
18天前
|
存储 JSON API
实战派教程!Python Web开发中RESTful API的设计哲学与实现技巧,一网打尽!
在数字化时代,Web API成为连接前后端及构建复杂应用的关键。RESTful API因简洁直观而广受欢迎。本文通过实战案例,介绍Python Web开发中的RESTful API设计哲学与技巧,包括使用Flask框架构建一个图书管理系统的API,涵盖资源定义、请求响应设计及实现示例。通过准确使用HTTP状态码、版本控制、错误处理及文档化等技巧,帮助你深入理解RESTful API的设计与实现。希望本文能助力你的API设计之旅。
44 3
|
18天前
|
存储 前端开发 API
告别繁琐,拥抱简洁!Python RESTful API 设计实战,让 API 调用如丝般顺滑!
在 Web 开发的旅程中,设计一个高效、简洁且易于使用的 RESTful API 是至关重要的。今天,我想和大家分享一次我在 Python 中进行 RESTful API 设计的实战经历,希望能给大家带来一些启发。
33 3
|
17天前
|
开发框架 JSON 缓存
震撼发布!Python Web开发框架下的RESTful API设计全攻略,让数据交互更自由!
在数字化浪潮推动下,RESTful API成为Web开发中不可或缺的部分。本文详细介绍了在Python环境下如何设计并实现高效、可扩展的RESTful API,涵盖框架选择、资源定义、HTTP方法应用及响应格式设计等内容,并提供了基于Flask的示例代码。此外,还讨论了版本控制、文档化、安全性和性能优化等最佳实践,帮助开发者实现更流畅的数据交互体验。
37 1
|
19天前
|
JSON API 开发者
惊!Python Web开发新纪元,RESTful API设计竟能如此性感撩人?
在这个Python Web开发的新纪元里,RESTful API的设计已经超越了简单的技术实现,成为了一种追求极致用户体验和开发者友好的艺术表达。通过优雅的URL设计、合理的HTTP状态码使用、清晰的错误处理、灵活的版本控制以及严格的安全性措施,我们能够让RESTful API变得更加“性感撩人”,为Web应用注入新的活力与魅力。
38 3