215 lines
11 KiB
Python
215 lines
11 KiB
Python
import yaml
|
||
import uuid
|
||
import sys
|
||
|
||
# Files
|
||
SOURCE_FILE = r"templates_work\template_windows_gold_ptbr.yaml"
|
||
TARGET_FILE = r"templates_work\template_windows_gold_ptbr.yaml"
|
||
|
||
# Translations Map (English substring -> Portuguese replacement)
|
||
TRANSLATIONS = {
|
||
# Itens Base
|
||
"Host name of Zabbix agent running": "Nome do Host (Agent)",
|
||
"Zabbix agent ping": "Status do Agente Zabbix (Ping)",
|
||
"Version of Zabbix agent running": "Versão do Agente Zabbix",
|
||
"Cache bytes": "Memória: Cache Bytes",
|
||
"Free system page table entries": "Memória: Entradas de Tabela de Página Livres",
|
||
"Memory page faults per second": "Memória: Page Faults/seg",
|
||
"Memory pages per second": "Memória: Pages/seg (Swap I/O)",
|
||
"Memory pool non-paged": "Memória: Non-paged Pool",
|
||
"Used swap space in %": "Swap: % de Uso",
|
||
"CPU DPC time": "CPU: Tempo DPC",
|
||
"CPU interrupt time": "CPU: Tempo de Interrupção",
|
||
"CPU privileged time": "CPU: Tempo Privilegiado (Kernel)",
|
||
"CPU user time": "CPU: Tempo de Usuário",
|
||
"Context switches per second": "CPU: Context Switches/seg",
|
||
"CPU queue length": "CPU: Tamanho da Fila (Queue Length)",
|
||
"Number of threads": "Sistema: Número de Threads",
|
||
"Number of processes": "Sistema: Número de Processos",
|
||
"CPU utilization": "CPU: Utilização Total",
|
||
"System name": "Sistema: Nome do Computador",
|
||
"System local time": "Sistema: Hora Local",
|
||
"Operating system architecture": "Sistema: Arquitetura do SO",
|
||
"Operating system": "Sistema: Versão do SO",
|
||
"Free swap space": "Swap: Espaço Livre",
|
||
"Total swap space": "Swap: Espaço Total",
|
||
"System description": "Sistema: Descrição",
|
||
"Uptime": "Sistema: Uptime",
|
||
"Total memory": "Memória: Total",
|
||
"Used memory": "Memória: Usada",
|
||
"Memory utilization": "Memória: % de Utilização",
|
||
"Number of cores": "Hardware: Número de Cores",
|
||
"Zabbix agent availability": "Disponibilidade do Agente Zabbix",
|
||
|
||
# Network Discovery
|
||
"Interface {#IFNAME}({#IFALIAS}): Inbound packets discarded": "Interface {#IFNAME}: Pacotes Descartados (In)",
|
||
"Interface {#IFNAME}({#IFALIAS}): Inbound packets with errors": "Interface {#IFNAME}: Erros de Pacote (In)",
|
||
"Interface {#IFNAME}({#IFALIAS}): Bits received": "Interface {#IFNAME}: Tráfego de Entrada",
|
||
"Interface {#IFNAME}({#IFALIAS}): Outbound packets discarded": "Interface {#IFNAME}: Pacotes Descartados (Out)",
|
||
"Interface {#IFNAME}({#IFALIAS}): Outbound packets with errors": "Interface {#IFNAME}: Erros de Pacote (Out)",
|
||
"Interface {#IFNAME}({#IFALIAS}): Bits sent": "Interface {#IFNAME}: Tráfego de Saída",
|
||
"Interface {#IFNAME}({#IFALIAS}): Speed": "Interface {#IFNAME}: Velocidade Negociada",
|
||
"Interface {#IFNAME}({#IFALIAS}): Operational status": "Interface {#IFNAME}: Status Operacional",
|
||
"Interface {#IFNAME}({#IFALIAS}): Interface type": "Interface {#IFNAME}: Tipo de Interface",
|
||
|
||
# Triggers & Descriptions & Event Names
|
||
"Windows: Number of free system page table entries is too low": "⚠️ Windows: Esgotamento de Tabela de Páginas",
|
||
"Windows: The Memory Pages/sec is too high": "⚠️ Windows: Excesso de Paginação (Swap)",
|
||
"Windows: CPU interrupt time is too high": "⚠️ Windows: CPU com muitas Interrupções (Hardware?)",
|
||
"Windows: CPU privileged time is too high": "⚠️ Windows: Uso Elevado de Kernel (Privileged Time)",
|
||
"Windows: High CPU utilization": "🔥 Windows: Uso de CPU Crítico",
|
||
"Windows: System name has changed": "ℹ️ Windows: Nome do Host Mudou",
|
||
"Windows: System time is out of sync": "⚠️ Windows: Hora do Sistema Dessincronizada",
|
||
"Windows: Operating system description has changed": "ℹ️ Windows: SO Atualizado/Alterado",
|
||
"Windows: Host has been restarted": "⚠️ Windows: Servidor Reiniciou",
|
||
"Windows: High memory utilization": "🧠 Windows: Memória Esgotada",
|
||
"Windows: Zabbix agent is not available": "🚨 Windows: Agente Zabbix Indisponível",
|
||
"Windows: Interface {#IFNAME}({#IFALIAS}): Link down": "🚨 Interface {#IFNAME}: Link Down",
|
||
"Windows: Interface {#IFNAME}({#IFALIAS}): Ethernet has changed to lower speed than it was before": "⚠️ Interface {#IFNAME}: Velocidade Reduzida (Negociação?)",
|
||
"Windows: Interface {#IFNAME}({#IFALIAS}): High bandwidth usage": "🔥 Interface {#IFNAME}: Saturação de Banda",
|
||
"Windows: Interface {#IFNAME}({#IFALIAS}): High error rate": "🔥 Interface {#IFNAME}: Alta Taxa de Erros",
|
||
|
||
# Common Description Terms
|
||
"The system is running out of free memory.": "O sistema está ficando sem memória livre. Verifique processos consumidores.",
|
||
"CPU utilization is too high. The system might be slow to respond.": "O uso de CPU está sitematicamente alto. O servidor pode ficar lento.",
|
||
"The host's system time is different from Zabbix server time.": "A hora do servidor difere da hora do Zabbix Server. Verifique o NTP.",
|
||
"The device uptime is less than 10 minutes.": "O servidor foi reiniciado recentemente (Uptime < 10m).",
|
||
"For passive agents only, host availability is used with `{$AGENT.TIMEOUT}` as a time threshold.": "O Agente Zabbix parou de responder. Verifique se o serviço está rodando ou se há bloqueio de firewall.",
|
||
|
||
# Generic replacements
|
||
"Windows by Zabbix agent": "Windows Gold Edition"
|
||
}
|
||
|
||
NEW_ITEMS = [
|
||
{
|
||
'uuid': '',
|
||
'name': 'RDP: Sessões Ativas (Total)',
|
||
'key': 'perf_counter_en["\\Terminal Services\\Total Sessions"]',
|
||
'delay': '1m',
|
||
'value_type': 'FLOAT',
|
||
'units': '',
|
||
'description': 'Número total de sessões de Terminal Services (RDP) ativas.',
|
||
'tags': [{'tag': 'component', 'value': 'security'}, {'tag': 'component', 'value': 'remote_access'}],
|
||
'triggers': [{
|
||
'uuid': '',
|
||
'expression': 'min(/Windows Gold Edition/perf_counter_en["\\Terminal Services\\Total Sessions"],15m)>2',
|
||
'name': '⚠️ Windows: Muitas Sessões RDP Ativas',
|
||
'event_name': '⚠️ Windows: Muitas Sessões RDP Ativas ({ITEM.LASTVALUE} > 2)',
|
||
'priority': 'WARNING',
|
||
'description': 'Existem muitas sessões de terminal abertas. Isso pode consumir recursos ou indicar sessões "penduradas".'
|
||
}]
|
||
},
|
||
{
|
||
'uuid': '',
|
||
'name': 'Disco: Tamanho da Fila (Queue Length)',
|
||
'key': 'perf_counter_en["\\PhysicalDisk(_Total)\\Current Disk Queue Length"]',
|
||
'delay': '1m',
|
||
'value_type': 'FLOAT',
|
||
'description': 'Número de solicitações de I/O aguardando serviço. Valores altos constantes indicam gargalo de disco.',
|
||
'tags': [{'tag': 'component', 'value': 'storage'}, {'tag': 'component', 'value': 'performance'}],
|
||
'triggers': [{
|
||
'uuid': '',
|
||
'expression': 'min(/Windows Gold Edition/perf_counter_en["\\PhysicalDisk(_Total)\\Current Disk Queue Length"],10m)>2',
|
||
'name': '🐢 Windows: Disco Lento (Queue Length Alta)',
|
||
'event_name': '🐢 Windows: Disco Lento (Queue Total > 2 por 10m)',
|
||
'priority': 'AVERAGE',
|
||
'description': 'A fila de disco está constantemente alta. O armazenamento não está dando conta das requisições.'
|
||
}]
|
||
},
|
||
{
|
||
'uuid': '',
|
||
'name': 'Segurança: Falhas de Login (Audit Failure)',
|
||
'key': 'eventlog[Security,,,,4625]',
|
||
'delay': '1m',
|
||
'value_type': 'LOG',
|
||
'description': 'Monitora o Event ID 4625 (Logon falhou) no log de Segurança.',
|
||
'tags': [{'tag': 'component', 'value': 'security'}],
|
||
'triggers': [{
|
||
'uuid': '',
|
||
'expression': 'count(/Windows Gold Edition/eventlog[Security,,,,4625],2m)>5',
|
||
'name': '👮 Windows: Possível Brute Force (Falhas de Login)',
|
||
'event_name': '👮 Windows: 5+ Falhas de Login em 2m',
|
||
'priority': 'HIGH',
|
||
'description': 'Foram detectadas múltiplas falhas de login (Event ID 4625) em curto período.'
|
||
}]
|
||
}
|
||
]
|
||
|
||
def load_yaml(path):
|
||
with open(path, 'r', encoding='utf-8') as f:
|
||
return yaml.safe_load(f)
|
||
|
||
def clean_tags_and_fix_uuids(data):
|
||
generated_uuids = set()
|
||
|
||
def process_node(node):
|
||
if isinstance(node, dict):
|
||
# Clean tags
|
||
for tag in ['wizard_ready', 'readme', 'vendor', 'config']:
|
||
if tag in node:
|
||
del node[tag]
|
||
|
||
# Fix UUIDs
|
||
if 'uuid' in node:
|
||
# Generate new UUID always to ensure clean slate, unless strictly needed to keep?
|
||
# Let's regenerate to be safe and Gold.
|
||
new_uuid = uuid.uuid4().hex
|
||
while new_uuid in generated_uuids:
|
||
new_uuid = uuid.uuid4().hex
|
||
node['uuid'] = new_uuid
|
||
generated_uuids.add(new_uuid)
|
||
|
||
# Translate Strings
|
||
for key in ['name', 'description', 'event_name', 'comment']:
|
||
if key in node and isinstance(node[key], str):
|
||
# Sort by length descending to avoid substring collisions
|
||
for eng, pt in sorted(TRANSLATIONS.items(), key=lambda x: len(x[0]), reverse=True):
|
||
node[key] = node[key].replace(eng, pt)
|
||
|
||
# Recursive
|
||
for k, v in list(node.items()):
|
||
process_node(v)
|
||
elif isinstance(node, list):
|
||
for item in node:
|
||
process_node(item)
|
||
|
||
process_node(data)
|
||
|
||
def main():
|
||
print(f"Loading {SOURCE_FILE}...")
|
||
try:
|
||
source = load_yaml(SOURCE_FILE)
|
||
except FileNotFoundError:
|
||
print("File not found! Make sure you are in the correct directory.")
|
||
return
|
||
|
||
# 1. Update Header
|
||
if 'zabbix_export' in source:
|
||
source['zabbix_export']['version'] = '7.0'
|
||
if 'templates' in source['zabbix_export']:
|
||
template = source['zabbix_export']['templates'][0]
|
||
template['name'] = "Windows Server Gold pt-BR"
|
||
template['description'] = "Template Windows Server Gold Edition (Pt-BR).\n\nMonitoramento Otimizado por Arthur 'O Farol'.\nInclui: RDP, Fila de Disco, Auditoria de Login e traduções completas."
|
||
|
||
# 2. Inject New Items
|
||
if 'items' not in template:
|
||
template['items'] = []
|
||
|
||
print(f"Injecting {len(NEW_ITEMS)} new items...")
|
||
for item in NEW_ITEMS:
|
||
template['items'].append(item)
|
||
|
||
# 3. Clean and Fix
|
||
print("Translating and checking UUIDs...")
|
||
clean_tags_and_fix_uuids(source)
|
||
|
||
# 4. Save
|
||
print(f"Saving to {TARGET_FILE}...")
|
||
with open(TARGET_FILE, 'w', encoding='utf-8') as f:
|
||
yaml.dump(source, f, sort_keys=False, indent=2, width=float("inf"), allow_unicode=True)
|
||
|
||
print("Build Complete!")
|
||
|
||
if __name__ == "__main__":
|
||
main()
|