ezKit 1.7.8__py3-none-any.whl → 1.8.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ezKit/bottle.py +7 -2
- ezKit/bottle_extensions.py +14 -18
- ezKit/database.py +104 -71
- ezKit/http.py +21 -22
- ezKit/mongo.py +3 -3
- ezKit/redis.py +5 -4
- ezKit/sendemail.py +0 -7
- ezKit/utils.py +2 -2
- {ezKit-1.7.8.dist-info → ezKit-1.8.0.dist-info}/METADATA +1 -1
- ezKit-1.8.0.dist-info/RECORD +17 -0
- ezKit/files.py +0 -348
- ezKit/plots.py +0 -155
- ezKit/qywx.py +0 -172
- ezKit/reports.py +0 -274
- ezKit/zabbix.py +0 -737
- ezKit-1.7.8.dist-info/RECORD +0 -22
- {ezKit-1.7.8.dist-info → ezKit-1.8.0.dist-info}/LICENSE +0 -0
- {ezKit-1.7.8.dist-info → ezKit-1.8.0.dist-info}/WHEEL +0 -0
- {ezKit-1.7.8.dist-info → ezKit-1.8.0.dist-info}/top_level.txt +0 -0
ezKit/zabbix.py
DELETED
@@ -1,737 +0,0 @@
|
|
1
|
-
import time
|
2
|
-
from copy import deepcopy
|
3
|
-
|
4
|
-
import requests
|
5
|
-
from loguru import logger
|
6
|
-
|
7
|
-
from . import utils
|
8
|
-
|
9
|
-
|
10
|
-
class Zabbix(object):
|
11
|
-
"""Zabbix"""
|
12
|
-
|
13
|
-
api: str | None = None
|
14
|
-
auth: str | None = None
|
15
|
-
debug: bool = False
|
16
|
-
|
17
|
-
def __init__(self, api: str, username: str, password: str, debug: bool = False):
|
18
|
-
''' Initiation '''
|
19
|
-
self.api = api
|
20
|
-
self.auth = self.login(username=username, password=password)
|
21
|
-
self.debug = debug
|
22
|
-
|
23
|
-
def request(
|
24
|
-
self,
|
25
|
-
method: str,
|
26
|
-
params: dict,
|
27
|
-
log_prefix: str = '',
|
28
|
-
**kwargs
|
29
|
-
) -> dict | None:
|
30
|
-
"""
|
31
|
-
Request API
|
32
|
-
"""
|
33
|
-
|
34
|
-
try:
|
35
|
-
|
36
|
-
log_prefix += f'[Request]({method})'
|
37
|
-
|
38
|
-
logger.info(f'{log_prefix}......')
|
39
|
-
|
40
|
-
'''
|
41
|
-
https://www.zabbix.com/documentation/current/en/manual/api#performing-requests
|
42
|
-
The request must have the Content-Type header set to one of these values:
|
43
|
-
application/json-rpc, application/json or application/jsonrequest.
|
44
|
-
'''
|
45
|
-
headers = {'Content-Type': 'application/json-rpc'}
|
46
|
-
|
47
|
-
# https://www.zabbix.com/documentation/6.0/en/manual/api#authentication
|
48
|
-
# jsonrpc - the version of the JSON-RPC protocol used by the API; the Zabbix API implements JSON-RPC version 2.0
|
49
|
-
# method - the API method being called
|
50
|
-
# params - parameters that will be passed to the API method
|
51
|
-
# id - an arbitrary identifier of the request (请求标识符, 这里使用UNIX时间戳作为唯一标示)
|
52
|
-
# auth - a user authentication token; since we don't have one yet, it's set to null
|
53
|
-
data: dict = {
|
54
|
-
'jsonrpc': '2.0',
|
55
|
-
'method': method,
|
56
|
-
'params': params,
|
57
|
-
'auth': self.auth,
|
58
|
-
'id': int(time.time())
|
59
|
-
}
|
60
|
-
|
61
|
-
logger.info(f'{log_prefix}data: {data}') if utils.v_true(self.debug, bool) else next
|
62
|
-
|
63
|
-
response = requests.post(self.api, headers=headers, json=data, timeout=10, **kwargs)
|
64
|
-
|
65
|
-
if response.status_code == 200:
|
66
|
-
logger.success(f'{log_prefix}success')
|
67
|
-
return response.json()
|
68
|
-
else:
|
69
|
-
logger.error(f'{log_prefix}failed')
|
70
|
-
return None
|
71
|
-
|
72
|
-
except Exception as e:
|
73
|
-
logger.error(f'{log_prefix}failed')
|
74
|
-
logger.exception(e) if utils.v_true(self.debug, bool) else logger.error(f'{log_prefix}{e}')
|
75
|
-
return None
|
76
|
-
|
77
|
-
def login(self, username: str, password: str) -> dict:
|
78
|
-
"""User Login"""
|
79
|
-
|
80
|
-
try:
|
81
|
-
|
82
|
-
log_prefix = '[Login]'
|
83
|
-
logger.info(f'{log_prefix}......')
|
84
|
-
|
85
|
-
response = self.request(
|
86
|
-
method='user.login',
|
87
|
-
params={'username': username, 'password': password},
|
88
|
-
log_prefix=log_prefix
|
89
|
-
)
|
90
|
-
|
91
|
-
if utils.v_true(response, dict) and response.get('result'):
|
92
|
-
logger.success(f'{log_prefix}success')
|
93
|
-
return response['result']
|
94
|
-
else:
|
95
|
-
logger.error(f'{log_prefix}failed')
|
96
|
-
return None
|
97
|
-
|
98
|
-
except Exception as e:
|
99
|
-
logger.error(f'{log_prefix}failed')
|
100
|
-
logger.exception(e) if utils.v_true(self.debug, bool) else logger.error(f'{log_prefix}{e}')
|
101
|
-
return None
|
102
|
-
|
103
|
-
def logout(self) -> bool:
|
104
|
-
"""User Logout"""
|
105
|
-
|
106
|
-
try:
|
107
|
-
|
108
|
-
log_prefix = '[Logout]'
|
109
|
-
logger.info(f'{log_prefix}......')
|
110
|
-
|
111
|
-
response = self.request(method='user.logout', params={}, log_prefix=log_prefix)
|
112
|
-
|
113
|
-
match True:
|
114
|
-
case True if utils.v_true(response, dict) and response.get('result'):
|
115
|
-
logger.success(f'{log_prefix}success')
|
116
|
-
return True
|
117
|
-
case True if utils.v_true(response, dict) and response.get('error'):
|
118
|
-
logger.error(f"{log_prefix}failed: {response.get('error',{}).get('data')}")
|
119
|
-
return False
|
120
|
-
case _:
|
121
|
-
logger.error(f"{log_prefix}failed")
|
122
|
-
return False
|
123
|
-
|
124
|
-
except Exception as e:
|
125
|
-
logger.error(f'{log_prefix}failed')
|
126
|
-
logger.exception(e) if utils.v_true(self.debug, bool) else logger.error(f'{log_prefix}{e}')
|
127
|
-
return False
|
128
|
-
|
129
|
-
def logout_and_exit(self):
|
130
|
-
'''Logout and Exit'''
|
131
|
-
|
132
|
-
try:
|
133
|
-
self.logout()
|
134
|
-
except Exception as e:
|
135
|
-
logger.exception(e)
|
136
|
-
finally:
|
137
|
-
exit()
|
138
|
-
|
139
|
-
def get_ids_by_template_name(self, name: str) -> list | None:
|
140
|
-
'''
|
141
|
-
Get ids by template name
|
142
|
-
|
143
|
-
name: string/array
|
144
|
-
example: 'Linux by Zabbix agent' / ['Linux by Zabbix agent', 'Linux by Zabbix agent active']
|
145
|
-
|
146
|
-
如果 name 为 '' (空), 返回所有 template id
|
147
|
-
'''
|
148
|
-
|
149
|
-
try:
|
150
|
-
response = self.request('template.get', {'output': 'templateid', 'filter': {'name': name}})
|
151
|
-
if utils.v_true(response, dict) and utils.v_true(response['result'], list):
|
152
|
-
return [i['templateid'] for i in response['result']]
|
153
|
-
else:
|
154
|
-
return None
|
155
|
-
except Exception as e:
|
156
|
-
logger.exception(e)
|
157
|
-
return None
|
158
|
-
|
159
|
-
def get_ids_by_hostgroup_name(self, name: str) -> list | None:
|
160
|
-
'''
|
161
|
-
Get ids by hostgroup name
|
162
|
-
|
163
|
-
name: string/array
|
164
|
-
example: 'Linux servers' / ['Linux servers', 'Discovered hosts']
|
165
|
-
|
166
|
-
如果 name 为 '' (空), 返回所有 hostgroup id
|
167
|
-
'''
|
168
|
-
|
169
|
-
try:
|
170
|
-
response = self.request('hostgroup.get', {'output': 'groupid', 'filter': {'name': name}})
|
171
|
-
if utils.v_true(response, dict) and utils.v_true(response.get('result'), list):
|
172
|
-
return [i['groupid'] for i in response['result']]
|
173
|
-
else:
|
174
|
-
return None
|
175
|
-
except Exception as e:
|
176
|
-
logger.exception(e)
|
177
|
-
return None
|
178
|
-
|
179
|
-
def get_hosts_by_template_name(self, name: str, output: str = 'extend', **kwargs) -> list | None:
|
180
|
-
'''
|
181
|
-
Get hosts by template name
|
182
|
-
|
183
|
-
name: string/array
|
184
|
-
example: 'Linux by Zabbix agent' / ['Linux by Zabbix agent', 'Linux by Zabbix agent active']
|
185
|
-
|
186
|
-
如果 name 为 '' (空), 返回所有 host
|
187
|
-
'''
|
188
|
-
try:
|
189
|
-
response = self.request('template.get', {'output': ['templateid'], 'filter': {'host': name}})
|
190
|
-
if utils.v_true(response, dict) and utils.v_true(response.get('result'), list):
|
191
|
-
ids = [i['templateid'] for i in response['result']]
|
192
|
-
hosts = self.request('host.get', {'output': output, 'templateids': ids, **kwargs})
|
193
|
-
if utils.v_true(hosts, dict) and utils.v_true(hosts.get('result', []), list):
|
194
|
-
return hosts['result']
|
195
|
-
else:
|
196
|
-
return None
|
197
|
-
else:
|
198
|
-
return None
|
199
|
-
except Exception as e:
|
200
|
-
logger.exception(e)
|
201
|
-
return None
|
202
|
-
|
203
|
-
def get_hosts_by_hostgroup_name(self, name: str, output: str = 'extend', **kwargs) -> list | None:
|
204
|
-
'''
|
205
|
-
Get hosts by hostgroup name
|
206
|
-
|
207
|
-
name: string/array
|
208
|
-
example: 'Linux servers' / ['Linux servers', 'Discovered hosts']
|
209
|
-
|
210
|
-
如果 name 为 '' (空), 返回所有 hosts
|
211
|
-
'''
|
212
|
-
try:
|
213
|
-
ids = self.get_ids_by_hostgroup_name(name)
|
214
|
-
if ids == []:
|
215
|
-
return None
|
216
|
-
hosts = self.request('host.get', {'output': output, 'groupids': ids, **kwargs})
|
217
|
-
if utils.v_true(hosts, dict) and utils.v_true(hosts.get('result', []), list):
|
218
|
-
return hosts['result']
|
219
|
-
else:
|
220
|
-
return None
|
221
|
-
except Exception as e:
|
222
|
-
logger.exception(e)
|
223
|
-
return None
|
224
|
-
|
225
|
-
def get_interface_by_host_id(self, hostid: str, output: str = 'extend') -> list | None:
|
226
|
-
'''
|
227
|
-
Get interface by host id
|
228
|
-
|
229
|
-
hostids: string/array
|
230
|
-
example: '10792' / ['10792', '10793']
|
231
|
-
'''
|
232
|
-
|
233
|
-
try:
|
234
|
-
response = self.request('hostinterface.get', {'output': output, 'hostids': hostid})
|
235
|
-
if utils.v_true(response, dict) and utils.v_true(response.get('result'), list):
|
236
|
-
return response['result']
|
237
|
-
else:
|
238
|
-
return None
|
239
|
-
except Exception as e:
|
240
|
-
logger.exception(e)
|
241
|
-
return None
|
242
|
-
|
243
|
-
def available_hosts(self, hosts: list = []) -> tuple | None:
|
244
|
-
'''可用服务器'''
|
245
|
-
try:
|
246
|
-
|
247
|
-
# 可用服务器, 不可用服务器
|
248
|
-
available_hosts, unavailable_hosts = [], []
|
249
|
-
|
250
|
-
# 服务器排查
|
251
|
-
for host in hosts:
|
252
|
-
if host['interfaces'][0]['available'] != '1':
|
253
|
-
unavailable_hosts.append(host['name'])
|
254
|
-
else:
|
255
|
-
available_hosts.append(host)
|
256
|
-
|
257
|
-
return available_hosts, unavailable_hosts
|
258
|
-
|
259
|
-
except Exception as e:
|
260
|
-
logger.exception(e)
|
261
|
-
return None
|
262
|
-
|
263
|
-
def get_history_by_item_key(
|
264
|
-
self,
|
265
|
-
hosts: list,
|
266
|
-
time_from: int = 0,
|
267
|
-
time_till: int = 0,
|
268
|
-
item_key: str = '',
|
269
|
-
data_type: int = 3
|
270
|
-
) -> list | None:
|
271
|
-
'''
|
272
|
-
1. 根据 item key 获取 item id, 通过 item id 获取 history
|
273
|
-
2. 根据 host 的 item id 和 history 的 item id 将数据提取为一个 history list
|
274
|
-
3. 根据 history list 中的 clock 排序, 然后将 history list 整合到 host 中
|
275
|
-
4. 返回包含有 item key, item id 和 history list 的 host 的 host list
|
276
|
-
|
277
|
-
通过 Item Key 获取 Item history
|
278
|
-
|
279
|
-
hosts: 主机列表
|
280
|
-
time_from: 开始时间
|
281
|
-
time_till: 结束时间
|
282
|
-
item_key: Item Key
|
283
|
-
data_type: 数据类型
|
284
|
-
|
285
|
-
参考文档:
|
286
|
-
|
287
|
-
https://www.zabbix.com/documentation/6.0/en/manual/api/reference/history/get
|
288
|
-
|
289
|
-
history
|
290
|
-
|
291
|
-
0 - numeric float
|
292
|
-
1 - character
|
293
|
-
2 - log
|
294
|
-
3 - numeric unsigned
|
295
|
-
4 - text
|
296
|
-
|
297
|
-
Default: 3
|
298
|
-
|
299
|
-
默认数据类型是 numeric unsigned (整数), 如果 history.get 返回的数据为 None, 有可能是 data_type 类型不对
|
300
|
-
'''
|
301
|
-
|
302
|
-
try:
|
303
|
-
|
304
|
-
match True:
|
305
|
-
case True if not utils.v_true(hosts, list):
|
306
|
-
logger.error('ERROR!! hosts is not list or none')
|
307
|
-
return None
|
308
|
-
case True if not utils.v_true(time_from, int):
|
309
|
-
logger.error('ERROR!! time_from is not integer or zero')
|
310
|
-
return None
|
311
|
-
case True if not utils.v_true(time_till, int):
|
312
|
-
logger.error('ERROR!! time_till is not integer or zero')
|
313
|
-
return None
|
314
|
-
case True if not utils.v_true(item_key, str):
|
315
|
-
logger.error('ERROR!! item_key is not string or none')
|
316
|
-
return None
|
317
|
-
|
318
|
-
# 初始化变量
|
319
|
-
# item_ids 获取历史数据时使用
|
320
|
-
# item_history 历史数据集合, 最后返回
|
321
|
-
item_ids: list = []
|
322
|
-
item_history: list = []
|
323
|
-
|
324
|
-
'''
|
325
|
-
Deep Copy (拷贝数据)
|
326
|
-
父函数的变量是 list 或者 dict 类型, 父函数将变量传递个子函数, 如果子函数对变量数据进行了修改, 那么父函数的变量的数据也会被修改
|
327
|
-
为了避免出现这种问题, 可以使用 Deep Copy 拷贝一份数据, 避免子函数修改父函数的变量的数据
|
328
|
-
'''
|
329
|
-
hosts = deepcopy(hosts)
|
330
|
-
|
331
|
-
# --------------------------------------------------------------------------------------
|
332
|
-
|
333
|
-
# Get Item
|
334
|
-
hostids = [i['hostid'] for i in hosts]
|
335
|
-
item_params = {
|
336
|
-
'output': ['name', 'itemid', 'hostid'],
|
337
|
-
'hostids': hostids,
|
338
|
-
'filter': {'key_': item_key}
|
339
|
-
}
|
340
|
-
items = self.request('item.get', item_params)
|
341
|
-
|
342
|
-
# --------------------------------------------------------------------------------------
|
343
|
-
|
344
|
-
# 因为 history 获取的顺序是乱的, 为了使输出和 hosts 列表顺序一致, 将 Item ID 追加到 hosts, 然后遍历 hosts 列表输出
|
345
|
-
if utils.v_true(items, dict) and utils.v_true(items.get('result'), list):
|
346
|
-
for host in hosts:
|
347
|
-
item: dict = next((item_object for item_object in items['result'] if host['hostid'] == item_object['hostid']), '')
|
348
|
-
if utils.v_true(item, dict) and item.get('itemid') != None:
|
349
|
-
host['itemkey'] = item_key
|
350
|
-
host['itemid'] = item['itemid']
|
351
|
-
item_ids.append(item['itemid'])
|
352
|
-
item_history.append(host)
|
353
|
-
else:
|
354
|
-
logger.error(f'ERROR!! item key {item_key} not find')
|
355
|
-
return None
|
356
|
-
|
357
|
-
# 如果 ID 列表为空, 则返回 None
|
358
|
-
if not utils.v_true(item_ids, list):
|
359
|
-
logger.error(f'ERROR!! item key {item_key} not find')
|
360
|
-
return None
|
361
|
-
|
362
|
-
# --------------------------------------------------------------------------------------
|
363
|
-
|
364
|
-
# Get History
|
365
|
-
history_params = {
|
366
|
-
'output': 'extend',
|
367
|
-
'history': data_type,
|
368
|
-
'itemids': item_ids,
|
369
|
-
'time_from': time_from,
|
370
|
-
'time_till': time_till
|
371
|
-
}
|
372
|
-
history = self.request('history.get', history_params)
|
373
|
-
|
374
|
-
# --------------------------------------------------------------------------------------------------
|
375
|
-
|
376
|
-
if utils.v_true(history, dict) and utils.v_true(history.get('result'), list):
|
377
|
-
|
378
|
-
for item in item_history:
|
379
|
-
# 根据 itemid 提取数据
|
380
|
-
item_history_data = [history_result for history_result in history['result'] if item['itemid'] == history_result['itemid']]
|
381
|
-
# 根据 clock 排序
|
382
|
-
item_history_data = utils.list_dict_sorted_by_key(item_history_data, 'clock')
|
383
|
-
# 整合数据
|
384
|
-
item['history'] = item_history_data
|
385
|
-
|
386
|
-
return item_history
|
387
|
-
|
388
|
-
else:
|
389
|
-
|
390
|
-
logger.error('ERROR!! item history not find')
|
391
|
-
return None
|
392
|
-
|
393
|
-
except Exception as e:
|
394
|
-
logger.exception(e)
|
395
|
-
return None
|
396
|
-
|
397
|
-
def get_history_by_interface(
|
398
|
-
self,
|
399
|
-
hosts: list,
|
400
|
-
interfaces: list,
|
401
|
-
time_from: int = 0,
|
402
|
-
time_till: int = 0,
|
403
|
-
direction: str = ''
|
404
|
-
) -> list | None:
|
405
|
-
'''获取网卡历史数据'''
|
406
|
-
|
407
|
-
try:
|
408
|
-
|
409
|
-
match True:
|
410
|
-
case True if not utils.v_true(hosts, list):
|
411
|
-
logger.error('ERROR!! hosts is not list or none')
|
412
|
-
return None
|
413
|
-
case True if not utils.v_true(interfaces, list):
|
414
|
-
logger.error('ERROR!! interfaces is not list or none')
|
415
|
-
return None
|
416
|
-
case True if not utils.v_true(time_from, int):
|
417
|
-
logger.error('ERROR!! time_from is not integer or zero')
|
418
|
-
return None
|
419
|
-
case True if not utils.v_true(time_till, int):
|
420
|
-
logger.error('ERROR!! time_till is not integer or zero')
|
421
|
-
return None
|
422
|
-
case True if not utils.v_true(direction, str):
|
423
|
-
logger.error('ERROR!! direction is not string or none')
|
424
|
-
return None
|
425
|
-
|
426
|
-
# 创建一个只有 网卡名称 的 列表
|
427
|
-
interfaces_names: set = set(interface['interface'] for interface in interfaces)
|
428
|
-
|
429
|
-
# 创建一个 Key 为 网卡名称 的 dictionary
|
430
|
-
interfaces_dict: dict = {key: [] for key in interfaces_names}
|
431
|
-
|
432
|
-
# 汇集 相同网卡名称 的 IP
|
433
|
-
for interface in interfaces:
|
434
|
-
interfaces_dict[interface['interface']].append(interface['host'])
|
435
|
-
|
436
|
-
# 获取历史数据
|
437
|
-
history: list = []
|
438
|
-
for key, value in interfaces_dict.items():
|
439
|
-
hosts_by_ip = [host for v in value for host in hosts if v == host['interfaces'][0]['ip']]
|
440
|
-
history += self.get_history_by_item_key(
|
441
|
-
hosts=hosts_by_ip,
|
442
|
-
time_from=time_from,
|
443
|
-
time_till=time_till,
|
444
|
-
item_key=f'net.if.{direction}["{key}"]',
|
445
|
-
data_type=3
|
446
|
-
)
|
447
|
-
|
448
|
-
# 根据 name 排序
|
449
|
-
history = utils.list_dict_sorted_by_key(history, 'name')
|
450
|
-
|
451
|
-
return history
|
452
|
-
|
453
|
-
except Exception as e:
|
454
|
-
logger.exception(e)
|
455
|
-
return None
|
456
|
-
|
457
|
-
def get_ips_by_hostgroup_name(self, hostgroup_name: str) -> list:
|
458
|
-
try:
|
459
|
-
hosts = self.get_hosts_by_hostgroup_name(hostgroup_name)
|
460
|
-
if utils.v_true(hosts, utils.NoneType):
|
461
|
-
return None
|
462
|
-
hostids = [i['hostid'] for i in hosts]
|
463
|
-
hostinterface = self.request(method='hostinterface.get', params={'hostids': hostids})
|
464
|
-
return [i['ip'] for i in hostinterface.get('result', [])]
|
465
|
-
except Exception as e:
|
466
|
-
logger.exception(e)
|
467
|
-
return None
|
468
|
-
|
469
|
-
def create_object(
|
470
|
-
self,
|
471
|
-
ips: list,
|
472
|
-
item: dict | None = None,
|
473
|
-
trigger: dict | None = None,
|
474
|
-
graph: bool | dict = False
|
475
|
-
) -> bool:
|
476
|
-
"""
|
477
|
-
创建对象
|
478
|
-
|
479
|
-
ips: IP列表
|
480
|
-
|
481
|
-
item:
|
482
|
-
|
483
|
-
name
|
484
|
-
key_
|
485
|
-
|
486
|
-
trigger:
|
487
|
-
|
488
|
-
description
|
489
|
-
expression (必须包含 {host}, 用于定义HOST)
|
490
|
-
"""
|
491
|
-
"""
|
492
|
-
参考文档:
|
493
|
-
|
494
|
-
https://www.zabbix.com/documentation/6.0/en/manual/api/reference/item/object
|
495
|
-
https://www.zabbix.com/documentation/6.0/en/manual/config/items/itemtypes/zabbix_agent
|
496
|
-
https://www.zabbix.com/documentation/6.0/en/manual/api/reference/trigger/object
|
497
|
-
|
498
|
-
type:
|
499
|
-
|
500
|
-
0 - Zabbix agent
|
501
|
-
2 - Zabbix trapper
|
502
|
-
3 - Simple check
|
503
|
-
5 - Zabbix internal
|
504
|
-
7 - Zabbix agent (active)
|
505
|
-
9 - Web item
|
506
|
-
10 - External check
|
507
|
-
11 - Database monitor
|
508
|
-
12 - IPMI agent
|
509
|
-
13 - SSH agent
|
510
|
-
14 - Telnet agent
|
511
|
-
15 - Calculated
|
512
|
-
16 - JMX agent
|
513
|
-
17 - SNMP trap
|
514
|
-
18 - Dependent item
|
515
|
-
19 - HTTP agent
|
516
|
-
20 - SNMP agent
|
517
|
-
21 - Script
|
518
|
-
|
519
|
-
value_type:
|
520
|
-
|
521
|
-
0 - numeric float
|
522
|
-
1 - character
|
523
|
-
2 - log
|
524
|
-
3 - numeric unsigned
|
525
|
-
4 - text
|
526
|
-
|
527
|
-
priority (integer): Severity of the trigger
|
528
|
-
|
529
|
-
0 - (default) not classified
|
530
|
-
1 - information
|
531
|
-
2 - warning
|
532
|
-
3 - average
|
533
|
-
4 - high
|
534
|
-
5 - disaster
|
535
|
-
"""
|
536
|
-
|
537
|
-
try:
|
538
|
-
|
539
|
-
logger.info('mission running')
|
540
|
-
|
541
|
-
match True:
|
542
|
-
case True if not utils.v_true(ips, list):
|
543
|
-
logger.error('ERROR!! ips is not list')
|
544
|
-
return False
|
545
|
-
case _:
|
546
|
-
next
|
547
|
-
|
548
|
-
for ip in ips:
|
549
|
-
|
550
|
-
# Host Object
|
551
|
-
|
552
|
-
log_prefix = 'get host object'
|
553
|
-
|
554
|
-
logger.info(f'{log_prefix} ......')
|
555
|
-
|
556
|
-
response = self.request('hostinterface.get', {'filter': {'ip': ip}, 'selectHosts': ['host']})
|
557
|
-
|
558
|
-
logger.warning(f'{log_prefix} hostinterface: {response}') if utils.v_true(self.debug, bool) else next
|
559
|
-
|
560
|
-
match True:
|
561
|
-
case True if utils.v_true(response, dict) and utils.v_true(response.get('result'), list):
|
562
|
-
logger.success(f"{log_prefix} success: {response['result'][0]['hosts'][0]['host']}")
|
563
|
-
case True if utils.v_true(response, dict) and response.get('error'):
|
564
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
565
|
-
continue
|
566
|
-
case True if utils.v_true(response, utils.NoneType):
|
567
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
568
|
-
continue
|
569
|
-
case _:
|
570
|
-
logger.error(f"{log_prefix} error: {ip}")
|
571
|
-
continue
|
572
|
-
|
573
|
-
host = response['result'][0]['hosts'][0]['host']
|
574
|
-
host_id = response['result'][0]['hostid']
|
575
|
-
interface_id = response['result'][0]['interfaceid']
|
576
|
-
|
577
|
-
# ----------------------------------------------------------------------------------
|
578
|
-
|
579
|
-
# Create Item
|
580
|
-
|
581
|
-
if utils.v_true(item, dict):
|
582
|
-
|
583
|
-
log_prefix = 'create item'
|
584
|
-
|
585
|
-
logger.info(f'{log_prefix} ......')
|
586
|
-
|
587
|
-
params = {
|
588
|
-
# 'name': None,
|
589
|
-
# 'key_': None,
|
590
|
-
'hostid': host_id,
|
591
|
-
'type': 7,
|
592
|
-
'value_type': 3,
|
593
|
-
'interfaceid': interface_id,
|
594
|
-
'delay': '1m',
|
595
|
-
'history': '7d',
|
596
|
-
'trends': '7d'
|
597
|
-
} | item
|
598
|
-
|
599
|
-
response = self.request('item.create', params)
|
600
|
-
|
601
|
-
logger.warning(f'{log_prefix} response: {response}') if utils.v_true(self.debug, bool) else next
|
602
|
-
|
603
|
-
match True:
|
604
|
-
case True if utils.v_true(response, dict) and response.get('result'):
|
605
|
-
logger.success(f"{log_prefix} success: {response.get('result')}")
|
606
|
-
case True if utils.v_true(response, dict) and response.get('error'):
|
607
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
608
|
-
continue
|
609
|
-
case True if utils.v_true(response, utils.NoneType):
|
610
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
611
|
-
continue
|
612
|
-
case _:
|
613
|
-
logger.error(f"{log_prefix} error: {item.get('name')}")
|
614
|
-
continue
|
615
|
-
|
616
|
-
item_id = response['result']['itemids'][0]
|
617
|
-
|
618
|
-
# ----------------------------------------------------------------------------------
|
619
|
-
|
620
|
-
# Create Trigger
|
621
|
-
|
622
|
-
if utils.v_true(trigger, dict):
|
623
|
-
|
624
|
-
log_prefix = 'create trigger'
|
625
|
-
|
626
|
-
logger.info(f'{log_prefix} ......')
|
627
|
-
|
628
|
-
params = {
|
629
|
-
# 'description': None,
|
630
|
-
'priority': '2',
|
631
|
-
# 'expression': None,
|
632
|
-
'manual_close': '1'
|
633
|
-
} | trigger
|
634
|
-
|
635
|
-
# Trigger 的 expression 需要指定 HOST, 例如:
|
636
|
-
# 'last(/DIYCL-110-30/system.uptime)<10m'
|
637
|
-
# DIYCL-110-30 就是 HOST
|
638
|
-
# 但是 HOST 是根据 IP 调用接口获取的, 所以可以写成动态的配置
|
639
|
-
# 'last(/{host}/system.uptime)<10m'.format(host='DIYCL-110-30')
|
640
|
-
# 所以, 传递参数的时候, expression 中就必须要有 {host}, 用于定义 HOST
|
641
|
-
# 如果传递参数的时候使用了 f-strings, 要保留 {host}, 再套一层 {} 即可
|
642
|
-
# f'last(/{{host}}/system.uptime)<10m'
|
643
|
-
params['expression'] = f"{params['expression']}".format(host=host)
|
644
|
-
|
645
|
-
# 注意: create trigger 的 params 的类型是 list
|
646
|
-
response = self.request('trigger.create', [params])
|
647
|
-
|
648
|
-
logger.warning(f'{log_prefix} response: {response}') if utils.v_true(self.debug, bool) else next
|
649
|
-
|
650
|
-
match True:
|
651
|
-
case True if utils.v_true(response, dict) and response.get('result'):
|
652
|
-
logger.success(f"{log_prefix} success: {response.get('result')}")
|
653
|
-
case True if utils.v_true(response, dict) and response.get('error'):
|
654
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
655
|
-
continue
|
656
|
-
case True if utils.v_true(response, utils.NoneType):
|
657
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
658
|
-
continue
|
659
|
-
case _:
|
660
|
-
logger.error(f"{log_prefix} error: {trigger.get('name')}")
|
661
|
-
continue
|
662
|
-
|
663
|
-
# ----------------------------------------------------------------------------------
|
664
|
-
|
665
|
-
# Create Graph
|
666
|
-
|
667
|
-
if utils.v_true(graph, bool) or utils.v_true(graph, dict):
|
668
|
-
|
669
|
-
log_prefix = 'create graph'
|
670
|
-
|
671
|
-
logger.info(f'{log_prefix} ......')
|
672
|
-
|
673
|
-
# Graph object:
|
674
|
-
#
|
675
|
-
# https://www.zabbix.com/documentation/current/en/manual/api/reference/graph/object
|
676
|
-
#
|
677
|
-
# yaxismax (float) The fixed maximum value for the Y axis.
|
678
|
-
# Default: 100.
|
679
|
-
# yaxismin (float) The fixed minimum value for the Y axis.
|
680
|
-
# Default: 0.
|
681
|
-
# ymax_type (integer) Maximum value calculation method for the Y axis.
|
682
|
-
# Possible values:
|
683
|
-
# 0 - (default) calculated;
|
684
|
-
# 1 - fixed;
|
685
|
-
# 2 - item.
|
686
|
-
# ymin_type (integer) Minimum value calculation method for the Y axis.
|
687
|
-
# Possible values:
|
688
|
-
# 0 - (default) calculated;
|
689
|
-
# 1 - fixed;
|
690
|
-
# 2 - item.
|
691
|
-
#
|
692
|
-
# 'ymin_type': 2,
|
693
|
-
# 'ymin_itemid':item_id,
|
694
|
-
# 'ymax_type': 2,
|
695
|
-
# 'ymax_itemid':item_id,
|
696
|
-
params: dict = {
|
697
|
-
'name': item.get('name'),
|
698
|
-
'width': 900,
|
699
|
-
'height': 200,
|
700
|
-
'gitems': [{'itemid': item_id, 'color': '0040FF'}]
|
701
|
-
}
|
702
|
-
|
703
|
-
if utils.v_true(graph, dict):
|
704
|
-
|
705
|
-
params = params | graph
|
706
|
-
|
707
|
-
if utils.v_true(params.get('gitems'), list):
|
708
|
-
for gitem in params.get('gitems'):
|
709
|
-
if utils.v_true(gitem, dict) and gitem.get('itemid') == '{}':
|
710
|
-
gitem['itemid'] = item_id
|
711
|
-
|
712
|
-
response = self.request('graph.create', params)
|
713
|
-
|
714
|
-
logger.warning(f'{log_prefix} response: {response}') if utils.v_true(self.debug, bool) else next
|
715
|
-
|
716
|
-
match True:
|
717
|
-
case True if utils.v_true(response, dict) and response.get('result'):
|
718
|
-
logger.success(f"{log_prefix} success: {response.get('result')}")
|
719
|
-
case True if utils.v_true(response, dict) and response.get('error'):
|
720
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
721
|
-
continue
|
722
|
-
case True if utils.v_true(response, utils.NoneType):
|
723
|
-
logger.error(f"{log_prefix} error: {response.get('error', {}).get('data')}")
|
724
|
-
continue
|
725
|
-
case _:
|
726
|
-
logger.error(f"{log_prefix} error: {params.get('name')}")
|
727
|
-
continue
|
728
|
-
|
729
|
-
# ----------------------------------------------------------------------------------
|
730
|
-
|
731
|
-
return True
|
732
|
-
|
733
|
-
except Exception as e:
|
734
|
-
logger.exception(e) if utils.v_true(self.debug, bool) else logger.error(e)
|
735
|
-
return False
|
736
|
-
finally:
|
737
|
-
logger.success('mission completed')
|