Создание 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» завершена.