####因公司需求,需要根据主机名称(hostname)模糊匹配查询出来,进行批量添加聚合图形(网卡流量监控)
- 试着在网上找案例,发现均是代码 潦潦草草 复制一大片,无任何重点
- 官方文档案例提笔带过
- 官方文档 网上 翻了个遍 找到了重点
思路点
- 需要从zabbix 数据库里面匹配传递进来的hostname模糊参数 进行匹配
zabbix api hosts.get
返回所有从数据库里面返回出来的hostsid- 用返回的hostsid 请求
zabbix api graph.get
(图形模版) 来匹配graphid
返回出来的name
为模版名称(这个很重要) - 通过返回出来的
graphid
再去请求zabbix api screen.add
创建聚合图形 - 至此,思路已经通了,和需求正是一样 下面开始 详解代码
当前目录下创建三个.py文件
QuerySet.py ### 查询数据库返回host主机
parame.py ### 请求的参数以及 mysql用户,密码 zabbixy用户,密码
screen_api.py ### 请求内容,返回结果
1: parame.py:
# -*- coding:utf-8 -*-
mysql_user = 'root'
mysql_host = 'localhost'
mysql_pass = 'your MySQL Password'
zabbix_user = 'your Zabbix user'
zabbix_pass = 'your zabbix Password'
host_get = {
"jsonrpc": "2.0",
"method": "host.get", ###此处为请求主机返回hostsid 的请求参数,当前为空,后期会append 进去
"params": {
"filter": {
"host": [
]
}
},
"id": 1
}
graph_get = {
"jsonrpc": "2.0",
"method": "graph.get", ###获取主机图形的方法
"params": {
"output": "extend",
"hostids":[],
"sortfield": "name"
},
"id": 1
}
screen_add = {
"jsonrpc": "2.0",
"method": "screen.create",###创建图形方法
"params": {
"hsize": 2,
"vsize": 60,
"screenitems": [
]
},
"id": 1
}
2: QuerySet.py:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import pymysql as mysql
import sys
import re
import parame
def kwargs(args): ###连接数据库
conn = mysql.connect(
host = parame.mysql_host, ###parame文件里面定义的host
port = 3306,
user = parame.mysql_user, ###parame文件里面定义的user
passwd = parame.mysql_pass, ###parame文件里面定义的passwd
db = 'zabbix',
)
cur = conn.cursor()
###模糊查询传递进来的参数例如 cmb-he-sjz1-123-34-5-
response = cur.execute('select host from hosts where host like %s',args)
result1 = [ i for i in cur.fetchmany(response)]
if len(result1) == 0:
return False
cur.close()
conn.commit()
conn.close()
result = []
###此处可以省略,因公司需求,名称前面带VIP的主机名不需要监控
for x in result1:
if re.match('VIP',x[0]):
pass
else:
result.append(x)
###排序,这块可以无视,将数据库查询出来的主机排序从小到大,一条命令就可以搞定
###sorted(hosts, key=lambda x: int(x.split("-")[6]))
### 因为每个公司的主机名定义不一致,这块大家 如果没有排序需求 删掉就可以,直接return result
after = [re.search('(.*?)-(.*?)-(.*?)-(.*?)-(.*?)-(.*?)-(.*?)',x[0]).group() for x in result]
before = [int(y[0].split('-')[6]) for y in result]
before.sort()
response = []
z = 0
for result in after:
response.append(result + str(before[z]))
z += 1
return response
if __name__ == '__main__':
try:
params = sys.argv[1]
print(kwargs(params + '%'))
except Exception as e:
raise TypeError
2: screen_api.py:
#!/usr/bin/env python
# -*- coding:utf-8 -*-
import sys
import json
import time
import requests
import parame
import sys
import re
from QuerySet import kwargs
class Api:
def __init__(self):
self.url = 'http://your addres /api_jsonrpc.php'
self.headers = {'Content-Type': 'application/json'}
auth = {
"jsonrpc": "2.0",
"method": "user.login",
"params": {
"user": parame.zabbix_user, ###验证
"password":parame.zabbix_pass
},
"id": 1,
"auth":None,
}
response = requests.post(self.url,data=json.dumps(auth),headers=self.headers)
self.authid = json.loads(response.text)['result'] ### auth的id
def get_host(self,hosts): #数据库传递进来的主机参数 一大堆~
data = parame.host_get
data['auth'] = self.authid ###将返回id 写进去 接口会验证这个唯一
if hosts: ### 判断是否为空 为空说明没有找到主机 直接退出
pass
else:
print("result not found")
sys.exit(10)
hosts = sorted(hosts, key=lambda x: int(x.split("-")[6])) ###这块是排序 QuerySet 已经做过了 没必要再写
for host in hosts:
data['params']['filter']['host'].append(host) 将主机加入参数里面
response = requests.post(self.url,data=json.dumps(data),headers=self.headers)
lists = json.loads(response.text)['result']
result = [ lists[i]['hostid'] for i in range(len(lists)) ]
return result ###返回主机hostsid
def graph_get(self,res): ###请求主机图形结果
hosts_id = self.get_host(res) ### 讲hostsid 赋值给hosts_id
data = parame.graph_get
data['auth'] = self.authid
for hosts in hosts_id:
data['params']['hostids'].append(hosts)
response = requests.post(self.url,data=json.dumps(data),headers=self.headers)
graph_id = json.loads(response.text)['result']
result = []
for index in range(len(graph_id)): ###循环遍布判断是否是网卡图形,需求不同意此处可以不用re 你们直接 append 就好
if re.search('Network traffic on em.',graph_id[index]['name']):
result.append(graph_id[index]['graphid'])
elif re.search('eth',graph_id[index]['name']):
result.append(graph_id[index]['graphid'])
else:
pass
return result
def screen_add(self,graph_ids,screen_name): ###创建图形
response = self.graph_get(graph_ids)
x = 0 ### x为行 此处的定义 取决于parame.screen_add 里面的hsize 和vsize 最多为 hsize - 1 or vsize -1
y = 0 ### y为列
parame.screen_add['params']['name'] = screen_name
parame.screen_add['auth'] = self.authid
for value in response:
parame.screen_add['params']['screenitems'].append({
"resourcetype": 0,
"resourceid": value,
"width": "500", ###宽高度
"height": "100",
"rowspan": 1,
"colspan": 1,
"x": x,
"y": y
})
if x == 1: ###此处判断 我们需求只需要两行一列 等于1 x为0
x = 0
y += 1
else:
x += 1
time.sleep(0.01)
response = requests.post(self.url,data=json.dumps(parame.screen_add),headers=self.headers)
print(response.text)
if __name__ == '__main__':
try:
func = Api()
res = kwargs("%" + str(sys.argv[4]) + "%") ###数据库传递的参数
func.screen_add(res,str(sys.argv[2])) ### 聚合图形群组名
except Exception as e:
print(e)
print('--name 聚合图形组名 --hostname 匹配加入的主机')
sys.exit(1)
此刻正是我们需要的结果,有问题 欢迎在下方留言 QQ:1301927919