一个简陋的批量操作zabbix监控项页面



个人博客地址

http://www.darkghost.life

继上篇zabbix-api,决定简单写一个页面来完成zabbix-api的批量操作

使用django完成

目录如下

一个简陋的批量操作zabbix监控项页面

这个简陋的页面长这样,登录

一个简陋的批量操作zabbix监控项页面

长这样,主页,展示groups

一个简陋的批量操作zabbix监控项页面

长这样,展示groups中的所有agent类host

一个简陋的批量操作zabbix监控项页面

长这样,展示host中筛选过的items

一个简陋的批量操作zabbix监控项页面

最后添加items页面长这样,可以多选key,批量添加

一个简陋的批量操作zabbix监控项页面

代码部分

自己日常工作用,页面不重要,重要的是功能,因为写页面太tm耗时了

下面贴下代码

urls.py

from django.contrib import admin
from django.urls import path
from DarkZabbix import views

urlpatterns = [
    path('admin/', admin.site.urls),
    path('', views.zabbix),
    path('login.html/', views.login),
    path('zabbix.html/', views.zabbix),
    path('zabbix_host.html/', views.zabbix_host),
    path('zabbix_items.html/', views.zabbix_items),
    path('additems.html/', views.add_items),
    path('keylist.html/', views.key_list),
    path('delitem.html/', views.del_items),
]

templates里只用两个html页面,一个用于登录,一个用于展示和操作

login.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>登录title>
    <style>
        .input{width: 300px; height: 20px;margin-top: 10px;}
    style>
head>
<body style="background-color: royalblue;">

<div style="position: absolute;top: 50%;left: 50%;transform: translate(-50%,-50%);">

    <form action="/login.html/" method="POST">
        {% csrf_token %}
        <h1 style="text-align: center; color: seashell;">Dark-zabbixh1>
        <input class="input" name="username" type="text" placeholder=username>
        <br>
        <input class="input" name="passwd" type="password" placeholder=passwd>
        <br>
        <button style="width: 300px;height: 30px; margin-top: 10px;" >登录button>
        <span>{{error}}span>
    form>
div>
body>

html>

zabbix.html

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>indextitle>
    <link href="/static/index.css" rel='stylesheet' type="text/css">
    <script src="/static/jquery-3.6.0.js">script>
    <script src="/static/jquery.cookie.js">script>
    <script src="/static/index.js">script>
head>
<body>
    {% csrf_token %}
    <div class="hidden block">div>
    <div class="top">
        <div class="top-left">
           DarkZabbix
        div>
        <div class="top-right">
            <div>用户:{{request.user}}div>
        div>
    div>
    <div class="left">
        {%for hostgroup in groupli%}
        <a class="leftmenu astyle" id={{hostgroup.groupid}} href="#">{{hostgroup.name}}a>
        {%endfor%}
    div>
    <div class="right">
    div>
body>
html>

statics里放登录用的证书和jquery文件,还有自定义的js css文件

index.js 里存放页面操作函数

token = $.cookie('csrftoken')
$(function(){
    hostshow()
    itemshow()
    additems()
    command()
    delitem()
})
function hostshow(){
$('.leftmenu').click(function(){
    var hostid = $(this).attr('id')
    $.ajax({
        url:'/zabbix_host.html/',
        data:{'id':hostid},
        type:'POST',
        headers:{'X-CSRFToken':token},
        success:function(host_li){
            $('.right').empty()
            $('.right').append(host_li)
        }
    })
})
}
function itemshow(){
$('.right').on('click','.host',function(){
    var hostid = $(this).attr('hostid')
    var hostname = $(this).text()
    var interfaceid = $(this).attr('interfaceid')
    $.ajax({
        url:'/zabbix_items.html/',
        data:{'hostid':hostid,'interfaceid':interfaceid,'hostname':hostname},
        type:'POST',
        headers:{'X-CSRFToken':token},
        success:function(items){
            $('.right').empty()
            $('.right').append(items)
        }
    })
})
}
function additems(){
    $('.right').on('click','.additem',function(){
        var hostid = $(this).attr('hostid')
        var interfaceid = $(this).attr('interfaceid')
        addlable=''+
        '提交'
        $.ajax({
            url:'/keylist.html/',
            data:{'hostid':hostid},
            type:'POST',
            headers:{'X-CSRFToken':token},
            success:function(ret){
                $('.right').empty()
                var lab = ret + addlable
                $('.right').append(lab)
            }
        })
    })
    }
function command(){
    $('.right').on('click','.command',function(){
        var data = $('.itemname').val()
        var key_ = $('select').val()
        var hostid = $(this).attr('hostid')
        var interfaceid = $(this).attr('interfaceid')
        console.log(data,key_)
        $.ajax({
            url:'/additems.html/',
            data:{'hostid':hostid,'interfaceid':interfaceid,'data':data,'key_':JSON.stringify(key_)},
            type:'POST',
            headers:{'X-CSRFToken':token},
            success:function(ret){
                $('.right').empty()
                $('.right').append(ret)
                 }
                })
            }
            )
        }

function delitem(){
    $('.right').on('click','.del',function(){
        itemid = $(this).attr('itemid')
        $.ajax({
            url:'/delitem.html/',
            data:{'itemid':itemid},
            type:'POST',
            headers:{'X-CSRFToken':token},
            success:function(ret){
                $("."+itemid).remove()
                var htm = $('.right').html()
                $('.right').empty()
                $('.right').append(htm)
            }
            })
        }
        )

    }

jquery.cook,js 官网下载文件,用于django的CSRF,防止跨站

一个简陋的批量操作zabbix监控项页面
/*!

 * jQuery Cookie Plugin v1.4.1
 * https://github.com/carhartl/jquery-cookie
 *
 * Copyright 2006, 2014 Klaus Hartl
 * Released under the MIT license
 */
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        // AMD (Register as an anonymous module)
        define(['jquery'], factory);
    } else if (typeof exports === 'object') {
        // Node/CommonJS
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals
        factory(jQuery);
    }
}(function ($) {

    var pluses = /\+/g;

    function encode(s) {
        return config.raw ? s : encodeURIComponent(s);
    }

    function decode(s) {
        return config.raw ? s : decodeURIComponent(s);
    }

    function stringifyCookieValue(value) {
        return encode(config.json ? JSON.stringify(value) : String(value));
    }

    function parseCookieValue(s) {
        if (s.indexOf('"') === 0) {
            // This is a quoted cookie as according to RFC2068, unescape...

            s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
        }

        try {
            // Replace server-side written pluses with spaces.

            // If we can't decode the cookie, ignore it, it's unusable.

            // If we can't parse the cookie, ignore it, it's unusable.

            s = decodeURIComponent(s.replace(pluses, ' '));
            return config.json ? JSON.parse(s) : s;
        } catch(e) {}
    }

    function read(s, converter) {
        var value = config.raw ? s : parseCookieValue(s);
        return $.isFunction(converter) ? converter(value) : value;
    }

    var config = $.cookie = function (key, value, options) {

        // Write

        if (arguments.length > 1 && !$.isFunction(value)) {
            options = $.extend({}, config.defaults, options);

            if (typeof options.expires === 'number') {
                var days = options.expires, t = options.expires = new Date();
                t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
            }

            return (document.cookie = [
                encode(key), '=', stringifyCookieValue(value),
                options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
                options.path    ? '; path=' + options.path : '',
                options.domain  ? '; domain=' + options.domain : '',
                options.secure  ? '; secure' : ''
            ].join(''));
        }

        // Read

        var result = key ? undefined : {},
            // To prevent the for loop in the first place assign an empty array
            // in case there are no cookies at all. Also prevents odd result when
            // calling $.cookie().

            cookies = document.cookie ? document.cookie.split('; ') : [],
            i = 0,
            l = cookies.length;

        for (; i < l; i++) {
            var parts = cookies[i].split('='),
                name = decode(parts.shift()),
                cookie = parts.join('=');

            if (key === name) {
                // If second argument (value) is a function it's a converter...

                result = read(cookie, value);
                break;
            }

            // Prevent storing a cookie that we couldn't decode.

            if (!key && (cookie = read(cookie)) !== undefined) {
                result[name] = cookie;
            }
        }

        return result;
    };

    config.defaults = {};

    $.removeCookie = function (key, options) {
        // Must not alter options, thus extending a fresh object...

        $.cookie(key, '', $.extend({}, options, { expires: -1 }));
        return !$.cookie(key);
    };

}));

View Code

index.css 页面简单渲染

*{margin: 0;padding: 0; }
.top{
    background-color: rgb(83, 83, 236);
    height: 52px;
    }

.top-left{
    width: 300px;height: 53px;
    float: left;
    text-align: center;line-height: 48px;
    color: seashell;

    }

.top-right{height: 53px;
    float: right;
    text-align: center;line-height: 48px;
    color: seashell;
    margin-right: 60px;

    }

.left{background-color: whitesmoke;
    position: absolute;left: 0;top: 48px;bottom: 0; z-index: 99;
    width: 300px;
    border-right:1px solid black;
    z-index: 99;
    overflow: auto;
    }

.right{
    background-color: whitesmoke;
    position: absolute;left: 301px;top: 48px;bottom: 0;right: 0; z-index: 99;
    overflow: scroll;
    z-index: 99;
    overflow: auto;
    }

a:hover{
    background-color: cornflowerblue;
    }

.astyle{
    display: block;padding: 10px;
    }

.block{
    position: absolute;top: 0;bottom: 0;right: 0;left: 0;
    background-color: black ;opacity: 0.2;z-index: 100;
}
.currsor:hover{
    cursor: pointer;
}
.hidden{
    display: none;
}
.pitch{
    background-color:black;color: white;
}
.unpitch{
    background-color: white;color: black;
}
.page{
    margin-left: 10px;
}

textarea{
    width: 453px;
    margin-top: 20px;
    margin-left: 10px;
}
.select{
    margin-top: 20px;
    margin-left: 10px;
    display: block;
}
.command{
    margin-top: 20px;
    margin-left: 10px;
    display: block;
}
table.gridtable {
    font-family: verdana,arial,sans-serif;
    font-size:11px;
    width: 100%;
    color:#333333;
    border-width: 1px;
    border-color: #666666;
    border-collapse: collapse;
    }
    table.gridtable th {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #dedede;
    }
    .change{
        width: 70px;
    }
    table.gridtable td {
    border-width: 1px;
    padding: 8px;
    border-style: solid;
    border-color: #666666;
    background-color: #ffffff;
    }

models.py 定义数据库,在这里除了登录用不上

from django.db import models

Create your models here.

class login(models.Model):
    username = models.CharField(max_length=64)
    passwd = models.CharField(max_length=64)
    def __str__(self):
        return self.username

zbauth.py 定义zabbix-api的登录和一系列操作

import requests
class ZabbixOperates:
    def __init__(self):
        self.zabbix_url = 'https://ex.zabbix.com/api_jsonrpc.php'
        self.user="user"
        self.pwd="passwd"
        self.verify_file,self.ssl_pem,self.ssl_key='/home/user.pem','/home/uer.pem','/home/user.key'
        self.head={"Content-Type":"application/json"}
        self.token = self.get_token()
    def get_token(self):
        data = {
        "jsonrpc":"2.0",
        "method":"user.login",
        "params":{
            "user":self.user,
            "password":self.pwd
        },
        "id":1
        }
        res = requests.post(self.zabbix_url,headers=self.head,json=data,verify=self.verify_file,cert=(self.ssl_pem,self.ssl_key))
        return res.json()['result']
    def reuqest(self,data):
        res = requests.post(self.zabbix_url,json=data,verify=self.verify_file,cert=(self.ssl_pem,self.ssl_key))
        return(res.json())
    def show(self,value,filter=None):
        if 'error' in value:
            return(value['error'])
    def operate(self,data):
        return self.reuqest(data)
    def get_host(self,groupid=None):
        data={
            "jsonrpc": "2.0",
            "method":"host.get",
            "params": {
                "groupids": groupid,
                "output": [
                    "hostid",
                    "host",
                    "interfaceid",

                ],
                "selectInterfaces": [
                    "interfaceid"
                ],
                "filter":{"type":"1"}
            },
            "id":1,
            "auth":self.token
            }
        return self.reuqest(data)
    def get_group(self):
        data={
                "jsonrpc": "2.0",
                "method": "hostgroup.get",

                "params": {
                    "output": ["name"],
                },
                "auth": self.token,
                "id": 1
            }
        return self.reuqest(data)
    def get_item(self,hostid,key):
        data = {
                "jsonrpc": "2.0",
                "method": "item.get",
                "params": {
                    "output": [
                                'itemid',
                                'name',
                                'key_'
                            ],
                    "hostids": hostid,
                    "search": {
                        "key_": key
                    },
                    "sortfield": "name"
                },
                "auth": self.token,
                "id": 1
                }
        return self.reuqest(data)
    def create_item(self,*value):
        hostid,interfaceid,name,key,units=value
        data={
            "jsonrpc": "2.0",
            "method": "item.create",
            "params": {
                "name": name,
                "key_": key,
                "hostid": hostid,
                "type": 0,
                "value_type": 0,
                "interfaceid": interfaceid,
                "delay": '20s',
                'history': '90d',
                'trends': '365d',
                'units': units,
                'lifetime': '30d',
            },
            "auth": self.token,
            "id": 3
            }
        return self.reuqest(data)
    def del_items(self,itemid):
        data = {
                "jsonrpc": "2.0",
                "method": "item.delete",
                "params": [
                    itemid
                ],
                "auth": self.token,
                "id": 1
            }
        return self.reuqest(data)

views.py 存放后端数据处理函数

from django.shortcuts import render,redirect,HttpResponse
from django.views.decorators.csrf import csrf_exempt
from DarkZabbix import models
from functools import wraps
from DarkZabbix.zbauth import ZabbixOperates
import json

Create your views here.

op = ZabbixOperates()
def auth(func):
    @wraps(func)
    def check_login(res,*args,**kwargs):
        try:
            res.session['name']
            return func(res,*args,**kwargs)
        except:
            return render(res,'login.html')
    return check_login

def deny_get(func):
    @wraps(func)
    def deny(res,*args,**kwatgs):
        if res.method == 'GET':
            return HttpResponse('已记录此次访问Ip地址')
        else:
            return func(res,*args,**kwatgs)
    return deny

def login(res):
    if res.method == 'GET':
        return render(res,'login.html')
    elif res.method == 'POST':
        username = res.POST.get('username')
        passwd = res.POST.get('passwd')
        if models.login.objects.filter(username=username,passwd=passwd):
            res.session.set_expiry(3600)
            res.session['name']=username
            return redirect('/zabbix.html')
        else:
            error = '用户名或密码错误'
            return render(res,'login.html',{'error':error})

@auth
def zabbix(res):
    groupli  = op.get_group()['result']
    return render(res,'zabbix.html',{'groupli':groupli})

@auth
@deny_get
def zabbix_host(res):
    group_id = res.POST.get('id')
    hostli = op.get_host(groupid=group_id)['result']
    lab=''
    for host in hostli:
        lab+='%s'%(host['hostid'],host['interfaces'][0]['interfaceid'],host['host'])
    return HttpResponse(lab)

@auth
@deny_get
def zabbix_items(res):
    host_id,interface_id,hostname = res.POST.get('hostid'),res.POST.get('interfaceid'),res.POST.get('hostname')
    lab='%s  添加itemnamekeyoperate'%(hostname,host_id,interface_id)
    items = op.get_item(host_id,'ping')['result']
    for item in items:
        lab+='%s%s删除'%(item['itemid'],item['name'],item['key_'],item['itemid'])
    lab+=''
    return HttpResponse(lab)

@auth
@deny_get
def key_list(res):
    import re
    key_list=['ping_pkloss[*]','ping_restime[*]']
    host_id = res.POST.get('hostid')
    items = op.get_item(host_id,'ping')['result']
    for item in items:
        key_ = item['key_']
        try:
            host  = re.findall('\[.*\]',key_)[0]
            key_= key_.replace(host,'[*]')
        except:
            pass
        if key_ not in key_list:
            key_list.append(key_)
    labli=['%s'%x for x in key_list]
    lab = 'key: '+''.join(labli)+''
    return HttpResponse(lab)

@auth
@deny_get
def add_items(res):
    hostid,interfaceid,itemname,key_list = res.POST.get('hostid'),res.POST.get('interfaceid'),res.POST.get('data'),res.POST.get('key_')
    key_list = json.loads(key_list)
    if not key_list:
        return HttpResponse('缺少必选项或格式错误')
    items = itemname.split('\n')
    for item in items:
        name = item
        item = item.strip()
        _,host = item.split('-')
        for key_ in key_list:
            key_ = key_.replace('*',host)
            type_ = 'restime' if 'restime' in key_ else 'pkloss'
            unit = 'ms' if type_ =='restime' else '%'
            ret = op.create_item(hostid,interfaceid,name+type_,key_,unit)
            if op.show(ret):
                return HttpResponse(json.dumps(op.show(ret)))
    lab='操作成功'
    return HttpResponse(lab)

@auth
@deny_get
def del_items(res):
    itemid = res.POST.get('itemid')
    ret = op.del_items(itemid)
    if op.show(ret):
        return HttpResponse(json.show(op.show(ret)))
    lab='操作成功'
    return HttpResponse(lab)

ending……

Original: https://www.cnblogs.com/darkchen/p/16295461.html
Author: 奔波的驱魔人
Title: 一个简陋的批量操作zabbix监控项页面

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/715271/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球