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

#!/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": "",
"ansible_ssh_user": "work",
"ansible_python_interpreter": "/usr/bin/python"
},
{
"name": "Srv02",
"ansible_ssh_host": "172.16.100.30",
"ansible_ssh_port": "",
"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", "")
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": "", "username": "root", "password": ""}] temphosts_dict = {
"Group1": {
"hosts": [{"ip": "192.168.200.10", "port": "", "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()

Python调用ansible API系列(四)动态生成hosts文件的更多相关文章

  1. Python调用ansible API系列(五)综合使用

    如何把动态生成资产信息.执行playbook以及自定义结果结合起来用呢? #!/usr/bin/env python # -*- coding: utf-8 -*- """ ...

  2. Python调用ansible API系列(一)获取资产信息

    你想让ansible工作首先就需要设置资产信息,那么我们如何通过使用Python调取Ansible的API来获取资产信息呢? 要提前准备一个hosts文件 获取组或者主机 #!/usr/bin/env ...

  3. Python调用ansible API系列(三)带有callback的执行adhoc和playbook

    在第二篇文章中虽然可以执行adhoc和playbook但是执行结果的输出并不是特别直观,虽然没有报错但是到底什么结果其实你是不知道的尤其是在执行adhoc的时候,这时候我们要利用callback来设置 ...

  4. Python调用ansible API系列(二)执行adhoc和playbook

    执行adhoc #!/usr/bin/env python # -*- coding: utf-8 -*- import sys from collections import namedtuple ...

  5. python调用ansible api 2.0 运行playbook带callback返回

    # -*- coding:utf8 -*- ''' Created on 2017年1月13日 @author: qiancheng ''' import os import json from co ...

  6. 关于python调用zabbix api接口

    因公司业务需要,引进了自动化运维,所用到的监控平台为zbbix3.2,最近正在学习python,计划使用python调用zabbix api接口去做些事情,如生成报表,我想最基本的是要取得zabbix ...

  7. 使用Python调用Flickr API抓取图片数据

    Flickr是雅虎旗下的图片分享网站,上面有全世界网友分享的大量精彩图片,被认为是专业的图片网站.其API也很友好,可以实现多种功能.这里我使用了Python调用其API获得了大量的照片数据.需要注意 ...

  8. 基于python调用libvirt API

    基于python调用libvirt API 1.程序代码 #!/usr/bin/python import libvirt import sys def createConnection(): con ...

  9. Ansible Tower系列 四(使用tower执行一个命令)【转】

    在主机清单页面中,选择一个主机清单,进入后,选择hosts里的主机 Paste_Image.png 点击 RUN COMMANDS MODULE 选择 commandARGUMENTS 填写 ifco ...

随机推荐

  1. tomcat7性能调优与配置(以windows版为例)

    一.配置tomcat服务状态查看帐号(E:\Tomcats\apache-tomcat-7.0.73Test\conf下面的tomcat-users.xml中)加入:<user username ...

  2. Hadoop生态圈初识

    一.简介 Hadoop是一个由Apache基金会所开发的分布式系统基础架构.Hadoop的框架最核心的设计就是:HDFS和MapReduce.HDFS为海量的数据提供了存储,则MapReduce为海量 ...

  3. 局部内部类访问它所在方法的局部变量时,要求该局部变量必须声明为final的原因

    这是java的一条规则.那么为什么会有这条规则呢?要想弄懂这个问题,就需要弄懂局部内部类对象和局部变量的生命周期的谁更长的问题. 首先,看一段代码,以没有将变量声明为final的代码作为例子,代码如下 ...

  4. 16.git命令汇总

  5. 云计算一:VMware workstation的安装和使用教程

    VMware workstation的安装和使用教程 一.VMware 安装 1.从网上找到VMware的安装包以及要安装的映像文件,下载到本地,然后备份一份存储到百度云盘. 链接:http://pa ...

  6. Global一点小经验

    Global: Global.asax 文件,有时候叫做 ASP.NET 应用程序文件,提供了一种在一个中心位置响应应用程序级或模块级事件的方法,他位于应用程序根目录下. 这个 Global.asax ...

  7. Centos7 升级 gcc

    特别蛋疼的开始 最痛苦的就是一步一个坑 为了安装 vue.js,听说要安装 node.js,听说为了安装 node.js碰上了gcc版本不够的问题,此时我特别特别特别的想念盖茨大大 下载 gcc gc ...

  8. 《Hadoop金融大数据分析》读书笔记

    <Hadoop金融大数据分析> Hadoop for Finance Essentials 使用Hadoop,是因为数据量大数据量如此之多,以至于无法用传统的数据处理工具和应用来处理的数据 ...

  9. Jenkins 的安装部署

    一.Windows环境中安装Jenkins 原文:http://www.cnblogs.com/yangxia-test/p/4354328.html 在最简单的情况下,Jenkins 只需要两个步骤 ...

  10. Extjs--12种布局方式

    按照Extjs的4.1的文档来看,extjs的布局方式大致有12种,下面一一介绍,有些代码就是文档中的. 1.Border 边界布局 border布局,最多可以将页面分割为"东南西北中&qu ...