|
|
@@ -1,194 +0,0 @@
|
|
|
|
Metadata-Version: 2.4
|
|
|
|
|
|
|
|
Name: heartbeat
|
|
|
|
|
|
|
|
Version: 0.1.0
|
|
|
|
|
|
|
|
Summary: Heartbeat daemon (hbd) — receive heartbeats and act on them
|
|
|
|
|
|
|
|
Author: heartbeat contributors
|
|
|
|
|
|
|
|
License: MIT
|
|
|
|
|
|
|
|
Keywords: heartbeat,monitoring,dns,websocket
|
|
|
|
|
|
|
|
Requires-Python: >=3.10
|
|
|
|
|
|
|
|
Description-Content-Type: text/markdown
|
|
|
|
|
|
|
|
Requires-Dist: websockets>=13.2
|
|
|
|
|
|
|
|
Requires-Dist: mattermostdriver>=7.3.0
|
|
|
|
|
|
|
|
Requires-Dist: PyYAML>=6.0
|
|
|
|
|
|
|
|
Requires-Dist: aiohttp>=3.8
|
|
|
|
|
|
|
|
Requires-Dist: Jinja2>=3.1.0
|
|
|
|
|
|
|
|
Provides-Extra: dev
|
|
|
|
|
|
|
|
Requires-Dist: pytest>=7.0; extra == "dev"
|
|
|
|
|
|
|
|
Requires-Dist: pytest-cov>=4.0; extra == "dev"
|
|
|
|
|
|
|
|
Requires-Dist: flake8>=5.0; extra == "dev"
|
|
|
|
|
|
|
|
Requires-Dist: mypy>=1.10; extra == "dev"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# Heartbeat Daemon (hbd) ✅
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
A lightweight daemon that listens for UDP heartbeat messages and acts on them: keeps host state, optionally updates DNS records via `nsupdate`, forwards messages to WebSocket clients, and sends notifications (email, Pushover, Mattermost, Signal). It is a refactor of a previously monolithic script into a modular Python package (`hbd`).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 📌 Features
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Receive and parse heartbeat datagrams (text or zlib-compressed) ✅
|
|
|
|
|
|
|
|
- Maintain host state and detect up/down transitions ✅
|
|
|
|
|
|
|
|
- Queue DNS updates via `nsupdate` and run them in a background thread ✅
|
|
|
|
|
|
|
|
- WebSocket API for live updates (hosts & messages) ✅
|
|
|
|
|
|
|
|
- Notification pipeline (email, Pushover, Mattermost, Signal) ✅
|
|
|
|
|
|
|
|
- Modular codebase suitable for unit testing and CI ✅
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## ⚙️ Quickstart
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Prerequisites:
|
|
|
|
|
|
|
|
- Python 3.10+ (project uses language features from recent Python)
|
|
|
|
|
|
|
|
- `nsupdate` (for DNS updates) if using dynamic DNS
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Install dependencies (recommended into a venv):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
python3 -m venv .venv
|
|
|
|
|
|
|
|
source .venv/bin/activate
|
|
|
|
|
|
|
|
python -m pip install --upgrade pip
|
|
|
|
|
|
|
|
python -m pip install -r requirements.txt
|
|
|
|
|
|
|
|
# for development/testing tools
|
|
|
|
|
|
|
|
python -m pip install -r requirements-dev.txt
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Run the daemon (example):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
# run with default config lookup (~/.hb.yaml)
|
|
|
|
|
|
|
|
PYTHONPATH=. hbd -c .hb.yaml -f -v
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You can also run it directly via the package entrypoint after installation:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
python -m hbd.cli -c /path/to/config.yaml
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 🐞 Debugging in VS Code
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This repository includes a ready-to-use `.vscode/launch.json` with configurations to run or attach the VS Code debugger to `hbd`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Ensure the **Python** extension is installed and select the project `.venv` as the interpreter (bottom-left of VS Code).
|
|
|
|
|
|
|
|
- Use **F5** and pick one of these configurations from the Run view:
|
|
|
|
|
|
|
|
- **Python: Run hbd (module)** — runs `hbd.cli` as a module and sets `PYTHONPATH` to the workspace root (recommended).
|
|
|
|
|
|
|
|
- **Python: Run hbd with debugpy (listen)** — launches `debugpy` and `hbd` together; useful when you want the process to listen for a debugger.
|
|
|
|
|
|
|
|
- **Python: Attach (localhost:5678)** — attach the debugger to a running process started with `debugpy`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To start `hbd` manually and wait for the debugger to attach, run:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
PYTHONPATH=. python -m debugpy --listen 5678 --wait-for-client -m hbd.cli -c .hb.yaml -f -v
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Set breakpoints in modules such as `hbd/udp.py`, `hbd/dns.py`, or `hbd/server.py`, and use the **Attach** configuration to connect. Use `justMyCode: false` if you need to step into third-party code.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 🛠 Configuration
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
`hbd` reads YAML configuration (optional). If `PyYAML` is not installed, built-in defaults are used. Example configuration keys (see `hbd/config.py`):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `hb_port`: UDP port to listen for heartbeats (default: 50003)
|
|
|
|
|
|
|
|
- `hbd_port`: internal control port (default: 50004)
|
|
|
|
|
|
|
|
- `hbd_host`: bind address for HTTP/WSS
|
|
|
|
|
|
|
|
- `pickfile`: path for persisted state
|
|
|
|
|
|
|
|
- `logfile`: path to log file
|
|
|
|
|
|
|
|
- `logfmt`: `text` or `msg`
|
|
|
|
|
|
|
|
- `pushsrv`: push service (`pushover`|`mattermost`|`all`)
|
|
|
|
|
|
|
|
- `interval` / `grace`: heartbeat timing configuration
|
|
|
|
|
|
|
|
- `dyndomains`: list of dyndomains to update via `nsupdate`
|
|
|
|
|
|
|
|
- `nsupdate_bin`: path to nsupdate binary
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Example `.hb.yaml` (minimal):
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```yaml
|
|
|
|
|
|
|
|
hbd_host: 0.0.0.0
|
|
|
|
|
|
|
|
hbd_port: 50004
|
|
|
|
|
|
|
|
dyndomains:
|
|
|
|
|
|
|
|
- example.com
|
|
|
|
|
|
|
|
nsupdate_bin: /usr/bin/nsupdate
|
|
|
|
|
|
|
|
pushsrv: pushover
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> Tip: `config.DEFAULTS` in `hbd/config.py` contains the canonical defaults and accepted configuration keys.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 🔧 Architecture & Modules
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- `hbd.proto` — serialization/deserialization of heartbeat messages (supports compressed payloads)
|
|
|
|
|
|
|
|
- `hbd.udp` — UDP parsing and `handle_datagram` implementation (main state machine)
|
|
|
|
|
|
|
|
- `hbd.dns` — `create_nsupdate_payload`, `nsupdate`, and a background DNS thread (`start_dns_thread`)
|
|
|
|
|
|
|
|
- `hbd.notify` — email and push notification helpers
|
|
|
|
|
|
|
|
- `hbd.ws` — WebSocket server and thread-safe broadcast helpers
|
|
|
|
|
|
|
|
- `hbd.http` — HTTP handler factory for the status UI/API
|
|
|
|
|
|
|
|
- `hbd.utils` — small utility helpers (`shortname`, `dur`, `initlog`)
|
|
|
|
|
|
|
|
- `hbd.cli` — CLI entrypoint and argument parsing
|
|
|
|
|
|
|
|
- `hbd.server` — async orchestration to run UDP/HTTP/WSS components
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This modular layout makes the code easier to test and maintain.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 🧪 Testing & Dev
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Tests are implemented using `unittest` and additional tests rely on `pytest` if you prefer. To run tests locally without installing anything beyond the dev requirements:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
# with project root on PYTHONPATH
|
|
|
|
|
|
|
|
PYTHONPATH=. python -m unittest discover -v
|
|
|
|
|
|
|
|
# or with pytest if installed
|
|
|
|
|
|
|
|
pytest -q
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Developer tooling included:
|
|
|
|
|
|
|
|
- `pyproject.toml` — project metadata and dependencies
|
|
|
|
|
|
|
|
- `requirements-dev.txt` — dev/test dependencies
|
|
|
|
|
|
|
|
- `tox.ini` — convenience wrappers for running tests, lint, and mypy
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
To run linters and type checks locally:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
|
|
# after installing dev deps
|
|
|
|
|
|
|
|
tox -e lint
|
|
|
|
|
|
|
|
tox -e mypy
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 🚀 Running in production
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
- Use your system service manager (systemd, launchd, etc.) to run `hbd` in the background.
|
|
|
|
|
|
|
|
- Ensure `nsupdate` and necessary credentials are available for dynamic DNS updates.
|
|
|
|
|
|
|
|
- Configure TLS for WSS if you enable secure websockets.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
> Note: The project contains a small example for obtaining DNS-verified certs (certbot with RFC2136) — see earlier commit history or ask me to re-add the example to this README if you want it documented here.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 🤝 Contributing
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Contributions welcome! Please:
|
|
|
|
|
|
|
|
1. Open an issue to discuss larger changes.
|
|
|
|
|
|
|
|
2. Create a topic branch and a clear PR.
|
|
|
|
|
|
|
|
3. Add tests for new features and run linters.
|
|
|
|
|
|
|
|
4. Keep changes focused and documented.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
## 📜 License
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
This repository is licensed under the MIT license. See `LICENSE` for details.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
---
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
If you'd like, I can also:
|
|
|
|
|
|
|
|
- add a **GitHub Actions** workflow that runs tests and lint on push/PR 🔁
|
|
|
|
|
|
|
|
- add a `CONTRIBUTING.md` template for PRs and code style 💬
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Which one should I do next? ✨
|
|
|
|
|
|
|
|
|
|
|
|
|