mirror of
https://github.com/thatmattlove/hyperglass.git
synced 2026-04-17 21:38:27 +00:00
96 lines
3.6 KiB
Python
96 lines
3.6 KiB
Python
"""Remove anything before the command if found in output."""
|
|
|
|
# Standard Library
|
|
import re
|
|
import typing as t
|
|
|
|
# Third Party
|
|
from pydantic import PrivateAttr
|
|
|
|
# Project
|
|
from hyperglass.log import log
|
|
from hyperglass.types import Series
|
|
|
|
# Local
|
|
from .._output import OutputType, OutputPlugin
|
|
|
|
if t.TYPE_CHECKING:
|
|
# Project
|
|
from hyperglass.models.api.query import Query
|
|
|
|
|
|
class MikrotikGarbageOutput(OutputPlugin):
|
|
"""Parse Mikrotik output to remove garbage before structured parsing."""
|
|
|
|
_hyperglass_builtin: bool = PrivateAttr(True)
|
|
platforms: t.Sequence[str] = ("mikrotik_routeros", "mikrotik_switchos", "mikrotik")
|
|
# Aplicar a todos os comandos para garantir a limpeza
|
|
directives: t.Sequence[str] = (
|
|
"__hyperglass_mikrotik_bgp_aspath__",
|
|
"__hyperglass_mikrotik_bgp_community__",
|
|
"__hyperglass_mikrotik_bgp_route__",
|
|
"__hyperglass_mikrotik_ping__",
|
|
"__hyperglass_mikrotik_traceroute__",
|
|
)
|
|
|
|
def process(self, *, output: OutputType, query: "Query") -> Series[str]:
|
|
"""
|
|
Clean raw output from a MikroTik device.
|
|
This plugin removes command echoes, prompts, flag legends, and interactive help text.
|
|
"""
|
|
|
|
# O 'output' é uma tupla de strings, onde cada string é a saída de um comando.
|
|
# Vamos processar cada uma delas.
|
|
cleaned_outputs = []
|
|
|
|
for raw_output in output:
|
|
|
|
# Se a saída já estiver vazia, não há nada a fazer.
|
|
if not raw_output or not raw_output.strip():
|
|
cleaned_outputs.append("")
|
|
continue
|
|
|
|
# 1. Dividir a saída em linhas para processamento individual.
|
|
lines = raw_output.splitlines()
|
|
|
|
# 2. Filtrar as linhas de "lixo" conhecidas.
|
|
filtered_lines = []
|
|
in_flags_section = False
|
|
for line in lines:
|
|
stripped_line = line.strip()
|
|
|
|
# Ignorar prompts e ecos de comando
|
|
if stripped_line.startswith("@") and stripped_line.endswith("] >"):
|
|
continue
|
|
|
|
# Ignorar a linha de ajuda interativa
|
|
if "[Q quit|D dump|C-z pause]" in stripped_line:
|
|
continue
|
|
|
|
# Iniciar a detecção da seção de Flags
|
|
if stripped_line.startswith("Flags:"):
|
|
in_flags_section = True
|
|
continue # Pula a própria linha "Flags:"
|
|
|
|
# Se estivermos na seção de flags, verificar se a linha ainda é parte dela.
|
|
# Uma linha de dados de rota real geralmente começa com flags (ex: "Ab") ou é indentada.
|
|
# Uma linha da legenda de flags não.
|
|
if in_flags_section:
|
|
# Se a linha não começar com espaço ou não tiver um "=" (sinal de dado),
|
|
# é provável que seja parte da legenda.
|
|
# A forma mais segura é procurar pelo fim da legenda.
|
|
# A primeira linha de dados real começa com flags ou indentação.
|
|
# Vamos assumir que a legenda termina quando encontramos uma linha que contém "=".
|
|
if "=" in stripped_line:
|
|
in_flags_section = False
|
|
else:
|
|
continue # Pula as linhas da legenda de flags
|
|
|
|
filtered_lines.append(line)
|
|
|
|
# 3. Juntar as linhas limpas de volta em uma única string.
|
|
cleaned_output = "\n".join(filtered_lines)
|
|
cleaned_outputs.append(cleaned_output)
|
|
|
|
log.debug(f"MikrotikGarbageOutput cleaned {len(output)} output blocks.")
|
|
return tuple(cleaned_outputs)
|