Add production installer and observability tooling

This commit is contained in:
2026-05-07 12:11:15 -03:00
parent a19ac9f00c
commit 5d92a6c99a
30 changed files with 3493 additions and 1015 deletions
+155 -55
View File
@@ -1,97 +1,197 @@
# V-Fire Monitor
Aplicacao Flask para monitoramento de centrais Notifier via Modbus/TCP, com painel web, descoberta de pontos, integracao com Zabbix e licenciamento por hardware.
# V-Fire Monitor
Aplicacao Flask para monitoramento de centrais Notifier via Modbus/TCP, com painel web, descoberta de pontos, integracao com Zabbix e licenciamento por hardware.
## O que mudou nesta refatoracao
- Persistencia JSON com escrita atomica e migracao de configuracao legada.
- Login com hash de senha em vez de senha em texto puro no arquivo de configuracao.
- Alteracao de credenciais pelo proprio painel, sem editar arquivo manualmente.
- Chave secreta do Flask persistida localmente, sem valor fixo no codigo.
- Cookies de sessao e headers HTTP endurecidos para operacao web basica em producao.
- Protecao CSRF para login e APIs mutaveis.
- Validacao de payloads da API e respostas de erro consistentes.
- Validacao de IPs de nodes e validacao do serial antes de gravar a licenca.
- Logging basico para diagnostico, no lugar de falhas silenciosas.
- Polling Modbus e discovery por blocos, reduzindo chamadas individuais.
- Frontend com tratamento de erro e textos corrigidos.
- Healthcheck publico e endpoint autenticado com status operacional do monitor.
- Shutdown mais limpo da thread de monitoramento.
- Frontend com assets locais, sem dependencia de CDN externa.
- Gerador de licenca com argumentos de linha de comando e validacao de data.
## Estrutura
## Estrutura
- `monitor.py`: entrypoint simples da aplicacao Flask.
- `simulator_nfs320.py`: simulador Modbus/TCP local de uma central NFS-320 para testes.
- `vfire_monitor/__init__.py`: app factory e bootstrap da aplicacao.
- `vfire_monitor/core.py`: regras de negocio, persistencia, licenca e engine de monitoramento.
- `vfire_monitor/routes.py`: rotas web e APIs.
- `vfire_monitor/core.py`: regras de negocio, persistencia, licenca e engine de monitoramento.
- `vfire_monitor/routes.py`: rotas web e APIs.
- `generator.py`: gerador de serial de licenca.
- `static/`: assets locais de interface carregados pela aplicacao.
- `templates/`: telas do login e dashboard.
- `tests/`: suite inicial de testes automatizados.
- `config_nodes.json`: configuracao persistida da aplicacao.
- `mapa_dispositivos.json`: mapa de dispositivos descobertos.
- `license.key`: serial instalado localmente.
- `app_secret.key`: segredo de sessao gerado automaticamente na primeira execucao.
- `tests/`: suite inicial de testes automatizados.
- `config_nodes.json`: configuracao persistida da aplicacao.
- `mapa_dispositivos.json`: mapa de dispositivos descobertos.
- `license.key`: serial instalado localmente.
- `app_secret.key`: segredo de sessao gerado automaticamente na primeira execucao.
## Requisitos
- Python 3.10+
- Conectividade com as centrais via Modbus/TCP
- Acesso ao servidor Zabbix, quando a integracao estiver habilitada
Instalacao:
```bash
pip install -r requirements.txt
```
## Variaveis de ambiente
Veja `.env.example`.
As principais:
- `VFM_DEFAULT_PASSWORD`: senha inicial do usuario `admin` na primeira carga do sistema.
- `VFM_APP_SECRET`: opcional, substitui o segredo salvo em `app_secret.key`.
- `VFM_LICENSE_MASTER_KEY`: chave mestre do licenciamento. Em producao, use esta variavel e remova a dependencia da chave legada.
- `VFM_ENV`: use `production` para obrigar `VFM_LICENSE_MASTER_KEY` no startup.
- Para instalacao automatizada da stack completa, Debian 13 (trixie)
Instalacao:
```bash
pip install -r requirements.txt
```
## Variaveis de ambiente
Veja `.env.example`.
As principais:
- `VFM_DEFAULT_PASSWORD`: senha inicial do usuario `admin` na primeira carga do sistema.
- `VFM_APP_SECRET`: opcional, substitui o segredo salvo em `app_secret.key`.
- `VFM_LICENSE_MASTER_KEY`: chave mestre do licenciamento. Em producao, use esta variavel e remova a dependencia da chave legada.
- `VFM_ENV`: use `production` para obrigar `VFM_LICENSE_MASTER_KEY` no startup.
- `VFM_LOG_LEVEL`: nivel de log, por exemplo `INFO` ou `DEBUG`.
- `VFM_SESSION_COOKIE_SECURE`: force cookie `Secure`, recomendado atras de HTTPS.
- `VFM_TRUST_PROXY`: habilita `ProxyFix` quando houver reverse proxy na frente.
- `VFM_MAX_CONTENT_LENGTH`: limite maximo do corpo HTTP em bytes.
- `HOST`: host HTTP do processo Flask.
- `PORT`: porta HTTP da aplicacao.
Cada central aceita:
- `nome`
- `ip`
- `unit`
- `port`: opcional na integracao Modbus, default `502`
## Execucao
```bash
python monitor.py
```
```bash
python monitor.py
```
O sistema sobe em `http://0.0.0.0:8080` por padrao.
## Geracao de licenca
Modo interativo:
Healthcheck:
```bash
python generator.py
curl http://127.0.0.1:8080/healthz
```
Modo por argumentos:
Status operacional autenticado:
```bash
curl http://127.0.0.1:8080/api/system/status
```
## Instalador Debian 13
O repositorio inclui um instalador para Debian 13 que provisiona:
- `V-Fire Monitor` como servico `systemd`
- `PostgreSQL`
- `Zabbix Server + frontend Nginx`
- `Grafana`
- importacao automatica do template `Notifier NFS320`
- criacao automatica do host monitorado no Zabbix
- datasource do Grafana apontando para o Zabbix
- dashboard inicial de planta baixa e icones SVG locais
Arquivos:
- [installer/install_debian13.sh](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/installer/install_debian13.sh)
- [installer/vfire-stack.env.example](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/installer/vfire-stack.env.example)
- [serve.py](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/serve.py): entrypoint de producao do app com Waitress
- [docs/INSTALACAO_DEBIAN13.md](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/docs/INSTALACAO_DEBIAN13.md)
- [docs/LICENCIAMENTO.md](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/docs/LICENCIAMENTO.md)
- [docs/GRAFANA_PLANTA_BAIXA.md](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/docs/GRAFANA_PLANTA_BAIXA.md)
- [floorplan/floorplan-map.example.json](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/floorplan/floorplan-map.example.json)
- [tools/build_floorplan_bundle.py](/mnt/c/Users/Syllas/Documents/V-Fire-Monitor/tools/build_floorplan_bundle.py)
Fluxo recomendado:
1. Copie `installer/vfire-stack.env.example` para `installer/vfire-stack.env`.
2. Ajuste senhas, hostname e `VFM_LICENSE_MASTER_KEY`.
3. Opcionalmente valide em dry-run:
```bash
./installer/install_debian13.sh --dry-run ./installer/vfire-stack.env
```
4. Execute como `root` no Debian 13:
```bash
chmod +x installer/install_debian13.sh
./installer/install_debian13.sh ./installer/vfire-stack.env
```
Portas padrao do instalador:
- `V-Fire Monitor`: `8088`
- `Zabbix frontend`: `8080`
- `Grafana`: `3000`
Ao final, o instalador grava um resumo em `/root/vfire-stack-summary.txt`.
## Geracao de licenca
Modo interativo:
```bash
python generator.py
```
Modo por argumentos:
```bash
python generator.py --hwid "UUID-DO-CLIENTE" --cliente "Cliente" --expira 2026-12-31
```
## Observacoes operacionais
## Simulador NFS-320
Para testar sem uma central fisica:
```bash
python simulator_nfs320.py --host 127.0.0.1 --port 1502
```
Depois, no painel do V-Fire Monitor, cadastre uma central com:
- `Nome`: `Sim NFS320`
- `IP`: `127.0.0.1`
- `Unit`: `3`
- `Porta`: `1502`
O simulador publica detectores, modulos e um painel repetidor com estados alternando entre normal, incidente, ack e removido.
## Observacoes operacionais
- A senha do painel fica armazenada como hash em `config_nodes.json`.
- O serial de licenca e validado antes de ser salvo em `license.key`.
- Em Linux, `app_secret.key` e `license.key` passam a ser gravados com permissao privada (`0600`).
- O painel exige token CSRF em login e chamadas mutaveis da API.
- Se existir configuracao antiga com `web_password`, ela e migrada automaticamente para `web_password_hash`.
- Em ambiente de desenvolvimento, o sistema ainda aceita a chave de licenca legada embutida para manter compatibilidade.
- Em ambiente de producao (`VFM_ENV=production`), `VFM_LICENSE_MASTER_KEY` passa a ser obrigatoria e o sistema falha no startup sem ela.
- Bootstrap continua sendo carregado via CDN. Se o ambiente nao tiver acesso externo, copie os assets localmente e ajuste os templates.
## Testes
- A interface web usa assets locais em `static/`, sem dependencia de internet para carregar CSS e JS.
## Testes
Executar:
```bash
pytest
python3 -m pytest
```
## Proximos passos recomendados
- Adicionar testes cobrindo polling Modbus e integracao com Zabbix com doubles dedicados.
- Separar configuracao e logging em modulos proprios se a aplicacao continuar crescendo.
- Trocar Bootstrap via CDN por assets locais se o ambiente alvo nao tiver acesso externo.
## Proximos passos recomendados
- Adicionar testes cobrindo polling Modbus e integracao com Zabbix com doubles dedicados.
- Separar configuracao e logging em modulos proprios se a aplicacao continuar crescendo.