Python調用ansible API系列(四)動態生成hosts文件

方法一:經過最原始的操做文件的方式

#!/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()
View Code

方法二:經過數據庫或者調用其餘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()
View Code

相關文章
相關標籤/搜索