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,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
数据采集 JSON API
如何实现高效率超简洁的实时数据采集?——Python实战电商数据采集API接口
你是否曾为获取重要数据而感到困扰?是否因为数据封锁而无法获取所需信息?是否因为数据格式混乱而头疼?现在,所有这些问题都可以迎刃而解。让我为大家介绍一款强大的数据采集API接口。
|
1月前
|
JSON API 数据库
解释如何在 Python 中实现 Web 服务(RESTful API)。
解释如何在 Python 中实现 Web 服务(RESTful API)。
26 0
|
18小时前
|
API Python
[AIGC] 使用Python刷LeetCode:常用API及技巧指南
[AIGC] 使用Python刷LeetCode:常用API及技巧指南
|
1天前
|
测试技术 API 网络架构
Python的api自动化测试 编写测试用例
【4月更文挑战第18天】使用Python进行API自动化测试,可以结合`requests`库发送HTTP请求和`unittest`(或`pytest`)编写测试用例。以下示例: 1. 安装必要库:`pip install requests unittest` 2. 创建`test_api.py`,导入库,定义基础URL。 3. 创建继承自`unittest.TestCase`的测试类,包含`setUp`和`tearDown`方法。 4. 编写测试用例,如`test_get_users`,检查响应状态码和内容。 5. 运行测试:`python -m unittest test_api.py`
7 2
|
1天前
|
JSON 测试技术 API
Python的Api自动化测试使用HTTP客户端库发送请求
【4月更文挑战第18天】在Python中进行HTTP请求和API自动化测试有多个库可选:1) `requests`是最流行的选择,支持多种请求方法和内置JSON解析;2) `http.client`是标准库的一部分,适合需要低级别控制的用户;3) `urllib`提供URL操作,适用于复杂请求;4) `httpx`拥有类似`requests`的API,提供现代特性和异步支持。根据具体需求选择,如多数情况`requests`已足够。
7 3
|
1天前
|
人工智能 机器人 API
【Python+微信】【企业微信开发入坑指北】3. 如何利用企业微信API给微信群推送消息
【Python+微信】【企业微信开发入坑指北】3. 如何利用企业微信API给微信群推送消息
4 0
|
1天前
|
缓存 人工智能 API
【Python+微信】【企业微信开发入坑指北】2. 如何利用企业微信API主动给用户发应用消息
【Python+微信】【企业微信开发入坑指北】2. 如何利用企业微信API主动给用户发应用消息
4 0
|
1月前
|
JSON API 数据格式
Python中使用API(四)
Python中使用API(四)
20 0
|
1月前
|
JSON API 数据格式
Python中使用API(三)
Python中使用API(三)
18 0
|
1月前
|
JSON API 数据格式
Python中使用API(二)
Python中使用API(二)
18 0