设为首页 收藏本站
查看: 1625|回复: 0

[经验分享] Ansible@一个高效的配置管理工具--Ansible configure management--翻译(十一)

[复制链接]

尚未签到

发表于 2015-11-26 09:54:52 | 显示全部楼层 |阅读模式
无书面授权,请勿转载

第五章 自定义模块
  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=&quot;http://img.blog.csdn.net/20140715213354437?1/1.jpg"2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc21hbGxmaXNoMTk4Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast&quot; alt=&quot;&quot; />
在playbook文件所在的目录下面建立一个library的文件夹,然后把hostname模块放进去,你的目录结构看起来就像这样:
DSC0000.jpg
  当我们运行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。恭喜恭喜!你现在已经创建并执行了一个你自己的模块。它非常简单,但是你你可以继续扩展它来获取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编写的模块可以使用引用,这可以节省大量代码
  • 模块的参数可以被自动处理
  • 输出&#26684;式自动被转换成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=&quot;http://img.blog.csdn.net/20140715221253046?1/1.jpg"2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc21hbGxmaXNoMTk4Mw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast&quot; alt=&quot;&quot; />


下面这段代码现实了模块如何管理init级别,注释已经包含在代码中了:
DSC0001.jpg


  上面这段python代码很简单,我就不解释了,有疑问的同学可以留言。
  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()
  把所有的代码加在一起,应该是这样的:
DSC0002.jpg
DSC0003.jpg
  


  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来测试模块时候被正确执行。


  

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-143753-1-1.html 上篇帖子: Ansible@一个高效的配置管理工具--Ansible configure management--翻译(九) 下篇帖子: Ansible@一个高效的配置管理工具--Ansible configure management--翻译(十二)
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表