Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,8 @@ jobs:
assert_absent "ghcr.io/lrqnet/netkeep:${VERSION}"
assert_absent "docker.io/lrqnet/netkeep-updater:${VERSION}"
assert_absent "ghcr.io/lrqnet/netkeep-updater:${VERSION}"
assert_absent "docker.io/lrqnet/netkeep-oxidized:0.37.0-r4"
assert_absent "ghcr.io/lrqnet/netkeep-oxidized:0.37.0-r4"
assert_absent "docker.io/lrqnet/netkeep-oxidized:0.37.0-r5"
assert_absent "ghcr.io/lrqnet/netkeep-oxidized:0.37.0-r5"

netkeep-image:
needs: preflight
Expand Down Expand Up @@ -165,7 +165,7 @@ jobs:
images: |
ghcr.io/lrqnet/netkeep-oxidized
docker.io/lrqnet/netkeep-oxidized
tags: type=raw,value=0.37.0-r4
tags: type=raw,value=0.37.0-r5
- id: build
uses: docker/build-push-action@10e90e3645eae34f1e60eeb005ba3a3d33f178e8
with:
Expand Down Expand Up @@ -268,7 +268,7 @@ jobs:
mkdir -p dist
sed \
-e "s#docker.io/lrqnet/netkeep:${VERSION}#docker.io/lrqnet/netkeep@${APP_DIGEST}#g" \
-e "s#docker.io/lrqnet/netkeep-oxidized:0.37.0-r4#docker.io/lrqnet/netkeep-oxidized@${OXIDIZED_DIGEST}#g" \
-e "s#docker.io/lrqnet/netkeep-oxidized:0.37.0-r5#docker.io/lrqnet/netkeep-oxidized@${OXIDIZED_DIGEST}#g" \
-e "s#docker.io/lrqnet/netkeep-updater:${VERSION}#docker.io/lrqnet/netkeep-updater@${UPDATER_DIGEST}#g" \
compose.yaml > dist/compose.yaml
grep -q "docker.io/lrqnet/netkeep@sha256:" dist/compose.yaml
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
.DS_Store
.env
.env.*
/.inventory-lab.env
!.env.example
.env.backup
.env.production
Expand Down
17 changes: 15 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,19 @@
Todas as mudanças relevantes serão registradas aqui. O projeto segue
[Semantic Versioning](https://semver.org/).

## [Unreleased]
## [1.0.8] - 2026-07-26

### Added

- laboratório Docker isolado e reproduzível para validar integrações reais com
LibreNMS e NetBox, com portas locais exclusivas, credenciais efêmeras fora
do Git e imagens fixadas por digest;

### Fixed

- falhas de sincronização manual de inventário agora preservam somente o código
estável `inventory_sync_failed` no estado e na auditoria, sem persistir ou
enviar detalhes brutos da origem externa ao navegador.

## [1.0.7] - 2026-07-24

Expand Down Expand Up @@ -334,7 +346,8 @@ Todas as mudanças relevantes serão registradas aqui. O projeto segue
- ambiente PostgreSQL do CI alinhado ao arquivo de teste e asserções de
mensagens independentes do idioma configurado.

[Unreleased]: https://github.com/lrqnet/NetKeep/compare/v1.0.7...HEAD
[Unreleased]: https://github.com/lrqnet/NetKeep/compare/v1.0.8...HEAD
[1.0.8]: https://github.com/lrqnet/NetKeep/compare/v1.0.7...v1.0.8
[1.0.7]: https://github.com/lrqnet/NetKeep/compare/v1.0.6...v1.0.7
[1.0.6]: https://github.com/lrqnet/NetKeep/compare/v1.0.5...v1.0.6
[1.0.5]: https://github.com/lrqnet/NetKeep/compare/v1.0.4...v1.0.5
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@

<p align="center">
<a href="LICENSE"><img src="https://img.shields.io/badge/license-AGPL--3.0-34d399" alt="AGPL-3.0 license"></a>
<a href="https://github.com/lrqnet/NetKeep/releases/tag/v1.0.7"><img src="https://img.shields.io/badge/release-v1.0.7-0f172a" alt="NetKeep v1.0.7"></a>
<a href="https://github.com/lrqnet/NetKeep/releases/tag/v1.0.8"><img src="https://img.shields.io/badge/release-v1.0.8-0f172a" alt="NetKeep v1.0.8"></a>
<a href="https://hub.docker.com/r/lrqnet/netkeep"><img src="https://img.shields.io/badge/Docker-amd64%20%7C%20arm64-2496ed?logo=docker&logoColor=white" alt="Docker images for amd64 and arm64"></a>
<a href="https://github.com/ytti/oxidized"><img src="https://img.shields.io/badge/Oxidized-0.37.0-475569" alt="Oxidized 0.37.0"></a>
</p>
Expand Down Expand Up @@ -105,13 +105,13 @@ administrative networks are strongly recommended.

## Quick installation

Create a directory, download the Compose file attached to the v1.0.7 release,
Create a directory, download the Compose file attached to the v1.0.8 release,
and start the stack:

```bash
sudo mkdir -p /opt/netkeep
cd /opt/netkeep
sudo curl -fsSLO https://github.com/lrqnet/NetKeep/releases/download/v1.0.7/compose.yaml
sudo curl -fsSLO https://github.com/lrqnet/NetKeep/releases/download/v1.0.8/compose.yaml
sudo docker compose up -d --wait
sudo docker compose ps
```
Expand Down
10 changes: 6 additions & 4 deletions app/Http/Controllers/IntegrationController.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,9 @@ public function index(): Response
'enabled' => $source->enabled,
'sync_interval' => $source->sync_interval,
'last_synced_at' => $source->last_synced_at,
'last_error' => $source->last_error,
'last_error' => $source->last_error === null
? null
: __('netkeep.integrations.sync_failed'),
'has_token' => filled($source->token),
]),
]);
Expand Down Expand Up @@ -62,9 +64,9 @@ public function syncInventory(InventorySource $source, InventorySynchronizer $sy
$audit->record('integration.inventory_synced', $source, $result);

return back()->with('success', __('netkeep.integrations.sync_completed', $result));
} catch (\Throwable $exception) {
$source->update(['last_error' => $exception->getMessage()]);
$audit->record('integration.inventory_failed', $source, ['error' => $exception->getMessage()]);
} catch (\Throwable) {
$source->update(['last_error' => 'inventory_sync_failed']);
$audit->record('integration.inventory_failed', $source, ['error_code' => 'inventory_sync_failed']);

return back()->with('error', __('netkeep.integrations.sync_failed'));
}
Expand Down
200 changes: 200 additions & 0 deletions compose.inventory-lab.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,200 @@
services:
app:
ports: !override
- target: 8080
published: '${NETKEEP_LAB_HTTP_PORT:-28180}'
host_ip: 127.0.0.1
protocol: tcp
- target: 8443
published: '${NETKEEP_LAB_HTTPS_PORT:-28543}'
host_ip: 127.0.0.1
protocol: tcp

netbox-postgres:
image: postgres:18.4-alpine@sha256:9a8afca54e7861fd90fab5fdf4c42477a6b1cb7d293595148e674e0a3181de15
environment:
POSTGRES_DB: netbox
POSTGRES_USER: netbox_lab
POSTGRES_PASSWORD: '${NETKEEP_LAB_NETBOX_DATABASE_PASSWORD}'
healthcheck:
test: ['CMD-SHELL', 'pg_isready -U netbox_lab -d netbox']
interval: 5s
timeout: 5s
retries: 30
volumes:
- netbox_lab_postgres:/var/lib/postgresql
networks:
- inventory_internal

netbox-redis:
image: valkey/valkey:8.1.3-alpine@sha256:d827e7f7552cdee40cc7482dbae9da020f42bc47669af6f71182a4ef76a22773
command:
[
'valkey-server',
'--requirepass',
'${NETKEEP_LAB_NETBOX_REDIS_PASSWORD}',
]
healthcheck:
test: ['CMD-SHELL', 'valkey-cli --pass "$$REDIS_PASSWORD" ping']
interval: 5s
timeout: 5s
retries: 30
environment:
REDIS_PASSWORD: '${NETKEEP_LAB_NETBOX_REDIS_PASSWORD}'
networks:
- inventory_internal

netbox:
image: netboxcommunity/netbox:v4.6-5.0.2@sha256:691ec1a4f569f3dfb9fefd9f086cca1b39689ad59c3eae753712a741447e5e60
depends_on:
netbox-postgres:
condition: service_healthy
netbox-redis:
condition: service_healthy
environment:
DB_HOST: netbox-postgres
DB_NAME: netbox
DB_USER: netbox_lab
DB_PASSWORD: '${NETKEEP_LAB_NETBOX_DATABASE_PASSWORD}'
REDIS_HOST: netbox-redis
REDIS_PASSWORD: '${NETKEEP_LAB_NETBOX_REDIS_PASSWORD}'
REDIS_CACHE_HOST: netbox-redis
REDIS_CACHE_PASSWORD: '${NETKEEP_LAB_NETBOX_REDIS_PASSWORD}'
SECRET_KEY: '${NETKEEP_LAB_NETBOX_SECRET_KEY}'
SUPERUSER_NAME: netkeep-lab
SUPERUSER_EMAIL: netkeep-lab@example.test
SUPERUSER_PASSWORD: '${NETKEEP_LAB_NETBOX_SUPERUSER_PASSWORD}'
NETKEEP_LAB_API_TOKEN: '${NETKEEP_LAB_NETBOX_V1_TOKEN}'
API_TOKEN_PEPPER_1: '${NETKEEP_LAB_NETBOX_TOKEN_PEPPER}'
GRANIAN_WORKERS: '1'
GRANIAN_BACKPRESSURE: '1'
SKIP_SUPERUSER: 'false'
healthcheck:
test:
[
'CMD-SHELL',
'curl --fail --silent http://localhost:8080/login/ >/dev/null',
]
interval: 10s
timeout: 5s
retries: 30
start_period: 60s
ports:
- target: 8080
published: '${NETKEEP_LAB_NETBOX_PORT:-28181}'
host_ip: 127.0.0.1
protocol: tcp
volumes:
- netbox_lab_media:/opt/netbox/netbox/media
networks:
inventory_internal:
egress:
aliases: [netbox-lab]

netbox-worker:
image: netboxcommunity/netbox:v4.6-5.0.2@sha256:691ec1a4f569f3dfb9fefd9f086cca1b39689ad59c3eae753712a741447e5e60
command:
[
'/opt/netbox/venv/bin/python',
'/opt/netbox/netbox/manage.py',
'rqworker',
]
depends_on:
netbox:
condition: service_healthy
environment:
DB_HOST: netbox-postgres
DB_NAME: netbox
DB_USER: netbox_lab
DB_PASSWORD: '${NETKEEP_LAB_NETBOX_DATABASE_PASSWORD}'
REDIS_HOST: netbox-redis
REDIS_PASSWORD: '${NETKEEP_LAB_NETBOX_REDIS_PASSWORD}'
REDIS_CACHE_HOST: netbox-redis
REDIS_CACHE_PASSWORD: '${NETKEEP_LAB_NETBOX_REDIS_PASSWORD}'
SECRET_KEY: '${NETKEEP_LAB_NETBOX_SECRET_KEY}'
API_TOKEN_PEPPER_1: '${NETKEEP_LAB_NETBOX_TOKEN_PEPPER}'
SKIP_SUPERUSER: 'true'
networks:
- inventory_internal

librenms-db:
image: mariadb:11.8.3@sha256:ae6119716edac6998ae85508431b3d2e666530ddf4e94c61a10710caec9b0f71
command:
[
'mariadbd',
'--innodb-file-per-table=1',
'--character-set-server=utf8mb4',
'--collation-server=utf8mb4_unicode_ci',
]
environment:
MARIADB_DATABASE: librenms
MARIADB_USER: librenms_lab
MARIADB_PASSWORD: '${NETKEEP_LAB_LIBRENMS_DATABASE_PASSWORD}'
MARIADB_ROOT_PASSWORD: '${NETKEEP_LAB_LIBRENMS_ROOT_PASSWORD}'
healthcheck:
test:
[
'CMD-SHELL',
'mariadb-admin ping -h localhost -u root -p"$$MARIADB_ROOT_PASSWORD" --silent',
]
interval: 5s
timeout: 5s
retries: 30
volumes:
- librenms_lab_database:/var/lib/mysql
networks:
- inventory_internal

librenms-redis:
image: valkey/valkey:8.1.3-alpine@sha256:d827e7f7552cdee40cc7482dbae9da020f42bc47669af6f71182a4ef76a22773
networks:
- inventory_internal

librenms:
image: librenms/librenms:25.7.0@sha256:9914600f06af9f45ba1e99516b3187a0009b93c3ce3a0e3260f24d3e462ef2b4
depends_on:
librenms-db:
condition: service_healthy
environment:
TZ: UTC
PUID: '1000'
PGID: '1000'
DB_HOST: librenms-db
DB_NAME: librenms
DB_USER: librenms_lab
DB_PASSWORD: '${NETKEEP_LAB_LIBRENMS_DATABASE_PASSWORD}'
DB_TIMEOUT: '60'
REDIS_HOST: librenms-redis
CACHE_DRIVER: redis
SESSION_DRIVER: redis
healthcheck:
test:
[
'CMD-SHELL',
'curl --fail --silent http://localhost:8000/ >/dev/null',
]
interval: 10s
timeout: 5s
retries: 40
start_period: 90s
ports:
- target: 8000
published: '${NETKEEP_LAB_LIBRENMS_PORT:-28182}'
host_ip: 127.0.0.1
protocol: tcp
volumes:
- librenms_lab_data:/data
networks:
inventory_internal:
egress:
aliases: [librenms-lab]

networks:
inventory_internal:
internal: true

volumes:
netbox_lab_postgres:
netbox_lab_media:
librenms_lab_database:
librenms_lab_data:
8 changes: 4 additions & 4 deletions compose.yaml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
name: netkeep

x-netkeep-image: &netkeep-image
image: ${NETKEEP_IMAGE:-docker.io/lrqnet/netkeep:1.0.7}
image: ${NETKEEP_IMAGE:-docker.io/lrqnet/netkeep:1.0.8}

x-netkeep-environment: &netkeep-environment
APP_ENV: production
Expand Down Expand Up @@ -251,7 +251,7 @@ services:
- egress

oxidized:
image: ${NETKEEP_OXIDIZED_IMAGE:-docker.io/lrqnet/netkeep-oxidized:0.37.0-r4}
image: ${NETKEEP_OXIDIZED_IMAGE:-docker.io/lrqnet/netkeep-oxidized:0.37.0-r5}
user: '30000:30000'
restart: unless-stopped
read_only: true
Expand Down Expand Up @@ -287,7 +287,7 @@ services:
- device_access

sandbox:
image: ${NETKEEP_OXIDIZED_IMAGE:-docker.io/lrqnet/netkeep-oxidized:0.37.0-r4}
image: ${NETKEEP_OXIDIZED_IMAGE:-docker.io/lrqnet/netkeep-oxidized:0.37.0-r5}
command: ['/usr/local/bin/netkeep-sandbox-controller']
user: '30000:30000'
restart: unless-stopped
Expand Down Expand Up @@ -364,7 +364,7 @@ services:
- internal

updater:
image: ${NETKEEP_UPDATER_IMAGE:-docker.io/lrqnet/netkeep-updater:1.0.7}
image: ${NETKEEP_UPDATER_IMAGE:-docker.io/lrqnet/netkeep-updater:1.0.8}
restart: unless-stopped
group_add:
- '20000'
Expand Down
5 changes: 5 additions & 0 deletions docs/ADMINISTRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@ somente leitura. Identidade, IP, local, tags e estado podem ser
sincronizados, mas credenciais, drivers e agendas de coleta permanecem sob
controle do NetKeep.

Uma sincronização que falha mantém a fonte configurada e apresenta somente uma
mensagem segura. O estado e a auditoria registram um código estável, sem corpo
de resposta, token, URL sensível ou detalhes de transporte da origem externa.
Revise conectividade, token e permissões da fonte antes de tentar novamente.

## Notificações

**Notificações** gerencia canais Webhook, Telegram e E-mail/SMTP. O resumo
Expand Down
3 changes: 3 additions & 0 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,9 @@ O cliente de saída resolve DNS em modo fail-closed, bloqueia loopback,
link-local, metadata, multicast, unspecified, IPv4 mapeado e nomes ou endereços
dos serviços Compose. A resolução validada é fixada à conexão e repetida a cada
uso. A proteção é aplicada a inventário, webhooks, Telegram, SMTP, S3 e Git.
Falhas de fontes de inventário são reduzidas a códigos estáveis antes de serem
persistidas, auditadas ou expostas na interface; respostas e erros brutos da
origem externa não cruzam esse limite.
IPs públicos e privados de equipamentos são permitidos depois da aprovação
administrativa. O Oxidized recebe um IP literal da resolução aprovada e não
refaz DNS, preservando o UUID como identidade estável do equipamento.
Expand Down
5 changes: 5 additions & 0 deletions docs/DEVELOPMENT.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,11 @@ docker compose down
Use `docker compose down --volumes` somente para apagar integralmente os dados
desse ambiente local.

## Laboratório de integrações

Para validar LibreNMS e NetBox reais sem compartilhar recursos com a instalação
local, siga o [guia do laboratório de inventário](INVENTORY_LAB.md).

## Testes PHP isolados

```bash
Expand Down
2 changes: 1 addition & 1 deletion docs/INSTALL.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ também são espelhadas no GHCR.
```bash
mkdir -p /opt/netkeep
cd /opt/netkeep
curl -fsSLO https://github.com/lrqnet/NetKeep/releases/download/v1.0.7/compose.yaml
curl -fsSLO https://github.com/lrqnet/NetKeep/releases/download/v1.0.8/compose.yaml
docker compose up -d --wait
docker compose ps
```
Expand Down
Loading
Loading