zabbix批量主機維護腳本兼容性更新

最近做新老版本zabbix監控主機遷移發現zabbix6.0后api安全有了效大升級,批量主機維護腳本出現認證兼容性問題,以下為腳本更新token支持:`在這里插入代碼片:

# /usr/bin/env python3
# -*- coding:utf-8 -*-
import requests
import json
import os
import re
from typing import List, Dict
import ipaddress## 用戶配置區域
ZABBIX_URL = "http://[IP]/api_jsonrpc.php"  # Zabbix API 地址(根據不同版本api接口地址調整)
USE_API_TOKEN = True  # 是否使用 API Token 認證(True/False,token與傳統認證方式二選一)
API_TOKEN = "[token]"  # zbx6創建固定Token時填寫,zbx5.0以下用動態auth-token忽略
USERNAME = "[user]"  # 傳統認證用戶名(zbx6以下兼容,使用api-token認證時忽略)
PASSWORD = "[password]"  # 傳統認證密碼(zbx6以下兼容,使用api-token認證時忽略)
HOSTS_FILE = "serverlist.txt"  # 主機列表文件路徑class ZabbixClient:def __init__(self, url: str, use_api_token: bool, token: str = None, username: str = None, password: str = None):self.url = urlself.use_api_token = use_api_tokenself.headers = {"Content-Type": "application/json-rpc"}# 配置認證if use_api_token:self.headers["Authorization"] = f"Bearer {token}"else:self.auth = self._login(username, password)def _login(self, username: str, password: str) -> str:"""傳統認證獲取Token"""payload = {"jsonrpc": "2.0","method": "user.login","params": {"user": username, "password": password},"id": 1}return self._send_request(payload, require_auth=False)["result"]def _send_request(self, payload: Dict, require_auth: bool = True) -> Dict:"""統一請求處理"""if require_auth and not self.use_api_token:payload["auth"] = self.authtry:response = requests.post(self.url,headers=self.headers,data=json.dumps(payload),timeout=10)response.raise_for_status()result = response.json()if "error" in result:error_info = result["error"]raise Exception(f"API錯誤 ({error_info['code']}): {error_info['message']}\n數據: {error_info.get('data', '')}")return resultexcept requests.exceptions.RequestException as e:raise Exception(f"請求失敗: {str(e)}")def check_host_exists(self, hostname: str) -> bool:"""檢查主機是否存在"""payload = {"jsonrpc": "2.0","method": "host.get","params": {"filter": {"host": hostname}, "output": ["hostid"]},"id": 2}result = self._send_request(payload, require_auth=True)return len(result["result"]) > 0def get_hostgroup(self, group_name: str) -> List[Dict]:"""獲取主機組ID"""payload = {"jsonrpc": "2.0","method": "hostgroup.get","params": {"filter": {"name": [group_name]},"output": ["groupid"]},"id": 3}return self._send_request(payload, require_auth=True).get("result", [])def create_hostgroup(self, group_name: str) -> str:"""創建主機組并返回ID"""payload = {"jsonrpc": "2.0","method": "hostgroup.create","params": {"name": group_name},"id": 4}result = self._send_request(payload, require_auth=True)return result["result"]["groupids"][0]def get_template(self, template_name: str) -> List[Dict]:"""獲取模板ID"""payload = {"jsonrpc": "2.0","method": "template.get","params": {"filter": {"host": [template_name]},"output": ["templateid"]},"id": 5}return self._send_request(payload, require_auth=True).get("result", [])def create_host(self, hostname: str, ip: str, groups: List[str], templates: List[str]) -> None:"""創建主機(帶完整參數校驗)"""self._validate_base_params(hostname, ip, groups, templates)if self.check_host_exists(hostname):print(f"主機 {hostname} 已存在,跳過")returngroup_ids = self._process_hostgroups(groups)template_ids = self._process_templates(templates)interface = self._build_interface(ip)payload = self._build_payload(hostname, interface, group_ids, template_ids)self._send_request(payload, require_auth=True)print(f"主機 {hostname} ({ip}) 創建成功")def _validate_base_params(self, hostname: str, ip: str, groups: List[str], templates: List[str]):"""基礎參數校驗"""if not hostname.strip():raise ValueError("主機名不可為空或僅包含空格")if not re.match(r'^[\w\-_.]+$', hostname):raise ValueError(f"主機名包含非法字符: {hostname}")if not self._is_valid_ip(ip):raise ValueError(f"無效IP地址: {ip}")if not groups or not all(groups):raise ValueError("主機組不可為空或包含空值")if not templates or not all(templates):raise ValueError("模板不可為空或包含空值")def _process_hostgroups(self, groups: List[str]) -> List[Dict]:"""處理主機組(創建不存在的組)"""group_ids = []for group in groups:group = group.strip()group_info = self.get_hostgroup(group)if not group_info:print(f"創建主機組 '{group}'...")group_id = self.create_hostgroup(group)group_ids.append({"groupid": group_id})else:group_ids.append({"groupid": group_info[0]["groupid"]})return group_idsdef _process_templates(self, templates: List[str]) -> List[Dict]:"""處理模板(校驗存在性)"""template_ids = []for template in templates:template = template.strip()template_info = self.get_template(template)if not template_info:raise Exception(f"模板 '{template}' 不存在,請檢查名稱(區分大小寫)")template_ids.append({"templateid": template_info[0]["templateid"]})return template_idsdef _build_interface(self, ip: str) -> Dict:"""構建接口參數(完整字段)"""return {"type": 1,          # Zabbix Agent接口"main": 1,          # 主接口"useip": 1,         # 使用IP地址"ip": ip,"port": "10050",     # 默認端口"dns": "",          # 可選字段,顯式為空"ipmi_dns": "","username": "","password": ""}def _build_payload(self, hostname: str, interface: Dict, group_ids: List[Dict], template_ids: List[Dict]) -> Dict:"""構建完整請求參數(移除無效庫存字段)"""return {"jsonrpc": "2.0","method": "host.create","params": {"host": hostname,"interfaces": [interface],"groups": group_ids,"templates": template_ids,"inventory_mode": 0  # 禁用自動發現,無需inventory字段},"id": 6}def _is_valid_ip(self, ip: str) -> bool:"""驗證IP地址格式(支持IPv4/IPv6)"""try:ipaddress.ip_address(ip)return Trueexcept ValueError:print(f"無效IP格式: {ip}")return Falsedef main():"""主函數:批量導入主機"""try:# 初始化客戶端if USE_API_TOKEN:zabbix = ZabbixClient(url=ZABBIX_URL,use_api_token=True,token=API_TOKEN)else:zabbix = ZabbixClient(url=ZABBIX_URL,use_api_token=False,username=USERNAME,password=PASSWORD)# 驗證主機列表文件if not os.path.exists(HOSTS_FILE):raise FileNotFoundError(f"文件 {HOSTS_FILE} 不存在")# 處理主機列表with open(HOSTS_FILE, "r", encoding="utf-8") as f:for line_num, line in enumerate(f, 1):line = line.strip()if not line or line.startswith("#"):continuetry:# 解析行數據parts = line.split("#", 3)if len(parts) != 4:raise ValueError("字段數量錯誤,必須為4個(主機名#IP#主機組#模板)")hostname, ip, groups_str, templates_str = partsgroups = groups_str.split(",") if groups_str else []templates = templates_str.split(",") if templates_str else []# 創建主機zabbix.create_host(hostname, ip, groups, templates)except ValueError as ve:print(f"行 {line_num} 格式錯誤: {str(ve)},跳過")except Exception as e:print(f"行 {line_num} 處理失敗: {str(e)}")except Exception as e:print(f"\n程序終止: {str(e)}")exit(1)if __name__ == "__main__":main()print("\n批量導入完成!")

注:輸入文件 serverlist.txt 格式:
每行 主機名#IP地址#主機組1,主機組2#模板1,模板,示例:

web-server#192.168.1.1#Web Servers,Linux#Template OS Linux
db-server#192.168.1.2#DB Servers#Template OS Linux,Template MySQL

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/82002.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/82002.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/82002.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java中static關鍵字深度解析:從入門到高階實戰

Java中static關鍵字深度解析:從入門到高階實戰 目錄 static的本質與核心特性靜態變量 vs 實例變量:底層對比靜態方法的設計哲學與應用場景高級用法:突破常規的static技巧 4.1 靜態代碼塊:類加載的“初始化引擎”4.2 靜態內部類&…

基于RT-Thread的STM32F4開發第五講——軟件模擬I2C

文章目錄 前言一、RT-Thread工程創建二、AT24C02三、函數編寫1.I2C_soft.c2.I2C_soft.h3.main.h 四、效果展示五、資源分享總結 前言 本章是基于RT-Thread studio實現軟件模擬I2C,開發板是正點原子的STM32F4探索者,使用的RT-Thread驅動是5.1.0&#xff0…

49、c# 能?foreach 遍歷訪問的對象需滿足什么條件?

在 C# 中,要使用 foreach 循環遍歷一個對象,該對象必須滿足以下條件之一: 1. 實現 IEnumerable 或 IEnumerable 接口 非泛型版本:System.Collections.IEnumerable public class MyCollection : IEnumerable {private int[] _da…

推客小程序系統開發:全棧式技術解決方案與行業賦能實踐?

? 在數字化營銷深度滲透各行業的當下,傳統推廣模式已難以滿足企業精細化運營與高效獲客的需求。專業的推客小程序系統憑借其強大的裂變傳播能力與靈活的推廣機制,成為企業構建私域流量池、提升推廣效能的核心工具。我們基于多年技術沉淀與行業洞察&…

WPF布局系統詳解:掌握界面設計的核心藝術

掌握界面設計的核心藝術 1. WPF布局系統概述2. Grid布局詳解2.1 基本行列定義2.2 單元格定位與跨行跨列 3. StackPanel布局4. DockPanel布局5. WrapPanel與Canvas5.1 WrapPanel自動換行布局 5. Canvas絕對定位6. 布局嵌套與綜合應用7. 布局性能優化8. 響應式布局技巧9. 實戰&am…

labview實現LED流水燈的第一種方法

目的:寫一個跑馬燈程序,7個燈從左到右不停的輪流點亮,閃爍間隔由滑動條調節。 一、方法1:使用順序結構 使用順序結構,平鋪式順序結構與創建局部變量實現LED流水燈 具體步驟如下: 第一步,選擇…

uniapp如何設置uni.request可變請求ip地址

文章目錄 簡介方法一:直接在請求URL中嵌入變量方法二:使用全局變量方法三:使用環境變量方法四:服務端配置方法五:使用配置文件(如config.js):總結 簡介 在uni-app中,uni.request 用…

深度學習篇---LSTMADF軌跡預測

文章目錄 前言LSTM 軌跡預測原理應用在行人軌跡預測方面在自動駕駛車輛的軌跡預測中優點缺點APF 軌跡預測原理應用在船舶運動規劃在無人駕駛車輛避障軌跡跟蹤優點缺點示例代碼前言 本文簡單介紹LSTM(長短期記憶網絡)和ADF(人工勢場法)這兩種不同的軌跡預測方法。 LSTM 軌跡…

python實現Web請求與響應

目錄 一:什么是Web請求與響應? 1:Web請求 2:Web響應 3:HTTP協議概述 4:常見的HTTP狀態碼包括: 二:python的requests庫 1:安裝requests庫 2:發送GET請…

Unity使用sherpa-onnx實現說話人識別

網友軟綿綿的面包人推薦,模型3dspeaker_speech_eres2net_base_200k_sv_zh-cn_16k-common.onnx的效果比3dspeaker_speech_eres2net_base_sv_zh-cn_3dspeaker_16k.onnx要好 具體代碼 using System; using System.Collections.Generic; using System.IO; using Sherpa…

ElasticSearch-集群

本篇文章依據ElasticSearch權威指南進行實操和記錄 1,空集群 即不包含任何節點的集群 集群大多數分為兩類,主節點和數據節點 主節點 職責:主節點負責管理集群的狀態,例如分配分片、添加和刪除節點、監控節點故障等。它們不直接…

LG P9844 [ICPC 2021 Nanjing R] Paimon Segment Tree Solution

Description 給定序列 a ( a 1 , a 2 , ? , a n ) a(a_1,a_2,\cdots,a_n) a(a1?,a2?,?,an?),有 m m m 次修改 ( l , r , v ) (l,r,v) (l,r,v): 對每個 i ∈ [ l , r ] i\in[l,r] i∈[l,r],令 a i ← a i v a_i\gets a_iv ai?←…

Google Prompt Tuning:文本嵌入優化揭秘

Google Research Prompt Tunin :from_embedded_string 在 Google Research 的 Prompt Tuning 項目代碼庫 中,from_embedded_string 函數主要用于基于字符串文本初始化提示詞的嵌入向量,其調用場景通常與提示詞優化或任務適配相關。 1. 核心代碼位置 from_embedded_string …

網頁 H5 微應用接入釘釘自動登錄

??關于云審批 云審批(cloud approve) ,一款專為小微企業打造,支持多租戶的在線審批神器。它簡化了申請和審批流程,讓您隨時隨地通過手機或電腦完成請款操作。員工一鍵提交申請,審批者即時響應&#xff0c…

idea無法識別Maven項目

把.mvn相關都刪除了 導致Idea無法識別maven項目 或者 添加導入各個模塊 最后把父模塊也要導入

飛槳paddle import fluid報錯【已解決】

跟著飛槳的安裝指南安裝了paddle之后 pip install paddlepaddle有一個驗證: import paddle.fluid as fluid fluid.install check.run check()報錯情況如下,但是我在pip list中,確實看到了paddle安裝上了 我import paddle別的包&#xff0c…

現代化SQLite的構建之旅——解析開源項目Limbo

現代化SQLite的構建之旅——解析開源項目Limbo 在當今飛速發展的技術世界中,輕量級且功能強大的數據庫已成為開發者的得力助手。當我們談論輕量級數據庫時,SQLite無疑是一個舉足輕重的名字。然而,隨著技術的進步,我們對數據庫的需求也變得更加多樣化。這正是Limbo項目誕生…

MinIO:從入門到精通,解鎖云原生存儲的奧秘

一、引言:為什么 MinIO 正在重塑存儲世界? 在云計算和大數據時代,傳統存儲系統面臨擴展性差、成本高、兼容性不足等挑戰。MinIO 憑借其 S3 兼容性、分布式架構、高性能存儲 等特性,成為企業構建現代化存儲基礎設施的首選。 本文…

vscode怎么關閉自動定位文件

關閉自動定位文件功能 方式1 在設置中搜索: explorer.autoReveal 方式2 直接在settings.json中增加"explorer.autoReveal": false 添加類似jetbrains IDE的文件定位功能 可以直接安裝插件市場搜索niushuaibing.vs-location, 安裝后會有文件定位按鈕, 點擊后即可…

學習路之uniapp--unipush2.0推送功能--給自己發通知

學習路之uniapp--unipush2.0推送功能--給自己發通知 一、綁定云空間及創建云函數二、編寫發送界面三、效果后期展望: 一、綁定云空間及創建云函數 package.json {"name": "server-push","dependencies": {},"main": "…