背景
一个组件发布会对应多台主机,如下:
‘component name’: {
'hosts': [{'ip': '0,0,0,0', port : 22 ,'username':'root', 'password': '11111111'},...]
group_vars: {}
}
hosts 对应的就是多台主机属于同一个组件
group_vars 就是发布部署所需要的一些配置信息,可以理解成业务变量信息
自定义二次开发 InventoryManager
from ansible.inventory.manager import InventoryManager
class WadeInventory(InventoryManager):
"""
用于动态生成Inventory的类.
"""
def __init__(self, loader, resource=None, sources=None):
"""
resource的数据格式是一个列表字典,比如
{
"group1": {
"hosts": [{"ip": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...],
"group_vars": {"var1": value1, "var2": value2, ...}
}
}
如果你只传入1个列表,这默认该列表内的所有主机属于default 组,比如
[{"ip": "10.0.0.0", "port": "22", "username": "test", "password": "pass"}, ...]
sources是原生的方法,参数是配置的inventory文件路径,可以指定一个,也可以以列表的形式可以指定多个
"""
super(MyInventory, self).__init__(loader=loader, sources=sources)
self.resource = resource
self.dynamic_inventory()
def add_dynamic_group(self, hosts, group_name, group_vars=None):
"""
将从数据库读取的组信息,主机信息等生成的resource信息解析成ansible可以读取的内容
:param hosts: 包含主机所有信息的的列表
:type hosts: list
:param group_name:
:param group_vars:
:type group_vars: dict
:return:
"""
# 添加主机组
self.add_group(group_name)
# 添加主机组变量
if group_vars:
for key, value in group_vars.items():
self.groups[group_name].set_variable(key, value)
for host in hosts:
ip = host.get('ip')
port = host.get('port')
# 添加主机到主机组
self.add_host(ip, group_name, port)
username = host.get('username')
password = host.get('password')
# 生成ansible主机变量
self.get_host(ip).set_variable('ansible_ssh_host', ip)
self.get_host(ip).set_variable('ansible_ssh_port', port)
self.get_host(ip).set_variable('ansible_ssh_user', username)
self.get_host(ip).set_variable('ansible_ssh_pass', password)
self.get_host(ip).set_variable('ansible_sudo_pass', password)
# 如果使用同一个密钥管理所有机器,只需把下方的注释去掉,ssh_key指定密钥文件,若是不同主机使用不同密钥管理,则需要单独设置主机变量或组变量
# self.get_host(ip).set_variable('ansible_ssh_private_key_file', ssh_key)
# set other variables
for key, value in host.items():
if key not in ["ip", "port", "username", "password"]:
self.get_host(ip).set_variable(key, value)
def dynamic_inventory(self):
if isinstance(self.resource, list):
self.add_dynamic_group(self.resource, 'default')
elif isinstance(self.resource, dict):
for groupname, hosts_and_vars in self.resource.items():
self.add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("group_vars"))