add admin panel
This commit is contained in:
154
readme.md
154
readme.md
@@ -76,12 +76,15 @@ S3_USE_SSL=true
|
||||
# Local ZFS fallback
|
||||
ZFS_BASE_DATASET=backup
|
||||
|
||||
# Database Configuration (SQLite)
|
||||
DATABASE_PATH=zfs-backup.db
|
||||
|
||||
# Server settings
|
||||
CONFIG_FILE=clients.json
|
||||
METADATA_FILE=metadata.json
|
||||
PORT=8080
|
||||
```
|
||||
|
||||
> **Note**: All client configuration and snapshot metadata is stored in a SQLite database (`zfs-backup.db` by default). The server automatically creates a default client (`client1` with API key `secret123`) if no clients exist.
|
||||
|
||||
### Client Configuration
|
||||
|
||||
```env
|
||||
@@ -90,10 +93,11 @@ API_KEY=secret123
|
||||
SERVER_URL=http://backup-server:8080
|
||||
LOCAL_DATASET=tank/data
|
||||
COMPRESS=true
|
||||
STORAGE_TYPE=s3
|
||||
```
|
||||
|
||||
> **Important**: The `API_KEY` in the client `.env` file must be the **raw (unhashed)** key. The server stores the SHA-256 hash in `clients.json`, and the client sends the raw key which the server then hashes for comparison. For example, if `clients.json` has `api_key: "fcf730b6d95236ecd3c9fc2d92d7b6b2bb061514961aec041d6c7a7192f592e4"` (hash of "secret123"), the client `.env` should have `API_KEY=secret123`.
|
||||
> **Important**:
|
||||
> - The `API_KEY` in the client `.env` file must be the **raw (unhashed)** key. The server stores the SHA-256 hash in the database.
|
||||
> - **Storage type is determined by the server**, not the client. The server decides whether to use S3 or local ZFS storage based on its configuration.
|
||||
|
||||
### Restore Tool Configuration
|
||||
|
||||
@@ -344,35 +348,55 @@ S3_BUCKET=zfs-backups
|
||||
S3_USE_SSL=true
|
||||
```
|
||||
|
||||
## Client Configuration File
|
||||
## Database Storage
|
||||
|
||||
The server maintains a `clients.json` file with client configurations:
|
||||
The server uses SQLite to store all configuration and metadata in a single database file (`zfs-backup.db` by default). This includes:
|
||||
|
||||
```json
|
||||
[
|
||||
{
|
||||
"client_id": "client1",
|
||||
"api_key": "hashed_key",
|
||||
"max_size_bytes": 107374182400,
|
||||
"dataset": "backup/client1",
|
||||
"enabled": true,
|
||||
"storage_type": "s3",
|
||||
"rotation_policy": {
|
||||
"keep_hourly": 24,
|
||||
"keep_daily": 7,
|
||||
"keep_weekly": 4,
|
||||
"keep_monthly": 12
|
||||
}
|
||||
}
|
||||
]
|
||||
```
|
||||
- **Admin users**: Authentication credentials for the admin panel
|
||||
- **Client configurations**: Authentication, quotas, storage type, rotation policies
|
||||
- **Snapshot metadata**: Timestamps, sizes, storage keys, incremental relationships
|
||||
|
||||
### Database Schema
|
||||
|
||||
The database contains four main tables:
|
||||
|
||||
**admins table:**
|
||||
- `id` - Unique identifier
|
||||
- `username` - Admin username (unique)
|
||||
- `password_hash` - SHA-256 hashed password
|
||||
- `role` - Admin role (default: "admin")
|
||||
- `created_at`, `updated_at` - Timestamps
|
||||
|
||||
**admin_sessions table:**
|
||||
- `id` - Unique identifier
|
||||
- `admin_id` - Foreign key to admins table
|
||||
- `token` - Session token
|
||||
- `expires_at` - Session expiration time
|
||||
|
||||
**clients table:**
|
||||
- `client_id` - Unique identifier
|
||||
- `api_key` - SHA-256 hashed API key
|
||||
- `max_size_bytes` - Storage quota
|
||||
- `dataset` - Target dataset for local ZFS storage
|
||||
- `enabled` - Client status
|
||||
- `storage_type` - "s3" or "local"
|
||||
- `keep_hourly`, `keep_daily`, `keep_weekly`, `keep_monthly` - Rotation policy
|
||||
|
||||
**snapshots table:**
|
||||
- `client_id` - Owner of the snapshot
|
||||
- `snapshot_id` - Unique identifier
|
||||
- `timestamp` - When the snapshot was taken
|
||||
- `size_bytes` - Snapshot size
|
||||
- `storage_key` - Location in storage
|
||||
- `storage_type` - Where it's stored
|
||||
- `compressed`, `incremental`, `base_snapshot` - Snapshot properties
|
||||
|
||||
### Server-Managed Rotation Policy
|
||||
|
||||
When `rotation_policy` is configured for a client in `clients.json`, the client **must** use this policy and cannot override it. This enables centralized control of snapshot retention policies:
|
||||
When a rotation policy is configured for a client in the database, the client **must** use this policy and cannot override it. This enables centralized control of snapshot retention policies:
|
||||
|
||||
- **Server-Managed**: If `rotation_policy` is set, the client fetches the policy from the server and applies it
|
||||
- **Client-Autonomous**: If no `rotation_policy` is set, the client uses its default policy
|
||||
- **Server-Managed**: If rotation policy is set, the client fetches the policy from the server and applies it
|
||||
- **Client-Autonomous**: If no rotation policy is set, the client uses its default policy
|
||||
|
||||
The rotation policy fields are:
|
||||
- `keep_hourly`: Number of hourly snapshots to keep (default: 24)
|
||||
@@ -403,6 +427,82 @@ Response:
|
||||
}
|
||||
```
|
||||
|
||||
## Admin Panel
|
||||
|
||||
The server includes a web-based admin panel for managing clients, snapshots, and admin users. Access it at `http://localhost:8080/admin/`.
|
||||
|
||||
### Default Admin Credentials
|
||||
|
||||
When the server starts for the first time, it creates a default admin user:
|
||||
- **Username**: `admin`
|
||||
- **Password**: `admin123`
|
||||
|
||||
> **Important**: Change the default password immediately after first login!
|
||||
|
||||
### Admin Panel Features
|
||||
|
||||
- **Dashboard**: View statistics (client count, total snapshots, storage usage)
|
||||
- **Client Management**:
|
||||
- Create, view, and delete clients
|
||||
- Configure storage type (S3 or local ZFS)
|
||||
- Set quotas and rotation policies
|
||||
- Enable/disable clients
|
||||
- **Snapshot Management**:
|
||||
- View all snapshots across all clients
|
||||
- Filter by client
|
||||
- Delete individual snapshots
|
||||
- **Admin User Management**:
|
||||
- Create additional admin users
|
||||
- Delete admin accounts
|
||||
|
||||
### Admin API Endpoints
|
||||
|
||||
All admin endpoints require authentication via session cookie.
|
||||
|
||||
| Endpoint | Method | Description |
|
||||
|----------|--------|-------------|
|
||||
| `/admin/login` | POST | Login with username/password |
|
||||
| `/admin/logout` | POST | Logout current session |
|
||||
| `/admin/check` | GET | Check authentication status |
|
||||
| `/admin/clients` | GET | List all clients with usage stats |
|
||||
| `/admin/client` | GET | Get specific client details |
|
||||
| `/admin/client/create` | POST | Create new client |
|
||||
| `/admin/client/update` | PUT | Update client configuration |
|
||||
| `/admin/client/delete` | POST | Delete client and all snapshots |
|
||||
| `/admin/snapshots` | GET | List all snapshots |
|
||||
| `/admin/snapshot/delete` | POST | Delete specific snapshot |
|
||||
| `/admin/stats` | GET | Get server statistics |
|
||||
| `/admin/admins` | GET | List all admin users |
|
||||
| `/admin/admin/create` | POST | Create new admin user |
|
||||
| `/admin/admin/delete` | POST | Delete admin user |
|
||||
|
||||
### Creating a Client via API
|
||||
|
||||
```bash
|
||||
# Login first (saves session cookie)
|
||||
curl -c cookies.txt -X POST http://localhost:8080/admin/login \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"username":"admin","password":"admin123"}'
|
||||
|
||||
# Create a new client
|
||||
curl -b cookies.txt -X POST http://localhost:8080/admin/client/create \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"client_id": "myclient",
|
||||
"api_key": "secretkey123",
|
||||
"storage_type": "s3",
|
||||
"dataset": "backup/myclient",
|
||||
"max_size_bytes": 107374182400,
|
||||
"enabled": true,
|
||||
"rotation_policy": {
|
||||
"keep_hourly": 24,
|
||||
"keep_daily": 7,
|
||||
"keep_weekly": 4,
|
||||
"keep_monthly": 12
|
||||
}
|
||||
}'
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
|
||||
Reference in New Issue
Block a user