方法一:通過最原始的操作文件的方式

#!/usr/bin/env python # -*- coding: utf-8 -*- """ 通過操作文件形式動態生成ansible的hosts文件 """ import sys class Inventory: def __init__(self): # ansible的hosts文件路徑 self._hostsfile = "./aaa" self._data = self._getInventoryInfo() if self._genHostsFile(): print("生成完成。") else: print("生成失敗。") def _getInventoryInfo(self): """ 從數據庫中獲取資產信息 :return: """ tempdata = [ { "Groupname": "Group1", "Items": [ { "name": "Srv01", "ansible_ssh_host": "172.16.100.20", "ansible_ssh_port": "22", "ansible_ssh_user": "work", "ansible_python_interpreter": "/usr/bin/python" }, { "name": "Srv02", "ansible_ssh_host": "172.16.100.30", "ansible_ssh_port": "22", "ansible_ssh_user": "work", "ansible_python_interpreter": "/usr/bin/python" }, ] }, ] return tempdata def _genHostsFile(self): """ 生成資產hosts文件 :return: 生成成功返回True """ try: with open(self._hostsfile, "w") as file1: for i in self._data: groupname = i.get("Groupname") file1.write("["+groupname+"]\n") for server in i.get("Items"): name = server.get("name") ansible_ssh_host = server.get("ansible_ssh_host") ansible_ssh_port = server.get("ansible_ssh_port") ansible_ssh_user = server.get("ansible_ssh_user") ansible_python_interpreter = server.get("ansible_python_interpreter") info = "ansible_ssh_host={0} ansible_ssh_port={1} ansible_ssh_user={2} ansible_python_interpreter={3}".\ format(ansible_ssh_host, ansible_ssh_port, ansible_ssh_user, ansible_python_interpreter) line = name + " " + info + "\n" file1.write(line) except Exception as err: print(err) return False return True def main(): Inventory() if __name__ == "__main__": try: main() finally: sys.exit()
方法二:通過數據庫或者調用其他API獲取數據來動態獲得

#!/usr/bin/env python # -*- coding: utf-8 -*- """ 通過ansible API動態生成ansible資產信息但不產生實際的hosts文件 主機信息都可以通過數據庫獲得,然后生成指定格式,最后調用這個類來 生成主機信息。 """ import sys # 用於讀取YAML和JSON格式的文件 from ansible.parsing.dataloader import DataLoader # 用於存儲各類變量信息 from ansible.vars.manager import VariableManager # 用於導入資產文件 from ansible.inventory.manager import InventoryManager # 操作單個主機信息 from ansible.inventory.host import Host # 操作單個主機組信息 from ansible.inventory.group import Group class MyInventory: def __init__(self, hostsresource): """ 初始化函數 :param hostsresource: 主機資源可以有2種形式 列表形式: [{"ip": "172.16.48.171", "port": "22", "username": "root", "password": "123456"}] 字典形式: { "Group1": { "hosts": [{"ip": "192.168.200.10", "port": "1314", "username": "root", "password": None}], "vars": {"var1": "ansible"} }, "Group2": {} } """ self._hostsresource = hostsresource self._loader = DataLoader() self._hostsfilelist = ["temphosts"] """ sources這個我們知道這里是設置hosts文件的地方,它可以是一個列表里面包含多個文件路徑且文件真實存在,在單純的執行ad-hoc的時候這里的 文件里面必須具有有效的hosts配置,但是當通過動態生成的資產信息的時候這個文件必須存在但是它里面可以是空的,如果這里配置成None那么 它不影響資產信息動態生成但是會有一個警告,所以還是要配置一個真實文件。 """ self._inventory = InventoryManager(loader=self._loader, sources=self._hostsfilelist) self._variable_manager = VariableManager(loader=self._loader, inventory=self._inventory) self._dynamic_inventory() def _add_dynamic_group(self, hosts_list, groupname, groupvars=None): """ 動態添加主機到指定的主機組 完整的HOSTS文件格式 [test1] hostname ansible_ssh_host=192.168.1.111 ansible_ssh_user="root" ansible_ssh_pass="123456" 但通常我們都省略hostname,端口也省略因為默認是22,這個在ansible配置文件中有,除非有非22端口的才會配置 [test1] 192.168.100.10 ansible_ssh_user="root" ansible_ssh_pass="123456" ansible_python_interpreter="/PATH/python3/bin/python3" :param hosts_list: 主機列表 [{"ip": "192.168.100.10", "port": "22", "username": "root", "password": None}, {}] :param groupname: 組名稱 :param groupvars: 組變量,格式為字典 :return: """ # 添加組 self._inventory.add_group(groupname) my_group = Group(name=groupname) # 添加組變量 if groupvars: for key, value in groupvars.items(): my_group.set_variable(key, value) # 添加一個主機 for host in hosts_list: hostname = host.get("hostname", None) hostip = host.get("ip", None) if hostip is None: print("IP地址為空,跳過該元素。") continue hostport = host.get("port", "22") username = host.get("username", "root") password = host.get("password", None) ssh_key = host.get("ssh_key", None) python_interpreter = host.get("python_interpreter", None) try: # hostname可以不寫,如果為空默認就是IP地址 if hostname is None: hostname = hostip # 生成一個host對象 my_host = Host(name=hostname, port=hostport) # 添加主機變量 self._variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_host", value=hostip) self._variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_port", value=hostport) if password: self._variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_pass", value=password) self._variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_user", value=username) if ssh_key: self._variable_manager.set_host_variable(host=my_host, varname="ansible_ssh_private_key_file", value=ssh_key) if python_interpreter: self._variable_manager.set_host_variable(host=my_host, varname="ansible_python_interpreter", value=python_interpreter) # 添加其他變量 for key, value in host.items(): if key not in ["ip", "hostname", "port", "username", "password", "ssh_key", "python_interpreter"]: self._variable_manager.set_host_variable(host=my_host, varname=key, value=value) # 添加主機到組 self._inventory.add_host(host=hostname, group=groupname, port=hostport) except Exception as err: print(err) def _dynamic_inventory(self): """ 添加 hosts 到inventory :return: """ if isinstance(self._hostsresource, list): self._add_dynamic_group(self._hostsresource, "default_group") elif isinstance(self._hostsresource, dict): for groupname, hosts_and_vars in self._hostsresource.items(): self._add_dynamic_group(hosts_and_vars.get("hosts"), groupname, hosts_and_vars.get("vars")) @property def INVENTORY(self): """ 返回資產實例 :return: """ return self._inventory @property def VARIABLE_MANAGER(self): """ 返回變量管理器實例 :return: """ return self._variable_manager def main(): temphosts_list = [{"ip": "192.168.200.10", "port": "22", "username": "root", "password": "123456"}] temphosts_dict = { "Group1": { "hosts": [{"ip": "192.168.200.10", "port": "1314", "username": "root", "password": None}], "vars": {"var1": "ansible"} }, # "Group2": {} } mi = MyInventory(temphosts_dict) # print(mi.INVENTORY.get_groups_dict()) # for group, hosts in mi.INVENTORY.get_groups_dict().items(): # print(group, hosts) host = mi.INVENTORY.get_host("192.168.200.10") print(mi.VARIABLE_MANAGER.get_vars(host=host)) if __name__ == "__main__": try: main() finally: sys.exit()