v0.71.0
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 migrations — snmp_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 queweb:não o recebe. - Recarga do Telegraf por
SIGHUP, semos.systemnemdocker restart.
Verificação feita nesta rodada
--dry-rundo aplicador rodado antes da aplicação real, sem erro.python -m py_compileem todos os arquivos Python tocados/adicionados.- Sintaxe de
map-link-monitoring.js(novo) verificada com esprima;
chaves demap-link-monitoring.cssbalanceadas;{% if %}/{% endif %}
detemplates/map.htmlbalanceados;docker-compose.ymlvalidado 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 usascope_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,
rotaapi/monitoring/registrada,websem/var/run/docker.sock,
nenhum token hardcoded emsettings.py— todas passam. - Encontrado e corrigido o bug de duplicação/omissão do filtro de
empresa emapps/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 --pollComo configurar depois do deploy
- Abrir uma Torre ou Rack → Equipamentos.
- Criar as portas físicas do switch/roteador/AP/rádio.
- Clicar em "Monitoramento", informar IP e community, salvar.
- Clicar em "Consultar agora", aguardar alguns segundos, clicar em
"Atualizar". - Associar cada interface SNMP à porta física correspondente.
- Repetir na outra ponta.
- 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). - 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.