Создание autodiscovery правил в Zabbix

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

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Этот сайт использует Akismet для борьбы со спамом. Узнайте, как обрабатываются ваши данные комментариев.