天天看点

ansible自定义模块

参考官网:http://www.ansible.com.cn/docs/developing_modules.html#tutorial

阅读 ansible 附带的模块(上面链接)是学习如何编写模块的好方法。但是请记住,ansible 源代码树中的某些模块是内在的,因此请查看service或yum,不要太靠近async_wrapper 之类的东西,否则您会变成石头。没有人直接执行 async_wrapper。

好的,让我们开始举例。我们将使用 Python。首先,将其保存为名为timetest.py的文件:

ansible自定义模块
ansible自定义模块

程序

ansible自定义模块

[root@mcw1 ~]$ mkdir /usr/share/my_modules   #这个目录并不存在,ansible配置中存在这个注释掉的路径

[root@mcw1 ~]$ vim uptime

执行结果:

ansible自定义模块

[root@mcw1 ~]$ grep library /etc/ansible/ansible.cfg   #将配置中的这行内容注释,取消掉,不需要重启任何服务

library = /usr/share/my_modules/

这里显示它使用的解释器路径了,这个解释器是python2的解释器,如果我写的是python3的脚本,并且不支持python2执行,我可能需要修改ansible默认使用的python解释器。有点问题,我脚本里写的是python2的解释器,我写成python3应该就是python3了吧

ansible自定义模块

按照上面想法试了下,果然是的,我另一个主机是没有安装python3的,所以报错了。使用python3,貌似不会显示python的路径,跟之前python2有点区别

ansible自定义模块

编写脚本:

ansible自定义模块

程序如下:

上面程序中,python2和python3去掉\n换行符存在区别。python2:rstrip("\n"),python3:rstrip("\\n")

无论是否dumps,打印结果都是一行。当将字典dumps后,结果好看很多

ansible自定义模块

 当不使用dumps时,都是报错,但是有标准输出的还是会一行打印出来

ansible自定义模块

 当我程序里将字典换成一行时,ansible输出内容还是有层次的显示出来。并且它把我们输出的字典所有键值对,相当于批量追加进ansible自己的输出字典中。同时它还会有自己的相关键值对,

ansible自定义模块

总结:我们可以写python(shell应该也可以)脚本,将需要的信息构建字典,打印出来。然后将脚本放到自定义模块目录下,无需添加执行权限,就可以使用ansible调用自定义模块,将输出结果显示在ansible的打印结果字典中

 思考:上面总结打印的结果我怎么用?python中如何使用这个结果,ansible剧本中是否能使用这个模块,如何使用,这么用到它的打印结果?

使用shell的方法还存在问题,有时间再看有办法解决这个问题

ansible自定义模块

设置变量,其它地方使用变量

我们通过set_fact模块定义了一个名为testvar的变量,变量值为testtest,然后使用debug模块输出了这个变量:

ansible自定义模块

如下:

ansible自定义模块
ansible自定义模块

剧本2

在剧本中定义变量testvar1,在剧本中可以引用这个变量。执行shell命令,将命令返回值注册为一个变量。set_fact模块设置两个变量,变量1让它等于前面设置的变量testvar1,变量2给它赋值shell命令的返回结果变量的标准输出。后面对这两个变量打印查看

剧本中想要查看信息,需要使用debug 模块(debug msg 打印)

set_fact:可以自定义变量,可以进行变量值的传递。可以用这个模块重新定义一个变量去接收其它变量的值,包括接收其它注册的变量值 

ansible自定义模块

上例中,我们先定义了一个变量testvar1,又使用register将shell模块的返回值注册到了变量shellreturn中,

之后,使用set_fact模块将testvar1变量的值赋予了变量testsf1,将shellreturn变量中的stdout信息赋值给了testsf2变量,(可以将注释去掉查看变量shellreturn的值)

最后,使用debug模块输出了testsf1与testsf2的值:

如上述示例所示,set_fact模块可以让我们在tasks中创建变量,也可以将一个变量的值赋值给另一个变量。

其实,通过set_fact模块创建的变量还有一个特殊性,通过set_fact创建的变量就像主机上的facts信息一样,可以在之后的play中被引用。

默认情况下,每个play执行之前都会执行一个名为”[Gathering Facts]”的默认任务,这个任务会收集对应主机的相关信息,我们可以称这些信息为facts信息,我们已经总结过怎样通过变量引用这些facts信息,此处不再赘述,而通过set_fact模块创建的变量可以在之后play中被引用,就好像主机的facts信息可以在play中引用一样,这样说可能还是不是特别容易理解,不如来看一个小例子,如下

ansible自定义模块
ansible自定义模块

剧本

ansible自定义模块

 变量1是vars关键字设置变量,在当前play生效,不能跨越play使用变量,但是变量2却可以跨越play使用变量,变量2是set_facts模块设置变量

ansible自定义模块

可以发现,这两个变量在第一个play中都可以正常的输出。但是在第二个play中,testvar2可以被正常输出了,testvar1却不能被正常输出,会出现未定义testvar1的错误,因为在第一个play中针对testB主机进行操作时,testvar1是通过vars关键字创建的,而testvar2是通过set_fact创建的,所以testvar2就好像testB的facts信息一样,可以在第二个play中引用到,而创建testvar1变量的方式则不能达到这种效果,虽然testvar2就像facts信息一样能被之后的play引用,但是在facts信息中并不能找到testvar2,只是”效果上”与facts信息相同罢了。

ansible自定义模块
ansible自定义模块
ansible自定义模块

3是vars定义变量,4是注册变量,4是可以跨play的,3却不行 。是需要4还是3看情况

ansible自定义模块

在第二个play中获取”testvar3″时会报错,而在第二个play中获取注册变量”testvar4″时则正常,但是,注册变量中的信息是模块的返回值,这并不是我们自定义的信息,所以,如果想要在tasks中给变量自定义信息,并且在之后的play操作同一个主机时能够使用到之前在tasks中定义的变量时,则可以使用set_facts定义对应的变量。

上述示例中,即使是跨play获取变量,也都是针对同一台主机。

找到过滤插件所在的目录,当前没有任何过滤插件,新增一个插件deal_list_num.py

[root@mcw1 ~]$ ls /usr/share/ansible/plugins/filter

deal_list_num.py

 插件的好处在于编写YML文件时可以减少我们的工作量,而且结果易于展示,只要学习一些比较重要的比如Filter、Callbacks等即可。

    在普通情况下,我们主要是以{{somevars|filter}对somevars使用filter方法过滤,Ansible已经为我们提供了很多的过滤方法,比如找到列表中最大、最小数的max、min,把数据转换成JSON格式的fromjson等,但这还远远不够,我们还需要自定义一些过滤的方法来满足一些特殊的需求,比如查找列表中大于某个常数的所有数字等。以这个例子,展示如何编写。

    首先,到ansible.cfg中去掉#,打开filter_plugins的存放目录,filter_plugins=/usr/share/ansible/plugins/filter。

    编写deal_list_num.py文件,他主要提供过滤列表中的正数、负数和查询列表大于某一个给定数值这3个方法。/usr/share/ansible/filter/deal_list_num.py。

ansible自定义模块
ansible自定义模块
ansible自定义模块

第一个是取列表中的正数,第二个是取列表中的负数。第三个是取列表中不小于4的数

ansible自定义模块
ansible自定义模块

变量引用和查看获取shell命令结果作为注册变量,该如何取到命令结果

ansible自定义模块
ansible自定义模块

过滤方法这里做个修改

ansible自定义模块
ansible自定义模块

 总结:

1、过滤插件定义类,类中定义方法,方法返回内容

2、将过滤插件放到ansible过滤插件目录下

3、剧本中{{变量}}的方式调用变量。然后变量后面|加过滤方法。这样就可以将变量传递进插件对应方法中,除了self之外的第一个位置参数就是这个剧本中的变量。

4、在过滤插件方法中对这个变量做过滤,然后返回结果(这里是定义空列表,然后将剧本变量列表遍历一次,筛选出指定条件的元素追加到新的列表中,方法返回新的列表这样剧本中就是使用过滤后的数据)

 参考地址:

剧本编写和定义模块: https://blog.csdn.net/weixin_46108954/article/details/104990063

设置和注册变量:https://blog.csdn.net/weixin_45029822/article/details/105280206

自定义插件:过滤插件:https://blog.csdn.net/JackLiu16/article/details/82121044