一、API简介
Zabbix API是在1.8版本中开始引进并且已经被广泛应用。所有的Zabbix移动客户端都是基于API,甚至原生的WEB前端部分也是建立在它之上。Zabbix API 中间件使得架构更加模块化也避免直接对数据库进行操作。它允许你通过JSON
RPC协议来创建、更新和获取Zabbix对象并且做任何你喜欢的操作【当然前提是你拥有认证账户】。
Zabbix API提供两项主要功能:
远程管理Zabbix配置
远程检索配置和历史数据
使用JSON
API 采用JSON-RPC实现。这意味着调用任何函数,都需要发送POST请求,输入输出数据都是以JSON格式。大致工作流如下:
- 准备JSON对象,它描述了你想要做什么(创建主机,获取图像,更新监控项等)。
- 采用POST方法向 http://example.com/zabbix/api_jsonrpc.php 发送此JSON对象;
http://example.com/zabbix/ 是Zabbix前端地址 ,api_jsonrpc.php是调用API的PHP脚本。可在安装可视化前端的目录下找到。
- 获取JSON格式响应。
- 注:请求除了必须是POST方法之外,HTTP Header Content-Type必须为【application/jsonrequest,application/json-rpc,application/json】其中之一。
可以采用脚本或者任何"手动"支持JSON RPC的工具来使用API。而首先需要了解的就是如何验证和如何使用验证ID来获取想要的信息。后面的演示会以Python脚本和基于Curl的例子来呈现API的基本使用。
基本请求格式
Zabbix API 简化的JSON请求如下:
{
"jsonrpc": "2.0",
"method": "method.name",
"params": {
"param_1_name": "param_1_value",
"param_2_name": "param_2_value"
},
"id": 1,
"auth": "159121b60d19a9b4b55d49e30cf12b81",
}
一行一行来看:
- "jsonrpc": "2.0"-这是标准的JSON RPC参数以标示协议版本。所有的请求都会保持不变。
- "method": "method.name"-这个参数定义了真实执行的操作。例如:host.create、item.update等等
- "params"-这里通过传递JSON对象来作为特定方法的参数。如果你希望创建监控项,"name"和"key_"参数是需要的,每个方法需要的参数在Zabbix API文档中都有描述。
- "id": 1-这个字段用于绑定JSON请求和响应。响应会跟请求有相同的"id"。在一次性发送多个请求时很有用,这些也不需要唯一或者连续
- "auth": "159121b60d19a9b4b55d49e30cf12b81"-这是一个认证令牌【authentication token】用以鉴别用户、访问API。这也是使用API进行相关操作的前提-获取认证ID。
以上参考:zabbix小结(八)Zabbix api
二 、直接上工具脚本
下面参考:利用zabbix api 添加监控
集合脚本,包含查询主机,主机组,模板,添加开启禁用删除主机等功能
> vim zbx_tool.py
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import json
import sys
import urllib2
import argparse
from urllib2 import URLError
reload(sys)
sys.setdefaultencoding('utf-8')
class zabbix_api:
def __init__(self):
self.url = 'http://zabbix.xxx.com/api_jsonrpc.php'
self.header = {"Content-Type":"application/json"}
def user_login(self):
data = json.dumps({
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": "admin",
"password": "zabbix"
},
"id": 0
})
request = urllib2.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
print "\033[041m 认证失败,请检查URL !\033[0m",e.code
except KeyError as e:
print "\033[041m 认证失败,请检查用户名密码 !\033[0m",e
else:
response = json.loads(result.read())
result.close()
#print response['result']
self.authID = response['result']
return self.authID
def hostid_get_hostname(self, hostId=''):
data = json.dumps({
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"output": "extend",
"filter": {"hostid": hostId}
},
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server could not fulfill the request.'
print 'Error code: ', e.code
else:
response = json.loads(result.read())
#print response
result.close()
if not len(response['result']):
print "hostId is not exist"
return False
#print "主机数量: \33[31m%s\33[0m" % (len(response['result']))
host_dict=dict()
for host in response['result']:
status = {"0": "OK", "1": "Disabled"}
available = {"0": "Unknown", "1": "available", "2": "Unavailable"}
#if len(hostId) == 0:
# print "HostID : %s\t HostName : %s\t Status :\33[32m%s\33[0m \t Available :\33[31m%s\33[0m" % (
# host['hostid'], host['name'], status[host['status']], available[host['available']])
#else:
# print "HostID : %s\t HostName : %s\t Status :\33[32m%s\33[0m \t Available :\33[31m%s\33[0m" % (
# host['hostid'], host['name'], status[host['status']], available[host['available']])
host_dict['name']=host['name']
host_dict['status']=status[host['status']]
host_dict['available']=available[host['available']]
return host_dict
def hostid_get_hostip(self, hostId=''):
data = json.dumps({
"jsonrpc": "2.0",
"method": "hostinterface.get",
"params": {
"output": "extend",
"filter": {"hostid": hostId}
},
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server could not fulfill the request.'
print 'Error code: ', e.code
else:
response = json.loads(result.read())
# print response
result.close()
if not len(response['result']):
print "\033[041m hostid \033[0m is not exist"
return False
#print "主机数量: \33[31m%s\33[0m" % (len(response['result']))
for hostip in response['result']:
#print hostip
#if len(hostip) == 0:
# print "HostID : %s\t HostIp : %s \t Port : %s " % (hostip['hostid'], hostip['ip'], hostip['port'])
#else:
# print "HostID : %s\t HostIp :\33[32m%s\33[0m \t Port :\33[31m%s\33[0m" % (
# hostip['hostid'], hostip['ip'], hostip['port'])
return hostip['ip']
def host_get(self,hostName=''):
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.get",
"params": {
"output": "extend",
#"filter":{"host":""}
"filter":{"host":hostName}
},
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server could not fulfill the request.'
print 'Error code: ', e.code
else:
response = json.loads(result.read())
#print reqponse
result.close()
if not len(response['result']):
print "\033[041m %s \033[0m is not exist" % hostName
return False
print "主机数量: \033[31m%s\033[0m"%(len(response['result']))
for host in response['result']:
status={"0":"OK","1":"Disabled"}
available={"0":"Unknown","1":"available","2":"Unavailable"}
#print host
if len(hostName)==0:
print "HostID : %s\t HostName : %s\t HostIp : %s\t Status :%s \t Available :%s"%(host['hostid'],host['name'],self.hostid_get_hostip(hostId=host['hostid']),status[host['status']],available[host['available']])
else:
print "HostID : %s\t HostName : %s\t HostIp : %s\t Status :\033[32m%s\033[0m \t Available :\033[31m%s\033[0m"%(host['hostid'],host['name'],self.hostid_get_hostip(hostId=host['hostid']),status[host['status']],available[host['available']])
return host['hostid']
def hostip_get(self, hostIp=''):
data = json.dumps({
"jsonrpc": "2.0",
"method": "hostinterface.get",
"params": {
"output": "extend",
"filter": {"ip": hostIp}
},
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
if hasattr(e, 'reason'):
print 'We failed to reach a server.'
print 'Reason: ', e.reason
elif hasattr(e, 'code'):
print 'The server could not fulfill the request.'
print 'Error code: ', e.code
else:
response = json.loads(result.read())
# print response
result.close()
if not len(response['result']):
print "\033[041m hostip \033[0m is not exist"
return False
print "主机数量: \33[31m%s\33[0m" % (len(response['result']))
for hostip in response['result']:
host = self.hostid_get_hostname(hostip['hostid'])
if len(hostip) == 0:
print "HostID : %s\t HostName : %s\t HostIp : %s\t Status :\33[32m%s\33[0m \t Available :\33[31m%s\33[0m"%(hostip['hostid'],host['name'],hostip['ip'],host['status'],host['available'])
else:
print "HostID : %s\t HostName : %s\t HostIp : %s\t Status :\33[32m%s\33[0m \t Available :\33[31m%s\33[0m"%(hostip['hostid'],host['name'],hostip['ip'],host['status'],host['available'])
return hostip['hostid']
def hostgroup_get(self, hostgroupName=''):
data = json.dumps({
"jsonrpc":"2.0",
"method":"hostgroup.get",
"params":{
"output": "extend",
"filter": {
"name": hostgroupName
}
},
"auth":self.user_login(),
"id":1,
})
request = urllib2.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
print "Error as ", e
else:
# result.read()
response = json.loads(result.read())
result.close()
#print response()
if not len(response['result']):
print "\033[041m %s \033[0m is not exist" % hostgroupName
return False
for group in response['result']:
if len(hostgroupName)==0:
print "hostgroup: \033[31m%s\033[0m \tgroupid : %s" %(group['name'],group['groupid'])
else:
print "hostgroup: \033[31m%s\033[0m\tgroupid : %s" %(group['name'],group['groupid'])
self.hostgroupID = group['groupid']
return group['groupid']
def template_get(self,templateName=''):
data = json.dumps({
"jsonrpc":"2.0",
"method": "template.get",
"params": {
"output": "extend",
"filter": {
"name":templateName
}
},
"auth":self.user_login(),
"id":1,
})
request = urllib2.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
print "Error as ", e
else:
response = json.loads(result.read())
result.close()
#print response
if not len(response['result']):
print "\033[041m %s \033[0m is not exist" % templateName
return False
for template in response['result']:
if len(templateName)==0:
print "template : %s \t id : %s" % (template['name'], template['templateid'])
else:
self.templateID = response['result'][0]['templateid']
print "Template Name :%s"%templateName
return response['result'][0]['templateid']
def hostgroup_create(self,hostgroupName):
if self.hostgroup_get(hostgroupName):
print "hostgroup \033[42m%s\033[0m is exist !" % hostgroupName
sys.exit(1)
data = json.dumps({
"jsonrpc": "2.0",
"method": "hostgroup.create",
"params": {
"name": hostgroupName
},
"auth": self.user_login(),
"id": 1
})
request=urllib2.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
except URLError as e:
print "Error as ", e
else:
response = json.loads(result.read())
result.close()
print "添加主机组:%s hostgroupID : %s"%(hostgroupName,self.hostgroup_get(hostgroupName))
def host_create(self, hostIp, hostgroupName, templateName, hostName):
if self.host_get(hostName) or self.hostip_get(hostIp):
print "该主机已经添加!"
sys.exit(1)
group_list=[]
template_list=[]
for i in hostgroupName.split(','):
var = {}
var['groupid'] = self.hostgroup_get(i)
group_list.append(var)
for i in templateName.split(','):
var={}
var['templateid']=self.template_get(i)
template_list.append(var)
data = json.dumps({
"jsonrpc":"2.0",
"method":"host.create",
"params":{
"host": hostName,
"interfaces": [
{
"type": 1,
"main": 1,
"useip": 1,
"ip": hostIp,
"dns": "",
"port": "10050"
}
],
"groups": group_list,
"templates": template_list,
},
"auth": self.user_login(),
"id":1
})
request = urllib2.Request(self.url, data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
response = json.loads(result.read())
result.close()
print "add host : %s id :%s" % (hostIp, hostName)
except URLError as e:
print "Error as ", e
except KeyError as e:
print "\033[041m 主机添加有误,请检查模板正确性或主机是否添加重复 !\033[0m",e
print response
def host_disable(self,hostip):
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.update",
"params": {
"hostid": self.host_get(hostip),
"status": 1
},
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url,data)
#opener = urllib2.build_opener(urllib2.HTTPBasicAuthHandler(TerminalPassword()))
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
#result = opener.open(request)
except URLError as e:
print "Error as ", e
else:
response = json.loads(result.read())
result.close()
print '------------主机现在状态------------'
print self.host_get(hostip)
def host_enable(self,hostip):
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.update",
"params": {
"hostid": self.host_get(hostip),
"status": 0
},
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
#result = opener.open(request)
except URLError as e:
print "Error as ", e
else:
response = json.loads(result.read())
result.close()
print '------------主机现在状态------------'
print self.host_get(hostip)
def host_delete(self,hostNames):
hostid_list=[]
for hostName in hostNames.split(','):
hostid = self.host_get(hostName=hostName)
if not hostid:
print "主机 \033[041m %s\033[0m 删除失败 !" % hostName
sys.exit()
hostid_list.append(hostid)
data=json.dumps({
"jsonrpc": "2.0",
"method": "host.delete",
"params": hostid_list,
"auth": self.user_login(),
"id": 1
})
request = urllib2.Request(self.url,data)
for key in self.header:
request.add_header(key, self.header[key])
try:
result = urllib2.urlopen(request)
result.close()
print "主机 \033[041m %s\033[0m 已经删除 !" % hostName
except Exception,e:
print e
if __name__ == "__main__":
zabbix=zabbix_api()
parser=argparse.ArgumentParser(description='zabbix api ',usage='%(prog)s [options]')
parser.add_argument('-H','--host',nargs='?',dest='listhost',default='host',help='查询主机')
parser.add_argument('-G','--group',nargs='?',dest='listgroup',default='group',help='查询主机组')
parser.add_argument('-T','--template',nargs='?',dest='listtemp',default='template',help='查询模板信息')
parser.add_argument('-A','--add-group',nargs=1,dest='addgroup',help='添加主机组')
parser.add_argument('-C','--add-host',dest='addhost',nargs=4,metavar=('192.168.2.1', 'groupname', 'Template01,Template02', 'hostName'),help='添加主机,多个主机组或模板使用逗号')
parser.add_argument('-d','--disable',dest='disablehost',nargs='+',metavar=('sh-aa-01'),help='禁用主机,填写主机名,多个主机名之间用逗号')
parser.add_argument('-e','--enable',dest='enablehost',nargs=1,metavar=('sh-aa-01'),help='开启主机')
parser.add_argument('-D','--delete',dest='deletehost',nargs='+',metavar=('sh-aa-01'),help='删除主机,多个主机之间用逗号')
parser.add_argument('-v','--version', action='version', version='%(prog)s 1.0')
if len(sys.argv) == 1:
#print parser.print_help()
#print zabbix.host_get(hostName='bbb')
#print zabbix.hostip_get(hostIp='127.0.0.1')
#print zabbix.hostid_get_hostname(hostId='10108')
#print zabbix.hostid_get_hostid(hostId='10105')
#print zabbix.hostgroup_get(hostgroupName='Linux servers')
#print zabbix.hostgroup_get(hostgroupName='aaa')
# ...
print zabbix.host_delete('hz-aaa-02')
else:
args = parser.parse_args()
if args.listhost != 'host':
if args.listhost:
zabbix.host_get(args.listhost)
else:
zabbix.host_get()
if args.listgroup != 'group':
if args.listgroup:
zabbix.hostgroup_get(args.listgroup)
else:
zabbix.hostgroup_get()
if args.listtemp != 'template':
if args.listtemp:
zabbix.template_get(args.listtemp)
else:
zabbix.template_get()
if args.addgroup:
zabbix.hostgroup_create(args.addgroup[0])
if args.addhost:
zabbix.host_create(args.addhost[0], args.addhost[1], args.addhost[2], args.addhost[3])
if args.disablehost:
zabbix.host_disable(args.disablehost)
if args.deletehost:
zabbix.host_delete(args.deletehost[0])
- 先用pip安装argparse
用法如下:
> python zbx_tool.py -h
usage: zbx_tool.py [options]
zabbix api
optional arguments:
-h, --help show this help message and exit
-H [LISTHOST], --host [LISTHOST]
查询主机
-G [LISTGROUP], --group [LISTGROUP]
查询主机组
-T [LISTTEMP], --template [LISTTEMP]
查询模板信息
-A ADDGROUP, --add-group ADDGROUP
添加主机组
-C 192.168.2.1 groupname Template01,Template02 hostName, --add-host 192.168.2.1 groupname Template01,Template02 hostName
添加主机,多个主机组或模板使用逗号
-d sh-aa-01 [sh-aa-01 ...], --disable sh-aa-01 [sh-aa-01 ...]
禁用主机,填写主机名,多个主机名之间
¨逗号
-e sh-aa-01, --enable sh-aa-01
开启主机
-D sh-aa-01 [sh-aa-01 ...], --delete sh-aa-01 [sh-aa-01 ...]
删除主机,多个主机之间用逗号
-v, --version show program's version number and exit
执行查看
> python zbx_tool.py -H
主机数量: 1
HostID : 10084 HostName : Zabbix server Status :OK Available :available
> python zbx_tool.py -G
hostgroup: Templates groupid : 1
hostgroup: Linux servers groupid : 2
hostgroup: Zabbix servers groupid : 4
hostgroup: Discovered hosts groupid : 5
hostgroup: Virtual machines groupid : 6
hostgroup: Hypervisors groupid : 7
> python zbx_tool.py -T
template : Template OS Linux id : 10001
template : Template App Zabbix Server id : 10047
template : Template App Zabbix Proxy id : 10048
template : Template App Zabbix Agent id : 10050
template : Template SNMP Interfaces id : 10060
...
> python zbx_tool.py -C 1.1.1.10 'Linux servers','Zabbix servers' 'Template OS Linux' hz-aaa-01
主机数量: 0
hostgroup: Linux servers groupid : 2
hostgroup: Zabbix servers groupid : 4
Template Name :Template OS Linux
add host : 1.1.1.10 id :[u'10105']
> python zbx_tool.py -C 1.1.1.10 'Linux servers','Zabbix servers' 'Template OS Linux' hz-aaa-01
主机数量: 0
hostgroup: Linux servers groupid : 2
hostgroup: Zabbix servers groupid : 4
Template Name :Template OS Linux
主机添加有误,请检查模板正确性或主机是否添加重复 ! 'result'
{u'jsonrpc': u'2.0', u'id': 1, u'error': {u'message': u'Invalid params.', u'code': -32602, u'data': u'Host with the same name "hz-aaa-01" already exists.'}}
> 还有其他用法就不一一举例了
脚本完成,在原作者基础上略作修改,以适应自己的项目 ~
三、批量操作脚本
准备target文件
> vim target
sh-aaa-01,1.1.1.1
sh-aaa-02,1.1.1.2
sh-aaa-03,1.1.1.3
sh-aaa-04,1.1.1.4
批量添加主机的target文件如上,主机名和ip用逗号分隔;
其他批量操作,只写入主机名即可;
批量脚本
#!/usr/bin/env python
#-*- coding: utf-8 -*-
import os
import sys
import argparse
# 导入zabbix_tool.py的zabbix_api类
from zbx_tool import zabbix_api
reload(sys)
sys.setdefaultencoding('utf-8')
host_file = 'target'
base_templates = "'aaa',"
cmd = 'python zbx_tool.py'
# 实例化zabbix_api
zabbix=zabbix_api()
def create_hosts():
groups = raw_input("Please Input Group Name: ")
add_templates = raw_input("Please Input Template Name: ")
templates = base_templates + add_templates
cmd1 = cmd + ' -A ' + groups
os.system(cmd1)
with open(host_file) as fb:
host_info = dict(line.strip().split(',') for line in fb)
for hostname in host_info:
cmd2 = cmd + ' -C ' + host_info[hostname] + ' ' + groups + ' ' +templates + ' ' + hostname
os.system(cmd2)
# 如果本机是sat,target文件可以只写主机名,然后用salt获取ip,上一段脚本如下修改:
# with open(host_file) as fb:
# host_info = list(line.strip() for line in fb)
#
# for hostname in host_info:
# ip_cmd='salt ' + hostname + ' grains.item fqdn_ip4|xargs'
# ip = os.popen(ip_cmd).read().split()[4]
# cmd2 = cmd + ' -C ' + ip + ' ' + groups + ' ' +templates + ' ' + hostname
# os.system(cmd2)
def get_hosts():
with open(host_file) as fb:
[zabbix.host_get(line.strip()) for line in fb]
def delete_hosts():
with open(host_file) as fb:
[zabbix.host_delete(line.strip()) for line in fb]
def enable_hosts():
with open(host_file) as fb:
[zabbix.host_enablee(line.strip()) for line in fb]
def disable_hosts():
with open(host_file) as fb:
[zabbix.host_disable(line.strip()) for line in fb]
if __name__ == "__main__":
if len(sys.argv) == 1 or sys.argv[1] == '-h':
print "you need a argv,like:"
print """
python zbx_cli.py -A #批量添加主机
python zbx_cli.py -C #批量查询主机
python zbx_cli.py -D #批量删除主机
python zbx_cli.py -e #批量开启主机
python zbx_cli.py -d #批量禁止主机
"""
else:
if sys.argv[1] == '-A':
create_hosts()
elif sys.argv[1] == '-C':
get_hosts()
elif sys.argv[1] == '-D':
delete_hosts()
elif sys.argv[1] == '-e':
disable_hosts()
elif sys.argv[1] == '-d':
enable_hosts()
执行测试
python zbx_cli.py -D
主机数量: 1
HostID : 12440 HostName : hz-xxx-xxx-api-online-07 HostIp : 1.1.1.1 Status :OK Available :available
主机 hz-xxx-xxx-api-online-07 已经删除 !
主机数量: 1
HostID : 12439 HostName : hz-xxx-xxx-api-online-08 HostIp : 1.1.1.2 Status :OK Available :available
主机 hz-xxx-xxx-api-online-08 已经删除 !
主机数量: 1
...
其他就不贴执行效果了,自己试;
这两个脚本最好放一块,因为zabbix_cli.py的批量操作是通过调用zabbix_tool.py完成的
~ 好了,zabbix API 尝试到此结束
脚本完成,在原作者基础上略作修改,以适应自己的项目 ~