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()