随着cmdb上记录的增多,每次都需要修改ansible的hosts文件, 实属麻烦。此次通过动态获取inventory的方法,这样可以省去配置ansible服务端的hosts。

#!/usr/bin/env python
# coding:utf-8

import json
import sys
import requests
from collections import defaultdict

'''
Region = {
    1: 'pro_sh',
    2: 'pro_ali',
    3: 'dev_ofc',
    4: 'test_ofc',
    5: ...
}
'''

null = ''
VIRTUAL_MACHINE_API = "http://IP:PORT/virtual/getAllVirtualMachine"
machine_list = eval(requests.get(VIRTUAL_MACHINE_API).content)
group_dict, host_dict = defaultdict(list), {}

CONFIG = 
    3: {
        'ansible_ssh_user': 'root',
        'ansible_ssh_port': 22,
        'ansible_ssh_private_key_file': '/root/.ssh/id_rsa'
    },
    4: {
        'ansible_ssh_user': 'root',
        'ansible_ssh_port': 12622,
        'ansible_ssh_private_key_file': '/root/.ssh/test_rsa'
    },
    ...
}

def group():
    for machine in machine_list:
        if machine.get("group"):
            group_dict[machine.get("group")].append(machine.get('ip'))
    print json.dumps(group_dict, indent=4)

def host(ip):
    for machine in machine_list:
        if machine.get('group'):
            host_dict[machine.get('ip')] = dict(CONFIG.get(machine.get('regionId'), CONFIG.get(3)),
                                                **{'ansible_ssh_host': machine.get('ip')})

    print json.dumps(host_dict.get(ip), indent=4)

if len(sys.argv) == 2 and (sys.argv[1] == '--list'):
    group()
elif len(sys.argv) == 3 and (sys.argv[1] == '--host'):
    host(sys.argv[2])
else:
    print "Usage: %s --list or --host " % sys.argv[0]
    sys.exit(1)

动态inventory脚本必须支如下两个命令行参数:

--host  (用来列出主机的详细信息)
--list    (用来列出群组)

执行结果

# ./ansible_host.py --list 

{
    "dev_php": [
        "10.101.11.14", 
        "10.101.11.15", 
        "10.101.11.16", 
        "10.101.11.17"
    ], 
    "dev_java": [
         "10.101.9.101",
         "10.101.9.102",
         ...
    ],
    ...
}

# ./ansible_host.py --host 10.101.11.14

{
    "ansible_ssh_host": "10.101.11.14", 
    "ansible_ssh_port": 22, 
    "ansible_ssh_private_key_file": "/root/.ssh/id_rsa", 
    "ansible_ssh_user": "root"
}

通过ansible命令调用

ansible -i ansible_hosts.py dev_php -m shell -a "ip a"

通过playbook来调用,脱离了对于hosts文件的依赖

#  ansible-playbook -i ansible_hosts.py test.yml -e "host=dev_php"

PLAY [dev_php] ***************************************************************************************************************************************************************************************

TASK [Gathering Facts] *******************************************************************************************************************************************************************************
ok: [10.101.11.14]
ok: [10.101.11.17]
ok: [10.101.11.16]
ok: [10.101.11.15]

TASK [echo] ******************************************************************************************************************************************************************************************
changed: [10.101.11.14]
changed: [10.101.11.15]
changed: [10.101.11.16]
changed: [10.101.11.17]

PLAY RECAP *******************************************************************************************************************************************************************************************
10.101.11.14               : ok=2    changed=1    unreachable=0    failed=0   
10.101.11.15               : ok=2    changed=1    unreachable=0    failed=0   
10.101.11.16               : ok=2    changed=1    unreachable=0    failed=0   
10.101.11.17               : ok=2    changed=1    unreachable=0    failed=0