Zabbix 4.0 API 實踐,主機/主機群組 批量新增模板和刪除模板

自由早晚亂餘生發表於2020-07-12

場景

我們日常在管理Zabbix 的時候,經常會需要批量新增模板和批量刪除模板,Zabbix頁面是提供的批量連結的功能,但是它連結的也只是當前頁的主機,我們想擴充套件這個功能,在連結的時候,可以批量連結整個主機群組,也可以指定連結某臺主機,也可以指定連結包含某個字元的多個主機。

提供的功能

查詢模板id

select_template(self, template_name)

查詢主機群組id

select_group(self, group_name)  

查詢指定主機id

select_host(self, hostname='', groupid=''):
  • 當需要查詢所有的主機id時

    online_zabbix.select_host()
    
  • 當需要查詢指定主機名稱id時

    online_zabbix.select_host(name)
    
  • 當需要查詢指定主機群組的指定主機名稱id時

    online_zabbix.select_host(name,groupid)
    
    hostslist = online_zabbix.select_host('biz')
    print(hostslist)
    

主機連結模板

hosts_add_template(self, template_name, hostname, group_name='')  
  • 當我們想所有的主機連結某個模板,寫法 為
    online_zabbix.hosts_add_template('Linux', '')
    
  • 當我們想包含 特定的主機名或者特定的主機關鍵字的主機連結某個模板 寫法為:
    online_zabbix.hosts_add_template('Linux', 'biz') 
    
  • 當我們想特定的主機群組 包含 特定的主機名或者特定的主機關鍵字的主機連結某個模板 寫法為:
    online_zabbix.hosts_add_template('Linux', 'biz','test') 
    

示例:

online_zabbix.hosts_add_template('Linux', 'biz',' test')

主機刪除模板

用法同上

hosts_delete_template(self, template_name, hostname, group_name='')
online_zabbix.hosts_delete_template('Linux', 'biz', 'test')

查詢指定業務的接入心跳服務(特定場景無需關注)

online_zabbix.statistics_service('djx', 'Heart Monitor',)

查詢所有業務接入心跳服務(特定場景無需關注)

online_zabbix.statistics_total()

指令碼

基於python3 , 需要安裝 requests 模組

#!/usr/bin/env   python3
# -*- coding: utf-8 -*-
# @Time    :  2020/7/1 15:04
# @Author  : dongjiaxiao
# @Email   : 
# @File    : hosts_template.py
# @Desc    :

import requests
import json


class ZabbixApi:
    def __init__(self, url,username,password):
        self.url = url
        self.headers = {
            'User-Agent': 'python/3.6',
            'Content-Type': 'application/json'
        }
        self.authdata = {
            "jsonrpc": "2.0",
            "method": "user.login",
            "params":
                {"user": username, "password": password},
            "id": 1666,
        }
        self.token = self.get_token()

    def post_request(self, data):
        """
        發起請求和獲取響應內容
        :param data: body 資料
        :return:
        """
        result = {'code': 0, 'data': '', 'msg': ''}
        postdata = json.dumps(data)
        try:
            response = requests.post(self.url, headers=self.headers, data=postdata, timeout=30)
            if response.status_code == 200:
                res = response.json()
                if res.get('result') != None:  # 當 [] 也表示執行成功
                    result['code'] = 1
                    result['data'] = res.get('result')
                else:
                    result['msg'] = res
            else:
                result['msg'] = response.text + "status_code:" + str(response.status_code)
        except Exception as e:
            result['msg'] = e
            print("error{}".format(e))
        return result

    def get_token(self):
        """
        獲取Token
        :return: token 值
        """
        token = None
        res = self.post_request(self.authdata)
        if res.get('code') and res.get('data'):
            token = res.get('data')
        else:
            print(res.get('msg'))
        return token

    def select_group(self, group_name):
        """
        尋找主機群組id
        :param groupname:  主機群組名
        :return group_ids:   主機群組id 列表
        """
        group_ids = []
        post_data = {
            "jsonrpc": "2.0",
            "method": "hostgroup.get",
            "params": {
                "output": ["hostid"],
                "search": {
                    "name": group_name
                }
            },
            "auth": self.token,
            "id": 1666
        }
        group_data = self.post_request(post_data)
        if group_data.get('code') and group_data.get('data'):
            for data in group_data.get('data'):
                group_ids.append(data.get('groupid'))
        return group_ids

    def select_host(self, hostname='', groupid=''):
        """
        通過主機群組id或者主機名 查詢主機id
        :param hostname: 主機名
        :param groupid: 主機群組id
        :return: 主機列表
        """
        host_info = None
        if groupid:  # 當不傳入主機群組id 進入直接查詢指定主機
            post_data = {
                "jsonrpc": "2.0",
                "method": "host.get",
                "params": {
                    "output": ["hostid"],
                    "groupids": groupid,
                    "search": {
                        "name": hostname
                    }
                },
                "auth": self.token,
                "id": 1666
            }
        else:
            post_data = {
                "jsonrpc": "2.0",
                "method": "host.get",
                "params": {
                    "output": ["hostid"],
                    "search": {
                        "name": hostname
                    }
                },
                "auth": self.token,
                "id": 1666
            }
        host_data = self.post_request(post_data)
        if host_data.get('code') and host_data.get('data'):
            host_info = host_data['data']
        return host_info

    def select_template(self, template_name):
        """
        通過模板名稱獲取模板id
        :param template_name:
        :return: 模板id資訊
        """
        template_info = None
        post_data = {
            "jsonrpc": "2.0",
            "method": "template.get",
            "params": {
                "output": ["templateid"],
                "search": {
                    "name": template_name
                }
            },
            "auth": self.token,
            "id": 1666
        }
        template_data = self.post_request(post_data)
        if template_data.get('code') and template_data.get('data'):
            template_info = template_data['data']
        return template_info

    def hosts_add_template(self, template_name, hostname, group_name=''):
        """
        主機群組的指定主機名 新增模板
        :param group_name: 主機群組(支援不輸入)
        :param template_name: 模板名
        :param hostname:  主機名(關鍵詞)
        :return:
        """
        result = {'code': 0, 'msg': ''}
        if group_name:
            hostlist = self.select_host(hostname, groupid=self.select_group(group_name))
        else:
            hostlist = self.select_host(hostname)
        templatelist = self.select_template(template_name)
        if hostlist and templatelist:
            post_data = {
                "jsonrpc": "2.0",
                "method": "template.massadd",
                "params": {
                    "templates": templatelist,
                    "hosts": hostlist,
                },
                "auth": self.token,
                "id": 1666
            }
            add_data = self.post_request(post_data)
            if add_data.get('code') and add_data.get('data').get('templateids') == templatelist:
                result['code'] = 1
            else:
                # 列印日誌,新增失敗
                result['msg'] = add_data
        else:
            result['msg'] = "未找到主機/主機群組"
        return result

    def hosts_delete_template(self, template_name, hostname, group_name=''):
        """
        主機刪除模板
        :param template_name: 模板名稱
        :param hostname:  主機名(關鍵詞)
        :param group_name: 可選,指定主機群組
        :return:
        """
        result = {'code': 0, 'msg': ''}
        hostdata = self.select_host(hostname, groupid=self.select_group(group_name))
        hostlist = list(map(lambda x: x['hostid'], hostdata))
        templatedata = self.select_template(template_name)
        templatelist = list(map(lambda x: x['templateid'], templatedata))
        if hostlist and templatelist:
            post_data = {
                "jsonrpc": "2.0",
                "method": "host.massremove",
                "params": {
                    "templateids_clear": templatelist,
                    "hostids": hostlist,
                },
                "auth": self.token,
                "id": 1666
            }
            add_data = self.post_request(post_data)
            if add_data.get('code') and add_data.get('data').get('hostids') == hostlist:
                result['code'] = 1
            else:
                # 列印日誌,新增失敗
                result['msg'] = add_data
        else:
            result['msg'] = "未找到主機/主機群組"
        return result

    def select_items(self, group_name, itemname, hostname=''):
        """
        查詢指定主機和模板的監控項
        :param group_name: 主機群組名稱
        :param itemname: 監控項關鍵詞
        :param hostname:  主機名稱
        :return:
        """
        result = {'code': 0, 'data': '', 'msg': ''}
        hostdata = self.select_host(hostname, groupid=self.select_group(group_name))
        hostlist = list(map(lambda x: x['hostid'], hostdata))
        if hostlist :
            post_data = {
                    "jsonrpc": "2.0",
                    "method": "item.get",
                    "params": {
                        "output": ["key_"],
                        "hostids": hostlist,
                        "search": {
                            "name": itemname
                        }
                    },
                    "auth": self.token,
                    "id": 1666
                }
            item_data = self.post_request(post_data)
            if item_data.get('code') and item_data.get('data'):
                result['code'] = 1
                result['data'] = list(map(lambda x: x['key_'].split('[')[1].split(']')[0], item_data['data']))
            else:
                # 列印日誌,新增失敗
                result['msg'] = item_data
        else:
            result['msg'] = "未找到主機/主機群組"
        return result

    def statistics_service(self, group_name, itemname, hostname=''):
        """
        統計心跳服務新增的應用和業務線
        :param group_name: 主機群組
        :param itemname: 對應的監控項
        :param hostname: 對應的主機名/主機名關鍵字。
        :return:
        """
        res = self.select_items(group_name, itemname, hostname)
        if res.get('code'):
            app_list = set(res.get('data'))  # 列表轉元組
            service_list = set(map(lambda x: '-'.join(x.replace('tomcat-', '').split('-')[0:-1]), app_list))
            project_list = set(map(lambda x: x.split('-')[0], service_list))
            print("{} 業務線新增了心跳檢測: {} 應用:{}, {} 服務:{}".format(project_list, len(service_list), service_list,len(app_list), app_list))
        else:
            print(res.get('msg'))

    def statistics_total(self,projects):
        """
        統計所有的心跳服務和應用和業務線
        :return:
        """
        projects = projects
        itemname = 'Heart Monitor'
        for project in projects:
            self.statistics_service(project, itemname,)



online_zabbix = ZabbixApi(url='https://zabbix/api_jsonrpc.php',Admin,zabbix) 

相關文章