Ansible@一个高效的配置管理工具--Ansible configure management--翻译(十一)
无书面授权,请勿转载
第五章 自己定义模块
Using a module
Now that we have written our very first module for Ansible, we should give it a
go in a playbook. Ansible looks at several places for its modules: first it looks at the
place specified in the library key in its config file ( /etc/ansible/ansible.cfg ),
next it will look in the location specified using the --module-path argument in the
command line, then it will look in the same directory as the playbook for a library
directory containing modules, and finally it will look in the library directories for any
roles that may be set.
Let's create a playbook that uses our new module and place it in a library directory
in the same place so that we can see it in action. Here is a playbook that uses the
hostname module:
---
- name: Test the hostname file
hosts: testmachine
tasks:
- name: Set the hostname
hostname: hostname=testmachine.example.com
使用自己定义模块
如今我们写完了第一个自己定义模块,让我们把它放到playbook中跑一跑。Ansible会从好几个地方搜寻模块:它首先查看/etc/ansible/ansible.cfg定义的位置,接着查找-module-path參数指定的位置。然后查找playbook文件所在文件夹。最后查找所属角色所在的文件夹。
让我们使用新建的模块创建一个playbook,并把他放到library文件夹以下,代码例如以下:
---
- name: Test the hostname file
hosts: testmachine
tasks:
- name: Set the hostname
hostname: hostname=testmachine.example.com
Then create a directory named library in the same directory as the playbook file.
Place the hostname module inside the library. Your directory layout should look
like this:
<img src="http://img.blog.csdn.net/20140715213354437? watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc21hbGxmaXNoMTk4Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
在playbook文件所在的文件夹以下建立一个library的文件夹。然后把hostname模块放进去。你的文件夹结构看起来就像这样:
当我们执行playbook的时候。它会从libray文件夹中找到hostname模块,输出例如以下:
PLAY [Test the hostname file] ***************************************
GATHERING FACTS *****************************************************
ok: [ansibletest]
TASK: [Set the hostname] ********************************************
changed: [ansibletest]
PLAY RECAP **********************************************************
ansibletest
: ok=2
changed=1
unreachable=0
failed=0
再次执行playbook,结果会从changed变成OK。
恭喜恭喜。你如今已经创建并执行了一个你自己的模块。它很easy,可是你你能够继续扩展它来获取hostname文件,或者用其它方法在系统启动的时候改动hostname。
Writing modules in Python
All of the modules that are distributed with Ansible are written in Python. Because
Ansible is also written in Python, these modules can directly integrate with Ansible.
This increases the speed at which they can run. Here are a few other reasons why
you might write modules in Python:
• Modules written in Python can use boilerplate, which reduces the amount of
code required
• Python modules can provide documentation to be used by Ansible
• Arguments to your module are handled automatically
• Output is automatically converted to JSON for you
• Ansible upstream only accepts plugins using Python with the boilerplate
code included
使用python编写模块
全部Ansible自带的模块都是用python编写的,由于Ansible也是python编写的。这些模块能够和Ansible集成在一起。
当他们执行的时候,还能够加高速度。以下是一些用python编写模块的理由:
- 使用python编写的模块能够使用引用,这能够节省大量代码
- 模块的參数能够被自己主动处理
- 输出格式自己主动被转换成JSON
- Ansible的上游插件之接受使用python的引用包括
You can still build Python modules without this integration by parsing the
arguments and outputting JSON yourself. However, with all the things you get for
free, it would be hard to make a case for it.
Let's build a Python module that lets us change the currently running init level of the
system. There is a Python module called pyutmp that will let us parse the utmp file.
Unfortunately, since Ansible modules have to be contained in a single file, we can't
use it unless we know it will be installed on the remote systems, so we will resort
to using the runlevel command and parsing its output. Setting the runlevel can be
done with the init command.
The first step is to figure out what arguments and features the module supports. For
the sake of simplicity, let's have our module only accept one argument. We'll use the
argument runlevel to get the runlevel the user wants to change to. To do this, we
instantiate the AnsibleModule class with our data.
module = AnsibleModule(
argument_spec = dict(
runlevel=dict(default=None, type='str')
)
)
你也能够不使用集成,由自己来解析參数并输出JSON。然而,既然全部这些都是免费的。你又何苦呢?
如今我们来用python写一个模块来改变系统当前的init级别。有一个叫pyutmp的模块能够让我们解析utmp文件,只是,自从Ansible的模块必须被包括在一个文件内。除非我们确定远程受管主机上也安装了它。否则我们没办法使用这个模块。所以我们仅仅好使用runlevel命令然后再解析它的输出。设置runlevel能够使用init命令。
第一步,指出哪些參数和特性是这个模块支持的。简单起见。我们仅仅同意我们的模块接受一个參数,我们使用runlevel參数来让用户指定他要改变的执行级别。为此,我们用我们的数据来实例化我们的AnsibleModule类。
module = AnsibleModule(
argument_spec = dict(
runlevel=dict(default=None, type='str')
)
)
Now we need to implement the actual guts of the module. The module object that
we created previously provides us with a few shortcuts. There are three that we will
be using in the next step. As there are way too many methods to document here, you
can see the whole AnsibleModule class and all the available helper functions in lib/
ansible/module_common.py .
• run_command : This method is used to launch external commands and retrieve
the return code, the output from stdout , and also the output from stderr .
• exit_json : This method is used to return data to Ansible when the module
has completed successfully.
• fail_json : This method is used to signal a failure to Ansible, with an error
message and return code.
第二步。接下来我们要来实现模块的实际功能,之前创建的类为我们提供了一些捷径。接下来我们就要使用这3个捷径。
由于这里有太多的方法能够使用,所以我们就不一一介绍了,要想了解全部AnsibleMidule类的函数帮助,请參考lib/ansible/module_common.py 。
- run_command:这种方法用来运行一个外部命令。然后返回代码,它能够输出到stdout和stderr
- exit_json:当模块成功运行的时候,用这种方法返回数据
- fail_json:当模块运行失败的时候,用这种方法返回一个失败的信号给Ansible
The following code actually manages the init level of the system. Comments have
been included in the following code to explain what it does.
def main():
module = AnsibleModule(
argument_spec = dict(
<img src="http://img.blog.csdn.net/20140715221253046?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc21hbGxmaXNoMTk4Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="" />
以下这段代码现实了模块怎样管理init级别。凝视已经包括在代码中了:
上面这段python代码非常easy。我就不解释了,有疑问的同学能够留言。
There is one final thing to add to the boilerplate to let Ansible know that it needs
to dynamically add the integration code into our module. This is the magic that
lets us use the AnsibleModule class and enables our tight integration with Ansible.
The boilerplate code needs to be placed right at the bottom of the file, with no code
afterwards. The code to do this looks as follows:
# include magic from lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()
So, finally, we have the code for our module built. Putting it all together, it should
look like the following code:
最后一件事是加入样板让Ansible知道它须要动态的集成代码到我们的模块。这就是我们能用AnsibleModule类和Ansible紧紧结合在一起的奇妙原因。样板代码须要被正确的放在文件底部,它后面应该不存在代码了。
代码例如以下:
# include magic from lib/ansible/module_common.py
#<<INCLUDE_ANSIBLE_MODULE_COMMON>>
main()
把全部的代码加在一起。应该是这种:
watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc21hbGxmaXNoMTk4Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast" alt="">
You can test this module the same way you tested the Bash module with the test-
module script. However, you need to be careful because if you run it with sudo , you
might reboot your machine or alter the init level to something you don't want. This
module is probably better tested by using Ansible itself on a remote test machine.
We follow the same process as described in the Using a module section earlier in this
chapter. We create a playbook that uses the module, and then place the module in a
library directory that has been made in the same directory as the playbook. Here is
the playbook we should use:
---
- name: Test the new init module
hosts: testmachine
user: root
tasks:
- name: Set the init level to 5
init: runlevel=5
你能够像測试bash写的模块一样来測试python编写的模块,只是当你使用sudo的时候要小心,由于你有可能发生重新启动你的机器,改变你的init级别。或者其它你意料之外的事情。最好的測试办法是在远程受管主机上执行。使用模块的方法和之前提到的使用bash编写的模块一样,playbook的代码例如以下:
---
- name: Test the new init module
hosts: testmachine
user: root
tasks:
- name: Set the init level to 5
init: runlevel=5
Now you should be able to try and run this on a remote machine. The first time
you run it, if the machine is not already in runlevel 5, you should see it change the
runlevel. Then you should be able to run it for a second time to see that nothing has
changed. You might also want to check to make sure the module fails correctly when
not run as root.
如今你能够在远程受管主机上測试你的模块了。第一次执行的时候,假设主机没有执行在5级别,你会看到执行级别被改变了,再次执行则不会改变不论什么东西。你还能够使用root来測试模块时候被正确执行。
Ansible@一个高效的配置管理工具--Ansible configure management--翻译(十一)的更多相关文章
- Ansible@一个高效的配置管理工具--Ansible configure management--翻译(一)
未经书面许可,请勿转载 --- Ansible is the simplest way to automate apps and IT infrastructure 这是Ansible官方站 ...
- Ansible@一个高效的配置管理工具--Ansible configure management--翻译(三)
未经书面许可.请勿转载 一张图简单概括 Simple Playbooks Ansible is useful as a command-line tool for making small chang ...
- Ansible@一个高效的配置管理工具--Ansible configure management--翻译(五)
无书面许可请勿转载 高级Playbook Extra variables You may have seen in our template example in the previous chapt ...
- Ansible@一个高效的配置管理工具--Ansible configure management--翻译(八)
如无书面授权,请勿转载 第四章,大型项目中Ansible的使用 Roles If your playbooks start expanding beyond what includes can hel ...
- Ansible@一个高效的配置管理工具--Ansible configure management--翻译(七)
如无书面授权,请勿转载 Larger Projects Until now, we have been looking at single plays in one playbook file. Th ...
- Ansible@一个有效的配置管理工具--Ansible configure management--翻译(四)
不要未经书面许可转载 第三章是长,因为,我会分几个部分来翻译. Advanced Playbooks So far the playbooks that we have looked at are s ...
- Ansible@一个有效的配置管理工具--Ansible configure management--翻译(十二)
如果没有书面授权,请勿转载 第五章 自己定义模块 External inventories In the first chapter we saw how Ansible needs an inven ...
- Ansible@一个有效的配置管理工具--Ansible configure management--翻译(十)
未经书面许可,.请勿转载 Custom Modules Until now we have been working solely with the tools provided to us by A ...
- Ansible 运维自动化 ( 配置管理工具 )
背景 出差背景,要搞项目的自动化部署.因为只直接对接生产分发,机器又非常多,这样以往使用的bat只能作为应急方案了,还是得考虑使用专业化的工具来做这个事情! 当下有许多的运维自动化工具( 配置管理 ) ...
随机推荐
- python 保留两位小数方法
原博客连接:https://blog.csdn.net/Jerry_1126/article/details/85009810 保留两位小数,并做四舍五入处理 方法一:使用字符串格式化 a = 12. ...
- java通过反射获取私有的构造方法,及反射擦除泛型数据类型约束
/* * 反射获取私有的构造方法运行 * 不推荐,破坏了程序的安全性,封装性 * 暴力私有 */ public class ReflectDemo4 { public static void main ...
- hdu 3639 有向图缩点+建反向图+搜索
题意:给个有向图,每个人可以投票(可以投很多人,一次一票),但是一个人只能支持一人一次,支持可以传递,自己支持自己不算,被投支持最多的人. 开始想到缩点,然后搜索,问题是有一点想错了!以为支持按票数计 ...
- nodejs Centos环境搭建
使用二进制文件安装: node 环境下载 https://nodejs.org/en/download/ 下载里面的windows 安装包 和 linux 安装包 1)windows安装 window ...
- 一个关于集合的问题,为什么添加进List集合中的元素被莫名其妙的改变了
以前自己理解的不够深刻,特此记录一下提醒自己,如果正好也帮到了你,我会很开心.相信只有自己正好遇到这个问题,才觉得哦,原来这样.自己小白,大神莫喷 为什么添加进List集合中的元素被莫名其妙的改变了? ...
- ConstraintLayout 约束布局
约束布局ConstraintLayout 这种布局方式出现已经有一段时间了,刚出现的时候一直以为这种布局只是针对拖拽使用的布局,最近在新项目里看到了这种布局,又重新学习了这种布局,才发现以前真的是图样 ...
- Cryptography I 学习笔记 --- 零碎
1. KDF(密钥推导函数,key derivation function),根据用户输入的一个初始密钥来生成一系列的后续密钥.可以使用PRF来生成 2. 可以用salt与slow hash func ...
- Linux和Cisco命令行通用快捷键。
Ctrl a e 行首,行尾(ahead,end)Esc f b 单词首,单词尾Ctrl f b 移动光标(forward,backwards) Ctrl u k 剪切光标前所有,剪切光标后所有Ctr ...
- [CF665F]Four Divisors
题目大意: 给定$n(n\leq10^{11})$,求$\displaystyle\sum_{i=1}^n[\tau(i)=4]$. 思路: 设$p,q$为不相等的质数,则满足$\tau(i)=4$的 ...
- 笔记-迎难而上之Java基础进阶-终
使用Stream流的方式,遍历集合 import java.util.*; public class StreamDemo{ public static void main(String[] args ...