575 lines
12 KiB
Markdown
575 lines
12 KiB
Markdown
# Provisioning API Server
|
|
|
|
A comprehensive REST API server for remote provisioning operations, enabling thin clients and CI/CD pipeline integration.
|
|
|
|
## Features
|
|
|
|
- **Comprehensive REST API**: Complete provisioning operations via HTTP
|
|
- **JWT Authentication**: Secure token-based authentication
|
|
- **RBAC System**: Role-based access control (Admin, Operator, Developer, Viewer)
|
|
- **Async Operations**: Long-running tasks with status tracking
|
|
- **Nushell Integration**: Direct execution of provisioning CLI commands
|
|
- **Audit Logging**: Complete operation tracking for compliance
|
|
- **Metrics**: Prometheus-compatible metrics endpoint
|
|
- **CORS Support**: Configurable cross-origin resource sharing
|
|
- **Health Checks**: Built-in health and readiness endpoints
|
|
|
|
## Architecture
|
|
|
|
```
|
|
┌─────────────────┐
|
|
│ REST Client │
|
|
│ (curl, CI/CD) │
|
|
└────────┬────────┘
|
|
│ HTTPS/JWT
|
|
▼
|
|
┌─────────────────┐
|
|
│ API Gateway │
|
|
│ - Routes │
|
|
│ - Auth │
|
|
│ - RBAC │
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Async Task Mgr │
|
|
│ - Queue │
|
|
│ - Status │
|
|
└────────┬────────┘
|
|
│
|
|
▼
|
|
┌─────────────────┐
|
|
│ Nushell Exec │
|
|
│ - CLI wrapper │
|
|
│ - Timeout │
|
|
└─────────────────┘
|
|
```
|
|
|
|
## Installation
|
|
|
|
### Building from Source
|
|
|
|
```bash
|
|
cd provisioning/platform/provisioning-server
|
|
cargo build --release
|
|
```
|
|
|
|
The binary will be at `target/release/provisioning-server`.
|
|
|
|
### Using Docker
|
|
|
|
```bash
|
|
# Build image
|
|
docker build -t provisioning-server .
|
|
|
|
# Run container
|
|
docker run -d \
|
|
-p 8083:8083 \
|
|
-e JWT_SECRET="your-secret-here" \
|
|
-e PROVISIONING_CLI_PATH="/usr/local/bin/provisioning" \
|
|
provisioning-server
|
|
```
|
|
|
|
### Using Docker Compose
|
|
|
|
```bash
|
|
# Start server
|
|
docker-compose up -d
|
|
|
|
# View logs
|
|
docker-compose logs -f
|
|
|
|
# Stop server
|
|
docker-compose down
|
|
```
|
|
|
|
## Configuration
|
|
|
|
### Configuration File
|
|
|
|
Create `config.toml`:
|
|
|
|
```toml
|
|
[server]
|
|
host = "0.0.0.0"
|
|
port = 8083
|
|
cors_enabled = true
|
|
|
|
[auth]
|
|
jwt_secret = "your-secret-key-here"
|
|
token_expiry_hours = 24
|
|
refresh_token_expiry_hours = 168
|
|
|
|
[provisioning]
|
|
cli_path = "/usr/local/bin/provisioning"
|
|
timeout_seconds = 300
|
|
max_concurrent_operations = 10
|
|
|
|
[logging]
|
|
level = "info"
|
|
json_format = false
|
|
```
|
|
|
|
### Environment Variables
|
|
|
|
Alternatively, use environment variables:
|
|
|
|
```bash
|
|
export SERVER_HOST=0.0.0.0
|
|
export SERVER_PORT=8083
|
|
export JWT_SECRET="your-secret-key"
|
|
export PROVISIONING_CLI_PATH="/usr/local/bin/provisioning"
|
|
export LOG_LEVEL=info
|
|
```
|
|
|
|
See `.env.example` for all available variables.
|
|
|
|
## Usage
|
|
|
|
### Starting the Server
|
|
|
|
```bash
|
|
# Using config file
|
|
provisioning-server --config config.toml
|
|
|
|
# Using environment variables
|
|
provisioning-server
|
|
|
|
# Custom settings
|
|
provisioning-server \
|
|
--host 0.0.0.0 \
|
|
--port 8083 \
|
|
--jwt-secret "my-secret" \
|
|
--cli-path "/usr/local/bin/provisioning" \
|
|
--log-level debug
|
|
```
|
|
|
|
### Authentication
|
|
|
|
#### Login
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8083/v1/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"username": "admin",
|
|
"password": "admin123"
|
|
}'
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"token": "eyJhbGc...",
|
|
"refresh_token": "eyJhbGc...",
|
|
"expires_in": 86400
|
|
}
|
|
```
|
|
|
|
#### Using Token
|
|
|
|
Include the token in subsequent requests:
|
|
|
|
```bash
|
|
export TOKEN="eyJhbGc..."
|
|
|
|
curl -X GET http://localhost:8083/v1/servers \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
```
|
|
|
|
#### Refresh Token
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8083/v1/auth/refresh \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"refresh_token": "eyJhbGc..."
|
|
}'
|
|
```
|
|
|
|
### Default Users
|
|
|
|
| Username | Password | Role |
|
|
|------------|--------------|-----------|
|
|
| admin | admin123 | admin |
|
|
| operator | operator123 | operator |
|
|
| developer | dev123 | developer |
|
|
|
|
**⚠️ IMPORTANT**: Change these credentials in production!
|
|
|
|
## API Endpoints
|
|
|
|
### Authentication
|
|
|
|
- `POST /v1/auth/login` - User login
|
|
- `POST /v1/auth/refresh` - Refresh access token
|
|
|
|
### Servers
|
|
|
|
- `GET /v1/servers` - List all servers
|
|
- `POST /v1/servers/create` - Create new server
|
|
- `DELETE /v1/servers/{id}` - Delete server
|
|
- `GET /v1/servers/{id}/status` - Get server status
|
|
|
|
#### Create Server Example
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8083/v1/servers/create \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"workspace": "production",
|
|
"provider": "upcloud",
|
|
"plan": "2xCPU-4GB",
|
|
"hostname": "web-01",
|
|
"zone": "de-fra1",
|
|
"check_mode": false,
|
|
"tags": ["web", "production"]
|
|
}'
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"status": "pending",
|
|
"created_at": "2025-10-06T12:00:00Z",
|
|
"updated_at": "2025-10-06T12:00:00Z",
|
|
"result": null,
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
### Taskservs
|
|
|
|
- `GET /v1/taskservs` - List all taskservs
|
|
- `POST /v1/taskservs/create` - Create taskserv
|
|
- `DELETE /v1/taskservs/{id}` - Delete taskserv
|
|
- `GET /v1/taskservs/{id}/status` - Get taskserv status
|
|
|
|
#### Create Taskserv Example
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8083/v1/taskservs/create \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"workspace": "production",
|
|
"name": "kubernetes",
|
|
"servers": ["web-01", "web-02"],
|
|
"check_mode": false
|
|
}'
|
|
```
|
|
|
|
### Workflows
|
|
|
|
- `POST /v1/workflows/submit` - Submit workflow
|
|
- `GET /v1/workflows/{id}` - Get workflow details
|
|
- `GET /v1/workflows/{id}/status` - Get workflow status
|
|
- `POST /v1/workflows/{id}/cancel` - Cancel workflow
|
|
|
|
#### Submit Workflow Example
|
|
|
|
```bash
|
|
curl -X POST http://localhost:8083/v1/workflows/submit \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"workspace": "production",
|
|
"workflow_type": "cluster_create",
|
|
"parameters": {
|
|
"cluster_name": "k8s-prod",
|
|
"node_count": 3
|
|
}
|
|
}'
|
|
```
|
|
|
|
### Operations
|
|
|
|
- `GET /v1/operations` - List all operations
|
|
- `GET /v1/operations/{id}` - Get operation status
|
|
- `POST /v1/operations/{id}/cancel` - Cancel operation
|
|
|
|
#### Check Operation Status
|
|
|
|
```bash
|
|
curl -X GET http://localhost:8083/v1/operations/550e8400-e29b-41d4-a716-446655440000 \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"id": "550e8400-e29b-41d4-a716-446655440000",
|
|
"status": "completed",
|
|
"created_at": "2025-10-06T12:00:00Z",
|
|
"updated_at": "2025-10-06T12:05:00Z",
|
|
"result": {
|
|
"server_id": "srv-abc123",
|
|
"ip_address": "10.0.0.1"
|
|
},
|
|
"error": null
|
|
}
|
|
```
|
|
|
|
### Workspaces
|
|
|
|
- `GET /v1/workspaces` - List workspaces
|
|
- `POST /v1/workspaces/create` - Create workspace
|
|
- `GET /v1/workspaces/{name}` - Get workspace details
|
|
|
|
### System
|
|
|
|
- `GET /health` - Health check (no auth required)
|
|
- `GET /v1/version` - Version information
|
|
- `GET /v1/metrics` - Prometheus metrics (requires auth)
|
|
|
|
## RBAC Permissions
|
|
|
|
### Admin Role
|
|
|
|
Full system access including:
|
|
- All server operations
|
|
- All taskserv operations
|
|
- All cluster operations
|
|
- Workspace management
|
|
- Workflow management
|
|
- System administration
|
|
- Audit log access
|
|
|
|
### Operator Role
|
|
|
|
Infrastructure operations:
|
|
- Create/delete/read servers
|
|
- Create/delete/read taskservs
|
|
- Create/delete/read clusters
|
|
- Submit/cancel workflows
|
|
- View operations
|
|
|
|
### Developer Role
|
|
|
|
Read access plus SSH:
|
|
- Read servers/taskservs/clusters
|
|
- SSH to servers
|
|
- View workflows
|
|
- View operations
|
|
|
|
### Viewer Role
|
|
|
|
Read-only access:
|
|
- List all resources
|
|
- View status
|
|
- System health checks
|
|
|
|
## Security Best Practices
|
|
|
|
### Production Deployment
|
|
|
|
1. **Change Default Credentials**: Update all default usernames/passwords
|
|
2. **Use Strong JWT Secret**: Generate a secure random string (32+ characters)
|
|
3. **Enable TLS**: Use HTTPS in production
|
|
4. **Restrict CORS**: Configure specific allowed origins
|
|
5. **Enable mTLS**: For client certificate authentication
|
|
6. **Regular Token Rotation**: Implement token refresh strategy
|
|
7. **Audit Logging**: Enable audit logs for compliance
|
|
|
|
### JWT Secret Generation
|
|
|
|
```bash
|
|
# Generate secure random secret
|
|
openssl rand -base64 32
|
|
```
|
|
|
|
### TLS Configuration
|
|
|
|
```toml
|
|
[server]
|
|
tls_cert = "/path/to/cert.pem"
|
|
tls_key = "/path/to/key.pem"
|
|
```
|
|
|
|
### mTLS Configuration
|
|
|
|
```toml
|
|
[auth]
|
|
mtls_enabled = true
|
|
mtls_ca_cert = "/path/to/ca.pem"
|
|
```
|
|
|
|
## Monitoring
|
|
|
|
### Health Check
|
|
|
|
```bash
|
|
curl http://localhost:8083/health
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"status": "healthy",
|
|
"version": "0.1.0",
|
|
"uptime_seconds": 3600
|
|
}
|
|
```
|
|
|
|
### Metrics
|
|
|
|
```bash
|
|
curl http://localhost:8083/v1/metrics \
|
|
-H "Authorization: Bearer $TOKEN"
|
|
```
|
|
|
|
Response:
|
|
```json
|
|
{
|
|
"uptime_seconds": 3600,
|
|
"tasks": {
|
|
"total": 42,
|
|
"running": 3
|
|
}
|
|
}
|
|
```
|
|
|
|
## Development
|
|
|
|
### Running Tests
|
|
|
|
```bash
|
|
cargo test
|
|
```
|
|
|
|
### Running with Debug Logging
|
|
|
|
```bash
|
|
RUST_LOG=debug provisioning-server
|
|
```
|
|
|
|
### Code Structure
|
|
|
|
```
|
|
src/
|
|
├── main.rs # Application entry point
|
|
├── lib.rs # Library exports
|
|
├── config.rs # Configuration management
|
|
├── error.rs # Error types
|
|
├── models/ # Request/response models
|
|
├── auth/ # Authentication & authorization
|
|
│ ├── jwt.rs # JWT token handling
|
|
│ ├── rbac.rs # Role-based access control
|
|
│ └── mod.rs # Auth module exports
|
|
├── executor/ # Command execution
|
|
│ ├── nushell.rs # Nushell CLI wrapper
|
|
│ ├── async_task.rs # Async task manager
|
|
│ └── mod.rs # Executor exports
|
|
└── api/ # API endpoints
|
|
├── routes.rs # Route definitions
|
|
├── servers.rs # Server endpoints
|
|
├── taskservs.rs # Taskserv endpoints
|
|
├── workflows.rs # Workflow endpoints
|
|
├── operations.rs # Operation endpoints
|
|
├── workspaces.rs # Workspace endpoints
|
|
├── auth.rs # Auth endpoints
|
|
├── system.rs # System endpoints
|
|
└── mod.rs # API module exports
|
|
```
|
|
|
|
## CI/CD Integration
|
|
|
|
### GitHub Actions Example
|
|
|
|
```yaml
|
|
name: Deploy Infrastructure
|
|
|
|
on:
|
|
push:
|
|
branches: [main]
|
|
|
|
jobs:
|
|
deploy:
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- name: Login
|
|
run: |
|
|
TOKEN=$(curl -X POST https://api.example.com/v1/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"username":"${{ secrets.API_USER }}","password":"${{ secrets.API_PASS }}"}' \
|
|
| jq -r '.token')
|
|
echo "TOKEN=$TOKEN" >> $GITHUB_ENV
|
|
|
|
- name: Create Server
|
|
run: |
|
|
curl -X POST https://api.example.com/v1/servers/create \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d '{
|
|
"workspace": "production",
|
|
"provider": "upcloud",
|
|
"plan": "2xCPU-4GB",
|
|
"hostname": "web-${{ github.run_number }}"
|
|
}'
|
|
```
|
|
|
|
### GitLab CI Example
|
|
|
|
```yaml
|
|
deploy:
|
|
stage: deploy
|
|
script:
|
|
- |
|
|
TOKEN=$(curl -X POST $API_URL/v1/auth/login \
|
|
-H "Content-Type: application/json" \
|
|
-d "{\"username\":\"$API_USER\",\"password\":\"$API_PASS\"}" \
|
|
| jq -r '.token')
|
|
- |
|
|
curl -X POST $API_URL/v1/workflows/submit \
|
|
-H "Authorization: Bearer $TOKEN" \
|
|
-H "Content-Type: application/json" \
|
|
-d @workflow.json
|
|
only:
|
|
- main
|
|
```
|
|
|
|
## Troubleshooting
|
|
|
|
### Common Issues
|
|
|
|
**Authentication Failed**
|
|
- Check JWT secret configuration
|
|
- Verify username/password
|
|
- Check token expiration
|
|
|
|
**Operation Timeout**
|
|
- Increase `timeout_seconds` in config
|
|
- Check provisioning CLI accessibility
|
|
- Verify network connectivity
|
|
|
|
**Permission Denied**
|
|
- Check user role assignments
|
|
- Verify RBAC permissions
|
|
- Review audit logs
|
|
|
|
**Server Not Starting**
|
|
- Check port availability
|
|
- Verify configuration file
|
|
- Check log output
|
|
|
|
### Debug Mode
|
|
|
|
Enable detailed logging:
|
|
|
|
```bash
|
|
RUST_LOG=debug provisioning-server --log-level debug
|
|
```
|
|
|
|
## License
|
|
|
|
See project root LICENSE file.
|
|
|
|
## Support
|
|
|
|
For issues and questions:
|
|
- Check documentation: `/docs`
|
|
- Review API reference: `/v1/health`
|
|
- Contact: infrastructure team
|