ansible module

  模块是一个独立的, 能够复用的脚本, 它能够被anisible API, Ansible 或者ansible-playbook使用.   在模块退出以前, 它经过输出一个json字符串到标准输出从而反馈信息给ansible.  你能够用任何一种语言去写一个模块. 写好的模块能够放在ANSIBLE_LIBRARY或者--module-path目录下. 一般状况下playbook的目录下的library目录也能够作为模块的默认目录.python

1. 模块的基本开发模式

  一个简单的模块, 之因此用这个做为例子, 是由于你能够用任何语言去开发本身的模块, 咱们须要了解模块最基本的开发模式git

#!/usr/bin/python

import datetime
import json

date = str(datetime.datetime.now())
print json.dumps({
    "time" : date
})

  模块测试github

git clone git://github.com/ansible/ansible.git --recursive
source ansible/hacking/env-setup

ansible/hacking/test-module -m ./timetest.py

  模块参数json

   ansible会自动的把参数保存到一个参数文件中, 因此咱们必须读取并分析这个文件. 这个参数文件只是一个字符串, 因此任何形式的参数都是合法的.  服务器

#!/usr/bin/python

# import some python modules that we'll use.  These are all
# available in Python's core

import datetime
import sys
import json
import os
import shlex

# read the argument string from the arguments file
args_file = sys.argv[1]
args_data = file(args_file).read()

arguments = shlex.split(args_data)
for arg in arguments:

    # ignore any arguments without an equals in it
    if "=" in arg:

        (key, value) = arg.split("=")
        if key == "time":


            rc = os.system("date -s \"%s\"" % value)

            if rc != 0:
                print json.dumps({
                    "failed" : True,
                    "msg"    : "failed setting the time"
                })
                sys.exit(1)

            date = str(datetime.datetime.now())
            print json.dumps({
                "time" : date,
                "changed" : True
            })
            sys.exit(0)


date = str(datetime.datetime.now())
print json.dumps({
    "time" : date
})
测试模块
ansible
/hacking/test-module -m ./timetest.py -a "time=\"March 14 12:23\""

 

  二进制模块app

  二进制模块的支持会在ansible2.2中加入,  当ansible发现是二进制模块是, 它会提供一个json文件argv[1]来保存参数.函数

  提供facts的模块学习

  setup模块能够提供不少系统相关的变量, 然而用户不修改系统模块也能够添加自定义变量, 只须要在模块的返回值中加入ansible_facts这个键值. 例如:测试

{
    "changed" : True,
    "rc" : 5,
    "ansible_facts" : {
        "leptons" : 5000,
        "colors" : {
            "red"   : "FF0000",
            "white" : "FFFFFF"
        }
    }
}

开发一个site_facts的模块而且在全部的playbook以前调用是一个较好的习惯,

 

2. 通用的模块样板

  若是你使用python来开发自定义模块, ansible提供了不少强大的快捷方式. 模块仍然保存在一个文件当中, 可是咱们不须要再去处理参数文件. 最好的学习方法是去学习ansible的核心模块.ui

from ansible.module_utils.basic import AnsibleModule
if __name__ == '__main__':
    main()

Note: 对于ansible2.1来讲, 上面的导入已经不能工做, 必须使用from ansible.module_utils.basic import *

 

def main():
    module = AnsibleModule(
        argument_spec = dict(
            state     = dict(default='present', choices=['present', 'absent']),
            name      = dict(required=True),
            enabled   = dict(required=True, type='bool'),
            something = dict(aliases=['whatever'])
        )
    )
AnsibleModule 提供和不少通用的函数来处理返回值, 分析参数并容许你检查输入
成功返回
module.exit_json(changed=True, something_else=12345)
失败退出
module.fail_json(msg="Something fatal happened")

还有不少其余的基础功能, 课参看lib/ansible/module_utils/basic.py

 

  check模式

  模块支持check模式. 若是用户在check模式下运行ansible, 模块会去尝试预判change是否发生. 若是想定义一个check模块, 用户必须在初始化模块的时候设置supports_check_mode=True

module = AnsibleModule(
    argument_spec = dict(...),
    supports_check_mode=True
)

if module.check_mode:
    # Check if any changes would be made but don't actually make those changes
    module.exit_json(changed=check_if_system_state_would_be_changed())
做为模块的开发者, 你有责任去保证在check模式下没有系统状态被改变?
Remember that, as module developer, you are responsible for ensuring that no system state is altered when the user enables check mode.

若是你的模块不支持check模式, 而用户却在check模式下运行ansible, 你的模块会被自动跳过

 

  在模块中永远不要使用"print "some status message"".  由于在ansible中输出被假定为一个可用的json.

  Modules must not output anything on standard error, because the system will merge standard out with standard error and prevent the JSON from parsing. Capturing standard error and returning it as a variable in the JSON on standard out is fine, and is, in fact, how the command module is implemented.

ANSIBLE_KEEP_REMOTE_FILES 这个参数会保留在远程服务器上执行的python脚本. 能够用来debug.

相关文章
相关标签/搜索