provisioning/EXTENSIONS.md
2025-09-22 23:11:41 +01:00

274 lines
7.0 KiB
Markdown

# Provisioning Extension System
The provisioning system supports extensions to add custom providers, task services, and access control without forking the main codebase.
## Extension Architecture
### Extension Discovery Paths
Extensions are loaded from multiple locations in priority order:
1. **Project-specific**: `.provisioning/extensions/` (highest priority)
2. **User-specific**: `~/.provisioning-extensions/`
3. **System-wide**: `/opt/provisioning-extensions/`
4. **Environment**: `$PROVISIONING_EXTENSIONS_PATH`
### Extension Types
#### 1. **Providers**
Custom cloud providers or infrastructure backends.
```
~/.provisioning-extensions/providers/
├── digitalocean/
│ ├── manifest.yaml
│ └── nulib/digitalocean/
│ ├── servers.nu
│ ├── env.nu
│ └── cache.nu
└── internal-cloud/
├── manifest.yaml
└── nulib/internal-cloud/
└── servers.nu
```
#### 2. **TaskServs**
Custom task services for application deployment or system configuration.
```
~/.provisioning-extensions/taskservs/
├── custom-app/
│ ├── manifest.yaml
│ ├── production/
│ │ └── install-custom-app.sh
│ ├── staging/
│ │ └── install-custom-app.sh
│ └── development/
│ └── install-custom-app.sh
└── monitoring/
├── manifest.yaml
└── default/
└── install-monitoring.sh
```
#### 3. **Profiles**
Access control profiles for restricted environments.
```
~/.provisioning-extensions/profiles/
├── cicd.yaml
├── developer.yaml
└── readonly.yaml
```
## Extension Configuration
### Environment Variables
| Variable | Description | Default |
|----------|-------------|---------|
| `PROVISIONING_EXTENSION_MODE` | Extension loading mode: `full`, `restricted`, `disabled` | `full` |
| `PROVISIONING_PROFILE` | Active access control profile | `""` (unrestricted) |
| `PROVISIONING_EXTENSIONS_PATH` | Custom extension base path | `""` |
| `PROVISIONING_ALLOWED_EXTENSIONS` | Comma-separated allowlist | `""` |
| `PROVISIONING_BLOCKED_EXTENSIONS` | Comma-separated blocklist | `""` |
### Configuration via Context
Add to `~/.provisioning/context.yaml`:
```yaml
extension_mode: restricted
profile: cicd
allowed_extensions: "digitalocean,custom-app"
blocked_extensions: "aws,dangerous-taskserv"
extensions_path: "/custom/path/to/extensions"
```
## Creating Extensions
### Provider Extension
1. **Create directory structure**:
```bash
mkdir -p ~/.provisioning-extensions/providers/myprovider/nulib/myprovider
```
2. **Create manifest.yaml**:
```yaml
name: myprovider
version: 1.0.0
type: provider
description: My custom cloud provider
requires:
- mycloud-cli
permissions:
- network
- compute
hooks:
pre_create: validate.nu
post_create: notify.nu
```
3. **Implement provider functions** in `nulib/myprovider/servers.nu`:
```nushell
export def myprovider_create_servers [settings: record, servers: table, check: bool, wait: bool] {
# Implementation here
}
export def myprovider_delete_servers [settings: record, servers: table, check: bool] {
# Implementation here
}
export def myprovider_query_servers [find: string, cols: string] {
# Implementation here
}
export def myprovider_get_ip [settings: record, server: record, ip_type: string, fallback: bool] {
# Implementation here
}
```
### TaskServ Extension
1. **Create directory structure**:
```bash
mkdir -p ~/.provisioning-extensions/taskservs/mytask/{production,staging,development}
```
2. **Create manifest.yaml**:
```yaml
name: mytask
version: 2.0.0
type: taskserv
description: My custom task service
requires:
- docker
- kubectl
profiles:
- production
- staging
- development
```
3. **Create installation scripts**:
```bash
# ~/.provisioning-extensions/taskservs/mytask/production/install-mytask.sh
#!/bin/bash
echo "Installing mytask in production mode"
# Implementation here
```
### Profile Extension
Create `~/.provisioning-extensions/profiles/myprofile.yaml`:
```yaml
profile: myprofile
description: Custom access profile
restricted: true
allowed:
commands: ["server list", "taskserv status"]
providers: ["local", "myprovider"]
taskservs: ["kubernetes", "mytask"]
blocked:
commands: ["server delete", "sops"]
providers: ["aws"]
taskservs: ["postgres"]
```
## Usage Examples
### Using Custom Provider
```bash
# Enable extensions
export PROVISIONING_EXTENSION_MODE=full
# Use custom provider in settings.k
servers = [
{
hostname: "web-01"
provider: "digitalocean" # Custom provider
region: "nyc1"
size: "s-1vcpu-1gb"
}
]
```
### Restricted CI/CD Environment
```bash
# Set CI/CD profile
export PROVISIONING_PROFILE=cicd
export PROVISIONING_EXTENSION_MODE=restricted
# These commands work
provisioning server list ✅
provisioning taskserv status ✅
# These commands are blocked
provisioning server delete ❌
provisioning sops edit secrets ❌
```
### Project-Specific Extensions
```bash
# In your project directory
mkdir -p .provisioning/extensions/taskservs/project-deploy/default
echo '#!/bin/bash\necho "Deploying project"' > .provisioning/extensions/taskservs/project-deploy/default/install-project-deploy.sh
# Use in taskservs
taskservs = [
{
name: "project-deploy" # Automatically discovered
profile: "default"
}
]
```
## Extension Management Commands
```bash
# List available extensions
provisioning extensions list
# Show extension details
provisioning extensions show digitalocean
# Validate extension
provisioning extensions validate ~/.provisioning-extensions/providers/myprovider
# Create example profiles
provisioning profiles create-examples
# Show current profile
provisioning profile show
```
## Security Considerations
1. **Profile Enforcement**: Use profiles in CI/CD to limit capabilities
2. **Extension Validation**: Check manifests and requirements before loading
3. **Path Isolation**: Extensions can't access core provisioning internals
4. **Permission System**: Extensions declare required permissions
5. **Allowlist/Blocklist**: Control which extensions can be loaded
## Migration Guide
### From Forked Provisioning
1. **Extract Custom Code**: Move custom providers/taskservs to extension directories
2. **Create Manifests**: Add `manifest.yaml` for each extension
3. **Update Configuration**: Use environment variables instead of code changes
4. **Test Extensions**: Verify functionality with extension system
### Gradual Adoption
1. **Start Small**: Begin with profile-based access control
2. **Move TaskServs**: Migrate custom task services to extensions
3. **Add Providers**: Create provider extensions as needed
4. **Full Migration**: Remove forks and use pure extension system
This extension system allows the main provisioning project to remain clean and focused while providing unlimited customization capabilities.