Python调用zabbix的api接口_宋晓坤的博客-程序员秘密

技术标签: python  运维  linux  自动化  Python  

官方文档地址:https://www.zabbix.com/documentation/3.4/zh/manual

在这里插入图片描述

  • 创建新的应用程序以使用Zabbix;
  • 将Zabbix与第三方软件集成;
  • 自动执行常规任务。

使用Zabbix API接口的要素

在这里插入图片描述

官方文档引用:

设置前端后,你就可以使用远程HTTP请求来调用API。为此,需要向 api_jsonrpc.php 位于前端目录中的文件发送HTTP POST请求。例如,如果你的Zabbix前端安装在 http://company.com/zabbix, 那么用HTTP请求来调用 apiinfo.version 方法就如下面这样:

POST http://company.com/zabbix/api_jsonrpc.php HTTP/1.1
       Content-Type: application/json-rpc

       {"jsonrpc":"2.0","method":"apiinfo.version","id":1,"auth":null,"params":{}}

请求的 Content-Type 头部必须设置为以下值之一: application/json-rpc, application/jsonapplication/jsonrequest

你可以使用任何HTTP客户端或JSON-RPC测试工具手动执行API请求,但对于开发应用程序,我们建议使用 社区维护的程序库

执行请求


  • 接口请求地址:http://192.168.106.72/zabbix/api_jsonrpc.php

  • 基于http协议向api_jsonrpc.php发送POST请求

  • 伪装http请求的头部字段Content-Type 的值是以下三种之一:

    • application/json
    • application/jsonrequest
    • application/json-rpc
  • 客户端和API之间的请求和响应使用JSON格式


python使用的模块


JSON模块(内置模块)

  • 主要用于实现json格式的数据对应python中的数据类型转换

1、将字典转换成json格式

使用dumps方法

json.dumps(字典)

2、将json格式转换成字典

使用loads方法

json.loads(json数据)

request模块(第三方模块)

用来发送HTTP请求

安装模块:

PS E:\python_venv> pip install requests

  • 常用方法:
    • get请求获取数据
    • post发起请求

get使用演示

import  requests
result = requests.get("http://www.baidu.com")
#这里接收到的是访问地址返回的http的相应数据
print(result)
#只接收纯字符的结果
print(result.text)
#只接收状态码
print (result.status_code)

在这里插入图片描述

post使用

这里还是以百度为例,发送用户信息(由于是访问百度,会返回错误)

import  requests
userinfo = {
    "username":"admin","passwd":"test"}
result = requests.post(url="http://www.baidu.com", data=userinfo)
print(result)
#这里就可以用.text和.status_code方法,处理接受到的数据,返回码和字符结果
#print(result.text)

POST里可以以url指定地址,可以传递data(例子里使用data传递了一个字典),也可以是json格式的数据。还支持一个参数是headers,用来伪装http的请求头部

在这里插入图片描述

自动监控案例

案例一、在zabbix为主机添加一个监控项

(官方文档案例)

1、获取token

在这里插入图片描述

  • 获取后,因为后边需要使用这个token,需要取出这个值

在这里插入图片描述在这里插入图片描述

官方文档内容:

在访问Zabbix中的任何数据之前,你需要登录并获取身份验证令牌。这可以使用该 user.login 方法完成。让我们假设你想要以标准Zabbix Admin用户身份登录。然后,你的JSON请求将如下所示:

{
    
    "jsonrpc": "2.0",
    "method": "user.login",
    "params": {
    
                "user": "Admin",
                "password": "zabbix"    
                },
    "id": 1,
    "auth": null
}

让我们仔细看看请求对象。它具有以下属性:

  • jsonrpc - API使用的JSON-RPC协议的版本; Zabbix API实现JSON-RPC版本2.0;
  • method - 调用的API方法;
  • params - 将被传递给API方法的参数;
  • id - 请求的任意标识符;
  • auth -用户认证令牌; 因为我们还没有一个,它的设置null。

如果你正确提供了凭据,API返回的响应将包含用户身份验证令牌:

{    "jsonrpc": "2.0",    "result": "0424bd59b807674191e7d77572075f33",    "id": 1}

响应对象又包含以下属性:

  • jsonrpc - JSON-RPC协议的版本;
  • result - 方法返回的数据;
  • id - 相应请求的标识符。

2、获取主机ID

在这里插入图片描述

获得结果如下:

{“jsonrpc”:“2.0”,“result”:[{“hostid”:“10254”,“host”:“node1.song”,“interfaces”:[{“interfaceid”:“2”,“ip”:“192.168.106.73”}]},{“hostid”:“10084”,“host”:“Zabbix server”,“interfaces”:[{“interfaceid”:“1”,“ip”:“127.0.0.1”}]}],“id”:2}

其中包含了jsonrpc的版本号,和result中是主机的信息,ID是请求的ID。

整理格式大概是这样:

一个字典里包含了三个内容,其中result里是一个列表写了主机的信息。

在这里插入图片描述

通过这个结构可以清楚的获取里边的hostID和接口ID:

result = requests.post(url=zabbix_url,data=json.dumps(data),headers=head)
#取hostid,先用loads将结果转成字典,get获取字典里的result键对应的值(是个列表)取下标为0的(是第一个字典),再get键为hostid的。
hostid = json.loads(result.text).get("result")[0].get("hostid")
#取接口ID,先用loads将结果转成字典,get获取字典里的result键对应的值(是个列表)取下标为0的(是第一个字典),再get键为interfaces的值(是个列表)取下标为0,再get键为interfaceid。
interface_id = json.loads(result.text).get("result")[0].get("interfaces")[0].get("interfaceid")
print(hostid,interface_id)

在这里插入图片描述

#两个结果输出到一个变量里是以元组格式输出,两个变量会分别接收

在这里插入图片描述

官方文档内容:

在这里插入图片描述

3、添加监控项(通过主机ID)

创建成功会返回监控项的ID

在这里插入图片描述

在这里插入图片描述

重复创建会报错

在这里插入图片描述

官方文档接口介绍:

在这里插入图片描述

接口中key_的值是写手动创建时的监控项的键值:

在这里插入图片描述

4、完整代码

#通过API添加主机监控项
import json
import requests

#定义变量
zabbix_url = "http://192.168.106.72/zabbix/api_jsonrpc.php"
zabbix_user = "Admin"
zabbix_passwd = "zabbix"

#定义函数,登录zabbix获取用户令牌token
def getUserToken():
#这里用官网提供的格式
    data = {
    
        "jsonrpc": "2.0",
        "method": "user.login",
        "params": {
    
            "user": zabbix_user,
            "password": zabbix_passwd
        },
        "id": 1
        #"auth": null 用不到可以去掉
        }
# 定义Content-Type头部,后边引用
    head = {
    "Content-Type":"application/json"}
    result = requests.post(url=zabbix_url,data=json.dumps(data),headers=head)
    #获取到令牌
    #print(result.text)
    #截取令牌
    #print(json.loads(result.text).get("result"))
    #使用return将这个值作为函数的返回值输出出来
    return  json.loads(result.text).get("result")

#获取被监控主机的信息
def GetHostID():
#定义一个变量,取token函数中的返回值
    user_token = getUserToken()
    data = {
    
        "jsonrpc": "2.0",
        "method": "host.get",
        "params": {
    
            "output": [
            #输出内容
                "hostid",
                "host"
            ],
            "selectInterfaces": [
            #这里输出的是主机配置里的给agent设置的接口方式对应的ID和ip
                "interfaceid",
                "ip"
            ]
        },
        "id": 2,
        #auth中写的是token值
        "auth": user_token
    }
    head = {
    "Content-Type":"application/json"}
    result = requests.post(url=zabbix_url,data=json.dumps(data),headers=head)
    #取hostid,先用loads将结果转成字典,get获取字典里的result键对应的值(是个列表)取下标为0的(是第一个字典),再get键为hostid的。
    hostid = json.loads(result.text).get("result")[0].get("hostid")
    #取接口ID,先用loads将结果转成字典,get获取字典里的result键对应的值(是个列表)取下标为0的(是第一个字典),再get键为interfaces的值(是个列表)取下标为0,再get键为interfaceid。
    interface_id = json.loads(result.text).get("result")[0].get("interfaces")[0].get("interfaceid")
    #print(hostid,interface_id)
    #定义return返回结果,这里返回两个结果,接收的时候会把结果放在一个元组里
    return   hostid, interface_id

#创建新的监控项:监控/分区大小
def itemCreate():
    user_token = getUserToken()
    #定义两个变量别接收hostid和interfaceID
    host_id, interface_id = GetHostID()
    data = {
    
        "jsonrpc": "2.0",
        #这里item.create是接口指定的方法
        "method": "item.create",
        "params": {
    
            "name": "Free disk space on $1",
            #这里格式是vfs.fs.size是定义监控项时选择的键值[分区,free表示剩余空间]
            "key_": "vfs.fs.size[/,free]",
            "hostid": host_id,
            "type": 0,
            "value_type": 3,
            "interfaceid": interface_id,
            "delay": 30
        },
        "auth": user_token,
        "id": 3
    }
    head = {
    "Content-Type":"application/json"}
    result = requests.post(url=zabbix_url, data=json.dumps(data), headers=head)
    print(result.text)

if __name__ == '__main__':
   itemCreate()

zabbix接口更多方法参考:https://www.zabbix.com/documentation/3.4/zh/manual/api/reference

案例二、实现新服务器自动监控

接口官方介绍:https://www.zabbix.com/documentation/3.4/zh/manual/api

  • 目的:用户输入服务器名称、ip完成自动添加到主机并使用Linux服务的监控模板

  • 需求:主机组指定Linux server 模板使用Template OS Linux

  • 用到的接口:

    • token获取(上边已经用过了)
    • 添加监控主机 host.create
    {
          
        "jsonrpc": "2.0",
        "method": "host.create",
        "params": {
          
            #传主机名
            "host": "Linux server",
            "interfaces": [
                {
          
                    "type": 1,
                    "main": 1,
                    "useip": 1,
            		#被监控端的ip
                    "ip": "192.168.3.1",
                    "dns": "",
            		#agent端口
                    "port": "10050"
                }
            ],
            "groups": [
                {
          
        #需要添加到那个主机组。主机组ID
                    "groupid": "50"
                }
            ],
            "templates": [
                {
          
         #使用的模板,模板ID
                    "templateid": "20045"
                }
            ],
    #inventory部分给主机添加清单信息可以不用
            "inventory_mode": 0,
            "inventory": {
          
                "macaddress_a": "01234",
                "macaddress_b": "56768"
            }
        },
        "auth": "038e1d7b1735c6a5436ee9eae095879e",
        "id": 1
    }
    

1、定义重复动作

前边例子可以看到每个函数都要发送请求和指定头部数据,这里吧这个内容写到一个函数里

在这里插入图片描述

2、获取token

和前边例子一样,只是通过定义的函数发送请求

在这里插入图片描述

3、获取主机组ID

在这里插入图片描述

4、获取模板ID

在这里插入图片描述

5、添加主机

在这里插入图片描述

在这里插入图片描述

这里因为添加过了,所以提示失败

成功截图:

在这里插入图片描述
在这里插入图片描述

6、完整代码

#自动添加主机,并使用Template OS Linux模板,自动添加主机组到Linux Servers
import json
import requests
import sys

#定义变量
zabbix_url = "http://192.168.106.72/zabbix/api_jsonrpc.php"
zabbix_user = "Admin"
zabbix_passwd = "zabbix"

#定义一些重复的操作的函数,并接收data变量数据
def SendPost(data):
#定义头部信息
    head = {
    "Content-type":"application/json"}
    # 判断请求发送失败,加一个try异常捕获
    try:
    #定义请求结果,这里用到接收进来的data内容,并把接收的字典格式转成json请求
        result = requests.post(url=zabbix_url,data=json.dumps(data),headers=head)
    except Exception as e:
        print("———post请求失败!!!———")
        #输出错误信息
        print(e)
        #退出程序
        sys.exit()
    #成功执行后,以字典形式返回访问结果
    return json.loads(result.text)

#获取用户令牌
def getUserToken():
#这里用官网提供的格式
    data = {
    
        "jsonrpc": "2.0",
        "method": "user.login",
        "params": {
    
            "user": zabbix_user,
            "password": zabbix_passwd
        },
        "id": 1
        #"auth": null 用不到可以去掉
        }
# 这里就不用在指定头部信息和request请求了,直接调用SendPost函数,并把data传过去就可以了
    result = SendPost(data=data)
    return result.get("result")
    #也可以写成:这个get先用和return中用都可以
    # result = SendPost(data=data).get("result")
    # return result

#获取主机组Linux Servers的ID
def getHostGroupID():
    #定义token变量
    user_token = getUserToken()
    data = {
    
        "jsonrpc": "2.0",
        "method": "hostgroup.get",
        "params": {
    
            "output": "extend",
            "filter": {
    
                "name": [
                    #主机组名,这里可以写多个,用逗号隔开
                    "Linux servers"
                ]
            }
        },
        "auth": user_token,
        "id": 1
    }
    result = SendPost(data=data)
    return result.get("result")[0].get("groupid")

#获取模板ID
def getTemplateID():
    user_token = getUserToken()
    data = {
    
        "jsonrpc": "2.0",
        "method": "template.get",
        "params": {
    
            "output": "extend",
            "filter": {
    
                "host": [
                    #模板名称,这里可以写多个,用逗号隔开
                    "Template OS Linux"
                ]
            }
        },
        "auth": user_token,
        "id": 1
    }
    result = SendPost(data=data).get("result")[0].get("templateid")
    return result

#创建监控主机,并接收主机名和ip两个变量
def AddHost(hostname, hostip):
    #设置变量
    user_token = getUserToken()
    host_group_id = getHostGroupID()
    template_id = getTemplateID()
    data = {
    
        "jsonrpc": "2.0",
        "method": "host.create",
        "params": {
    
            "host": hostname,
            "interfaces": [
                {
    
                    "type": 1,
                    "main": 1,
                    "useip": 1,
                    "ip": hostip,
                    "dns": "",
                    "port": "10050"
                }
            ],
            "groups": [
                {
    
                    "groupid": host_group_id
                }
            ],
            "templates": [
                {
    
                    "templateid": template_id
                }
            ]
        },
        "auth": user_token,
        "id": 1
    }
    result = SendPost(data=data)
    #这里可以加个判断,如果失败返回值里会有error,通过这个判断,并提示结果
    if "error" not in result:
        print("服务器%s监控添加成功" % hostip)
    else:
        print("服务器%s监控添加失败" % hostip)


if __name__ ==  '__main__':
    hostname = input("请设置服务器名称:")
    hostip = input("请输入服务器地址:")
    AddHost(hostname=hostname,hostip=hostip)


zabbix接口更多方法参考:https://www.zabbix.com/documentation/3.4/zh/manual/api

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/Sxiaokun/article/details/124284988

智能推荐

C++ 虚函数,纯虚函数_panfengsoftware的博客-程序员秘密

虚函数、纯虚函数详解1.首先:强调一个概念        定义一个函数为虚函数,不代表函数为不被实现的函数。定义他为虚函数是为了允许用基类的指针来调用子类的这个函数。       定义一个函数为纯虚函数,才代表函数没有被实现。定义他是为了实现一个接口,起到一个规范的作用,规范继承这个。类的程序员必须实现这个函数。 2.关于实例化一个类: 有纯虚函数的类是不可能生成类

无法从共享目录中映射段 linux,dopen():未作为root用户运行时,“无法从共享对象映射段”..._跑焦的博客-程序员秘密

我正在尝试在自制的Yocto Linux下加载一些自行编写的库。当以root身份运行同一程序,但不能以另一个后来添加的用户身份运行该程序时,它运行良好。for (){m_HModule = dlopen(Filename.c_str(), RTLD_NOW | RTLD_GLOBAL);if (m_HModule == NULL){fprintf(stderr, "Error: %s\n", dl...

windows 7 下安装Oracle 9i 解决方法_zhensoft163的博客-程序员秘密_oracle9i win7

      这里首先申明下,windows7下安装oracle9i 9.0.1版本肯定是不成功的,楼主安装过无数次,网上也找过很多方法,都不可行,所以就不用试了。这里说下oracle9i 9.2版本安装出现的问题和解决办法。下载 :cd1:http://download.oracle.com/otn/nt/oracle9i/9201/92010NT_Disk1.zipcd2:http://do

SQLserver安装配置_Ln2116525889的博客-程序员秘密_配置sqlserver

sqlserver安装和配置1、下载地址:https://www.microsoft.com/zh-cn/download/404Error.aspx2、把下载的文件进行解压,打开找到setup.exe,右键以管理员身份运行3、开始安装,选择第一个4、等待操作完成,点击确定5、输入微软的产品密匙,然后点击下一步,接受条款6、安装更新,没有网的情况下会提示无法更新,更新完成后点击下一步7、设置角色,选中sql server(功能安装),点击下一步8、 建议全选,避免以后免得需要时,需要

Java自定义日期处理工具类_神探小五的博客-程序员秘密

1、主要使用Calendar类、SimpleDateFormat类2、同时注意add方法是相对当前月而言的,而set方法是对应整体而言,整体是月就是从月的第一天开始,是年就从年的第一天开始3、工具类代码如下:public class CalendarUtil { publicstatic final String FORMAT_1="yyyyMMdd"; public

计算机组成原理微操作课程设计,微程序设计——计算机组成原理课程设计报告.doc..._weixin_39826984的博客-程序员秘密

目 录TOC \o "1-3" \h \z HYPERLINK \l _Toc19423 1 课程设计的目的和要求 PAGEREF _Toc19423 1HYPERLINK \l _Toc29593 1.1课程设计目的 PAGEREF _Toc29593 1HYPERLINK \l _Toc11720 1.2 课程设计的要求 PAGEREF _Toc11720 1HYPERLINK \l _To...

随便推点

动态规划--资源分配问题_wlx嘿的博客-程序员秘密_求解资源分配问题

问题描述:资源分配问题是将数量一定的一种或若干种资源(原木料、资金、设备或劳动力等)合理地分配给若干个使用者,使总收益最大。例如,某公司有3个商店A、B、C,拟将新招聘的5名员工分配给这3个商店,各商店得到新员工后每年的赢利情况如表所示,求分配给各商各多少员工才能使公司的赢利最大?解析:其实就是完全背包的变形用dp[i][j]表示为前i个商店共分配j个人时盈利的最大值,状态转移方程如下(k表示为i商店分配的人数):dp[i][j] = max(dp[i][j], dp[i-.

华为2021届 硬件工程师 逻辑岗位(FPGA)超详细面经!!!_InspireHH的博客-程序员秘密_fpga面经

应聘岗位:华为 逻辑面试前准备:数字电路基础部分、FPGA常见面试问题(同步、异步、亚稳态、跨时钟域、FPGA内部逻辑、时序约束等等常见问题)、熟悉个人向项目(一定得非常细致的复习!),我是提前一个月就开始准备。笔试(八月底):华为笔试主要考察一些数电基础知识,Verilog基础知识,FPGA中常见的基础知识,少量C语言与模电题,整体题目难度不大,比较容易通过。一面(专业面试)(九月3日):一面时间较长,主要问了学习成绩、成绩为什么没有更好(因为被自己蠢死了,填了前百分之50,实际前30%左右

华为与H3C的前世今生-昊群计算机_biqianfeng5426的博客-程序员秘密

在中国的网络通信设备市场,有两个华字辈的选手,一名叫“华为技术有限公司”,另一名叫“杭州华三通信技术有限公司”。这两个人有着血浓于水的情谊,在历史上为了抵挡强敌思科的***,一起并肩战斗过。而这俩人曾经肝胆相照,互相立下城下之约,发誓井水不犯河水,你玩你的运营商,我玩我的企业网。然而在利益面前,任何人心都会改变,为了瓜分市场,两人大打出手,我抢你的地,你吞我的城,曾经的情谊荡然无存。如今,这...

java 获取服务器信息_ttkop的博客-程序员秘密

通过使用第三方开源jar包sigar.jar我们可以获得本地的信息1.下载sigar.jarsigar官方主页sigar-1.6.4.zip2.按照主页上的说明解压包后将相应的文件copy到java路径。比如windows32位操作系统需要将lib中sigar-x86-winnt.dll文件拷贝到java SDK目录的bin内参考官方主页上的配置项。

hostname和/etc/hosts的区别_Torres的博客-程序员秘密

hostname和/etc/hosts的区别hostname和/etc/hosts的区别 很多人一提到更改hostname首先就想到修改/etc/hosts文件,认为hostname的配置文件就是/etc/hosts。其实不是的。hosts文件的作用相当于DNS,提供IP地址hostname的对应。早期的互联网计算机少,单机hosts文件里足够存放所有联网计算机。不过随着互联网

【人人都是Pythoner】——当路径中出现了python转义符‘\’__忽如远行客的博客-程序员秘密_python 的目录转义

转义字符是什么?按照通常定义来说,转义字符是让以它为首的字符串“变脸”的符号。’\’ 是常用的转义字符,它会和后面字符结合起来转义成具有其他意义的字符。比如,“n”本来是一个乖巧的字符,前面加上转义字符“\”变成"\n"之后,在程序中就另有意义:换行。转义字符‘\’应用“\n”是常见的转义字符应用,而双引号字符(")在程序语言中作为字符串的分界,若需要在字符串内引入双引号字符,则用反斜杠字...

推荐文章

热门文章

相关标签