From 25de6f5211962c3b0aeb5645eaa1d96bcd246482 Mon Sep 17 00:00:00 2001 From: "thiago.purkote" Date: Mon, 30 Sep 2024 11:00:01 -0300 Subject: [PATCH] =?UTF-8?q?integra=C3=A7=C3=A3o=20com=20api=20do=20zabbix?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- python/json/itguys.json | 4 +- python/requirements.txt | 1 + python/server.py | 257 +++++++++++++++++++++++++++++++++++----- 3 files changed, 233 insertions(+), 29 deletions(-) diff --git a/python/json/itguys.json b/python/json/itguys.json index 57c04fd..5ceae83 100644 --- a/python/json/itguys.json +++ b/python/json/itguys.json @@ -9,7 +9,7 @@ "imagem_User_2_segumento_2": "../Acessts/Imagens/Iconis/profile-user.png", "texto_User_segumento_2": "Usuario", "texto_Empresa_segumento_2": "itguys", - "Menu_home_a": "../Ambiente do usuario/Tela_home/Home_page.html", + "Menu_home_a": "https://dev.itguys.com.br/ambiente_do_usu%C3%A1rio/html/construindo.html", "Menu_home_img": "../Acessts/Imagens/Iconis/home.png", "Menu_home_text": "Home", "Menu_Monitor_a": "./Tela_Monitoramento/Monitoramento copy.html", @@ -24,7 +24,7 @@ "Menu_Config_a": "./Tela_config/Config_Ambiente_usuario.html", "Menu_Config_img": "../Acessts/Imagens/Iconis/engrenagem - Copia.png", "Menu_Config_text": "Configuracões", - "Tela": "./Tela_home/Home_page.html" + "Tela": "https://dev.itguys.com.br/ambiente_do_usu%C3%A1rio/html/construindo.html" } ], "config_influxdb": [ diff --git a/python/requirements.txt b/python/requirements.txt index fdb9dbb..7d49e38 100644 --- a/python/requirements.txt +++ b/python/requirements.txt @@ -8,3 +8,4 @@ Flask-WTF==1.1.1 # Proteção contra CSRF (Cross-Site Request Forgery) Flask-Talisman==0.8.1 # Para melhorar a segurança da aplicação influxdb-client==1.35.0 # Cliente para InfluxDB gunicorn==20.1.0 # Servidor WSGI (opcional, caso deseje usar em produção) +requests==2.26.0 \ No newline at end of file diff --git a/python/server.py b/python/server.py index 8efa30a..dc984f9 100644 --- a/python/server.py +++ b/python/server.py @@ -1,7 +1,9 @@ from flask import Flask, request, jsonify, send_from_directory from flask_mysqldb import MySQL +from MySQLdb.cursors import DictCursor import ldap3 import re +import requests import os import json from functools import wraps @@ -51,33 +53,6 @@ app.config['SMTP_RECIPIENT'] = os.getenv('SMTP_RECIPIENT') mysql = MySQL(app) -# Função para derivar a chave usando PBKDF2 -def derive_key(password: bytes, salt: bytes): - kdf = PBKDF2HMAC( - algorithm=hashes.SHA512(), - length=32, # O tamanho da chave de AES-256 é 32 bytes - salt=salt, - iterations=500000, - backend=default_backend() - ) - key = kdf.derive(password) - return key - -# Função para descriptografar dados -def decrypt_aes_cbc(ciphertext, key, iv): - cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) - decryptor = cipher.decryptor() - plaintext = decryptor.update(ciphertext) + decryptor.finalize() - return plaintext - -def recebe_smtp_variaveis_env(): - return { - 'SMTP_USERNAME': app.config['SMTP_USERNAME'], - 'SMTP_HOST': app.config['SMTP_HOST'], - 'SMTP_PASSWORD': app.config['SMTP_PASSWORD'], - 'SMTP_PORT': app.config['SMTP_PORT'], - 'SMTP_RECIPIENT': app.config['SMTP_RECIPIENT'] - } def token_required(f): @wraps(f) # Adiciona wraps aqui para manter o nome da função original @@ -485,6 +460,234 @@ def execute_query(uid): if client: client.close() +# Função para buscar as configurações dos servidores Zabbix do banco de dados +# Ajustar o cursor para usar DictCursor +def get_zabbix_configs(): + cursor = mysql.connection.cursor(DictCursor) # Usando DictCursor para retornar dicionários + query = "SELECT * FROM connections_zabbix" + cursor.execute(query) + configs = cursor.fetchall() # Agora retorna uma lista de dicionários + cursor.close() + return configs + +# Função para autenticar no Zabbix via API JSON-RPC +def zabbix_login(url, username, password): + headers = {'Content-Type': 'application/json-rpc'} + payload = { + "jsonrpc": "2.0", + "method": "user.login", + "params": { + "user": username, + "password": password + }, + "id": 1, + "auth": None + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + result = response.json() + + if 'result' in result: + return result['result'] # Retorna o token de autenticação + else: + raise Exception(f"Erro na autenticação: {result}") + +def get_zabbix_host_groups(auth_token, url): + headers = {'Content-Type': 'application/json-rpc'} + payload = { + "jsonrpc": "2.0", + "method": "hostgroup.get", + "params": { + "output": ["groupid", "name"], # Retorna o ID e o nome dos grupos + "real_hosts": True # Apenas grupos com hosts reais, excluindo templates + }, + "auth": auth_token, + "id": 1 + } + + # Faz a requisição para a API do Zabbix + response = requests.post(url, headers=headers, data=json.dumps(payload)) + + # Captura e retorna o resultado da resposta + return response.json().get("result", []) + +# Função para buscar os hosts de um grupo no Zabbix +def get_zabbix_hosts(auth_token, url, group_id): + headers = {'Content-Type': 'application/json-rpc'} + payload = { + "jsonrpc": "2.0", + "method": "host.get", + "params": { + "groupids": group_id, + "output": ["hostid", "name"] # Retorna o ID e o nome dos hosts + }, + "auth": auth_token, + "id": 2 + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + return response.json().get("result", []) + +# Função para buscar os itens de um host no Zabbix +def get_zabbix_items(auth_token, url, host_id): + headers = {'Content-Type': 'application/json-rpc'} + payload = { + "jsonrpc": "2.0", + "method": "item.get", + "params": { + "hostids": host_id, + "output": ["itemid", "name", "key_"] # Retorna o ID, nome e chave dos itens + }, + "auth": auth_token, + "id": 3 + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + return response.json().get("result", []) + +# Função para buscar o valor de um item específico no Zabbix +def get_item_data(auth_token, url, item_id): + headers = {'Content-Type': 'application/json-rpc'} + payload = { + "jsonrpc": "2.0", + "method": "history.get", + "params": { + "output": "extend", + "history": 0, # Tipo 0 para dados numéricos + "itemids": item_id, + "sortfield": "clock", # Ordena pelos mais recentes + "sortorder": "DESC", + "limit": 10 # Limite de 10 resultados + }, + "auth": auth_token, + "id": 4 + } + + response = requests.post(url, headers=headers, data=json.dumps(payload)) + return response.json().get("result", []) + +@app.route('/zabbix/servers', methods=['GET']) +@token_required +def get_zabbix_servers(): + try: + # Busca as configurações do banco de dados + zabbix_configs = get_zabbix_configs() # Certifique-se de que essa função está retornando dados válidos + + # Verifique se não há servidores Zabbix + if not zabbix_configs: + return jsonify({"message": "Nenhum servidor Zabbix encontrado"}), 404 + + # Formata os servidores para o frontend + servers = [] + for config in zabbix_configs: + servers.append({ + "name": config['name'], # Acessa a coluna 'name' + "type": config['type'], # Acessa a coluna 'type' + "url": config['url'] # Acessa a coluna 'url' + }) + + return jsonify(servers) + + except Exception as e: + # Mostra o erro exato que está ocorrendo para facilitar o debug + return jsonify({"error": str(e)}), 500 + + + +@app.route('/zabbix//groups', methods=['GET']) +@token_required +def get_host_groups(server_name): + try: + # Busca as configurações do banco de dados para o servidor Zabbix com o nome "server_name" + zabbix_configs = get_zabbix_configs() + config = next((conf for conf in zabbix_configs if conf['name'] == server_name), None) + + if config is None: + return jsonify({"error": "Servidor Zabbix não encontrado"}), 404 + + # Autentica no servidor Zabbix + auth_token = zabbix_login(config['url'], config['username'], config['password']) + + # Busca os grupos de hosts reais, excluindo os templates + groups = get_zabbix_host_groups(auth_token, config['url']) + + return jsonify(groups) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + + +# Rota para listar os hosts de um grupo específico +@app.route('/zabbix//groups//hosts', methods=['GET']) +@token_required +def get_hosts_by_group(server_name, group_id): + try: + # Busca as configurações do servidor Zabbix no banco de dados + zabbix_configs = get_zabbix_configs() + config = next((conf for conf in zabbix_configs if conf['name'] == server_name), None) + + if config is None: + return jsonify({"error": "Servidor Zabbix não encontrado"}), 404 + + # Autentica no servidor Zabbix + auth_token = zabbix_login(config['url'], config['username'], config['password']) + + # Busca os hosts do grupo + hosts = get_zabbix_hosts(auth_token, config['url'], group_id) + + return jsonify(hosts) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + +# Rota para listar os itens de um host específico +@app.route('/zabbix//hosts//items', methods=['GET']) +@token_required +def get_items_by_host(server_name, host_id): + try: + # Busca as configurações do servidor Zabbix no banco de dados + zabbix_configs = get_zabbix_configs() + config = next((conf for conf in zabbix_configs if conf['name'] == server_name), None) + + if config is None: + return jsonify({"error": "Servidor Zabbix não encontrado"}), 404 + + # Autentica no servidor Zabbix + auth_token = zabbix_login(config['url'], config['username'], config['password']) + + # Busca os itens do host + items = get_zabbix_items(auth_token, config['url'], host_id) + + return jsonify(items) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + +# Rota para retornar os dados de um item específico +@app.route('/zabbix//items//data', methods=['GET']) +@token_required +def get_item_history(server_name, item_id): + try: + # Busca as configurações do servidor Zabbix no banco de dados + zabbix_configs = get_zabbix_configs() + config = next((conf for conf in zabbix_configs if conf['name'] == server_name), None) + + if config is None: + return jsonify({"error": "Servidor Zabbix não encontrado"}), 404 + + # Autentica no servidor Zabbix + auth_token = zabbix_login(config['url'], config['username'], config['password']) + + # Busca os dados do item + item_data = get_item_data(auth_token, config['url'], item_id) + + return jsonify(item_data) + + except Exception as e: + return jsonify({"error": str(e)}), 500 + + + if __name__ == '__main__':