Skip to content

v0.71.0

Choose a tag to compare

@adrianfiio adrianfiio released this 02 Aug 00:35

AFService Map v0.71.0 — Monitoramento de portas e enlaces

Backup/ponto de rollback desta rodada: tag v0.70.0 (também disponível
como branch backup/mapa-pre-monitoramento-v071). Pacote preparado pelo
ChatGPT, construído em cima do apps.snmp_monitoring já existente (da
v0.68.0), aplicado via apply_monitoring_links_v071.py (validado antes
com --dry-run, sem erro).

Tem migrationssnmp_monitoring.0002_link_monitoring e
alerts.0002_network_monitoring_alerts — vieram prontas no pacote desta
vez (diferente da Master Suite v0.70.0, não precisei escrever nenhuma à
mão). Revisei as duas por completo: só criação de tabela, AddField
opcional (null=True) e AlterField de choices — nada destrutivo.

Um bug real encontrado e corrigido antes de liberar

O aplicador do pacote tem uma função (patch_core_views) que insere
Q(company_id__in=company_ids) em dois filtros de alerta dentro de
apps/core/views.py. Ela usa um laço que chama .replace(old, new, 1)
duas vezes — mas como o texto de substituição (new) contém o próprio
texto original (old) como sufixo, a segunda chamada encontrou de novo
o texto recém-substituído (que ainda continha old embutido) em vez do
segundo ponto do arquivo. Resultado: o filtro novo saiu duplicado no
primeiro ponto (DashboardView._provider_context, inofensivo — só uma
condição OR repetida) e completamente ausente no segundo, que é a
view de verdade da página "Central de alertas"
(company_alerts).

Na prática, sem esse ajuste, um alerta de porta ou enlace monitorado
(que tem company preenchido diretamente, mas não cto/olt/route)
nunca apareceria na Central de alertas de ninguém — o próprio recurso
principal desta versão ficaria invisível na tela que deveria mostrá-lo.
Corrigi manualmente: removi a duplicata, adicionei o filtro certo em
company_alerts, e ampliei o select_related da view pra incluir
monitored_link/container_equipment/equipment_port (o template já
passou a exibir esses campos; sem o select_related cada linha da
lista faria consultas extras).

O que entrou

Monitoramento nos equipamentos internos

Switch, roteador, firewall, servidor, access point, rádio PTP, ONU/ONT e
outros equipamentos ativos de Rack/Torre ganham a opção "Monitoramento":
IP de gerência, porta SNMP, community (criptografada, nunca retorna pela
API) e intervalo de coleta. OLT continua bloqueada neste fluxo
universal — ela usa a integração própria já existente.

Descoberta e mapeamento de portas

Depois da primeira coleta, o sistema mostra ifName/ifIndex/ifAlias/
status/última coleta, e cada interface pode ser associada a uma porta
física já cadastrada no equipamento, com uma função: Backbone, Uplink,
Acesso, Wireless/PTP, Gerência ou Outro. Só as portas vinculadas
controlam o status de enlaces — uma interface de cliente ou desligada
sem vínculo não derruba o equipamento inteiro.

Backbone entre cidades (com dois caminhos)

Um enlace liga duas portas monitoradas e opcionalmente um FiberCable
do mapa. Dá pra cadastrar dois caminhos independentes (ex.: principal e
secundário), cada um com portas, cabo, cor e alerta próprios — uma queda
no principal deixa só aquele cabo vermelho, o backup continua normal.

Estados: UP+UP = normal, UP+DOWN ou DOWN+DOWN = offline, UP+sem dado =
degradado, sem dados nas duas pontas = sem dados.

Quando confirma a queda (após o debounce): porta, equipamento, estrutura
e linha do enlace ficam vermelhos, o FiberCable.status vira offline (o
cabo aparece vermelho no mapa) e um alerta é criado. Na recuperação,
tudo volta ao normal e o alerta fecha sozinho.

Enlaces PTP wireless

Mesmo conceito, mas sem exigir cabo óptico: linha reta tracejada entre
as torres, cor roxa por padrão (configurável), mostra o status das duas
pontas no popup.

Debounce

Configurável por porta/enlace — padrão 30s pra confirmar queda e 30s
pra confirmar recuperação, evitando abrir e fechar alerta por oscilação
SNMP passageira.

Central de alertas ampliada

Novos escopos: equipamento, porta monitorada, enlace monitorado.
AlertEvent passa a ter company diretamente (além de elemento,
equipamento, porta, enlace, cabo, rota, projeto) — funciona pra empresa
com IXCSoft, com outro ERP, ou só com cadastro manual (antes só existiam
vínculos com OLT/PON/ONU/CTO/rota).

Desempenho

Consulta ao InfluxDB deixou de ser uma por equipamento — agora os
perfis são consultados em lote, portas atualizadas numa única passada, e
os enlaces avaliados depois. Atualização visual do mapa a cada 15s,
coleta Celery a cada 30s (SNMP_STATUS_POLL_SECONDS, configurável).

Além disso, corrigido um problema já existente desde a v0.68.0: o sinal
que recarrega o Telegraf disparava a cada save() do perfil — inclusive
os saves de telemetria feitos pela própria task de coleta (a cada ~30s).
Agora só dispara reload quando um campo de configuração de verdade muda
(IP, community, alvo etc.), não a cada ciclo de telemetria.

Segurança

  • Token do InfluxDB só por variável de ambiente — nunca no código. Se o
    token que foi colado numa conversa anterior ainda não foi rotacionado
    no InfluxDB, isso continua pendente (é uma ação fora do repositório,
    só o painel do InfluxDB resolve).
  • Community SNMP criptografada, nunca em texto puro.
  • Socket do Docker continua montado só no worker — verificado
    manualmente que web: não o recebe.
  • Recarga do Telegraf por SIGHUP, sem os.system nem docker restart.

Verificação feita nesta rodada

  • --dry-run do aplicador rodado antes da aplicação real, sem erro.
  • python -m py_compile em todos os arquivos Python tocados/adicionados.
  • Sintaxe de map-link-monitoring.js (novo) verificada com esprima;
    chaves de map-link-monitoring.css balanceadas; {% if %}/{% endif %}
    de templates/map.html balanceados; docker-compose.yml validado como
    YAML.
  • Leitura completa dos dois modelos novos, das duas migrations, da task
    de coleta, do módulo de status/debounce, da API (6 endpoints) e do
    influx_client.py: todo endpoint usa scope_company_queryset/
    can_edit_company; toda query ao InfluxDB valida o formato do
    influx_id (regex ^[a-f0-9]{32}$) antes de compor a query Flux,
    mesmo esse valor sendo gerado pelo servidor (nunca vindo direto do
    usuário) — proteção extra contra injeção na query.
  • Rodei de verdade os testes puros incluídos no pacote
    (test_link_status.py, que não depende de banco): as 5 asserções de
    UP/UP, UP/DOWN, ponta ausente e debounce de queda/recuperação passaram
    quando executadas diretamente neste ambiente.
  • Verifiquei manualmente as 4 asserções do teste estático
    (test_monitoring_package_static.py): CSS/JS carregados no template,
    rota api/monitoring/ registrada, web sem /var/run/docker.sock,
    nenhum token hardcoded em settings.py — todas passam.
  • Encontrado e corrigido o bug de duplicação/omissão do filtro de
    empresa em apps/core/views.py (detalhado acima).

A suíte Django completa (manage.py check, manage.py test), as
migrations reais e os testes com equipamento físico (docs/TEST_PLAN_MONITORAMENTO_ENLACES.md)
dependem de banco, PostGIS, InfluxDB, Telegraf e SNMP reais — não rodam
neste ambiente de preparação.

Atualização

Execute apply no servidor — roda as duas migrations automaticamente.
Depois, rode manualmente (o apply não faz isso sozinho):

docker compose exec web python manage.py rebuild_snmp_monitoring --poll

Como configurar depois do deploy

  1. Abrir uma Torre ou Rack → Equipamentos.
  2. Criar as portas físicas do switch/roteador/AP/rádio.
  3. Clicar em "Monitoramento", informar IP e community, salvar.
  4. Clicar em "Consultar agora", aguardar alguns segundos, clicar em
    "Atualizar".
  5. Associar cada interface SNMP à porta física correspondente.
  6. Repetir na outra ponta.
  7. Abrir o botão de enlaces na barra do mapa → escolher Backbone óptico/
    Fibra/Cobre/PTP wireless → selecionar as duas portas (e o cabo, se
    for backbone/fibra).
  8. Também dá pra usar "Monitorar enlace" direto no popup do cabo.

Teste sugerido: derrubar administrativamente uma porta de teste e
confirmar que, após ~30s, a porta/marcador/linha ficam vermelhos, o cabo
(se houver) vira offline, e um alerta abre na Central de alertas da
empresa certa; reativar a porta e confirmar que tudo volta ao normal e o
alerta fecha sozinho após outros ~30s.