要寫這篇博客其實我的內心是糾結的,老實說,我對zabbix的了解實在不多。但新公司的需求不容置疑,當我頂着有兩個頭大的腦袋懵懵轉入運維領域時,面前擺着兩百多組、上千台機器等着寫入zabbix監控的需求(這種心境你們隨意感受下就好),也嘗試從網上查各種現成的資料,希望能找到解救自我的一些蛛絲馬跡,然而發現大家在使用zabbix的時候都局限在“主機、查詢組、模板的增刪改查上”,甚至還貼心的封裝成“類”以供調用。卻不符合我要對Action進行配置的需求。幾經掙扎,還是結合官網解釋+自我臆測得到了想要的答案。最終實現了幾百條action規則的批量創建,完成了自救。
zabbix API簡介
為什么要調用zabbix API?
zabbix是一個基於WEB界面的提供分布式系統監視以及網絡監視功能的企業級的開源解決方案,隨着zabbix在企業中被廣泛的應用,Zabbix API開始扮演着越來越重要的角色,尤其是在集成第三方軟件和自動化日常任務時。很難想象管理數千台服務器而沒有自動化是多么的困難。Zabbix API為批量操作、第三方軟件集成以及其他作用提供可編程接口。
Zabbix API是在1.8版本中開始引進並且已經被廣泛應用。所有的Zabbix移動客戶端都是基於API,甚至原生的WEB前端部分也是建立在它之上。Zabbix API 中間件使得架構更加模塊化也避免直接對數據庫進行操作。它允許你通過JSON
RPC協議來創建、更新和獲取Zabbix對象並且做任何你喜歡的操作【當然前提是你擁有認證賬戶】。
Zabbix API提供兩項主要功能:
-
遠程管理Zabbix配置
-
遠程檢索配置和歷史數據
調用zabbix接口基本流程
在zabbix調用zabbix接口的時候,需要帶一個auth參數,這個auth參數需要先經過一次登錄認證之后返回給客戶端,然后客戶端在請求的接口數據中需要帶上這個auth字符串。具體的流程如下圖:
以zabbix Action 開始的API調用旅程
zabbix Action簡介
上述簡單的介紹一下zabbix API的用途,具體zabbix的架構或者深奧的底層代碼在網上已經有很多介紹,但是針對“python調用zabbix接口實現對Action配置的批量操作”的介紹確非常少,而這又是我們在給大批量機器定制策略的時候要邁出的第一步,所以今天我們的重點放在用python實現zabbix接口調用上(代碼,代碼,代碼)。一開始還覺得這篇博客寫的內容有些狹隘了,但是誰能說一個姑娘講述她那條泡泡紗裙子不是一種故事呢?所以最終一拍腦袋就決定這篇了~
zabbix的接口功能非常強大、豐富,我在開篇已經說過現有網上資料的局限性,既然是以zabbix action的創建為題,還是要簡單說一下zabbix的action(也就是zabbix報警)支持如下事件:
- Trigger 觸發器事件 - 觸發器狀態在OK和PROBLEM之間變化
- Discovery 發現事件
- Auto Registration 自動注冊事件 - 新的客戶端注冊進來
- Interval 內部事件 - item轉變為unsupported狀態,觸發器轉變為unknown狀態
調用接口數據格式說明
在官網中已經有創建trigger和discovery action的例子,(zabbix3.0官網API地址:https://www.zabbix.com/documentation/3.0/manual/api/reference),我們今天主要談談建立Auto Registration所需要的接口數據,這在官網中並沒有明確的列出,需要自己再加工一下,精簡后的json數據如下:
{ "jsonrpc": "2.0", "method": "action.create", "params": { "name": name, "eventsource": 2,
"filter": {
"conditions": [ { "conditiontype": 24, "operator":2, "value": condition }, ] }, "operations": [ { "operationtype": 4, "opgroup": [ { "groupid": groupid } ], }, { "operationtype": 6, "optemplate": [ { "templateid":10110 } ], } ] }, "auth": auth, "id": 1 }
下面一行一行來看:
-
"jsonrpc": "2.0"-這是標准的JSON RPC參數以標示協議版本,所有的請求都會保持不變。
-
"method": "action.create",這個參數定義了真實執行的操作(我們這里要進行的就是action的創建)。
-
"params": 這里通過傳遞JSON對象來作為特定方法的參數。
- name 對應的就是action的name;
- eventsource 條件類型,從官網上看來這是一個必要的條件;
- filter 對應的是conditions中的條件,由於可以有多個條件,所以conditions是一個列表,每一個條件是一個字典;
- operations 對應的就是Action operations也就是告警之后對應的操作,這里的operations也可以定義多條,所以是一個列表,每一個操作對應一個字典。
-
"id":1-這個字段用於綁定JSON請求和響應。響應會跟請求有相同的"id",在一次性發送多個請求時很有用,這些也不需要唯一或者連續。
- "auth": "159121b60d19a9b4b55d49e30cf12b81"-這是一個認證令牌【authentication token】用以鑒別用戶、訪問API。這也是使用API進行相關操作的前提-獲取認證ID。
API 使用
明白了參數,去調用API的就非常簡單了,所有不上代碼的技術貼都是耍流氓~所以就直接上代碼:

# - * -coding:utf-8 - * - __author__ = 'Eva_J' import json import urllib2 def login(): data = { "jsonrpc": "2.0", "method": "user.login", "params": { "user": "Eva_J", "password": "~RdzvwqTSf" }, "id": 0 } response = request(data) return response['result'] def request(data): url = "http://monitor.dt.zw.ted/api_jsonrpc.php" header = {"Content-Type": "application/json"} data = json.dumps(data) request = urllib2.Request(url,data) for key in header: request.add_header(key,header[key]) response = {} try: result = urllib2.urlopen(request) except Exception as e: print e else: response = json.loads(result.read()) result.close() return response def getgroupId(auth,groupName): data = { "jsonrpc": "2.0", "method": "hostgroup.get", "params": { "output": "extend", "filter": { "name":groupName } }, "auth": auth, "id": 0 } return request(data) def create(auth): condition = u'codition name' name = u"lottery-zookeeper" groupid = 1 data = { "jsonrpc": "2.0", "method": "action.create", "params": { "name": name, "eventsource": 2, "filter": { "evaltype": 0, "conditions": [ { "conditiontype": 24, "operator":2, "value": condition }, ] }, "operations": [ { "operationtype": 4, "opgroup": [ { "groupid": groupid } ], }, { "operationtype": 6, "optemplate": [ { "templateid":10110 } ], } ] }, "auth": auth, "id": 1 } response = request(data) return response def getGroupDic(): fileObj = open('group.txt','r') groupsDic = {} for line in fileObj: lineLst = line.decode('GB2312').split('\t') groupsDic[lineLst[1].strip('\n')] = lineLst[0] return groupsDic if __name__ == '__main__': auth = login() response = create(auth) print response