Page_c76a3fcf https://linux-notes.org Unix/ Linux блог, на котором можно найти полезную информацию по настройке ОС и ПО. Mon, 11 Jun 2018 16:15:56 +0000 ru-RU hourly 1 https://wordpress.org/?v=6.7.2 Page_c76a3fcf https://linux-notes.org/upravlenie-polzovateljami-v-grafana-cherez-python/ https://linux-notes.org/upravlenie-polzovateljami-v-grafana-cherez-python/#respond Mon, 11 Jun 2018 16:15:56 +0000 http://linux-notes.org/?p=15620 Управление пользователями в Grafana через Python Когда-то писал скрипт для работы с пользователями в Grafana. Нашел немного времени чтобы поделится данным скриптом с миром. Не всегда есть время, но желание и материал всегда имеется! И так, приступим… Полезное чтиво: Установка grafana в Unix/Linux Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux Экспорт […]

The post Управление пользователями в Grafana через Python first appeared on linux-notes.org.]]>

Управление пользователями в Grafana через Python

Когда-то писал скрипт для работы с пользователями в Grafana. Нашел немного времени чтобы поделится данным скриптом с миром. Не всегда есть время, но желание и материал всегда имеется! И так, приступим…

Полезное чтиво:

Установка grafana в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

Экспорт дашбордов из grafana в Unix/Linux

Собственно, катаю скрипт:

$ cat work_with_users_in_grafana.py

Скрипт содержит:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import argparse
import json


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 search_grafana_user(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    get_data_req = requests.get(
        g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users?perpage=10&page=1')
    pars_json = json.loads(get_data_req.text)
    for user in pars_json:
        if user['email'] == email:
            account_id = user['id']
        else:
            account_id = -1

    return account_id


def get_grafana_users(gurl, g_user, g_password):
    users_array = []

    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    get_data_req = requests.get(g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users')
    pars_json = json.loads(get_data_req.text)
    for user in pars_json:
        users_array.append(user['email'])
        # print (user)

    return users_array


def add_grafana_user(gurl, g_user, g_password, created_email, created_password):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    grafana_users = get_grafana_users(gurl, g_user, g_password)
    for user in grafana_users:
        if user == created_email:
            print(Bgcolors().get['FAIL'] + 'User already exist: ', user, '\nUse another name!' + Bgcolors().get['ENDC'])
            exit(0)
    data = {"name": created_email,
            "email": created_email,
            "login": created_email,
            "password": created_password,
            }

    get_data_req = requests.post(g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users',
                                 data)
    pars_json = json.loads(get_data_req.text)
    print(pars_json)
    print('URL: ' + gurl, '\nemail: ' + created_email, '\npassword: ' + created_password)

    return add_grafana_user


def update_grafana_users(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    state_of_admin = str.lower('True')
    data_put = {"Accept": "application/json",
                "Content-Type": "application/json",
                "isGrafanaAdmin": state_of_admin,
                }

    account_id = search_grafana_user(gurl, g_user, g_password, email)
    if account_id != -1:
        get_data_req = requests.put(
            g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users/%s/permissions' % account_id,
            data=data_put)
        pars_json = json.loads(get_data_req.text)
        print(pars_json)

        get_data_req = requests.get(
            g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users?perpage=10&page=1')
        pars_json = json.loads(get_data_req.text)
        for user in pars_json:
            if user['email'] == email:
                print(user)
    else:
        print('Unfortunately, I cant find [%s] email in grafana to update role!' % email)
        print('Please, use current EMAIL!')
        exit(0)

    return update_grafana_users


def update_grafana_user_password(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    data_put = {"password": "password"}
    account_id = search_grafana_user(gurl, g_user, g_password, email)
    if account_id != -1:
        get_data_req = requests.put(
            g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users/%s/password' % account_id,
            data=data_put)
        pars_json = json.loads(get_data_req.text)
        print(pars_json)

    else:
        print('Unfortunately, I cant find [%s] email in grafana to update PW!' % email)
        print('Please, use current EMAIL!')
        exit(0)

    return update_grafana_users


def delete_grafana_users(gurl, g_user, g_password, email):
    g_protocol = gurl.split(':')[0]
    g_url = gurl.split('//')[1]

    account_id = search_grafana_user(gurl, g_user, g_password, email)
    get_data_req = requests.delete(
        g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/admin/users/%s' % account_id)
    pars_json = json.loads(get_data_req.text)
    print(pars_json)

    get_data_req = requests.get(g_protocol + '://' + g_user + ':' + g_password + '@' + g_url + '/api/users')
    pars_json = json.loads(get_data_req.text)
    for user in pars_json:
        print(user)

    return update_grafana_users


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.5')
    parser.add_argument('--gtoken', '--token', dest='gtoken', help='Token of grafana server', default=None)
    parser.add_argument('--gurl', '--url', dest='gurl', help='URL from grafana', default=None)
    parser.add_argument('--glogin', dest='glogin', help='A login to grafana', default=None)
    parser.add_argument('--gpassword', dest='gpassword', help='A password of grafana user', default=None)
    parser.add_argument('--email', dest='email', help='A email to create a new user in grafana', default=None)
    parser.add_argument('--password', dest='password', help='A password of grafana user which need to create',
                        default=None)

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--show', dest='show', help='Show grafana users', action='store_true')
    group.add_argument('--s', dest='show', help='Show grafana users', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--add', dest='add', help='Add grafana user', action='store_true')
    group2.add_argument('--a', dest='add', help='Add grafana user', action='store_true')

    group3 = parser.add_mutually_exclusive_group(required=False)
    group3.add_argument('--update', dest='update', help='Update grafana user', action='store_true')
    group3.add_argument('--u', dest='update', help='Update grafana user', action='store_true')

    group4 = parser.add_mutually_exclusive_group(required=False)
    group4.add_argument('--cpassword', dest='changepassword', help='Change grafana user PW', action='store_true')
    group4.add_argument('--changepw', dest='changepassword', help='Change grafana user PW', action='store_true')

    group5 = parser.add_mutually_exclusive_group(required=False)
    group5.add_argument('--delete', dest='delete', help='Delete grafana user', action='store_true')
    group5.add_argument('--d', dest='delete', help='Delete grafana user', action='store_true')

    results = parser.parse_args()
    grafana_url = results.gurl
    grafana_login = results.glogin
    grafana_password = results.gpassword
    user_email = results.email
    user_password = results.password

    if results.add:
        if (grafana_url is not None) and (user_email is not None) and (user_password is not None):
            add_grafana_user(grafana_url, grafana_login, grafana_password, user_email, user_password)
        else:
            print('Please add [--gurl] or [--email] or [--password]')
            print('For help, use: script_name.py -h')
            exit(0)

    elif results.update:
        if user_email is not None:
            update_grafana_users(grafana_url, grafana_login, grafana_password, user_email)
        else:
            print('Please add [--gurl] or [--email]')
            print('For help, use: script_name.py -h')
            exit(0)

    elif results.changepassword:
        if user_email is not None:
            update_grafana_user_password(grafana_url, grafana_login, grafana_password, user_email)
        else:
            print('Please add [--gurl] or [--email]')
            print('For help, use: script_name.py -h')
            exit(0)
    elif results.delete:
        if user_email is not None:
            delete_grafana_users(grafana_url, grafana_login, grafana_password, user_email)
        else:
            print('Please add [--gurl] or [--email]')
            print('For help, use: script_name.py -h')
            exit(0)
    elif results.show:
        if (grafana_url is not None) and (grafana_login is not None) and (grafana_password is not None):
            # print(get_grafana_users(grafana_url, grafana_login, grafana_password))
            users = get_grafana_users(grafana_url, grafana_login, grafana_password)
            for user in users:
                print(user)
        else:
            print('Please add [--gurl] or [--email] or [--password]')
            print('For help, use: script_name.py -h')
            exit(0)
    else:
        print('For help, use: script_name.py -h')
        exit(0)

    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()

Для помощи можно воспользоватся следующей командой:

$ work_with_users_in_grafana.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
  --gtoken GTOKEN, --token GTOKEN
                        Token of grafana server
  --gurl GURL, --url GURL
                        URL from grafana
  --glogin GLOGIN       A login to grafana
  --gpassword GPASSWORD
                        A password of grafana user
  --email EMAIL         A email to create a new user in grafana
  --password PASSWORD   A password of grafana user which need to create
  --show                Show grafana users
  --s                   Show grafana users
  --add                 Add grafana user
  --a                   Add grafana user
  --update              Update grafana user
  --u                   Update grafana user
  --cpassword           Change grafana user PW
  --changepw            Change grafana user PW
  --delete              Delete grafana user
  --d                   Delete grafana user

created by Vitalii Natarov

Собственно, скрипт умеет:

  • —show — Показывает всех пользователей графана.
  • —add — Добавляет пользователя.
  • —update — Обновляет роль (пока не работает)….
  • —cpassword — Служит функцией для смены пароля.
  • — delete — Удаляет пользователя.
$ python3 work_with_users_in_grafana.py --gurl="https://grafana.local" --glogin "grafana_login" --gpassword "grafana_password" --add --email="vnatarov@ololo.com" --password="my_passWD"

Кому будет не понятно как использовать или возникнут ошибки, — пишите в комментариях, помогу. Я по мере необходимости, переписываю куски кода во всех моих скриптах и всегда обновляю материал на сайте.

Вот и все, статья «Управление пользователями в Grafana через Python» завершена.

The post Управление пользователями в Grafana через Python first appeared on linux-notes.org.]]>
https://linux-notes.org/upravlenie-polzovateljami-v-grafana-cherez-python/feed/ 0
Page_c76a3fcf https://linux-notes.org/sozdanie-autodiscovery-pravil-v-zabbix/ https://linux-notes.org/sozdanie-autodiscovery-pravil-v-zabbix/#respond Fri, 08 Jun 2018 16:23:10 +0000 http://linux-notes.org/?p=15610 Создание autodiscovery правил в Zabbix У меня на работе, появилась очередная задача — добавлять дискавери правила для обнаружения машин. Руками делать — это хорошо, но с каждым разом напрягает. Тем более, сейчас все больше наберает оборты «Monitoring as Code» и по этом — пришло время — автоматизировать хоть что-то. Вообще, данный скрипт я писал для […]

The post Создание autodiscovery правил в Zabbix first appeared on linux-notes.org.]]>

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

The post Создание autodiscovery правил в Zabbix first appeared on linux-notes.org.]]>
https://linux-notes.org/sozdanie-autodiscovery-pravil-v-zabbix/feed/ 0
Page_c76a3fcf https://linux-notes.org/jeksport-zabbix-triggers/ https://linux-notes.org/jeksport-zabbix-triggers/#respond Wed, 30 May 2018 18:05:42 +0000 http://linux-notes.org/?p=15591 Экспорт zabbix triggers У меня на работе, появилась задача — выполнить проверку всех имеющихся триггеров в заббиксе + обновить документацию. Я очень ленивый и всегда стараюсь оптимизировать процесс так, чтобы в последующие разы я тратил как можно меньше времени. Так произошло и в этот раз! 🙂 Для этой цели, я создал скрипт: # cat get_triggers.py […]

The post Экспорт zabbix triggers first appeared on linux-notes.org.]]>

Экспорт zabbix triggers

У меня на работе, появилась задача — выполнить проверку всех имеющихся триггеров в заббиксе + обновить документацию. Я очень ленивый и всегда стараюсь оптимизировать процесс так, чтобы в последующие разы я тратил как можно меньше времени. Так произошло и в этот раз! 🙂

Для этой цели, я создал скрипт:

# cat get_triggers.py

Который имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import argparse
import time
import os

from datetime import datetime
from pyzabbix import ZabbixAPI
from pathlib import Path


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 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_group):
    needed_groups = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    if z_group is None:
        get_groups = zapi.hostgroup.get(filter={"name": z_group}, output=['groupid', 'name'])
        for group_name in get_groups:
            needed_groups.append(group_name)
    else:
        get_groups = zapi.hostgroup.get(search={"name": z_group}, output=['groupid', 'name'])
        for group_name in get_groups:
            needed_groups.append(group_name)

    return needed_groups


def get_needed_templates(z_host, z_user, z_password, z_group):
    needed_templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    groups = get_needed_groups(z_host, z_user, z_password, z_group)

    needed_group_ids = []
    for group in groups:
        needed_group_ids.append(group['groupid'])

    get_templates = zapi.template.get(groupids=needed_group_ids, output=['templateid', 'name'])
    for template in get_templates:
        needed_templates.append(template)

    return needed_templates


def get_needed_triggers(z_host, z_user, z_password, z_group):
    needed_triggers = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    templates = get_needed_templates(z_host, z_user, z_password, z_group)

    needed_template_ids = []
    for template in templates:
        needed_template_ids.append(template['templateid'])

    get_triggers = zapi.trigger.get(templateids=needed_template_ids,
                                    output=['status', 'priority', 'description'],
                                    sortfield='priority',
                                    sortorder='DESC'
                                    )
    for trigger in get_triggers:
        needed_triggers.append({'status': trigger['status'],
                                'priority': trigger['priority'],
                                'description': trigger['description']})

    return needed_triggers


def write_data_to_file(z_host, z_user, z_password, z_group, z_severity):
    severity = {'Not_classified': '0', 'Information': '1', 'Warning': '2', 'Average': '3', 'High': '4', 'Disaster': '5'}

    name_out = './' + str(z_group) + '.txt'
    my_file = Path(name_out)
    if my_file.is_file():
        os.remove(name_out)

    triggers = get_needed_triggers(z_host, z_user, z_password, z_group)
    sorted_triggers = []
    for trigger in triggers:
        if trigger['priority'] >= severity[z_severity]:
            if trigger not in sorted_triggers:
                sorted_triggers.append(trigger)

    for trigger in sorted_triggers:
        try:
            f = open(name_out, 'a')
            f.write(trigger['description'] + '\n')
            f.close()
        except ValueError:
            print ('I cant write to file: ', ValueError)

    return write_data_to_file


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', dest='group', help='Group name', default=None)
    parser.add_argument('--zabbix-host', dest='zabbix_host',
                        help='Zabbix host',
                        default='https://zabbix.local')
    parser.add_argument('--zabbix-user', dest='zabbix_user',
                        help='Zabbix user',
                        default='Vitalii_Natarov')
    parser.add_argument('--zabbix-password', dest='zabbix_password',
                        help='Zabbix password of user',
                        default='PASSWORD')
    parser.add_argument('--zabbix-severity', dest='zabbix_severity', help='Set Zabbix severity for triggers',
                        default='Average')

    # group = parser.add_mutually_exclusive_group(required=False)
    # group.add_argument('--show-acc', dest='show_acc', help='Show account names', action='store_true')
    # group.add_argument('--s', dest='show_acc', help='Show account names', action='store_true')
    results = parser.parse_args()
    group_name = results.group
    # host, login, password to connect to zabbix-server
    zabbix__host = results.zabbix_host
    zabbix__user = results.zabbix_user
    zabbix__password = results.zabbix_password
    zabbix__trigger_severity = results.zabbix_severity

    write_data_to_file(zabbix__host, zabbix__user, zabbix__password, group_name, zabbix__trigger_severity)

    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()

Запускаем:

# python3 get_triggers.py --group "CM-Shared"

Вывод получим:

--- 2.97 seconds ---
 ============================================================
 ==========================FINISHED==========================
 ============================================================

Т.е за 3 секунды, мой скрипт прошелся по всем группам (которая имеет вхождение — «CM-Shared»), нашел какие прилинкованы к группам шаблоны. И по каждому шаблону, вывел триггеры. Конечно, чтобы не было повторений, я отсеял мусор.  Есть идея дописать скрипт так, чтобы он генерировал полностью пейджу для конфлюенса. Не сложно, но было бы желание — появится и результат! 😉

На данный скрипт ушло около 2-х часов моего времени. Если бы я руками все это делал — часов 5, не меньше!

Полезные статьи:

Экспортирование zabbix templates

Импортирование zabbix templates

На этом у меня все, статья «Экспорт zabbix triggers» завершена.

The post Экспорт zabbix triggers first appeared on linux-notes.org.]]>
https://linux-notes.org/jeksport-zabbix-triggers/feed/ 0
Page_c76a3fcf https://linux-notes.org/ustanovka-s-tui-v-unix-linux/ https://linux-notes.org/ustanovka-s-tui-v-unix-linux/#respond Wed, 21 Feb 2018 22:55:41 +0000 http://linux-notes.org/?p=15219 Установка s-tui в Unix/Linux S-tui — бесплатный пользовательский интерфейс с открытым исходным кодом для мониторинга вашего компьютера. Утилита s-tui позволяет контролировать температуру процессора, частоту и его мощность. Данная тулза, написана на Python и требует root права для ее использования. Установка s-tui в Unix/Linux Для этой утилиты, понадобится PIP, установить его можно по следующей статье: Установка […]

The post Установка s-tui в Unix/Linux first appeared on linux-notes.org.]]>

Установка s-tui в Unix/Linux

S-tui — бесплатный пользовательский интерфейс с открытым исходным кодом для мониторинга вашего компьютера. Утилита s-tui позволяет контролировать температуру процессора, частоту и его мощность. Данная тулза, написана на Python и требует root права для ее использования.

Установка s-tui в Unix/Linux

Для этой утилиты, понадобится PIP, установить его можно по следующей статье:

Установка pip/setuptools/wheel в Unix/Linux

Так же, понадобится утилита stress.

Установка stress в Mac OS X

Стоит установить homebrew — Установка homebrew на Mac OS X и после чего, выполняем:

$ brew install stress

Установка stress в Debian/Ubuntu

Установка очень простая, выполняем:

# apt-get install stress

Установка stress в CentOS/Redhat/Fedora

Установка очень простая, выполняем:

# yum -y install stress

Установка s-tui в Unix/Linux

Чтобы установить утилиту s-tui выполняем:

# pip install s-tui

ИЛИ:

# pip3 install s-tui

Перейдем к использованию.

Использование s-tui в Unix/Linux

Использование очень простое, стоит выполнить:

$ sudo s-tui

Вот как выглядит утилита в работе:

Установка s-tui в Unix/Linux

Для помощи, можно использовать команду:

$ s-tui --help

Вот и все, статья «Установка s-tui в Unix/Linux» завершена.

The post Установка s-tui в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/ustanovka-s-tui-v-unix-linux/feed/ 0
Page_c76a3fcf https://linux-notes.org/nastrojka-new-relic-s-grafana-v-unix-linux/ https://linux-notes.org/nastrojka-new-relic-s-grafana-v-unix-linux/#respond Fri, 22 Dec 2017 08:14:45 +0000 http://linux-notes.org/?p=14412 Настройка New Relic с Grafana в Unix/Linux New Relic — это инструмент для мониторинга приложений. Grafana — это инструмент, который позволяет отображать метрики, стоить графики (дашборды) и умеет работать с различными инструментами (Prometheus, InfluxDB, ElasticSearch и многие другие). У меня на работе, имеется заббикс сервер, графана и некоторые люди используют нью релик. Как по мне, […]

The post Настройка New Relic с Grafana в Unix/Linux first appeared on linux-notes.org.]]>

Настройка New Relic с Grafana в Unix/Linux

New Relic — это инструмент для мониторинга приложений.

Grafana — это инструмент, который позволяет отображать метрики, стоить графики (дашборды) и умеет работать с различными инструментами (Prometheus, InfluxDB, ElasticSearch и многие другие).

У меня на работе, имеется заббикс сервер, графана и некоторые люди используют нью релик. Как по мне, все должно (это очень удобно) быть в одном месте.

Я описывал процесс установки данных компонентов в своих статьях:

Установка New Relic Platform Installer (NPI) в Unix/Linux

Мониторинг приложений с New Relic в Unix/Linux

Установка плагинов для New Relic

Установка grafana в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

Экспорт дашбордов из grafana в Unix/Linux

И так, приступим к настройке!

Настройка New Relic с Grafana в Unix/Linux

Я предпологаю что уже имеется установленный New Relic на нодах которые стоит мониторить и уже мониторится все. Так же, я предпологаю что уже имеется сервер с grafana.

Устанавливаем git, статья тут:

Установка GIT на RedHat/CentOS/Fedora или Установка git на CentOS, для других ОС, нет ничего сложного чтобы установить.

Перейдем в папку с плагинами самой графаны:

# cd /var/lib/grafana/plugins

И клонируем плагин:

$ git clone https://github.com/wevanscfi/grafana-newrelic-apm-datasource.git

Далее, открываем сайт с new relic, логинимся в него и регистрируем токен. Я не буду офишировать его, по этому не сделаю скрин.

Открываем сайт с графана и переходим в «plugins» -> «APPS» -> «newrelic-app». В Поле «Api key» вводим API ключ с new relic-а:

Активация grafana-newrelic-apm-datasource плагина для grafana

Затем, переходим в «datasources» и, нажимаем на » Add data source». В поле «type» выбираем наш установленный плагин в качестве БД:

Добавляем datasource в grafana

В поле «Aplication» выбираем апликейшин для мониторинга. По идее, можно не выбирать, он все равно будет выбиратся из листинга (в дальнейшем). Нажимаем на «add» для добавления датасорса. Собственно — это и вся установка. Осталось создать дашборд и вывести необходимые метрики.

Вот пример моего тестового дашборда:

new relic + grafana

Вот и все, статья «Настройка New Relic с Grafana в Unix/Linux» завершена.

The post Настройка New Relic с Grafana в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/nastrojka-new-relic-s-grafana-v-unix-linux/feed/ 0
Page_c76a3fcf https://linux-notes.org/e-ksport-dashbordov-iz-grafana-v-unix-linux/ https://linux-notes.org/e-ksport-dashbordov-iz-grafana-v-unix-linux/#comments Fri, 24 Nov 2017 00:51:36 +0000 http://linux-notes.org/?p=14174 Экспорт дашбордов из grafana в Unix/Linux У меня на работе, установлена grafana и ее активно используют коллеги для снятия различных метрик по дашбордам. Как у нас частенько бывает — ложатся сервера и если нет бэкапов, то все печально! Руками бэкапить дашборды с графаны — это нормально, но я люблю автоматизацию. И решил написать скрипт для […]

The post Экспорт дашбордов из grafana в Unix/Linux first appeared on linux-notes.org.]]>

Экспорт дашбордов из grafana в Unix/Linux

У меня на работе, установлена grafana и ее активно используют коллеги для снятия различных метрик по дашбордам. Как у нас частенько бывает — ложатся сервера и если нет бэкапов, то все печально! Руками бэкапить дашборды с графаны — это нормально, но я люблю автоматизацию. И решил написать скрипт для экспорта всех дашбордов из grafana себе на компьютер. Я совсем не много пишу на питон и по этому — хотел написать на нем (так и будет немного позже)….. но на скорую руку пришелся — bash.

Полезное чтиво:

Установка grafana в Unix/Linux

Настройка Grafana с Graphite/Zabbix/Prometheus/MySQL/InfluxDB/Elasticsearch/CloudWatch для сбора и отображения метрик в Unix/Linux

-=== СПОСОБ 1 — Использование BASH===-

Предположим, скрипт у меня лежит прям в текущей директории:

# cat get_grafana_dashes.sh

Собственно, вот сие чудо:

#!/bin/bash -x
#
# Vitaliy Natarov
#
# Set some colors for status OK, FAIL and titles
SETCOLOR_SUCCESS="echo -en \\033[1;32m"
SETCOLOR_FAILURE="echo -en \\033[1;31m"
SETCOLOR_NORMAL="echo -en \\033[0;39m"

SETCOLOR_TITLE="echo -en \\033[1;36m" #Fuscia
SETCOLOR_TITLE_GREEN="echo -en \\033[0;32m" #green
SETCOLOR_TITLE_PURPLE="echo -en \\033[0;35m" #purple 
SETCOLOR_NUMBERS="echo -en \\033[0;34m" #BLUE

KEY="XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"
HOST="http://graffana-server.local"
DASH_DIR="/home/captain/Grafana/dashboards"

if [ ! -d "$DASH_DIR" ]; then
	 mkdir -p dashboards 
else
	 $SETCOLOR_TITLE_PURPLE
	 echo "|-------------------------------------------------------------------------------|";
	 echo "| A $DASH_DIR directory is already exist! |";
	 echo "|-------------------------------------------------------------------------------|";
	 $SETCOLOR_NORMAL
fi
  
#curl -sS -k -H "Authorization: Bearer $KEY" $HOST/api/search\?query\=\& |tr ']{' '\n'| cut -d ':' -f4| cut -d ',' -f1| cut -d '"' -f2 | grep -Ev "(^$|\[)"| cut -c 4-

for dash in $(curl -sS -k -H "Authorization: Bearer $KEY" $HOST/api/search\?query\=\& |tr ']{' '\n'| cut -d ':' -f4| cut -d ',' -f1| cut -d '"' -f2 | grep -Ev "(^$|\[)"| cut -c 4-); do
	curl -sS -k -H "Authorization: Bearer $KEY" $HOST/api/dashboards/db/$dash > dashboards/$dash.json
	$SETCOLOR_TITLE_GREEN
	echo "The [ $dash ] dashboard has been exported"  
	$SETCOLOR_NORMAL
done

$SETCOLOR_TITLE
echo "|-------------------------------------------------------------------------------|";
echo "|----------------------------------FINISHED-------------------------------------|";
echo "|-------------------------------------------------------------------------------|";
$SETCOLOR_NORMAL

Где:

  • KEY=»XXXXXXXXXXXXXXXXXXXXXXXX» — Ключ для использования API. Можно сгенерировать в админ-панеле самой графаны.
  • HOST=»http://graffana-server.local» — УРЛ где находится графана-сервер.
  • DASH_DIR=»/home/captain/Grafana/dashboards» — Путь где будут лежать все шаблоны (дашборды) после экспорта.

Запускаем:

$ bash Get_grafana_dashes.sh

Получаем:

Экспорт дашбордов из grafana в Unix/Linux

Экспорт дашбордов из grafana в Unix/Linux

Вроде бы все нормально. Кому режит глаза, могут убрать расскраску 🙂

-=== СПОСОБ 2 — Использование PYTHON===-

Будет скоро, постараюсь написать на днях. Возможно после выходных….

Так вот, прошло несколько дней и мой скрипт — готов.

Открываю его:

$ vim grafana_dashboards.py

Он имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import os
import argparse
import json
import glob

# from datetime import datetime
from requests.packages.urllib3.exceptions import InsecureRequestWarning


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_grafana_dashboards(g_url, g_token):
    dashboards_array = []
    headers = {'Authorization': str('Bearer ' + g_token), 'Content-type': 'application/json'}
    get_data_req = requests.get(g_url + '/api/search?query=&', headers=headers)

    pars_json = json.loads(get_data_req.text)
    for dash in pars_json:
        # print(dash['uri'][3::])
        dashboards_array.append(dash['uri'][3::])

    return dashboards_array


def export_grafana_dashboards(g_token, g_url, dir_path, e_dash):
    headers = {'Authorization': str('Bearer ' + g_token),
               'Content-type': 'application/json'
               }
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
        print(dir_path, 'has been created')

    dashboard_names = get_grafana_dashboards(g_url, g_token)
    dash_count = 1

    if e_dash == 'all':
        # print('I will export ALL DASHes!')
        for d in dashboard_names:
            dashboard_name_out = dir_path + '/' + d + '.json'
            get_dashboard = requests.get(g_url + '/api/dashboards/db/' + d, headers=headers)
            try:
                f = open(dashboard_name_out, 'w')
                f.write(json.dumps(get_dashboard.json(), indent=4))
                f.close()
                print('[', dash_count, ']', d)
                dash_count += 1
            except EOFError:
                print('I cant write to file: ', EOFError)

    else:
        # print('I will export %s dashbourd(s)!' % e_dash)
        for d in dashboard_names:
            for dd in e_dash:
                if d == dd:
                    dashboard_name_out = dir_path + '/' + d + '.json'
                    get_dashboard = requests.get(g_url + '/api/dashboards/db/' + d, headers=headers)
                    try:
                        f = open(dashboard_name_out, 'w+')
                        f.write(json.dumps(get_dashboard.json(), indent=4))
                        f.close()
                        print('[', dash_count, ']', d)
                        dash_count += 1
                    except ValueError:
                        print('I cant write to file: ', ValueError)
    #

    return export_grafana_dashboards


def import_grafana_dashboards(g_token, g_url, dir_path, i_dash):
    headers = {'Authorization': str('Bearer ' + g_token),
               'Content-type': 'application/json',
               'Accept': 'application/json'
               }
    dash_count = 1

    if i_dash == 'all':
        # print('I will import ALL DASHes!')
        files = glob.glob(dir_path + "/" + "*.json")
    else:
        # print('I will import %s dashbourd(s)!' % i_dash)
        for d in i_dash:
            files = glob.glob(str(dir_path) + "/" + str(d) + ".json")
    for f in files:
        d = f.split('.')[0].split('/')[1]

        with open(f, 'r') as file:
            dashboard = file.read()
            try:
                print('[%s] Need to create an import to grafana [%s]' % (dash_count, f))
                datas = json.loads(dashboard)

                protocol = g_url.split(':')[0]
                if protocol == "http":
                    i__dash = requests.post(g_url + '/api/dashboards/db/', headers=headers, json=datas)
                elif protocol == "https":
                    verify = False
                    if not verify:
                        requests.packages.urllib3.disable_warnings(InsecureRequestWarning)
                    i__dash = requests.post(g_url + '/api/dashboards/db/', headers=headers, json=datas, verify=verify)
                    if i__dash.status_code != 200:
                        print(i__dash.status_code)
                        exit(0)
                else:
                    print('Incorrect URL! Use url with http|https protocol')
                    exit(0)
                print(i__dash)
            except EOFError as e:
                print(e)
        dash_count += 1

    return import_grafana_dashboards


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('--dash', '--dashboard', nargs='+', dest='dashboard', help='Indicate a dashboard(s)',
                        default='all')
    parser.add_argument('--gtoken', '--token', dest='gtoken', help='Token of grafana server', default=None)
    parser.add_argument('--gurl', '--url', dest='gurl', help='URL from grafana', default=None)
    parser.add_argument('--dir', '--directory', dest='dashboards_dir', help='Indicate a folder for dashboard(s)',
                        default='CM-Shared_Grafana', metavar='folder')

    group = parser.add_mutually_exclusive_group(required=False)
    group.add_argument('--i', dest='imports', help='Import function', action='store_true')
    group.add_argument('--import', dest='imports', help='Import function', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--e', dest='exports', help='Export function', action='store_true', default=argparse.SUPPRESS)
    group2.add_argument('--export', dest='exports', help='Export function', action='store_true')

    results = parser.parse_args()
    dashboards_dir = results.dashboards_dir
    dashboard = results.dashboard
    grafana_token = results.gtoken
    grafana_url = results.gurl

    if (grafana_token is not None) and (grafana_url is not None):
        if results.exports:
            print('EXPORT function!')
            export_grafana_dashboards(grafana_token, grafana_url, dashboards_dir, dashboard)

        elif results.imports:
            print('IMPORT function')
            import_grafana_dashboards(grafana_token, grafana_url, dashboards_dir, dashboard)
    else:
        print('Please add [--gurl] and/or [--gtoken] option(s).Use "--e" to export, "--i" to import dashboards as well')
        print('For help, use: script_name.py -h')
        exit(0)
    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()

Для помощи можно использовать:

$ python3 grafana_dashboards.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
  --dash DASHBOARD [DASHBOARD ...], --dashboard DASHBOARD [DASHBOARD ...]
                        Indicate a dashboard(s)
  --dir folder, --directory folder
                        Indicate a folder for dashboard(s)
  --i                   Import function
  --import              Import function
  --e                   Export function
  --export              Export function

created by Vitalii Natarov

Чтобы выполнить экспорт шалонов, выполняем:

$ python3 grafana_dashboards.py --e --gurl GRAFANA_URL_HERE --gtoken GRAFANA_TOKEN_HERE

Можно указать другую директорию:

$ python3 grafana_dashboards.py --e --dir some_another_dir --gurl GRAFANA_URL_HERE --gtoken GRAFANA_TOKEN_HERE

Или, можно экспортировать не все шаблоны, а только выбранные, — например:

$ python3 grafana_dashboards.py --e --dir --dash some_dashboard --gurl GRAFANA_URL_HERE --gtoken GRAFANA_TOKEN_HERE

Для импортирования, служит другая команда:

$ python3 grafana_dashboards.py --i

-=== СПОСОБ 3 — Использование модуля для grafana===-

Для начала, потребуется python3 + pip3:

Установка pip/setuptools/wheel в Unix/Linux

Ставим нужный пакет:

$ pip3 install grafcli

Теперь создайте конфигурационный файл grafcli.conf. Пока это в вашем рабочем каталоге в порядке:

[grafcli]
editor = vim
verbose = off

[hosts]
$GRAFANA_URL = on

[$GRAFANA_URL]
type = api
url = https://$GRAFANA_URL:$PORT
ssl = on
user = admin
password = $GRAFANA_ADMIN_PASSWORD
#token = $GRAFANA_TOKEN

[resources]
data-dir = ~/.grafcli

Если вы используете token, то вам не нужно прописывать user/password. Чтобы проверить, действительно ли ваш файл конфигурации настроен корректно, попробуйте выполнить:

$ grafcli ls remote

Он должен показать URL-адрес Grafana, который вы прописали. Чтобы создать резервную копию всех дашбордов, используйте команду:

$ grafcli backup remote/$GRAFANA_URL/ backup.tgz

Восстановление из резервной копии также простое:

$ grafcli restore backup.tgz remote/$GRAFANA_URL/

Вот и все, статья «Экспорт дашбордов из grafana в Unix/Linux» завершена.

The post Экспорт дашбордов из grafana в Unix/Linux first appeared on linux-notes.org.]]>
https://linux-notes.org/e-ksport-dashbordov-iz-grafana-v-unix-linux/feed/ 4
Page_c76a3fcf https://linux-notes.org/pishem-upstart-skript/ https://linux-notes.org/pishem-upstart-skript/#respond Thu, 23 Nov 2017 19:32:11 +0000 http://linux-notes.org/?p=6719 Пишем Upstart скрипт Upstart — это система инициализации ОС, которая управляет запуском демонов в течение загрузки системы, их остановку, а также управляет ими во время работы системы. Основанная на событиях замена системы инициализации init в UNIX и Linux системах. Изначально разрабатывалась для дистрибутива Ubuntu, но предназначен для развертывания во всех дистрибутивах Linux в качестве альтернативной замены. Основные […]

The post Пишем Upstart скрипт first appeared on linux-notes.org.]]>

Пишем Upstart скрипт

Upstart — это система инициализации ОС, которая управляет запуском демонов в течение загрузки системы, их остановку, а также управляет ими во время работы системы. Основанная на событиях замена системы инициализации init в UNIX и Linux системах. Изначально разрабатывалась для дистрибутива Ubuntu, но предназначен для развертывания во всех дистрибутивах Linux в качестве альтернативной замены.

Основные характеристики

  • Задачи и службы запускаются и/или останавливаются через события;
  • События генерируются при запуске и остановке задач и сервисов;
  • События могут быть получены от любого другого процесса в системе;
  • Слыжбы могут быть возрождены, если они неожиданно кильнулись;
  • Наблюдение и возрождение демонов, которые отделены от их родительского процесса;
  • Связь с init демоном через D-Bus;
  • Пользовательские сервисы, которые пользователи могут запускать и останавливать сами.

И так, хотелось бы рассказать как можно запускать томкат. Но для начала, нужно узнать какой механизм инициализации используется:

# ps -s1| awk '{print $4}'| grep -Ev "CMD"

Т.к речь идет о Upstart, то и продолжим тему.

PS: Вот еще полезное чтиво:

Система инициализации в Unix/Linux

Система инициализации Systemd

Система инициализации SysVinit

Пишем systemd Unit файл

Инициализация — важнейшая процедура, лежащая в основе любой операционной системы на основе Unix/Linux для управления работой каждого скрипта и службы.

По сути, инициализация следует за этим процессом:

  • Загрузка сервера.
  • Запуск init процесса (обычно как PID 1).
  • Запуск предопределенного набора задач для запуска активируется последовательно.

Инициализация отвечает за то, чтобы сервер мог загрузиться и отключиться. В некоторых Unix/Linux дистрибутивах  используется стандартный процесс инициализации init/systemD/Upstart. В этой статье я расскажу о том, как использовать Upstart или Init.

Традиционная инициализация следует за линейным процессом: загрузка отдельных задач в предопределенную последовательность при загрузке системы. Это не так полезно, особенно в быстро меняющихся ситуациях. Чтобы понять, почему, представьте, например, вы изменили среду сервера, добавив дополнительное устройство хранения.

Процесс инициализации не может принимать во внимание внезапные изменения в среде, а это означает, что ваш облачный сервер должен быть повторно инициализирован, прежде чем он сможет распознать дополнительное хранилище. Обнаружение «на лету» — это то, что необходимо, хотя это не возможность классической процедуры инициализации.

Загрузка в линейную последовательность также требует времени, что особенно невыгодно в облачной среде, где быстрое развертывание имеет важное значение.

Вы также можете быть обеспокоены состоянием своих задач после загрузки системы. К сожалению, init связан с последовательностью только при загрузке или отключении питания.

Синхронные последовательности загрузки больше не желательны. На смену init-у, пришел Upstart — решение этих проблем с расширенными возможностями.

На основе событий в реальном времени вместо заданного списка задач в последовательности этот замещающий демон инициализации запускает и останавливает задачи и контролирует эти процессы во время работы системы — «полный охват» — лучший способ описать его.

Эта новая асинхронная обработка устраняет необходимость в жесткой последовательности загрузки. Обработка в режиме реального времени может быть беспорядочной для концептуализации, но Upstart может поддерживать самые сложные системы и держать все под контролем, используя структуру задач.

Jobs

В мире Upstart, jobs — это рабочие процессы, разделенные на задания (целью) и рабочие задания (которые могут выполняться в фоновом режиме). Существуют также абстрактные задания — процессы, которые выполняются всегда, до тех пор, пока пользователь не будет заблокирован административными привилегиями.

Events

Однако событиями являются сигналы или «вызовы», используемые для запуска определенного действия с заданием или другим событием. Общие формы событий относятся к мониторингу процесса: запуск (пред-запуск) и остановка (пред-остановка).

Emitting Events

Процесс трансляции события называется «испусканием» (emitting). Обычно это вызвано состоянием процесса или задания, хотя администратор также может выпустить событие вручную, выпустив «initctl emit <event>» команду.

Состояния Job и Events

Джобы (задания или job-ы) в системе находятся в каталоге /etc/init/, а задания пользователя находятся в собственном каталоге ~/.init/.

Пользовательские задания запускаются в собственной сессии пользователя, поэтому они также известны как сеансовые задания. Они не работают в общесистемном режиме и не входят в обозначение PID1.

Независимо от его типа, задание всегда определяется в файле конфигурации (.conf), где его имя файла должно представлять связанную службу или задачу.

У каждой из этих заданий есть цель — запустить или остановить. Между этими двумя целями находятся множество состояний задач, которые определяют текущие действия работы в отношении цели. Важными являются следующие состояния:

  • waiting: Начальное состояние процесса.
  • starting: Запуск джобы.
  • pre-start: Загрузка или пред-старт некоторых действий.
  • spawned: Начало скрипта.
  • post-start: После-запуск или действия после запуска задания.
  • running: Запущенная джоба.
  • pre-stop: Пред-остановка или действия который выполняються перед остановкой задания.
  • stopping: Остановка джобы.
  • killed: Прибиваение процесса. Остановка задания.
  • post-stop: После-остановка или действия после остановки джобы.

После post-start состояния, задание определяется как running (запущено). Он остается включенным до тех пор, пока не будет выполнена предварительная остановка, когда задание будет готово к остановке, тогда работа будет убита, а процедуры очистки после остановки выполнят свои действия( если они будут определены).

Вы можете просмотреть, как задание переходит между состояниями, установив приоритет системного журнала Upstart (расположенный в каталоге /var/ log/upstart/) для отладки с помощью этой команды:

# initctl log-priority debug

Помните, что состояния не являются событиями, а события не являются состояниями. Четыре события (starting, started, stopping и stopped) испускаются Upstart, но состояния задачи определяют переход между этапами жизненного цикла работы.

Примеры Upstart скриптов

Открываем (создаем) файл:

# vim /etc/init/testjob.conf

Для начала, прописываем следующие строки:

description "My first Upstart script"
author "Vitaliy Natarov"

Тем самым, я описал что это за скрипт (поле description) и прописал автора (поле — author). После чего, сейчас я пропишу следующую строку для того чтобы это задание выполнялось после того, как системные службы и процессы уже загружены (чтобы предотвратить конфликт):

start on runlevel [2345]

Возможно, вам интересно, что такое уровень запуска. По сути, это единственное значение, которое представляет текущую конфигурацию системы. [2345] относится ко всем состояниям конфигурации с общим доступом к Linux и сетям, что идеально подходит для базового тестового примера.

Идем дальше и прописываем следующей строчкой:

stop on shutdown

Это остановит созданную задачу при отключения питания (завершения работы) сервера.

Затем мы добавим код выполнения:

script
echo $$ > /var/run/testjob.pid
end script

Определим действия перед запуском:

pre-start script
    echo "[`date`] testjob Starting" >> /var/log/testjob.log
end script

Так же, определим пред-остановку:

pre-stop script
    rm /var/run/nodetest.pid
    echo "[`date`] testjob Stopping" >> /var/log/testjob.log
end script

Сохраните и закройте этот файл.

Вы можете убедиться, что это работает, вручную запустив задание, но давайте сначала проверим синтаксис файла конфигурации:

# init-checkconf /etc/init/testjob.conf

Если обнаружены какие-либо проблемы, эта команда укажет номер конкретную линию(ии) и проблему. Однако с тестовым заданием вы должны увидеть вывод следующим образом:

File /etc/init/testjob.conf: syntax ok

Эта команда может использоваться для управления заданиями Upstart и другими фоновыми службами, такими как веб-сервер.

Основной синтаксис команды:

# service <servicename> <control>

Где, <control> может быть:

  • restart — Перезапустит службу.
  • start — Запустит службу.
  • stop — Остановит службу.
  • status — Проверит состояние службы.

Давайте запустим написанный скрипт:

# service testjob start

Теперь проверьте файл testjob.log, выполнив следующую команду:

# cat /var/log/testjob.log

Я не буду больше заострять внимания т.к это уже не актуально и в большенстве случаев, уже используется systemD/init скрипты.

Вот и все, статья «Пишем Upstart скрипт» завершена.

The post Пишем Upstart скрипт first appeared on linux-notes.org.]]>
https://linux-notes.org/pishem-upstart-skript/feed/ 0
Page_c76a3fcf https://linux-notes.org/dobavlenie-rds-hostov-v-zabbix-c-ispol-zovaniem-boto3-python3/ https://linux-notes.org/dobavlenie-rds-hostov-v-zabbix-c-ispol-zovaniem-boto3-python3/#respond Fri, 13 Oct 2017 23:15:19 +0000 http://linux-notes.org/?p=13730 Добавление RDS хостов в zabbix c использованием boto3 + python3 На работе потребовалось добавлять RDS хосты (с различных учеток AWS) в заббикс. Руками делать, — это конечно нормальное явление, но я люблю оптимизацию и автоматизацию. И для этого готов был написать скрипт. Пал выбор на питон. Полезное чтиво: Установка Zabbix + nginx+php-fpm + mariaDB в […]

The post Добавление RDS хостов в zabbix c использованием boto3 + python3 first appeared on linux-notes.org.]]>

Добавление RDS хостов в zabbix c использованием boto3 + python3

На работе потребовалось добавлять RDS хосты (с различных учеток AWS) в заббикс. Руками делать, — это конечно нормальное явление, но я люблю оптимизацию и автоматизацию. И для этого готов был написать скрипт. Пал выбор на питон.

Полезное чтиво:

Установка Zabbix + nginx+php-fpm + mariaDB в Unix/Linux

Установка Zabbix-agent в Unix/Linux

Установка pip/setuptools/wheel в Unix/Linux

Автоматическое выключение хостов в zabbix

Автоматическое удаление хостов в zabbix

Открываем файл:

# vim Add_Hosts_from_AWS_RDS_to_Zabbix.py

Он выглядит следующим образом:

#!/bin/env python3
# -*- coding: utf-8 -*-
import requests
import sys
import boto3
import glob
import smtplib

from pyzabbix import ZabbixAPI, ZabbixAPIException
#


class bgcolors:
    def __init__(self):
        self.colors = {
            '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_creds_from_assum_role():
    auth_params = []

    # create an STS client object that represents a live connection to the
    # STS service

    #sts_client = boto3.setup_default_session(region_name='us-east-1')
    sts_client = boto3.client('sts', region_name='us-east-1')
    #
    Assum_Roles = ['arn:aws:iam::93388403184:role/CW-RDS-READ-ONLY'
        , 'arn:aws:iam::4131648289989:role/CLOUDWATCH-READONLY-ACCESS-CMSHARED'
        , 'arn:aws:iam::067785372661:role/CLOUDWATCH-READONLY-ACCESS-DEV'
        , 'arn:aws:iam::66803035257:role/CLOUDWATCH-READONLY-ACCESS-CMSHARED'
        , 'arn:aws:iam::505163668321:role/CLOUDWATCH-READONLY-ACCESS-ZABBIX'
        , 'arn:aws:iam::378494444851:role/CLOUDWATCH-READONLY-ACCESS-ZABBIX']

    # Call the assume_role method of the STSConnection object and pass the role
    # ARN and a role session name.

    for Assum_Role in Assum_Roles:
        assumedRoleObject = sts_client.assume_role(
            RoleArn=Assum_Role,
            RoleSessionName="ElastiCache"
        )

        # From the response that contains the assumed role, get the temporary
        # credentials that can be used to make subsequent API calls

        credentials = assumedRoleObject['Credentials']
        auth_param = {
            'access_key': credentials['AccessKeyId'],
            'secret_key': credentials['SecretAccessKey'],
            'session_token': credentials['SessionToken']
        }
        auth_params.append(auth_param)
    # print(auth_params)
    return auth_params


def get_rds_hosts_from_assum_role():
    hosts_from_rds = []
    # RDS
    Creds_Data = get_creds_from_assum_role()
    for get_greds_from_acc in Creds_Data:
        access_key = get_greds_from_acc['access_key']
        secret_key = get_greds_from_acc['secret_key']
        session_token = get_greds_from_acc['session_token']
        #
        rds_client = boto3.setup_default_session(region_name='us-east-1'
                                                 , aws_access_key_id=access_key
                                                 , aws_secret_access_key=secret_key
                                                 , aws_session_token=session_token)
        rds_client = boto3.client('rds'
                              , region_name='us-east-1'
                              , aws_access_key_id=access_key
                              , aws_secret_access_key=secret_key
                              , aws_session_token=session_token)
        try:
            # get all of the db instances
            rdses = rds_client.describe_db_instances()
            for rds in rdses['DBInstances']:
                hosts_from_rds.append(rds['Endpoint']['Address'])
        except Exception as error:
            print (error)
    # print(hosts_from_rds)
    return hosts_from_rds  # def get_elasticache_hosts_from_assum_role():


def login_to_zabbix():
    # host, login, password to connect to DEV zabbix-server
    Zabbix_Host = 'https://zabbix.com/'
    Zabbix_User = 'apiuser'
    Zabbix_Password = 'gkjhjhvjh5uigkjhg'
    # You can use the Connection_Timeout
    Connection_Timeout = 25
    # Verify SSL
    Verify_SSL = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(Zabbix_Host, 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)
    r = requests.get(Zabbix_Host, verify=Verify_SSL)
    #
    zapi.login(Zabbix_User, Zabbix_Password)
    zapi.session.auth = (Zabbix_User, Zabbix_Password)
    # You can re-define Connection_Timeout after
    zapi.timeout = Connection_Timeout
    return zapi


def add_group_to_zabbix(group):
    zapi = login_to_zabbix()
    zapi.hostgroup.create(name=group)
    return add_group_to_zabbix


def add_host_to_zabbix(host, group, template, port=666):
    zapi = login_to_zabbix()
    Get_Templates = zapi.template.get(search={"name": template})
    for template in Get_Templates:
        # print(template['templateid'])
        templateid = template['templateid']
    Get_Groups = zapi.hostgroup.get(search={"name": group})
    for group in Get_Groups:
        if len(host) > 64:
            print ('Host is more than 64 characters: ', host)
            sender = 'captain@localhost'
            receivers = 'vitalii_natarov@epam.com'
            message = ('Host is more than 64 characters: %s' % host)
            smtpObj = smtplib.SMTP('localhost')
            smtpObj.sendmail(sender, receivers, message)
        else:
            zapi.host.create({"host": host,
                              "interfaces": [{
                                "type": 1,
                                "main": 1,
                                "useip": 0,
                                "ip": "",
                                "dns": host,
                                "port": port,
                                }],
                              "groups": [{
                                "groupid": group['groupid'],
                                }],
                              "templates": [{
                                "templateid": templateid,
                                }],
                            })
    return add_host_to_zabbix

def add_template_to_zabbix():
    zapi = login_to_zabbix()
    rules = {
        'applications': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'discoveryRules': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'graphs': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'groups': {
            'createMissing': 'true'
        },
        'hosts': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'images': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'items': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'maps': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'screens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateLinkage': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templates': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateScreens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'triggers': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
    }
    path = 'Zabbix_Templates/Template_AWS_RDS.xml'
    files = glob.glob(path)
    for file in files:
        with open(file, 'r') as f:
            template = f.read()
            try:
                zapi.confimport('xml', template, rules)
            except ZabbixAPIException as e:
                print(e)
    return add_template_to_zabbix


def main():
    zapi = login_to_zabbix()
    Zabbix_Version = zapi.do_request('apiinfo.version')
    print(bgcolors().colors['OKGREEN'],"============================================================", bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'],'Zabbix Version:', Zabbix_Version['result'] + bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'],"============================================================", bgcolors().colors['ENDC'])
    # find needed group, template, host
    Needed_groups = ['AWS RDS']
    Needed_IPs = get_rds_hosts_from_assum_role()
    Needed_Templates = ['Template_AWS_RDS']
    Get_Templates = zapi.template.get(search={"name": Needed_Templates})
    for template in Get_Templates:
        Needed_Template = template['name']
    for Needed_group in Needed_groups:
        Get_Groups = zapi.hostgroup.get(search={"name": Needed_group})
        if (len(Get_Groups)) is not 0:
            # check host in provided group
            for Needed_IP in Needed_IPs:
                Get_Hosts = zapi.host.get(search={"name": Needed_IP})
                if (len(Get_Hosts)) is 0:
                    #for h in Get_Hosts:
                     add_host_to_zabbix(Needed_IP, Needed_group, Needed_Template)
                     print('Added ', Needed_IP, 'host to zabbix')
                else:
                    #pass
                    print ('The', Needed_IP, 'already exist')
        else:
            add_group_to_zabbix(Needed_group)
            print ('Added the', Needed_group, 'group to zabbix')
            # find needed template
            for Needed_Template in Needed_Templates:
                Get_Templates = zapi.hostgroup.get(filter={"name": Needed_Templates})
                if (len(Get_Templates)) is 0:
                    add_template_to_zabbix()
                    print('Added', Needed_Template, 'template to zabbix')
                else:
                    pass
            for Needed_IP in Needed_IPs:
                Get_Hosts = zapi.host.get(filter={"name": Needed_IP}, output=['hostid', 'host', 'name', 'status'])
                if (len(Get_Hosts)) is 0:
                    add_host_to_zabbix(Needed_IP, Needed_group, Needed_Template)
                    print('Added ', Needed_IP, 'host to zabbix')
                else:
                    pass
    print(bgcolors().colors['OKGREEN'], "============================================================", bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'], "==========================FINISHED==========================", bgcolors().colors['ENDC'])
    print(bgcolors().colors['OKGREEN'], "============================================================", bgcolors().colors['ENDC'])

if __name__ == '__main__':
    main()

В теле скрипта нужно изменить некоторые переменные. Я не буду рассказывать что нужно менять, думаю и так очевидно, если нет — то можете написать в комментариях и я помогу с этим.

Создаем темплейт:

# mkdir Zabbix_Templates

Открываем файл:

# vim Zabbix_Templates/Template_AWS_RDS.xml

И вставляем в него:

<?xml version="1.0" encoding="UTF-8"?>
<zabbix_export>
    <version>2.0</version>
    <date>2017-08-18T17:25:33Z</date>
    <groups>
        <group>
            <name>AWS RDS</name>
        </group>
        <group>
            <name>Templates</name>
        </group>
    </groups>
    <templates>
        <template>
            <template>Template_AWS_RDS</template>
            <name>Template_AWS_RDS</name>
            <description>AWS RDS monitoring</description>
            <groups>
                <group>
                    <name>AWS RDS</name>
                </group>
                <group>
                    <name>Templates</name>
                </group>
            </groups>
            <applications>
                <application>
                    <name>RDS</name>
                </application>
            </applications>
            <items>
                <item>
                    <name>RDS::BinLogDiskUsage</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.BinLogDiskUsage.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of disk space occupied by binary logs on the master. Applies to MySQL read replicas.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::CPUUtilization</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.CPUUtilization.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>%</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The percentage of CPU utilization.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::DatabaseConnections</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.DatabaseConnections.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The number of database connections in use.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::DiskQueueDepth</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.DiskQueueDepth.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units/>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The number of outstanding IOs (read/write requests) waiting to access the disk.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::FreeableMemory</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.FreeableMemory.Minimum</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of available random access memory.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::FreeStorageSpace</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.FreeStorageSpace.Minimum</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of available storage space.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::NetworkReceiveThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.NetworkReceiveThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The incoming (Receive) network traffic on the DB instance, including both customer database traffic and Amazon RDS traffic used for monitoring and replication.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::NetworkTransmitThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.NetworkTransmitThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The outgoing (Transmit) network traffic on the DB instance, including both customer database traffic and Amazon RDS traffic used for monitoring and replication.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReadIOPS</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReadIOPS.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>ops/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of disk I/O operations per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReadLatency</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReadLatency.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average amount of time taken per disk I/O operation.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReadThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReadThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of bytes read from disk per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::ReplicaLag</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.ReplicaLag.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of time a Read Replica DB Instance lags behind the source DB Instance. Applies to MySQL read replicas.&#13;
&#13;
The ReplicaLag metric reports the value of the Seconds_Behind_Master field of the MySQL SHOW SLAVE STATUS command.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::SwapUsage</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.SwapUsage.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The amount of swap space used on the DB Instance.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::WriteIOPS</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.WriteIOPS.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>ops/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of disk I/O operations per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::WriteLatency</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.WriteLatency.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average amount of time taken per disk I/O operation.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
                <item>
                    <name>RDS::WriteThroughput</name>
                    <type>2</type>
                    <snmp_community/>
                    <multiplier>0</multiplier>
                    <snmp_oid/>
                    <key>RDS.WriteThroughput.Average</key>
                    <delay>0</delay>
                    <history>15</history>
                    <trends>365</trends>
                    <status>0</status>
                    <value_type>0</value_type>
                    <allowed_hosts/>
                    <units>B/s</units>
                    <delta>0</delta>
                    <snmpv3_contextname/>
                    <snmpv3_securityname/>
                    <snmpv3_securitylevel>0</snmpv3_securitylevel>
                    <snmpv3_authprotocol>0</snmpv3_authprotocol>
                    <snmpv3_authpassphrase/>
                    <snmpv3_privprotocol>0</snmpv3_privprotocol>
                    <snmpv3_privpassphrase/>
                    <formula>1</formula>
                    <delay_flex/>
                    <params/>
                    <ipmi_sensor/>
                    <data_type>0</data_type>
                    <authtype>0</authtype>
                    <username/>
                    <password/>
                    <publickey/>
                    <privatekey/>
                    <port/>
                    <description>The average number of bytes written to disk per second.</description>
                    <inventory_link>0</inventory_link>
                    <applications>
                        <application>
                            <name>RDS</name>
                        </application>
                    </applications>
                    <valuemap/>
                    <logtimefmt/>
                </item>
            </items>
            <discovery_rules/>
            <macros>
                <macro>
                    <macro>{$TH_P2_FREE_STORAGE}</macro>
                    <value>1G</value>
                </macro>
                <macro>
                    <macro>{$TH_P2_LATENCY}</macro>
                    <value>0.2</value>
                </macro>
                <macro>
                    <macro>{$TH_P3_CPU_USAGE}</macro>
                    <value>90</value>
                </macro>
                <macro>
                    <macro>{$TH_P3_FREE_STORAGE}</macro>
                    <value>2G</value>
                </macro>
                <macro>
                    <macro>{$TH_P3_LATENCY}</macro>
                    <value>0.1</value>
                </macro>
                <macro>
                    <macro>{$TH_P4_CPU_USAGE}</macro>
                    <value>85</value>
                </macro>
            </macros>
            <templates/>
            <screens>
                <screen>
                    <name>RDS::Statistics</name>
                    <hsize>2</hsize>
                    <vsize>3</vsize>
                    <screen_items>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>0</x>
                            <y>0</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>2</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::DB Connections</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>1</x>
                            <y>0</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>1</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::Latency</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>0</x>
                            <y>1</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>2</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::Storage Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>1</x>
                            <y>1</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>1</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::System Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>0</x>
                            <y>2</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>2</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::Network Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                        <screen_item>
                            <resourcetype>0</resourcetype>
                            <width>500</width>
                            <height>100</height>
                            <x>1</x>
                            <y>2</y>
                            <colspan>1</colspan>
                            <rowspan>1</rowspan>
                            <elements>0</elements>
                            <valign>1</valign>
                            <halign>1</halign>
                            <style>0</style>
                            <url/>
                            <dynamic>0</dynamic>
                            <sort_triggers>0</sort_triggers>
                            <resource>
                                <name>RDS::IO Stats</name>
                                <host>Template_AWS_RDS</host>
                            </resource>
                            <max_columns>3</max_columns>
                            <application/>
                        </screen_item>
                    </screen_items>
                </screen>
            </screens>
        </template>
    </templates>
    <triggers>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.CPUUtilization.Average.min(#3)}&gt;{$TH_P4_CPU_USAGE} and {Template_AWS_RDS:RDS.CPUUtilization.Average.max(#3)}&lt;{$TH_P3_CPU_USAGE}</expression>
            <name>RDS::High CPU Usage (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>2</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.CPUUtilization.Average.min(#3)}&gt;{$TH_P3_CPU_USAGE}</expression>
            <name>RDS::High CPU Usage (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.ReadLatency.Average.last()}&gt;{$TH_P3_LATENCY} and {Template_AWS_RDS:RDS.ReadLatency.Average.last()}&lt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Read Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.ReadLatency.Average.last()}&gt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Read Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>4</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.WriteLatency.Average.last()}&gt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Write Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>4</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.WriteLatency.Average.last()}&gt;{$TH_P3_LATENCY} and {Template_AWS_RDS:RDS.WriteLatency.Average.last()}&lt;{$TH_P2_LATENCY}</expression>
            <name>RDS::High Write Latency (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.FreeStorageSpace.Minimum.last()}&lt;{$TH_P3_FREE_STORAGE} and {Template_AWS_RDS:RDS.FreeStorageSpace.Minimum.last()}&gt;{$TH_P2_FREE_STORAGE}</expression>
            <name>RDS::Low free storage space (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>3</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
        <trigger>
            <expression>{Template_AWS_RDS:RDS.FreeStorageSpace.Minimum.last()}&lt;{$TH_P2_FREE_STORAGE}</expression>
            <name>RDS::Low free storage space (LV={ITEM.VALUE})</name>
            <url/>
            <status>0</status>
            <priority>4</priority>
            <description/>
            <type>0</type>
            <dependencies/>
        </trigger>
    </triggers>
    <graphs>
        <graph>
            <name>RDS::DB Connections</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>00C800</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.DatabaseConnections.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::IO Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.ReadIOPS.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>DDDD00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.WriteIOPS.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <drawtype>0</drawtype>
                    <color>CC0000</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.DiskQueueDepth.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::Latency</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.ReadThroughput.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>DDDD00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.WriteThroughput.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <drawtype>0</drawtype>
                    <color>0000DD</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.ReadLatency.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>3</sortorder>
                    <drawtype>0</drawtype>
                    <color>DD0000</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.WriteLatency.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::Network Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>0000DD</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.NetworkReceiveThroughput.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.NetworkTransmitThroughput.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::Storage Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>0000DD</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.BinLogDiskUsage.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>00CC00</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.FreeStorageSpace.Minimum</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
        <graph>
            <name>RDS::System Stats</name>
            <width>800</width>
            <height>200</height>
            <yaxismin>0.0000</yaxismin>
            <yaxismax>100.0000</yaxismax>
            <show_work_period>1</show_work_period>
            <show_triggers>1</show_triggers>
            <type>0</type>
            <show_legend>1</show_legend>
            <show_3d>0</show_3d>
            <percent_left>0.0000</percent_left>
            <percent_right>0.0000</percent_right>
            <ymin_type_1>1</ymin_type_1>
            <ymax_type_1>0</ymax_type_1>
            <ymin_item_1>0</ymin_item_1>
            <ymax_item_1>0</ymax_item_1>
            <graph_items>
                <graph_item>
                    <sortorder>0</sortorder>
                    <drawtype>5</drawtype>
                    <color>0000EE</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.SwapUsage.Average</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>1</sortorder>
                    <drawtype>5</drawtype>
                    <color>00C800</color>
                    <yaxisside>1</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.FreeableMemory.Minimum</key>
                    </item>
                </graph_item>
                <graph_item>
                    <sortorder>2</sortorder>
                    <drawtype>2</drawtype>
                    <color>EE0000</color>
                    <yaxisside>0</yaxisside>
                    <calc_fnc>7</calc_fnc>
                    <type>0</type>
                    <item>
                        <host>Template_AWS_RDS</host>
                        <key>RDS.CPUUtilization.Average</key>
                    </item>
                </graph_item>
            </graph_items>
        </graph>
    </graphs>
</zabbix_export>

Запускаем скрипт:

# python3 Add_Hosts_from_AWS_RDS_to_Zabbix.py

PS: Не забываем ставить зависимости через pip3.

Вот и все, статья «Добавление RDS хостов в zabbix c использованием boto3 + python3» завершена.

The post Добавление RDS хостов в zabbix c использованием boto3 + python3 first appeared on linux-notes.org.]]>
https://linux-notes.org/dobavlenie-rds-hostov-v-zabbix-c-ispol-zovaniem-boto3-python3/feed/ 0
Page_c76a3fcf https://linux-notes.org/importirovanie-zabbix-templates/ https://linux-notes.org/importirovanie-zabbix-templates/#respond Tue, 26 Sep 2017 23:07:51 +0000 http://linux-notes.org/?p=13831 Импортирование zabbix templates Люблю оптимизировать рабочий процесс и данная тема — еще одно подтверждение моих слов. Я описывал процесс экспортирования заббикс шаблонов в своей статье: Экспортирование zabbix templates И сейчас я расскажу как я реализовал обратное действие — импортирование заббикс темплейтов. Мне пришлось немного потратить времени, чтобы написать данную реализацию. Мой скрипт: # vim zabbix_templates.py Он […]

The post Импортирование zabbix templates first appeared on linux-notes.org.]]>

Импортирование zabbix templates

Люблю оптимизировать рабочий процесс и данная тема — еще одно подтверждение моих слов.

Я описывал процесс экспортирования заббикс шаблонов в своей статье:

Экспортирование zabbix templates

И сейчас я расскажу как я реализовал обратное действие — импортирование заббикс темплейтов.

Мне пришлось немного потратить времени, чтобы написать данную реализацию.

Мой скрипт:

# vim zabbix_templates.py

Он выглядит следующим образом:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import os
import xml.dom.minidom
import argparse
import gitlab
import glob
import sys

from datetime import datetime
from pyzabbix import ZabbixAPI, ZabbixAPIException
# from setuptools import setup, find_packages
from sys import exit


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 login_to_zabbix(z_host, z_user, z_password):
    # You can use the connection__timeout
    connection__timeout = 45
    # Verify SSL
    verify__ssl = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(z_host, 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(z_user, z_password)
    zapi.session.auth = (z_user, z_password)
    # You can re-define connection__timeout after
    zapi.timeout = connection__timeout
    return zapi


def get_template(z_host, z_user, z_password, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__template = zapi.template.get(filter={"name": template}, output=['templateid', 'name'])
    return get__template


def export_template(z_host, z_user, z_password, dir_path, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get_template_name = get_template(template)
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    template_id = get_template_name[0]['templateid']
    template_name = get_template_name[0]['name']
    rules = {
        "options": {
            "templates": [template_id]
        },
        "format": "xml"
    }
    template_name_out = dir_path + '/' + template_name + '.xml'
    result = zapi.do_request('configuration.export', rules)
    template = xml.dom.minidom.parseString(result['result'].encode('utf-8'))
    date = template.getElementsByTagName("date")[0]
    # We are backing these up to git, steralize date so it doesn't appear to change
    # each time we export the templates
    date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
    try:
        f = open(template_name_out, 'wb')
        f.write(template.toprettyxml().encode('utf-8'))
        f.close()
        print (template_name + '.xml', 'file has been created')
    except ValueError:
        print ('I cant write to file: ', ValueError)

    return export_template


def get_templates(z_host, z_user, z_password):
    templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__templates = zapi.template.get(output=['templateid', 'name'])
    for template in get__templates:
        templates.append(template)
    return templates


def export_templates(z_host, z_user, z_password, dir_path):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    templates = get_templates(z_host, z_user, z_password)

    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    for template in templates:
        template_id = template['templateid']
        template_name = template['name']

        template_name_out = dir_path + '/' + template_name + '.xml'
        result = zapi.configuration.export(
            options={"templates": [template_id]},
            format='xml'
        )
        template = xml.dom.minidom.parseString(result.encode('utf-8'))
        date = template.getElementsByTagName("date")[0]
        # We are backing these up to git, steralize date so it doesn't appear to change
        # each time we export the templates
        date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
        try:
            f = open(template_name_out, 'wb')
            f.write(template.toprettyxml().encode('utf-8'))
            f.close()
            print (template_name + '.xml', 'file has been created')
        except ValueError:
            print('I cant write to file')

    return export_templates


def import_templates(z_host, z_user, z_password, dir_path, templates):
    global files
    zapi = login_to_zabbix(z_host, z_user, z_password)

    rules = {
        'applications': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'discoveryRules': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'graphs': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'groups': {
            'createMissing': 'true'
        },
        'hosts': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'images': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'items': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'maps': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'screens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateLinkage': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templates': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateScreens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'triggers': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
    }
    if templates == 'all':
        files = glob.glob(dir_path + "/" + "*.xml")
    else:
        for template in templates:
            files = glob.glob(str(dir_path) + "/" + str(template) + ".xml")
    for f in files:
        with open(f, 'r') as file:
            template = file.read()
            try:
                zapi.confimport('xml', template, rules)
            except ZabbixAPIException as e:
                print(e)
    return import_templates


def export_groups(z_host, z_user, z_password):
    file_out = 'exported_groups.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__groups = zapi.hostgroup.get(output=['groupid', 'name'])
    try:
        for group in get__groups:
            f = open(file_out, 'a')
            f.write(str(group['name'] + '\n'))
            f.close()
        print("All groups has been exported to %s!" % file_out)
    except ValueError:
        print('I cant write to file')

    return export_groups


def export_autodiscovery_rules(z_host, z_user, z_password):
    file_out = 'exported_autodiscovery_rules.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__actions = zapi.action.get(selectOperations='extend', selectFilter='extend', filter={"eventsource": 2})
    try:
        for action in get__actions:
            print (action)
            # f = open(file_out, 'a')
            # f.write(json.loads(action))
            # f.close()
        # print("All autodiscovery rules has been exported to %s!" % file_out)
    except TypeError:
        print('I cant write to file')

    return export_autodiscovery_rules


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('--t', '--template', nargs='+', dest='template', help='Indicate a template(s)', default='all')
    parser.add_argument('--d', '--dir', dest='templates_dir', help='Indicate a folder for template(s)',
                        default='exported_templates', metavar='folder')
    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('--i', dest='imports', help='Import function', action='store_true')
    group.add_argument('--import', dest='imports', help='Import function', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--e', dest='exports', help='Export function', action='store_true', default=argparse.SUPPRESS)
    group2.add_argument('--export', dest='exports', help='Export function', action='store_true')

    results = parser.parse_args()
    template = results.template
    templates_dir = results.templates_dir

    # 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):
        zapi = login_to_zabbix(zabbix__host, zabbix__user, zabbix__password)
        zabbix__version = zapi.do_request('apiinfo.version')
        print(
            Bgcolors().get['OKGREEN'], "============================================================",
            Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            'Zabbix Version:',
            zabbix__version['result'] + Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            "============================================================",
            Bgcolors().get['ENDC'])
        if results.exports:
            print ('EXPORT function!')
            if template == 'all':
                export_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir)
            else:
                export_template(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
            export_groups(zabbix__host, zabbix__user, zabbix__password)
            #export_autodiscovery_rules(zabbix__host, zabbix__user, zabbix__password)
        elif results.imports:
            print('IMPORT function')
            import_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
        else:
            print('Please add [--e] for export or [--i] for import')
            print('For help, use: script_name.py -h')
            exit(0)
    else:
        print('Please add [--zabbix-host] or [--zabbix-user] or [--zabbix-password]')
        print('For help, use: script_name.py -h')
        exit(0)

    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()

На мой взгляд, получилось не плохая реализация.

Для использования, введите:

# python3 zabbix_templates.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
  --t TEMPLATE [TEMPLATE ...], --template TEMPLATE [TEMPLATE ...]
                        Indicate a template(s)
  --d folder, --dir folder
                        Indicate a folder for template(s)
  --i                   Import function
  --import              Import function
  --e                   Export function
  --export              Export function

created by Vitalii Natarov

Т.е, чтобы заэкспортировать все щаблоны, используйте:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --e

PS: Так же, можно указать папку, в которую будет складыватся шаблоны:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --d some_folder

Если не нужно экспортировать все шаблоны, а есть необходимость в одном, можно использовать:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --d some_folder --t "some_template"

Для импорта, аналогичные действия:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://ui-zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --i

Или:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --i --d some_folder

Или:

$ python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsdsfdsfs" --i --d some_folder --t "some_template"

Он полностью готовый, только нужно вписать URL, USER, PASSWORD для заббикса.

А на этом, я завершаю свою статью «Импортирование zabbix templates».

The post Импортирование zabbix templates first appeared on linux-notes.org.]]>
https://linux-notes.org/importirovanie-zabbix-templates/feed/ 0
Page_c76a3fcf https://linux-notes.org/e-ksportirovanie-zabbix-templates/ https://linux-notes.org/e-ksportirovanie-zabbix-templates/#respond Wed, 30 Aug 2017 20:44:41 +0000 http://linux-notes.org/?p=13749 Экспортирование zabbix templates В последнее время, я начал плотно изучать python и zabbix API для автоматизации различных процессов. Последнее что пришло на ум — это выполнить экспорт всех zabbix шаблонов. Для этой цели, я создал скрипт: # cat Export_Templates_from_Zabbix.py Который имеет следующее содержание: #!/usr/bin/env python3 # -*- coding: utf-8 -*- import requests import time import os […]

The post Экспортирование zabbix templates first appeared on linux-notes.org.]]>

Экспортирование zabbix templates

В последнее время, я начал плотно изучать python и zabbix API для автоматизации различных процессов. Последнее что пришло на ум — это выполнить экспорт всех zabbix шаблонов.

Для этой цели, я создал скрипт:

# cat Export_Templates_from_Zabbix.py

Который имеет следующее содержание:

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import requests
import time
import os
import xml.dom.minidom
import argparse
import gitlab
import glob
import sys

from datetime import datetime
from pyzabbix import ZabbixAPI, ZabbixAPIException
# from setuptools import setup, find_packages
from sys import exit


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 login_to_zabbix(z_host, z_user, z_password):
    # You can use the connection__timeout
    connection__timeout = 45
    # Verify SSL
    verify__ssl = False
    # Connect to zabbix-server
    zapi = ZabbixAPI(z_host, 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(z_user, z_password)
    zapi.session.auth = (z_user, z_password)
    # You can re-define connection__timeout after
    zapi.timeout = connection__timeout
    return zapi


def get_template(z_host, z_user, z_password, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__template = zapi.template.get(filter={"name": template}, output=['templateid', 'name'])
    return get__template


def export_template(z_host, z_user, z_password, dir_path, template):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get_template_name = get_template(template)
    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    template_id = get_template_name[0]['templateid']
    template_name = get_template_name[0]['name']
    rules = {
        "options": {
            "templates": [template_id]
        },
        "format": "xml"
    }
    template_name_out = dir_path + '/' + template_name + '.xml'
    result = zapi.do_request('configuration.export', rules)
    template = xml.dom.minidom.parseString(result['result'].encode('utf-8'))
    date = template.getElementsByTagName("date")[0]
    # We are backing these up to git, steralize date so it doesn't appear to change
    # each time we export the templates
    date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
    try:
        f = open(template_name_out, 'wb')
        f.write(template.toprettyxml().encode('utf-8'))
        f.close()
        print (template_name + '.xml', 'file has been created')
    except ValueError:
        print ('I cant write to file: ', ValueError)

    return export_template


def get_templates(z_host, z_user, z_password):
    templates = []
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__templates = zapi.template.get(output=['templateid', 'name'])
    for template in get__templates:
        templates.append(template)
    return templates


def export_templates(z_host, z_user, z_password, dir_path):
    zapi = login_to_zabbix(z_host, z_user, z_password)
    templates = get_templates(z_host, z_user, z_password)

    if not os.path.exists(dir_path):
        os.makedirs(dir_path)
    for template in templates:
        template_id = template['templateid']
        template_name = template['name']

        template_name_out = dir_path + '/' + template_name + '.xml'
        result = zapi.configuration.export(
            options={"templates": [template_id]},
            format='xml'
        )
        template = xml.dom.minidom.parseString(result.encode('utf-8'))
        date = template.getElementsByTagName("date")[0]
        # We are backing these up to git, steralize date so it doesn't appear to change
        # each time we export the templates
        date.firstChild.replaceWholeText('1970-01-01T01:01:01Z')
        try:
            f = open(template_name_out, 'wb')
            f.write(template.toprettyxml().encode('utf-8'))
            f.close()
            print (template_name + '.xml', 'file has been created')
        except ValueError:
            print('I cant write to file')

    return export_templates


def import_templates(z_host, z_user, z_password, dir_path, templates):
    global files
    zapi = login_to_zabbix(z_host, z_user, z_password)

    rules = {
        'applications': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'discoveryRules': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'graphs': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'groups': {
            'createMissing': 'true'
        },
        'hosts': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'images': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'items': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'maps': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'screens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateLinkage': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templates': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'templateScreens': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
        'triggers': {
            'createMissing': 'true',
            'updateExisting': 'true'
        },
    }
    if templates == 'all':
        files = glob.glob(dir_path + "/" + "*.xml")
    else:
        for template in templates:
            files = glob.glob(str(dir_path) + "/" + str(template) + ".xml")
    for f in files:
        with open(f, 'r') as file:
            template = file.read()
            try:
                zapi.confimport('xml', template, rules)
            except ZabbixAPIException as e:
                print(e)
    return import_templates


def export_groups(z_host, z_user, z_password):
    file_out = 'exported_groups.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__groups = zapi.hostgroup.get(output=['groupid', 'name'])
    try:
        for group in get__groups:
            f = open(file_out, 'a')
            f.write(str(group['name'] + '\n'))
            f.close()
        print("All groups has been exported to %s!" % file_out)
    except ValueError:
        print('I cant write to file')

    return export_groups


def export_autodiscovery_rules(z_host, z_user, z_password):
    file_out = 'exported_autodiscovery_rules.txt'
    if os.path.isfile(file_out):
        os.remove(file_out)
    zapi = login_to_zabbix(z_host, z_user, z_password)
    get__actions = zapi.action.get(selectOperations='extend', selectFilter='extend', filter={"eventsource": 2})
    try:
        for action in get__actions:
            print (action)
            # f = open(file_out, 'a')
            # f.write(json.loads(action))
            # f.close()
        # print("All autodiscovery rules has been exported to %s!" % file_out)
    except TypeError:
        print('I cant write to file')

    return export_autodiscovery_rules


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('--t', '--template', nargs='+', dest='template', help='Indicate a template(s)', default='all')
    parser.add_argument('--d', '--dir', dest='templates_dir', help='Indicate a folder for template(s)',
                        default='exported_templates', metavar='folder')
    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('--i', dest='imports', help='Import function', action='store_true')
    group.add_argument('--import', dest='imports', help='Import function', action='store_true')

    group2 = parser.add_mutually_exclusive_group(required=False)
    group2.add_argument('--e', dest='exports', help='Export function', action='store_true', default=argparse.SUPPRESS)
    group2.add_argument('--export', dest='exports', help='Export function', action='store_true')

    results = parser.parse_args()
    template = results.template
    templates_dir = results.templates_dir

    # 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):
        zapi = login_to_zabbix(zabbix__host, zabbix__user, zabbix__password)
        zabbix__version = zapi.do_request('apiinfo.version')
        print(
            Bgcolors().get['OKGREEN'], "============================================================",
            Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            'Zabbix Version:',
            zabbix__version['result'] + Bgcolors().get['ENDC'])
        print(
            Bgcolors().get['OKGREEN'],
            "============================================================",
            Bgcolors().get['ENDC'])
        if results.exports:
            print ('EXPORT function!')
            if template == 'all':
                export_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir)
            else:
                export_template(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
            export_groups(zabbix__host, zabbix__user, zabbix__password)
            #export_autodiscovery_rules(zabbix__host, zabbix__user, zabbix__password)
        elif results.imports:
            print('IMPORT function')
            import_templates(zabbix__host, zabbix__user, zabbix__password, templates_dir, template)
        else:
            print('Please add [--e] for export or [--i] for import')
            print('For help, use: script_name.py -h')
            exit(0)
    else:
        print('Please add [--zabbix-host] or [--zabbix-user] or [--zabbix-password]')
        print('For help, use: script_name.py -h')
        exit(0)

    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()

Запускаем:

# python3 Export_Templates_from_Zabbix.py --zabbix-host "https://zabbix.local" --zabbix-user "cleanup_apiuser" --zabbix-password "fdsfsdff" --dir exported_zabbix_templates_PROD_OLD --e

Вывод получим:

 ============================================================
 Zabbix Version: 2.4.8
 ============================================================
Template OS Linux.xml file has been created
Template App Zabbix Server.xml file has been created
Template App Zabbix Proxy.xml file has been created
Template App Zabbix Agent.xml file has been created
Template SNMP Interfaces.xml file has been created
Template SNMP Generic.xml file has been created
Template SNMP Device.xml file has been created
Template SNMP OS Windows.xml file has been created
Template SNMP Disks.xml file has been created
Template SNMP OS Linux.xml file has been created
Template SNMP Processors.xml file has been created
Template IPMI Intel SR1530.xml file has been created
Template IPMI Intel SR1630.xml file has been created
Template App MySQL.xml file has been created
Template OS OpenBSD.xml file has been created
Template OS FreeBSD.xml file has been created
Template OS AIX.xml file has been created
Template OS HP-UX.xml file has been created
Template OS Solaris.xml file has been created
Template OS Mac OS X.xml file has been created
Template OS Windows.xml file has been created
Template JMX Generic.xml file has been created
Template JMX Tomcat.xml file has been created
Template Virt VMware.xml file has been created
Template Virt VMware Guest.xml file has been created
Template Virt VMware Hypervisor.xml file has been created
Template App FTP Service.xml file has been created
Template App HTTP Service.xml file has been created
Template App HTTPS Service.xml file has been created
Template App IMAP Service.xml file has been created
Template App LDAP Service.xml file has been created
Template App NNTP Service.xml file has been created
Template App NTP Service.xml file has been created
Template App POP Service.xml file has been created
Template App SMTP Service.xml file has been created
Template App SSH Service.xml file has been created
Template_role_App_Puppet.xml file has been created
Template_AWS_RDS.xml file has been created
--- 223.18 seconds ---
 ============================================================
 ==========================FINISHED==========================
 ============================================================

PS: Данный скрипт поддерживает и импорт дашбордов. Но кое-что в нем все еще чтоит оптимизировать!

Для поддержки, можно выполнить:

$ python3 Export_Templates_from_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
  --t TEMPLATE [TEMPLATE ...], --template TEMPLATE [TEMPLATE ...]
                        Indicate a template(s)
  --d folder, --dir folder
                        Indicate a folder for template(s)
  --zabbix-host ZABBIX_HOST
                        Zabbix host
  --zabbix-user ZABBIX_USER
                        Zabbix user
  --zabbix-password ZABBIX_PASSWORD
                        Zabbix password of user
  --i                   Import function
  --import              Import function
  --e                   Export function
  --export              Export function

created by Vitalii Natarov

Такой скрипт, можно закинуть в crontab, чтобы выполнялся бэкап автоматически. У меня появилась идея  — это в указанную папку, установить GIT, который будет коммитить (версионировать) ваши шаблоны в определенную, созданную ветку. При необходимости, можно будет смерджить в мастер (как вариант). Это даст возможность откатить все изменения до нужного состояния.

На этом у меня все, статья «Экспортирование zabbix templates» завершена.

The post Экспортирование zabbix templates first appeared on linux-notes.org.]]>
https://linux-notes.org/e-ksportirovanie-zabbix-templates/feed/ 0