python创建zabbix主机导入xml信息

使用python xml.etree.ElementTree 模块创建可导入zabbix的主机列表文档,加快监控添加效率。

问题来源

工作中需要批量添加大量主机到zabbix监控。虽然zabbix自动发现功能自动添加,但是添加的无描述信息,监控组无法通过告警信息快速联系责任人,所以监控主机需要手工添加。zabbix系统中添加监控信息的途径有:1)自动发现添加 2)web界面手动一台一台添加 3)编辑xml文件,批量导入 4)使用api导入。本文完成第三种模式的添加。

IOP(input、process、output)分析

创建xml文件有两种方法:一是引用一个xml模板,解析其中的结构,然后复用解析的元素;二是从零生成一个满足导入需求的xml文件。第一种操作快,但涉及的流程复杂,第二种为笨办法,但流程清晰,故采用从零创建。

  • input
    input为一个ip列表,可以是一个范围
  • process
    分析了zabbix导出的xml结构,发现主机信息在xml文件中部子节点中。故先创建主xml结构,然后通过循环创建子节点。子节点创建定义一个函数方便调用。
  • output
    输出为一个xml文件

代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
#-*- coding: UTF-8 -*-
import xml.etree.ElementTree as xml
import os
def createXML(filename):
root = xml.Element("zabbix_export")
z_version=xml.SubElement(root,"version")
z_version.text="3.0"
z_date = xml.SubElement(root,"date")
z_date.text="2017-08-11T08:50:11Z"
z_groups = xml.SubElement(root,"groups")
g_group = xml.SubElement(z_groups,"group")
g_name = xml.SubElement(g_group,"name")
g_name.text = "Linux servers"
z_hosts = xml.SubElement(root,"hosts")
#hosts_host = xml.SubElement(z_hosts,"host")

for ip in range(1,3):
host=createHost(str(ip))
z_hosts.append(host)
tree = xml.ElementTree(root)
with open(filename,"w") as fh:
tree.write(fh)

def createHost(ip):
ip_addr = "192.168.200." + ip
host_top=xml.Element("host")
host_ip=xml.SubElement(host_top,"host")
host_ip.text=ip_addr
host_name = xml.SubElement(host_top,"name")
host_name.text=u"abcd中文"+"("+ip_addr+u")中文-name"
h_description=xml.SubElement(host_top,"description")
h_proxy = xml.SubElement(host_top,"proxy")
h_status = xml.SubElement(host_top,"status")
h_status.text="0"
h_ipmi_authtype=xml.SubElement(host_top,"ipmi_authtype")
h_ipmi_authtype.text="-1"
h_ipmi_privileg=xml.SubElement(host_top,"ipmi_privilege")
h_ipmi_privileg.text="2"
h_ipmi_username=xml.SubElement(host_top,"ipmi_username")
h_ipmi_password=xml.SubElement(host_top,"ipmi_password")
h_tls_connect=xml.SubElement(host_top,"tls_connect")
h_tls_connect.text="1"
h_tls_accept=xml.SubElement(host_top,"tls_accept")
h_tls_accept.text="1"
h_tls_issuer=xml.SubElement(host_top,"tls_issuer")
h_tls_subject=xml.SubElement(host_top,"tls_subject")
h_tls_psk_identity=xml.SubElement(host_top,"tls_psk_identity")
h_tls_psk=xml.SubElement(host_top,"tls_psk")
h_templates=xml.SubElement(host_top,"templates")
t_template=xml.SubElement(h_templates,"template")
t_name=xml.SubElement(t_template,"name")
t_name.text="Linux-Templates"
h_groups = xml.SubElement(host_top,"groups")
g_group = xml.SubElement(h_groups,"group")
g_name=xml.SubElement(g_group,"name")
g_name.text="Linux servers"
h_interfaces=xml.SubElement(host_top,"interfaces")
i_interface=xml.SubElement(h_interfaces,"interface")
i_default=xml.SubElement(i_interface,"default")
i_default.text="1"
i_type=xml.SubElement(i_interface,"type")
i_type.text="1"
i_useip=xml.SubElement(i_interface,"useip")
i_useip.text="1"
i_ip=xml.SubElement(i_interface,"ip")
i_ip.text=ip_addr
i_dns=xml.SubElement(i_interface,"dns")
i_port=xml.SubElement(i_interface,"port")
i_port.text="10050"
i_bulk=xml.SubElement(i_interface,"bulk")
i_bulk.text="1"
i_interface_ref=xml.SubElement(i_interface,"interface_ref")
i_interface_ref.text="if1"
h_applications=xml.SubElement(host_top,"applications")
h_items=xml.SubElement(host_top,"items")
h_discovery_rules=xml.SubElement(host_top,"discovery_rules")
h_macros=xml.SubElement(host_top,"macros")
h_inventory=xml.SubElement(host_top,"inventory")
return host_top


if __name__ == "__main__":
createXML("appt.xml")

遇到的问题

  1. 导入的xml模块需要使用python2.7环境,python3.5环境报错
  2. “Invalid tag “/zabbix_export/version”: ”发现version版本写的“3”,而模板是“3.0”,改为3.0后问题解决
  3. 中文编码问题,生成xml文件中有中文字符会报错。程序运行为ubuntu,python文件编码为utf-8,python内部编码为unicode。应该把中文字符转换为unicode后能解决。解决办法:python文件采用utf-8,在文件头添加“#-- coding: UTF-8 --”解决“None-ASSIC”问题,中文字符采用”u’中文’”模式,解决“UnicodeDecodeError”
  4. port标签忘赋值,添加后导入不报错。

后续改进

ansible上有添加zabbix监控主机的模块,应该使用api实现的。后期要么使用ansible的zabbix模板,要么自己封装api。

参考链接

http://www.blog.pythonlibrary.org/2013/04/30/python-101-intro-to-xml-parsing-with-elementtree/