ansible的二次开发

ansible api

ansible是个好东西,但好的东西也要来折腾下,最近看了看ansible的api,于是就探究了下

简单实例

1
2
3
4
5
6
7
8
import ansible.runner
fun = ansible.runner.Runner(
module_name = 'shell', #调用shell模块,这个代码是为了示例执行shell命令
module_args = 'hostname', #shell命令
host_list = 'aa.py', #host文件路径,我这调用的是dynamic inventory脚本,
pattern = 'AA', #host组名,需要执行shell命令的ip组,AA是在上面aa.py中定义的
) #其它没写的参数,都为是系统默认的
ruselt = fun.run()

Runner类详解

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
class Runner(object):
''' core API interface to ansible '''
# see bin/ansible for how this is used...
def __init__(self,
host_list=C.DEFAULT_HOST_LIST, 这里不仅可以放 静态的hosts文件,也可以放 inventory的脚本,脚本要777权限。
module_path=None, 这个是ansible的路径,一般不用写
module_name=C.DEFAULT_MODULE_NAME, 模块的名字,模块的位置要选定在/usr/share/absible下,不然会识别不到。 要注意下~
module_args=C.DEFAULT_MODULE_ARGS, # ex: "src=/tmp/a dest=/tmp/b" 模块的参数
forks=C.DEFAULT_FORKS, # parallelism level 进程的数目,他的逻辑是这样,你如果填入了20个进程,他会判断你的list_hosts是否有20个,没有的话,他就会根据主机的数目来派生进程,如果超过20个,那就用multiprocess进程池pool来调度。mulitiprocess本身有个isalive的东西,来判断分离出去进程的存活状态。
timeout=C.DEFAULT_TIMEOUT, 这个就是超时的时间
pattern=C.DEFAULT_PATTERN, # which hosts? ex: 'all', 'acme.example.org' 这个是做相关的匹配,是关于inventory的匹配
remote_user=C.DEFAULT_REMOTE_USER, # ex: 'username' 远端用户的选择
remote_pass=C.DEFAULT_REMOTE_PASS, # ex: 'password123' or None if using key 远端密码的选择
remote_port=None, # if SSH on different ports 远端端口的选择
private_key_file=C.DEFAULT_PRIVATE_KEY_FILE, # if not using keys/passwords 还可以用指定key
sudo_pass=C.DEFAULT_SUDO_PASS, # ex: 'password123' or None sudo之后的密码的推送
background=0, # async poll every X seconds, else 0 for non-async 看字眼就知道他是做什么的了,他非常的像 saltstack的 event, 当派生出了一个任务后,
产生一个ansible_job_id,然后时不时的去拿数据
transport=C.DEFAULT_TRANSPORT, # 'ssh', 'paramiko', 'local' 这里是选择你的链接得到方式,默认是用的 paramiko
conditional='True', # run only if this fact expression evals to true 这个是什么呢? 相当与 puppet saltstack 里面的require,状态的判断。
callbacks=None, # used for output 回调的输出
sudo=False, # whether to run sudo or not 是否是sudo
sudo_user=C.DEFAULT_SUDO_USER, # ex: 'root' sudo的时候,用到的用户名
): # 参数结束
实现

ansible_playbook api

ansible_playbook api 部分在官方文档上并没有提,不过通过查看ansible模块的帮助信息可以看到其是支持的。

实例

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

注意

在用api的方式执行playbook的时候,playbook,stats,callbacks,runner_callbacks这几个参数是必须的。

  • 执行流程
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    arguments = []
    if playbook is None:
    arguments.append('playbook')
    if callbacks is None:
    arguments.append('callbacks')
    if runner_callbacks is None:
    arguments.append('runner_callbacks')
    if stats is None:
    arguments.append('stats')
    if arguments:
    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进行计算,汇总。

小结

  • 当需要先对前一次作任务执行的结果进行处理,并将相应的结果对应的作为输入再在一次任务传入时,这里使用api 更方便;
  • 需要对结果输出进行整形时,也比较api 方便;
  • playbook 之间进行调用或都playbook比较复杂时,想要理清任务之间的关系势必累显麻烦,而通过api,从上一层任务到下一层任务之间的调用关系明子。而且playbook之间可以是平行的关系。方便小的功能模块的复用。
  • 方便二次开发及和其他程序之间的耦合调用

后续会进行基于Tornado的ansible的二次封装