Создание autodiscovery правил в Zabbix
У меня на работе, появилась очередная задача — добавлять дискавери правила для обнаружения машин. Руками делать — это хорошо, но с каждым разом напрягает. Тем более, сейчас все больше наберает оборты «Monitoring as Code» и по этом — пришло время — автоматизировать хоть что-то. Вообще, данный скрипт я писал для своих нужд, но 2 дня назад ко мне пришли и сказали что у нас фигня на ПРОДе и нужно все переделать. Я прикинул, что оно все однотипное, и к тому-же у меня завалялся скрипт. Этим скриптом, я ократил время ручной работы, часа на 2-3.
Для этой цели, я создал скрипт:
# cat add_discoveryrules_to_zabbix.py
Который имеет следующее содержание:
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import requests
import argparse
import time
from datetime import datetime
from pyzabbix import ZabbixAPI
class Bgcolors:
def __init__(self):
self.get = {
'HEADER': '\033[95m',
'OKBLUE': '\033[94m',
'OKGREEN': '\033[92m',
'WARNING': '\033[93m',
'FAIL': '\033[91m',
'ENDC': '\033[0m',
'BOLD': '\033[1m',
'UNDERLINE': '\033[4m'
}
def get_time():
timestamp = datetime.fromtimestamp(int(time.mktime(datetime.now().timetuple()))).strftime('%d-%m-%Y-%H_%M')
print (timestamp)
return get_time
def login_to_zabbix(url, user, password):
# You can use the connection__timeout
connection__timeout = 45
# Verify SSL
verify__ssl = False
# Connect to zabbix-server
zapi = ZabbixAPI(url, timeout=connection__timeout)
zapi.session.verify = verify__ssl
if not verify__ssl:
from requests.packages.urllib3.exceptions import InsecureRequestWarning
requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
zapi.login(user, password)
zapi.session.auth = (user, password)
# You can re-define connection__timeout after
zapi.timeout = connection__timeout
return zapi
def get_needed_groups(z_host, z_user, z_password, z_groups):
needed_groups = []
zapi = login_to_zabbix(z_host, z_user, z_password)
if z_groups is not None:
get_groups = zapi.hostgroup.get(filter={"name": z_groups}, output=['groupid', 'name'])
for group_name in get_groups:
needed_groups.append(group_name)
else:
print(Bgcolors().get['FAIL'], 'Please set/add [--group]', Bgcolors().get['ENDC'])
print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
exit(0)
return needed_groups
def get_needed_templates(z_host, z_user, z_password, z_templates):
needed_templates = []
zapi = login_to_zabbix(z_host, z_user, z_password)
if z_templates is not None:
get_templates = zapi.template.get(filter={"name": z_templates}, output=['templateid', 'name'])
for template in get_templates:
needed_templates.append(template)
else:
print(Bgcolors().get['FAIL'], 'Please set/add [--template]', Bgcolors().get['ENDC'])
print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
exit(0)
return needed_templates
def get_needed_discoveryrules(z_host, z_user, z_password, discoveryrule_name):
discoveryrules = []
zapi = login_to_zabbix(z_host, z_user, z_password)
get_discoveryrules = zapi.action.get(search={"name": discoveryrule_name}, output=['actionid', 'name'])
if len(get_discoveryrules) is not 0:
for discoveryrule in get_discoveryrules:
discoveryrules.append(discoveryrule['name'])
else:
discoveryrules.append('None')
return discoveryrules
def create_group(z_host, z_user, z_password, z_groups):
zapi = login_to_zabbix(z_host, z_user, z_password)
for group in z_groups:
get_group = zapi.hostgroup.get(filter={"name": group}, output=['groupid', 'name'])
if len(get_group) is 0:
zapi.hostgroup.create({"name": group})
print(Bgcolors().get['OKGREEN'], 'Group: [' + group + '] has been created', Bgcolors().get['ENDC'])
else:
print(Bgcolors().get['FAIL'], 'Group already exist: ' + group, Bgcolors().get['ENDC'])
return create_group
def create_discoveryrule(z_host, z_user, z_password, z_groups, z_templates, z_rule_name, z_conditions, z_formula):
zapi = login_to_zabbix(z_host, z_user, z_password)
groups = get_needed_groups(z_host, z_user, z_password, z_groups)
templates = get_needed_templates(z_host, z_user, z_password, z_templates)
if len(groups) is 0:
print(Bgcolors().get['FAIL'], 'Group(s) do/does not exist in Zabbix!', Bgcolors().get['ENDC'])
print('Set the following groups: ', z_groups)
exit(0)
else:
groups_array = []
for group in groups:
g_id = group['groupid']
g = {"groupid": g_id}
groups_array.append(g)
if len(templates) is 0:
print(Bgcolors().get['FAIL'], 'Template(s) do/does not exist in Zabbix!', Bgcolors().get['ENDC'])
print(z_templates)
exit(0)
else:
templates_array = []
for template in templates:
t_id = template['templateid']
t = {"templateid": t_id}
templates_array.append(t)
if z_conditions is None:
print(Bgcolors().get['FAIL'], 'Please set/add [--condition]', Bgcolors().get['ENDC'])
print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
exit(0)
else:
conditions_array = []
formula_ids_array = []
formula_ids = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S',
'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
i = 0
while i < len(z_conditions):
conditions = {
"conditiontype": 24,
"operator": '2',
"value": str(z_conditions[i]),
"formulaid": str(formula_ids[i]),
}
conditions_array.append(conditions)
formula_ids_array.append(formula_ids[i])
i += 1
if z_formula is None:
formula = " and ".join(formula_ids_array)
else:
formula = z_formula
action_status = {'turn_on': '0', 'turn_off': '1'}
eventsource = {'trigger': '0', 'discovery_rule': '1', 'auto_registration': '2', 'internal_event': '3'}
evaltype = {'AND/OR': '0', 'AND': '1', 'OR': '2', 'CUSTOM': '3'}
if z_rule_name is None:
product = 'PRODUCT'
env = 'ENV'
color = ''
service = 'SERVICE-test'
if color is '':
discovery_rule_name = 'ADD_%s_%s_%s' % (product, env, service)
else:
discovery_rule_name = 'ADD_%s_%s_%s_%s' % (product, env, color, service)
else:
discovery_rule_name = z_rule_name
found_discoveryrules = get_needed_discoveryrules(z_host, z_user, z_password, discovery_rule_name)
if found_discoveryrules[0] is not 'None':
print(
Bgcolors().get['FAIL'], 'Please use another name for discovery rule',
Bgcolors().get['ENDC'])
print('I have found the following occurrences:')
print(Bgcolors().get['OKGREEN'], found_discoveryrules, Bgcolors().get['ENDC'])
exit(0)
else:
rules = {
"name": discovery_rule_name,
"eventsource": eventsource['auto_registration'],
"status": action_status['turn_on'],
"esc_period": '0',
"def_shortdata": 'Auto registration: {HOST.HOST}',
"def_longdata": 'Host name: {HOST.HOST}\r\nHost IP: {HOST.IP}\r\nAgent port: {HOST.PORT}',
"recovery_msg": '0',
"r_shortdata": '',
"filter": {
"evaltype": evaltype['CUSTOM'],
"formula": formula,
"conditions": conditions_array,
},
"operations": [
{
"operationtype": '2',
"esc_step_from": '1',
"esc_step_to": '1',
"esc_period": '0',
"evaltype": '0',
"opconditions": [],
},
{
"esc_step_from": '1',
"esc_period": '0',
"operationtype": '4',
"esc_step_to": '1',
"opconditions": [],
"opgroup": groups_array,
},
{
"esc_step_from": '1',
"esc_period": '0',
"operationtype": '6',
"esc_step_to": '1',
"opconditions": [],
"optemplate": templates_array,
},
]
}
zapi.action.create(rules)
print(Bgcolors().get['OKGREEN'],'Discoveryrule [' + discovery_rule_name + '] has been created',
Bgcolors().get['ENDC'])
return create_discoveryrule
def main():
start__time = time.time()
parser = argparse.ArgumentParser(prog='python3 script_name.py -h',
usage='python3 script_name.py {ARGS}',
add_help=True,
prefix_chars='--/',
epilog='''created by Vitalii Natarov''')
parser.add_argument('--version', action='version', version='v1.0.0')
parser.add_argument('--group', nargs='+', dest='group', help='Group name of zabbix', default=None)
parser.add_argument('--template', nargs='+', dest='template', help='Template name of zabbix', default=None)
parser.add_argument('--condition', nargs='+', dest='condition', help='Set condition name of zabbix (hostmetadata)',
default=None)
parser.add_argument('--formula', dest='formula', help='Set formula. Default - AND', default=None)
parser.add_argument('--name', dest='rule_name', help='Set name of zabbix rule', default=None)
parser.add_argument('--zabbix-host', dest='zabbix_host',
help='Zabbix host',
default=None)
parser.add_argument('--zabbix-user', dest='zabbix_user',
help='Zabbix user',
default=None)
parser.add_argument('--zabbix-password', dest='zabbix_password',
help='Zabbix password of user',
default=None)
group = parser.add_mutually_exclusive_group(required=False)
group.add_argument('--create-group', dest='create_group', help='Create group in zabbix', action='store_true')
group.add_argument('--gcreate', dest='create_group', help='Create group in zabbix', action='store_true')
results = parser.parse_args()
group_name = results.group
template_name = results.template
condition = results.condition
formula = results.formula
rule_name = results.rule_name
# host, login, password to connect to zabbix-server
zabbix__host = results.zabbix_host
zabbix__user = results.zabbix_user
zabbix__password = results.zabbix_password
if (zabbix__host is not None) and (zabbix__user is not None) and (zabbix__password is not None):
if results.create_group:
create_group(zabbix__host, zabbix__user, zabbix__password, group_name)
else:
create_discoveryrule(zabbix__host, zabbix__user, zabbix__password, group_name, template_name, rule_name,
condition, formula)
else:
print(Bgcolors().get['FAIL'], 'Please set/add [--zabbix-user] or [--zabbix-password]', Bgcolors().get['ENDC'])
print(Bgcolors().get['OKGREEN'], 'For help, use: script_name.py -h', Bgcolors().get['ENDC'])
exit(0)
# get_needed_discoveryrules(zabbix__host, zabbix__user, zabbix__password, 'test')
# get_needed_templates(zabbix__host, zabbix__user, zabbix__password, group_name)
# get_needed_groups(zabbix__host, zabbix__user, zabbix__password, group_name)
end__time = round(time.time() - start__time, 2)
print("--- %s seconds ---" % end__time)
print(
Bgcolors().get['OKGREEN'], "============================================================",
Bgcolors().get['ENDC'])
print(
Bgcolors().get['OKGREEN'], "==========================FINISHED==========================",
Bgcolors().get['ENDC'])
print(
Bgcolors().get['OKGREEN'], "============================================================",
Bgcolors().get['ENDC'])
if __name__ == '__main__':
main()Если его запустить вот так:
(captain@Macbook)─(✓)─(07:16 PM Fri Jun 08) └─(~)─(19 files, 2312b)─> python3 add_discoveryrules_to_zabbix.py Please set/add [--zabbix-user] or [--zabbix-password] For help, use: script_name.py -h ┌(captain@Macbook)─(✓)─(07:16 PM Fri Jun 08) └─(~)─(19 files, 2312b)─>
То выдает подсказки что ему неоходимо. Помощь можно получить:
$ python3 add_discoveryrules_to_zabbix.py --h
usage: python3 script_name.py {ARGS}
optional arguments:
-h, --help show this help message and exit
--version show program's version number and exit
--group GROUP [GROUP ...]
Group name of zabbix
--template TEMPLATE [TEMPLATE ...]
Template name of zabbix
--condition CONDITION [CONDITION ...]
Set condition name of zabbix (hostmetadata)
--formula FORMULA Set formula. Default - AND
--name RULE_NAME Set name of zabbix rule
--zabbix-host ZABBIX_HOST
Zabbix host
--zabbix-user ZABBIX_USER
Zabbix user
--zabbix-password ZABBIX_PASSWORD
Zabbix password of user
--create-group Create group in zabbix
--gcreate Create group in zabbix
created by Vitalii Natarov
Наглядный пример как создать группы:
$ python3 add_discoveryrules_to_zabbix.py --create-group "CUSTOMER_PRE-PROD" "CUSTOMER_PRE-PROD_TOMCAT"
После чего, можно запустить создание автодискавери рулов:
$ $ add_discoveryrules_to_zabbix.py --group "CUSTOMER_PRE-PROD" "CUSTOMER_PRE-PROD_TOMCAT" --template "Template_env_CUSTOMER_PRE-PROD" "Template_role_CUSTOMER_SOLR_system" --condition "CUSTOMER_" "_SOLR_system" --name "TEST"
Вроде бы я предусмотрел и на момент использования меня и коллег, не было обнаружено проблем.
Полезные статьи:
Экспортирование zabbix templates
Импортирование zabbix templates
На этом у меня все, статья «Создание autodiscovery правил в Zabbix» завершена.