feat: basic
This commit is contained in:
396
README.md
396
README.md
@@ -1 +1,395 @@
|
||||
# galvanize
|
||||
# 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>
|
||||
|
||||
Reference in New Issue
Block a user