ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

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

2022-05-22 21:01:37  阅读:148  来源: 互联网

标签:return 批量 get res self host zabbix key 页面


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

使用django完成

目录如下

 

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

 

 长这样,主页,展示groups

 

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

 

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

 

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

 

 

代码部分

自己日常工作用,页面不重要,重要的是功能,因为写页面太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-zabbix</h1>
        <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>index</title>
    <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='<textarea placeholder="itemname 格式示例:郑州电信-10.0.0.1或郑州电信-10.0.0.1,80" class="itemname"  rows="20" ></textarea><br>'+
        '<button class="command"'+'hostid='+ '\"'+hostid+'\"'+'interfaceid='+'\"'+interfaceid+'\"'+'>提交</button>'
        $.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,防止跨站

/*!
 * 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+='<a href="#" class="host astyle" hostid=%s interfaceid=%s>%s</a>'%(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='<p>%s  <button class="additem" hostid=%s interfaceid=%s>添加item</button></p><table class="gridtable"><tr><td>name</td><td>key</td><td>operate</td></tr>'%(hostname,host_id,interface_id)
    items = op.get_item(host_id,'ping')['result']
    for item in items:
        lab+='<tr class=%s><td>%s</td><td>%s</td><td><button itemid=%s class=del>删除</button></td></tr>'%(item['itemid'],item['name'],item['key_'],item['itemid'])
    lab+='</table>'
    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=['<option>%s</option>'%x for x in key_list]
    lab = '<p class="select">key: <select multiple="multiple">'+''.join(labli)+'</select></p>'
    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......

标签:return,批量,get,res,self,host,zabbix,key,页面
来源: https://www.cnblogs.com/darkchen/p/16295461.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有