Commit graph

112 commits

Author SHA1 Message Date
Graham McIntire
129c641f1c
Merge pull request #3 from towerops-app/dependabot/cargo/clap-4.5.56
Bump clap from 4.5.54 to 4.5.56
2026-02-02 12:32:50 -06:00
dependabot[bot]
f31a756fad
Bump clap from 4.5.54 to 4.5.56
Bumps [clap](https://github.com/clap-rs/clap) from 4.5.54 to 4.5.56.
- [Release notes](https://github.com/clap-rs/clap/releases)
- [Changelog](https://github.com/clap-rs/clap/blob/master/CHANGELOG.md)
- [Commits](https://github.com/clap-rs/clap/compare/clap_complete-v4.5.54...clap_complete-v4.5.56)

---
updated-dependencies:
- dependency-name: clap
  dependency-version: 4.5.56
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-02 18:31:02 +00:00
Graham McIntire
1c636381a1
Merge pull request #2 from towerops-app/dependabot/cargo/prost-types-0.14.3
Bump prost-types from 0.13.5 to 0.14.3
2026-02-02 12:30:38 -06:00
dependabot[bot]
a5056e3616
Bump prost-types from 0.13.5 to 0.14.3
Bumps [prost-types](https://github.com/tokio-rs/prost) from 0.13.5 to 0.14.3.
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.5...v0.14.3)

---
updated-dependencies:
- dependency-name: prost-types
  dependency-version: 0.14.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-02 18:30:20 +00:00
fbf2435165
build arm/amd in parallel natively 2026-02-02 12:29:35 -06:00
Graham McIntire
3b6f0ca8fd
Merge pull request #1 from towerops-app/dependabot/cargo/prost-0.14.3
Bump prost from 0.13.5 to 0.14.3
2026-02-02 12:29:11 -06:00
dependabot[bot]
7f0d63df41
Bump prost from 0.13.5 to 0.14.3
Bumps [prost](https://github.com/tokio-rs/prost) from 0.13.5 to 0.14.3.
- [Release notes](https://github.com/tokio-rs/prost/releases)
- [Changelog](https://github.com/tokio-rs/prost/blob/master/CHANGELOG.md)
- [Commits](https://github.com/tokio-rs/prost/compare/v0.13.5...v0.14.3)

---
updated-dependencies:
- dependency-name: prost
  dependency-version: 0.14.3
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-02-02 18:27:09 +00:00
001d713688
dependabot fix 2026-02-02 12:26:22 -06:00
eb330b2f6f
protobufs update for mikrotik things 2026-02-02 12:25:40 -06:00
Graham McIntire
224c2b5898
Create dependabot.yml for version updates
Add initial configuration for Dependabot version updates.
2026-02-02 12:25:02 -06:00
fa42254cfb
ci cache improvements 2026-02-01 08:28:56 -06:00
a4745f55bf
readme update 2026-02-01 08:17:00 -06:00
72ea5d56f0
improve ci speed 2026-01-31 17:21:09 -06:00
4254f47ea5
github release fix 2026-01-31 17:01:09 -06:00
be054323a6
more caching in github ci 2026-01-31 16:53:25 -06:00
5636b00f33
add github ci 2026-01-31 16:48:28 -06:00
98d1bbbb21
structured logging 2026-01-31 15:40:42 -06:00
b8aecf0a55
more tests 2026-01-31 15:26:36 -06:00
6e57918386
cleanup and readme update 2026-01-31 14:56:36 -06:00
c7c286204e
temporarilly disable tests in ci 2026-01-31 14:47:55 -06:00
92c7675141
Update CI to Rust 1.91 to match local environment 2026-01-31 14:42:51 -06:00
4cd357777f
Add TRAP_ENABLED env var to conditionally enable trap listener 2026-01-31 14:39:24 -06:00
89adc3a6b3
Add SNMP trap listener for v1 and v2c traps
- Add trap.rs with BER/ASN.1 parser for SNMP trap PDUs
- Support both SNMPv1 and SNMPv2c trap formats
- Listen on configurable UDP port (default 162)
- Log received traps at INFO level
- Add LOG_LEVEL env var for log verbosity control
- Add TRAP_PORT env var and CLI flag
- Update docker-compose with trap port mapping
2026-01-31 14:14:56 -06:00
61e7fe1c47
Add SNMP trap listener design document 2026-01-31 14:11:04 -06:00
8ed2208271
poll each device simultaneously 2026-01-31 14:00:00 -06:00
bf1c6314cb
agent version tracking 2026-01-30 17:25:08 -06:00
c3e6e8c5b0
fix clippy error 2026-01-30 16:00:33 -06:00
380beaca1a
Agent overhaul with zero persistence 2026-01-30 15:50:20 -06:00
3793477e2f
relax ping failures 2026-01-29 12:12:01 -06:00
b8932f16b0
fix clippy issues 2026-01-29 12:02:20 -06:00
cee8d693da
make websocket client more robust 2026-01-29 11:55:01 -06:00
dbf66af5c0
support snmp v1 2026-01-29 11:28:45 -06:00
0548ca313d
include device id and ip in snmp error logs 2026-01-25 12:20:45 -06:00
cf08b0589b
cleanup 2026-01-24 12:43:24 -06:00
8ee809d21e
websocket improvements 2026-01-23 12:43:11 -06:00
9cb924fd77
connectivity improvements 2026-01-23 10:33:13 -06:00
ee7ce7fe00
feat: use system ping instead of raw ICMP sockets
- Replace raw ICMP socket implementation with system ping command
- Add regex-lite dependency for parsing ping output
- Add tokio process feature for async command execution
- Support macOS and Linux ping output formats
- Add iputils to Dockerfile for setuid-root ping
- Remove socket2 dependency (no longer needed)

This eliminates the need for CAP_NET_RAW capability in containers.
2026-01-21 13:11:24 -06:00
84b7519ad0
cargo clippy fix 2026-01-20 11:33:52 -06:00
6cea690e6b
format 2026-01-20 11:33:37 -06:00
71267870b0
refactor: remove log dependency, replace with custom macros
- Added custom logging macros (log_error!, log_warn!, log_info!, log_debug!)
- Implemented LogLevel enum and LOG_LEVEL static for runtime level control
- Exported macros with #[macro_export] for use across all modules
- Replaced all log:: calls in websocket_client.rs, health.rs, and version.rs
- Removed obsolete test code referencing old log crate
- Removed log dependency from Cargo.toml
- Fixed useless comparison warning in test
- Binary size: still 1.5M (no change - log was lightweight)
- Tests: 65 passing, 0 warnings

This completes the removal of 9 dependencies (thiserror, hostname, chrono,
base64, rand, ureq, tiny_http, anyhow, log). Dependency count: 19 → 10.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-01-19 17:31:12 -06:00
0daaf9ed68
refactor: start replacing log crate with custom macros (WIP)
Added custom logging macros to main.rs to prepare for removing the
log crate dependency:
- Added LogLevel enum and LOG_LEVEL static
- Created log_error!, log_warn!, log_info!, log_debug! macros
- Replaced log calls in main.rs with custom macros
- Made format_timestamp() public for use in macros

Still TODO:
- Update websocket_client.rs, health.rs, version.rs
- Remove log from Cargo.toml

This is work in progress toward removing more dependencies.
2026-01-19 17:23:59 -06:00
55fb691440
refactor: remove 4 more dependencies (rand, ureq, tiny_http, anyhow)
Removed dependencies:
- rand: Replaced with SystemTime-based random for ICMP ID/sequence
- ureq: Removed Docker Hub version checking (Watchtower handles updates)
- tiny_http: Replaced with raw TCP listener for /health endpoint
- anyhow: Replaced with std::error::Error trait

Benefits:
- Binary size: 2.3M → 1.5M (800KB reduction, 35% smaller!)
- Dependencies: 19 → 11 direct dependencies (-8 total)
- Tests: 80 → 67 (removed Docker Hub API tests)
- All tests passing

Custom implementations:
- ICMP random: Use nanosecond timestamp for ID/sequence
- Health endpoint: Simple HTTP/1.1 parser on raw TCP
- Error handling: type Result<T> = std::result::Result<T, Box<dyn Error>>

Total progress from initial state:
- Binary: 2.4M → 1.5M (37.5% reduction!)
- Dependencies removed: 8 (thiserror, hostname, chrono, base64, rand, ureq, tiny_http, anyhow)
2026-01-19 17:20:49 -06:00
d02193921d
Increase SNMP timeout from 5s to 30s to reduce timeout errors
Problem:
- Rust agent was experiencing frequent SNMP timeouts
- 5-second timeout is too aggressive for slow devices or congested networks
- Phoenix app uses 30-second timeout with better reliability

Solution:
- Increased SNMP_TIMEOUT_SECS constant from 5 to 30 seconds
- Applied to both get() and walk() operations
- Now matches Phoenix application timeout configuration

Benefits:
- Reduces false positive timeout errors
- Better handling of slow network devices
- Consistent timeout behavior across Elixir and Rust pollers
- Maintains reliability during network congestion

Note: SNMP timeout is per-request. Total polling time may still be
limited by Task::spawn_blocking timeout in poller executor (40s).

🤖 Generated with Claude Code
2026-01-19 17:17:45 -06:00
d132f03d8b
refactor: replace 4 dependencies with custom implementations
Removed dependencies and replaced with custom code:
- thiserror: Not used (only pulled by tokio-tungstenite)
- hostname: Replaced with /proc/sys/kernel/hostname reader
- chrono: Replaced with std::time::SystemTime + custom formatting
- base64: Replaced with custom base64 encoder/decoder

Benefits:
- Binary size: 2.4M → 2.3M (100KB reduction)
- Reduced dependency count: 19 → 15 direct dependencies
- Added 7 new tests (73 → 80 total tests)
- All tests pass

Custom implementations:
- format_timestamp(): YYYY-MM-DD HH:MM:SS.mmm format
- get_hostname(): Read from /proc/sys/kernel/hostname
- get_uptime_seconds(): Read from /proc/uptime
- base64_encode/decode(): Standard base64 encoding

No functionality changes, all existing features work identically.
2026-01-19 17:15:07 -06:00
c0fe57cd44
fix: properly inject version into Docker image builds
The agent version was always showing 0.1.0 because build.rs tried to
run 'git describe' inside the Docker build, but .git directory wasn't
copied into the image.

Changes:
- Add VERSION build arg to Dockerfile
- Pass VERSION as env var to cargo build commands
- Update GitLab CI to pass --build-arg VERSION
- Modify build.rs to prefer BUILD_VERSION env var over git commands

This ensures the version displayed by the agent matches the Docker
image tag it was built with.
2026-01-19 15:31:26 -06:00
da3088f87f
fix: relax ICMP identifier validation for DGRAM sockets
When using SOCK_DGRAM for ICMP on Linux, the kernel manages the
identifier field and may overwrite the value we set. This causes
validation failures when we receive replies with kernel-assigned
identifiers.

The fix is to only validate:
- Type (0 = ECHO REPLY)
- Code (0)
- Sequence number (matches our random value)

The sequence number is sufficient for uniqueness given our polling
intervals (300+ seconds per device). This is the standard approach
for DGRAM ICMP sockets.
2026-01-19 15:27:51 -06:00
78a9672ad9
chore: remove unused rusqlite dependency
The agent uses WebSocket streaming instead of SQLite buffering,
so rusqlite is not needed. Removing it reduces compile time and
simplifies the dependency tree.
2026-01-19 15:26:18 -06:00
2b5a67d26c
fix: correct ICMP diagnostic message when IP header present
The diagnostic error message was reading ICMP fields from the wrong
offset when an IP header was present. It was showing bytes from the
IP header instead of the actual ICMP identifier and sequence fields.

Now properly detects and skips IP header before extracting ICMP
fields for diagnostic output. Also added total packet length to help
distinguish between raw ICMP and IP-wrapped packets.

Example before:
  Invalid ICMP reply packet (expected id=24079, seq=12918):
  type=0 code=0 id=29 seq=12918 len=21
  (id=29 was reading from IP header, not ICMP)

Example after:
  Invalid ICMP reply packet (expected id=24079, seq=12918):
  type=0 code=0 id=24079 seq=12918 len=21 (total=41)
  (now correctly shows ICMP identifier)
2026-01-19 15:20:10 -06:00
0b3cc9121e
Add comprehensive unit test coverage (29.19%)
Add 73 unit tests covering all testable business logic:

- src/snmp/types.rs: 100% coverage (17/17 lines)
  * SnmpError display formatting
  * SnmpValue conversions (as_i64, as_f64)

- src/snmp/client.rs: 34.4% coverage (32/93 lines)
  * OID parsing/formatting/validation
  * SNMP value conversion for all types
  * Error mapping from snmp crate
  * Helper functions (starts_with, format_oid)

- src/ping.rs: 65.2% coverage (58/89 lines)
  * ICMP checksum calculation and verification
  * Echo request packet building
  * Reply packet parsing (raw and IP-wrapped)
  * IP header length extraction (IHL field)
  * Error handling for invalid packets

- src/version.rs: 54.0% coverage (27/50 lines)
  * Version parsing with optional 'v' prefix
  * Version comparison and sorting
  * Docker Hub response deserialization
  * Latest version extraction from tags

- src/websocket_client.rs: 7.7% coverage (17/221 lines)
  * SnmpValue to string conversion
  * Agent ID generation
  * Phoenix message serialization/deserialization
  * Helper functions (get_uptime_seconds, get_local_ip)

- src/main.rs: 20.0% coverage (11/55 lines)
  * SimpleLogger enabled() logic
  * HTTP/HTTPS to WebSocket URL conversion

- .gitlab-ci.yml: Add 'cargo test' to CI pipeline

Uncovered code requires integration testing:
- Network I/O (WebSocket, HTTP, Docker Hub API)
- System privileges (raw ICMP sockets)
- External services (SNMP devices, WebSocket servers)
- Runtime initialization (tokio main, logger setup)

All 73 tests pass. No test failures.
2026-01-19 15:07:00 -06:00
aa32be93be
fix: remove unused code to pass clippy CI checks 2026-01-19 13:42:00 -06:00