396 lines
9.4 KiB
Markdown
396 lines
9.4 KiB
Markdown
# Galvanize
|
|
|
|
<p align="center">
|
|
<img src="docs/assets/logo.svg" alt="Galvanize Logo" width="200" />
|
|
</p>
|
|
|
|
<p align="center">
|
|
<strong>A modern, Rust-based Wake-on-LAN control plane with HTTP/MQTT APIs, pluggable auth, and an optional React + shadcn Web UI.</strong>
|
|
</p>
|
|
|
|
<p align="center">
|
|
<a href="https://github.com/aitiome/galvanize/actions"><img src="https://github.com/aitiome/galvanize/workflows/CI/badge.svg" alt="CI Status" /></a>
|
|
<a href="https://github.com/aitiome/galvanize/releases"><img src="https://img.shields.io/github/v/release/aitiome/galvanize" alt="Release" /></a>
|
|
<a href="https://hub.docker.com/r/aitiome/galvanize"><img src="https://img.shields.io/docker/pulls/aitiome/galvanize" alt="Docker Pulls" /></a>
|
|
<a href="LICENSE-MIT"><img src="https://img.shields.io/badge/license-MIT%2FApache--2.0-blue" alt="License" /></a>
|
|
</p>
|
|
|
|
---
|
|
|
|
## ✨ Features
|
|
|
|
- **🚀 Multi-Protocol Support** — Listen on HTTP REST API and/or MQTT for maximum flexibility
|
|
- **🔐 Pluggable Authentication** — Simple username/password auth or external OIDC provider integration
|
|
- **💾 Persistent Configuration** — WoL device configurations stored as JSON with hot-reload support
|
|
- **🎨 Modern Web UI** — Optional React + shadcn/ui dashboard (can be disabled with `--webui=false`)
|
|
- **📦 Easy Deployment** — Pre-built binaries, Docker images, and docker-compose ready
|
|
- **🦀 Built with Rust** — Fast, safe, and reliable
|
|
|
|
## 📋 Table of Contents
|
|
|
|
- [Installation](#-installation)
|
|
- [Quick Start](#-quick-start)
|
|
- [Configuration](#-configuration)
|
|
- [API Reference](#-api-reference)
|
|
- [Authentication](#-authentication)
|
|
- [Web UI](#-web-ui)
|
|
- [Docker](#-docker)
|
|
- [Development](#-development)
|
|
- [Related Projects](#-related-projects)
|
|
- [Contributing](#-contributing)
|
|
- [License](#-license)
|
|
|
|
## 📦 Installation
|
|
|
|
### Pre-built Binaries
|
|
|
|
Download the latest release for your platform from the [Releases](https://github.com/aitiome/galvanize/releases) page.
|
|
|
|
| Platform | Architecture | Download |
|
|
|----------|--------------|----------|
|
|
| Linux | x86_64 | `galvanize-linux-x86_64` |
|
|
| Linux | aarch64 | `galvanize-linux-aarch64` |
|
|
| macOS | x86_64 | `galvanize-darwin-x86_64` |
|
|
| macOS | aarch64 (Apple Silicon) | `galvanize-darwin-aarch64` |
|
|
| Windows | x86_64 | `galvanize-windows-x86_64.exe` |
|
|
|
|
### Docker
|
|
|
|
```bash
|
|
docker pull aitiome/galvanize:latest
|
|
|
|
# Run with default settings
|
|
docker run -d \
|
|
--name galvanize \
|
|
--network host \
|
|
-v ./config:/app/config \
|
|
aitiome/galvanize:latest
|
|
```
|
|
|
|
### Build from Source
|
|
|
|
```bash
|
|
# Clone the repository
|
|
git clone https://github.com/aitiome/galvanize.git
|
|
cd galvanize
|
|
|
|
# Build release binary
|
|
cargo build --release
|
|
|
|
# Build with Web UI (requires Node.js)
|
|
cd webui && pnpm install && pnpm build && cd ..
|
|
cargo build --release --features webui
|
|
```
|
|
|
|
## 🚀 Quick Start
|
|
|
|
1. **Start the server:**
|
|
|
|
```bash
|
|
galvanize serve --config ./config
|
|
```
|
|
|
|
2. **Add a device via API:**
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8080/api/v1/devices \
|
|
-H "Content-Type: application/json" \
|
|
-H "Authorization: Bearer <token>" \
|
|
-d '{
|
|
"name": "my-server",
|
|
"mac": "AA:BB:CC:DD:EE:FF",
|
|
"broadcast": "192.168.1.255",
|
|
"port": 9
|
|
}'
|
|
```
|
|
|
|
3. **Wake a device:**
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8080/api/v1/devices/my-server/wake \
|
|
-H "Authorization: Bearer <token>"
|
|
```
|
|
|
|
## ⚙️ Configuration
|
|
|
|
Galvanize uses a configuration directory structure:
|
|
|
|
```
|
|
config/
|
|
├── galvanize.toml # Main configuration file
|
|
├── devices/ # Device configurations (JSON)
|
|
│ ├── my-server.json
|
|
│ └── nas.json
|
|
└── users.toml # Local user credentials (optional)
|
|
```
|
|
|
|
### Main Configuration (`galvanize.toml`)
|
|
|
|
```toml
|
|
[server]
|
|
host = "0.0.0.0"
|
|
port = 8080
|
|
webui = true
|
|
|
|
[mqtt]
|
|
enabled = false
|
|
broker = "mqtt://localhost:1883"
|
|
topic_prefix = "galvanize"
|
|
client_id = "galvanize-server"
|
|
|
|
[auth]
|
|
# Authentication mode: "none", "basic", "oidc", or "both"
|
|
mode = "basic"
|
|
|
|
[auth.basic]
|
|
# Path to users file or inline users
|
|
users_file = "users.toml"
|
|
|
|
[auth.oidc]
|
|
enabled = false
|
|
issuer = "https://auth.example.com"
|
|
client_id = "galvanize"
|
|
client_secret = "${OIDC_CLIENT_SECRET}"
|
|
redirect_uri = "http://localhost:8080/auth/callback"
|
|
|
|
[storage]
|
|
# Directory for device configurations
|
|
path = "./config/devices"
|
|
# Watch for file changes and auto-reload
|
|
watch = true
|
|
```
|
|
|
|
### Device Configuration
|
|
|
|
```json
|
|
{
|
|
"id": "my-server",
|
|
"name": "My Server",
|
|
"mac": "AA:BB:CC:DD:EE:FF",
|
|
"broadcast": "192.168.1.255",
|
|
"port": 9,
|
|
"interface": null,
|
|
"tags": ["servers", "homelab"],
|
|
"metadata": {
|
|
"location": "Rack 1",
|
|
"os": "Ubuntu 22.04"
|
|
}
|
|
}
|
|
```
|
|
|
|
## 📡 API Reference
|
|
|
|
### HTTP Endpoints
|
|
|
|
| Method | Endpoint | Description |
|
|
|--------|----------|-------------|
|
|
| `GET` | `/api/v1/devices` | List all devices |
|
|
| `GET` | `/api/v1/devices/:id` | Get device by ID |
|
|
| `POST` | `/api/v1/devices` | Create a new device |
|
|
| `PUT` | `/api/v1/devices/:id` | Update a device |
|
|
| `DELETE` | `/api/v1/devices/:id` | Delete a device |
|
|
| `POST` | `/api/v1/devices/:id/wake` | Send WoL magic packet |
|
|
| `POST` | `/api/v1/wake` | Wake device by MAC address (body) |
|
|
| `GET` | `/api/v1/health` | Health check endpoint |
|
|
|
|
### MQTT Topics
|
|
|
|
When MQTT is enabled, Galvanize subscribes to:
|
|
|
|
| Topic | Payload | Description |
|
|
|-------|---------|-------------|
|
|
| `galvanize/wake/:device_id` | `{}` | Wake device by ID |
|
|
| `galvanize/wake` | `{"mac": "AA:BB:..."}` | Wake by MAC address |
|
|
|
|
And publishes to:
|
|
|
|
| Topic | Description |
|
|
|-------|-------------|
|
|
| `galvanize/status` | Server status updates |
|
|
| `galvanize/events` | Wake events and results |
|
|
|
|
## 🔐 Authentication
|
|
|
|
### Basic Authentication
|
|
|
|
Create a `users.toml` file:
|
|
|
|
```toml
|
|
[[users]]
|
|
username = "admin"
|
|
# Generate with: galvanize hash-password
|
|
password_hash = "$argon2id$v=19$m=19456,t=2,p=1$..."
|
|
roles = ["admin"]
|
|
|
|
[[users]]
|
|
username = "user"
|
|
password_hash = "$argon2id$v=19$m=19456,t=2,p=1$..."
|
|
roles = ["user"]
|
|
```
|
|
|
|
### OIDC Authentication
|
|
|
|
Configure your OIDC provider in `galvanize.toml`:
|
|
|
|
```toml
|
|
[auth.oidc]
|
|
enabled = true
|
|
issuer = "https://auth.example.com"
|
|
client_id = "galvanize"
|
|
client_secret = "${OIDC_CLIENT_SECRET}"
|
|
redirect_uri = "http://localhost:8080/auth/callback"
|
|
scopes = ["openid", "profile", "email"]
|
|
```
|
|
|
|
## 🎨 Web UI
|
|
|
|
The Web UI provides a modern dashboard for managing your Wake-on-LAN devices.
|
|
|
|
<p align="center">
|
|
<img src="docs/assets/webui-screenshot.png" alt="Web UI Screenshot" width="800" />
|
|
</p>
|
|
|
|
### Features
|
|
|
|
- 📱 Responsive design for desktop and mobile
|
|
- 🌙 Light/Dark mode support
|
|
- 🔍 Search and filter devices
|
|
- 📊 Device status monitoring
|
|
- ⚡ One-click wake functionality
|
|
|
|
### Disable Web UI
|
|
|
|
To run in API-only mode:
|
|
|
|
```bash
|
|
galvanize serve --webui=false
|
|
```
|
|
|
|
Or in configuration:
|
|
|
|
```toml
|
|
[server]
|
|
webui = false
|
|
```
|
|
|
|
## 🐳 Docker
|
|
|
|
### Docker Compose
|
|
|
|
```yaml
|
|
version: "3.8"
|
|
|
|
services:
|
|
galvanize:
|
|
image: aitiome/galvanize:latest
|
|
container_name: galvanize
|
|
network_mode: host # Required for WoL broadcast
|
|
volumes:
|
|
- ./config:/app/config
|
|
environment:
|
|
- GALVANIZE_AUTH_MODE=basic
|
|
- OIDC_CLIENT_SECRET=${OIDC_CLIENT_SECRET}
|
|
restart: unless-stopped
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
| Variable | Description | Default |
|
|
|----------|-------------|---------|
|
|
| `GALVANIZE_HOST` | Server bind address | `0.0.0.0` |
|
|
| `GALVANIZE_PORT` | Server port | `8080` |
|
|
| `GALVANIZE_WEBUI` | Enable Web UI | `true` |
|
|
| `GALVANIZE_AUTH_MODE` | Auth mode | `none` |
|
|
| `GALVANIZE_CONFIG_PATH` | Config directory | `/app/config` |
|
|
| `OIDC_CLIENT_SECRET` | OIDC client secret | - |
|
|
|
|
## 🛠️ Development
|
|
|
|
### Prerequisites
|
|
|
|
- Rust 1.75+
|
|
- Node.js 20+ (for Web UI)
|
|
- pnpm (for Web UI)
|
|
|
|
### Setup
|
|
|
|
```bash
|
|
# Clone repository
|
|
git clone https://github.com/aitiome/galvanize.git
|
|
cd galvanize
|
|
|
|
# Install Rust dependencies
|
|
cargo build
|
|
|
|
# Install Web UI dependencies
|
|
cd webui
|
|
pnpm install
|
|
pnpm dev # Start dev server on :5173
|
|
```
|
|
|
|
### Project Structure
|
|
|
|
```
|
|
galvanize/
|
|
├── src/ # Rust server source
|
|
│ ├── main.rs
|
|
│ ├── api/ # HTTP API handlers
|
|
│ ├── mqtt/ # MQTT handlers
|
|
│ ├── auth/ # Authentication modules
|
|
│ ├── wol/ # Wake-on-LAN implementation
|
|
│ └── storage/ # Configuration persistence
|
|
├── webui/ # React Web UI
|
|
│ ├── src/
|
|
│ │ ├── components/ # shadcn/ui components
|
|
│ │ ├── pages/
|
|
│ │ └── lib/
|
|
│ └── package.json
|
|
├── config/ # Example configurations
|
|
├── docs/ # Documentation
|
|
└── Cargo.toml
|
|
```
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
# Run all tests
|
|
cargo test
|
|
|
|
# Run with coverage
|
|
cargo tarpaulin
|
|
|
|
# Web UI tests
|
|
cd webui && pnpm test
|
|
```
|
|
|
|
## 🔗 Related Projects
|
|
|
|
Other projects from the [aitiome](https://github.com/aitiome) organization:
|
|
|
|
- **[outposts](https://github.com/aitiome/outposts)** — Distributed monitoring agents
|
|
- **[securitydept](https://github.com/aitiome/securitydept)** — Security policy management
|
|
|
|
## 🤝 Contributing
|
|
|
|
Contributions are welcome! Please read our [Contributing Guide](CONTRIBUTING.md) for details on:
|
|
|
|
- Code of Conduct
|
|
- Development workflow
|
|
- Pull request process
|
|
- Coding standards
|
|
|
|
## 📄 License
|
|
|
|
Galvanize is dual-licensed under:
|
|
|
|
- [MIT License](LICENSE-MIT)
|
|
- [Apache License 2.0](LICENSE-APACHE)
|
|
|
|
You may choose either license at your option.
|
|
|
|
---
|
|
|
|
<p align="center">
|
|
Made with ❤️ by <a href="https://github.com/aitiome">aitiome</a>
|
|
</p>
|