templates-zabbix-itguys/export_hosts_zabbix.py

181 lines
6.6 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import requests
import json
import sys
import argparse
from datetime import datetime
# ==============================================================================
# 🛠️ CONFIGURAÇÕES DO USUÁRIO - EDITE AQUI
# ==============================================================================
# URL do seu Zabbix antigo (ex: http://192.168.1.100/zabbix/api_jsonrpc.php)
ZABBIX_URL = "http://172.16.254.11/zabbix/api_jsonrpc.php"
# Credenciais de um usuário com permissão de leitura total (Admin ou Super Admin)
ZABBIX_USER = "Admin"
ZABBIX_PASS = "M@dC@tMK11"
# Nome do arquivo de saída
OUTPUT_FILE = "zabbix_hosts_export.json"
# ==============================================================================
# 🚀 INÍCIO DO SCRIPT (Não precisa editar abaixo, a menos que saiba o que faz)
# ==============================================================================
def print_header():
print("="*60)
print(" 📦 EXPORTADOR DE HOSTS ZABBIX - BASEADO NO PADRÃO ARTHUR")
print("="*60)
print(f"📅 Data: {datetime.now().strftime('%d/%m/%Y %H:%M:%S')}")
print(f"🎯 Alvo: {ZABBIX_URL}")
print("="*60 + "\n")
def zabbix_api_call(method, params, auth_token=None, request_id=1):
"""
Faz uma chamada JSON-RPC para a API do Zabbix.
"""
headers = {'Content-Type': 'application/json-rpc'}
payload = {
"jsonrpc": "2.0",
"method": method,
"params": params,
"id": request_id
}
if auth_token:
# Padrão: Auth no corpo. O main() pode alterar isso se detectar 6.4+
# Se o token começar com 'Bearer', usamos via header (adaptação dinâmica)
if str(auth_token).startswith("USE_HEADER:"):
real_token = auth_token.split(":", 1)[1]
headers["Authorization"] = f"Bearer {real_token}"
else:
payload["auth"] = auth_token
try:
# verify=False é crucial para Zabbix legados com certificados inválidos
response = requests.post(ZABBIX_URL, data=json.dumps(payload), headers=headers, verify=False, timeout=30)
response.raise_for_status()
decoded = response.json()
if 'error' in decoded:
# Se for erro de "Unexpected parameter 'auth'", tentamos retry sem auth no body?
# Melhor garantir na detecção de versão.
print(f"\n❌ ERRO NA API ZABBIX ({method}):")
print(f" Mensagem: {decoded['error'].get('message', 'Sem mensagem')}")
print(f" Detalhes: {decoded['error'].get('data', 'Sem detalhes')}")
sys.exit(1)
return decoded['result']
except requests.exceptions.ConnectionError:
print(f"\n❌ ERRO DE CONEXÃO:")
print(f" Não foi possível conectar em: {ZABBIX_URL}")
print(" Verifique se a URL está correta e se o servidor está acessível.")
sys.exit(1)
except requests.exceptions.Timeout:
print(f"\n❌ ERRO DE TIMEOUT:")
print(" O servidor demorou muito para responder.")
sys.exit(1)
except Exception as e:
print(f"\n❌ ERRO INESPERADO: {e}")
sys.exit(1)
def main():
# Desabilita warnings chatos de SSL inseguro
requests.packages.urllib3.disable_warnings()
print_header()
# 1. Autenticação
print("🔐 1. Autenticando no Zabbix...", end=" ")
try:
# Tenta conectar usando 'username' (padrão 5.4+)
try:
auth_token = zabbix_api_call("user.login", {"username": ZABBIX_USER, "password": ZABBIX_PASS})
except SystemExit:
# Se falhar (ex: Zabbix antigo < 5.4), tenta com 'user'
print("⚠️ Falha com 'username', tentando com método legado 'user'...")
auth_token = zabbix_api_call("user.login", {"user": ZABBIX_USER, "password": ZABBIX_PASS})
print(f"✅ Sucesso!\n 🔑 Token: {auth_token[:10]}...")
except SystemExit:
raise
except Exception as e:
print(f"❌ Falha: {e}")
sys.exit(1)
# 2. Obter versão da API (opcional, mas bom pra debug)
print("\n🔍 2. Verificando versão da API...", end=" ")
api_info = zabbix_api_call("apiinfo.version", {}, auth_token=None)
print(f"✅ Versão detectada: {api_info}")
# DECISÃO DE AUTH: Zabbix 6.4+ prefere Bearer Token no Header
use_header_auth = False
try:
major_minor = float(api_info[:3]) # Pega "6.0", "7.0"
if major_minor >= 6.4:
print(f" Zabbix moderno (>6.4) detectado. Usando Auth via Header.")
# Marcamos o token para ser usado via header
auth_token = f"USE_HEADER:{auth_token}"
use_header_auth = True
except ValueError:
pass # Versão estranha, mantém legado
# 3. Listar Hosts
print("\n📋 3. Buscando lista de hosts...", end=" ")
hosts = zabbix_api_call("host.get", {
"output": ["hostid", "name"],
"preservekeys": True
}, auth_token)
host_ids = list(hosts.keys())
count = len(host_ids)
print(f"✅ Encontrados: {count} hosts.")
if count == 0:
print("\n⚠️ Nenhum host encontrado para exportar. Encerrando.")
return
# 4. Exportar (O Heavy Lifting)
print(f"\n📦 4. Iniciando exportação completa (Configuration Export)...")
print(" Isso pode demorar um pouco dependendo do tamanho da base. Aguarde...")
export_params = {
"options": {
"hosts": host_ids
},
"format": "json"
}
try:
export_data = zabbix_api_call("configuration.export", export_params, auth_token)
except SystemExit:
print("\n❌ Falha na exportação. Verifique se o usuário tem permissão para exportar hosts.")
sys.exit(1)
# 5. Salvar Arquivo
print(f"\n💾 5. Salvando arquivo '{OUTPUT_FILE}'...", end=" ")
try:
with open(OUTPUT_FILE, 'w', encoding='utf-8') as f:
if isinstance(export_data, str):
f.write(export_data)
else:
json.dump(export_data, f, indent=4, ensure_ascii=False)
print("✅ Sucesso!")
except Exception as e:
print(f"\n❌ Erro ao salvar arquivo: {e}")
sys.exit(1)
# Conclusão
print("\n" + "="*60)
print("🎉 PROCESSO CONCLUÍDO COM SUCESSO!")
print(f" Arquivo gerado: {OUTPUT_FILE}")
print(" Total de hosts: ", count)
print("="*60)
print("\n👉 COMO IMPORTAR:")
print(" 1. Vá no seu novo Zabbix > Configuration > Hosts")
print(" 2. Clique em 'Import'")
print(f" 3. Selecione o arquivo '{OUTPUT_FILE}'")
print(" 4. Marque 'Create new' e 'Update existing'")
if __name__ == "__main__":
main()