ansible api 与ansible-playbook api 本应该是后面放在 ansible条件与循环、ansible变量篇之后讲的,不过使用过后实在按捺不住提前写的冲动,这个插个队先讲讲API 部分。

一、ansible api

ansible api 的使用非常强大,也非常简单,只不过把模块需要使用的参数写到了脚本中,这里先来看下官方给的示例,不过同于官方的是,我这里增我将结果进行了json美化输出。

  1. [root@361way api]# cat test_api.py
  2. #!/usr/bin/env python
  3. # coding=utf-8
  4. import ansible.runner
  5. import json
  6. runner = ansible.runner.Runner(
  7. module_name=‘ping’,
  8. module_args=,
  9. pattern=‘all’,
  10. forks=10
  11. )
  12. datastructure = runner.run()
  13. data = json.dumps(datastructure,indent=4)
  14. print data

其输出结果如下:

ansible-api

注:如果主机是不通或失败的,结果将会输出到dark部分里,一个含有失败主机的结果类似如下:

  1. {
  2. “dark” : {
  3. “web1.example.com” : “failure message”
  4. },
  5. “contacted” : {
  6. “web2.example.com” : 1
  7. }
  8. }

再为看下第二个示例:

  1. #!/usr/bin/python
  2. import ansible.runner
  3. import sys
  4. # construct the ansible runner and execute on all hosts
  5. results = ansible.runner.Runner(
  6. pattern=‘*’, forks=10,
  7. module_name=‘command’, module_args=‘/usr/bin/uptime’,
  8. ).run()
  9. if results is None:
  10. print “No hosts found”
  11. sys.exit(1)
  12. print “UP ***********”
  13. for (hostname, result) in results[‘contacted’].items():
  14. if not ‘failed’ in result:
  15. print “%s >>> %s” % (hostname, result[‘stdout’])
  16. print “FAILED *******”
  17. for (hostname, result) in results[‘contacted’].items():
  18. if ‘failed’ in result:
  19. print “%s >>> %s” % (hostname, result[‘msg’])
  20. print “DOWN *********”
  21. for (hostname, result) in results[‘dark’].items():
  22. print “%s >>> %s” % (hostname, result)

上面的示例中对主机的输出结果进行了判断,并且结果的输出进行了定制化,上面执行的结果你可以和ansible all -m command -a ‘uptime’ 的结果进行下比对,看下有什么不同。

上面的示例基本上都是参照官方页面进行执行的,更多用法可以通过pydoc ansible或者通过python里的help(ansible)查看。另外在多主机执行时,可以使用async(异部)方式运行。

二、ansible_playbook api

ansible_playbook api 部分在官方文档上并没有提,不过通过查看ansible模块的帮助信息可以看到其是支持的。在ansible google论坛里(需翻墙),有老外也给出里代码,其实它和执行ansible的api方式一样,只是多了个几个参数:

  1. import ansible.playbook
  2. from ansible import callbacks
  3. from ansible import utils
  4. stats = callbacks.AggregateStats()
  5. playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
  6. runner_cb = callbacks.PlaybookRunnerCallbacks(stats, verbose=utils.VERBOSITY)
  7. pb = ansible.playbook.PlayBook(
  8. playbook=“nseries.yml”,
  9. stats=stats,
  10. callbacks=playbook_cb,
  11. runner_callbacks=runner_cb,
  12. check=True
  13. )
  14. for (play_ds, play_basedir) in zip(pb.playbook, pb.play_basedirs):
  15. import ipdb
  16. ipdb.set_trace()
  17. # Can play around here to see what’s going on.
  18. pb.run()

大致看了下代码,在用api的方式执行playbook的时候,playbook,stats,callbacks,runner_callbacks这几个参数是必须的。不使用的时候会报错。

  1. arguments = []
  2. if playbook is None:
  3. arguments.append(‘playbook’)
  4. if callbacks is None:
  5. arguments.append(‘callbacks’)
  6. if runner_callbacks is None:
  7. arguments.append(‘runner_callbacks’)
  8. if stats is None:
  9. arguments.append(‘stats’)
  10. if arguments:
  11. raise Exception(‘PlayBook missing required arguments: %s’ % ‘, ‘.join(arguments))

playbook用来指定playbook的yaml文件

stats用来收集playbook执行期间的状态信息,最后会进行汇总

callbacks用来输出playbook执行的结果

runner_callbacks用来输出playbook执行期间的结果。但是它返回的结果太简单,我想让它详细点,如果用自定义callback的方法插入到mongo里面的话也行,或者是直接输出,但是我想所有task都执行完后,把每个task的详细信息输出到终端上,最后发现结果输出都是靠callbacks.py里的AggregateStats这个类,在每执行完一个task后,都会调用AggregateStats进行计算,汇总。

  1. [root@361way api]# cat playbook_api.py
  2. #!/usr/bin/env python
  3. # coding=utf-8
  4. import ansible.playbook
  5. from ansible import callbacks
  6. from ansible import utils
  7. import json
  8. stats = callbacks.AggregateStats()
  9. playbook_cb = callbacks.PlaybookCallbacks(verbose=utils.VERBOSITY)
  10. runner_cb = callbacks.PlaybookRunnerCallbacks(stats,verbose=utils.VERBOSITY)
  11. res=ansible.playbook.PlayBook(
  12. playbook=‘/etc/ansible/playbooks/user.yml’,
  13. stats=stats,
  14. callbacks=playbook_cb,
  15. runner_callbacks=runner_cb
  16. ).run()
  17. data = json.dumps(res,indent=4)
  18. print data
  19. # 执行结果如下:
  20. [root@361way api]# python playbook_api.py
  21. PLAY [create user] ************************************************************
  22. TASK: [create test “{{ user }}”] **********************************************
  23. changed: [10.212.52.16]
  24. changed: [10.212.52.14]
  25. {
  26. “10.212.52.16”: {
  27. “unreachable”: 0,
  28. “skipped”: 0,
  29. “ok”: 1,
  30. “changed”: 1,
  31. “failures”: 0
  32. },
  33. “10.212.52.14”: {
  34. “unreachable”: 0,
  35. “skipped”: 0,
  36. “ok”: 1,
  37. “changed”: 1,
  38. “failures”: 0
  39. }
  40. }
  41. [root@361way api]#

三、总结

从上面的例子来看,感觉作用似乎有点鸡肋。多条ansible shell 指令的执行可以写成playbook 来执行,ansbile-playbook 也可以通过include 调用子playbook ,似乎API 部分用处并不大 。咋一听深感有理,不过细究一下,

1、当需要先对前一次作任务执行的结果进行处理,并将相应的结果对应的作为输入再在一次任务传入时,这里使用api 更方便;

2、需要对结果输出进行整形时,也比较api 方便;

3、playbook 之间进行调用或都playbook比较复杂时,想要理清任务之间的关系势必累显麻烦,而通过api,从上一层任务到下一层任务之间的调用关系明子。而且playbook之间可以是平行的关系。方便小的功能模块的复用。

4、方便二次开发及和其他程序之间的耦合调用----目前感觉这条是最实用的。

Leave a Reply

Your email address will not be published. Required fields are marked *