写在前面
虽然Ansible用了几年了,但是动态主机清单还真的没接触过,今天演示下如何从文件中获取ip列表相关信息,脚本很简单,主要是要理顺整个约定条件
一、整个流程
- [ ] 从ini文件中读取ip到列表中
- [ ] 然后组合数据返回符合规范的数据(特定的json串格式)
- [ ] 测试是否可行
二、需要了解的约定条件
—list
当我们向脚本输入—list参数时,脚本必须将要管理的所有组以json编码的形式输出到标准输出stdout。每个组的值应该是包含每个主机/ip的列表以及定义的变量。下面给出一个简单示例
—host
当我们向脚本输入 —host参数时,脚本必须输出一个空的json字符串或一个变量的列表/字典,以便temlates和playbook可以使用。输出变量是可选的,如果脚本不希望输出,那输出一个空的列表/字典也是可以的
三、参考文档
[Ansible 开发插件之【动态主机清单】](http://www.jianshu.com/p/706c98215c02)
[代码参考地址](https://www.jeffgeerling.com/blog/creating-custom-dynamic-inventories-ansible)
[官方文档](http://docs.ansible.com/ansible/latest/intro_dynamic_inventory.html)
四、代码如下
代码语言:javascript复制#!/usr/bin/env python
# -*- coding: utf-8 -*-
# Author: zhuima
# zhuima @ 2017-08-15 15:06:39
# Function: create ansible dynamic inventory from ini fileimport json
import sys
import argparse
from ConfigParser import ConfigParsertry:
import json
except ImportError:
import simplejson as jsonclass AnsibleInventoryFILE(object):
def __init__(self):
"""
Arguments:
--list
resp:
{
"group": {
"hosts": [
"192.168.28.71",
"192.168.28.72"
],
"vars": {
"ansible_ssh_user": "zhuima",
"ansible_ssh_port": 22,
"ansible_ssh_pass": "zhuimaTestfornode",
}
},
"_meta": {
"hostvars": {
"192.168.28.72": {
"host_specific_var": "bar"
},
"192.168.28.71": {
"host_specific_var": "foo"
}
}
}
} --host
resp:
{
"ansible_ssh_host": "127.0.0.1",
"_meta": {
"hostvars": {}
},
"ansible_ssh_port": 22,
"ansible_ssh_pass": "zhuimaTestfornode",
"ansible_ssh_user": "zhuima"
}
""" # Tempfile for store iplist
self.ipfile = "/tmp/hosts.man"
self.host_list = [] # Parse arguments passed at cli
self.parse_arguments() # Init process
self.ip_from_file() #print self.args.host if self.args.list:
self.inventory = self.group_info() # Called with `--host [hostname]`.
elif self.args.host:
# Not implemented, since we return _meta info `--list`.
self.inventory = self.host_info()
# If no groups or vars are present, return an empty inventory.
else:
self.inventory = self.host_info() print json.dumps(self.inventory, indent=4) def ip_from_file(self):
"""get iplist from ini file create by shell"""
config = ConfigParser(allow_no_value=True)
config.read(self.ipfile)
secs = config.sections()
for sec in secs:
self.host_list.extend(config.options(sec)) def group_info(self):
"""resp for --list or -l"""
return {
'hlists': {
'hosts': self.host_list,
'vars': {
"ansible_ssh_port": 22,
"ansible_ssh_pass": "zhuimaTestfornode",
"ansible_ssh_user": "zhuima"
},
},
'_meta': {
'hostvars': {
},
},
} def host_info(self):
"""resp for --host or -h"""
return {'_meta': {'hostvars': {}}} def parse_arguments(self):
"""CLI interface"""
parser = argparse.ArgumentParser(description='Populate ansible inventory from Tempfiles.')
args_hostlist = parser.add_mutually_exclusive_group()
args_hostlist.add_argument('--list', help='List all nodes from Tempfile.', action="store_true")
args_hostlist.add_argument('--host', help='Not implemented.', action="store")
self.args = parser.parse_args()if __name__ == '__main__':
# Instantiate the inventory object
AnsibleInventoryFILE()
五、测试结果
代码语言:javascript复制脚本输出
[root@zhuima ansible_inventory]# python /var/www/dynamic_inventory.py --list
{ "hlists": {
"hosts": [
"192.168.100.200",
"192.168.100.180"
],
"vars": {
"ansible_ssh_port": 22,
"ansible_ssh_pass": "zhuimaTestfornode",
"ansible_ssh_user": "zhuima"
}
},
"_meta": {
"hostvars": {}
}
}
[root@zhuima ansible_inventory]#
代码语言:javascript复制Ad-Hoc测试
[root@zhuima ansible_inventory]# ansible -i /var/www/dynamic_inventory.py hlists -mping
192.168.100.180 | SUCCESS => { "changed": false, "ping": "pong"}
192.168.100.200 | SUCCESS => { "changed": false, "ping": "pong"}
[root@zhuima ansible_inventory]#
代码语言:javascript复制Playbook测试
[root@zhuima ansible_inventory]# ap -i /var/www/dynamic_inventory.py /var/www/iplist.yml
PLAY [hlists] ******************************************************************TASK [ls /tmp] *****************************************************************
changed: [192.168.100.180]
changed: [192.168.100.200]PLAY RECAP *********************************************************************
192.168.100.180 : ok=1 changed=1 unreachable=0 failed=0
192.168.100.200 : ok=1 changed=1 unreachable=0 failed=0
[root@zhuima ansible_inventory]#