provisioning/docs/src/api-reference/path-resolution.md

731 lines
16 KiB
Markdown
Raw Normal View History

# Path Resolution API
2026-01-12 04:42:18 +00:00
This document describes the path resolution system used throughout the provisioning infrastructure for discovering configurations, extensions, and
resolving workspace paths.
## Overview
The path resolution system provides a hierarchical and configurable mechanism for:
- Configuration file discovery and loading
- Extension discovery (providers, task services, clusters)
- Workspace and project path management
- Environment variable interpolation
- Cross-platform path handling
## Configuration Resolution Hierarchy
The system follows a specific hierarchy for loading configuration files:
```plaintext
1. System defaults (config.defaults.toml)
2. User configuration (config.user.toml)
3. Project configuration (config.project.toml)
4. Infrastructure config (infra/config.toml)
5. Environment config (config.{env}.toml)
6. Runtime overrides (CLI arguments, ENV vars)
2026-01-12 04:42:18 +00:00
```
### Configuration Search Paths
The system searches for configuration files in these locations:
```bash
# Default search paths (in order)
/usr/local/provisioning/config.defaults.toml
$HOME/.config/provisioning/config.user.toml
$PWD/config.project.toml
$PROVISIONING_KLOUD_PATH/config.infra.toml
$PWD/config.{PROVISIONING_ENV}.toml
2026-01-12 04:42:18 +00:00
```
## Path Resolution API
### Core Functions
#### `resolve-config-path(pattern: string, search_paths: list<string>) -> string`
Resolves configuration file paths using the search hierarchy.
**Parameters:**
- `pattern`: File pattern to search for (for example, "config.*.toml")
- `search_paths`: Additional paths to search (optional)
**Returns:**
- Full path to the first matching configuration file
- Empty string if no file found
**Example:**
```nushell
use path-resolution.nu *
let config_path = (resolve-config-path "config.user.toml" [])
# Returns: "/home/user/.config/provisioning/config.user.toml"
2026-01-12 04:42:18 +00:00
```
#### `resolve-extension-path(type: string, name: string) -> record`
Discovers extension paths (providers, taskservs, clusters).
**Parameters:**
- `type`: Extension type ("provider", "taskserv", "cluster")
- `name`: Extension name (for example, "upcloud", "kubernetes", "buildkit")
**Returns:**
```nushell
{
base_path: "/usr/local/provisioning/providers/upcloud",
schemas_path: "/usr/local/provisioning/providers/upcloud/schemas",
nulib_path: "/usr/local/provisioning/providers/upcloud/nulib",
templates_path: "/usr/local/provisioning/providers/upcloud/templates",
exists: true
}
2026-01-12 04:42:18 +00:00
```
#### `resolve-workspace-paths() -> record`
Gets current workspace path configuration.
**Returns:**
```nushell
{
base: "/usr/local/provisioning",
current_infra: "/workspace/infra/production",
kloud_path: "/workspace/kloud",
providers: "/usr/local/provisioning/providers",
taskservs: "/usr/local/provisioning/taskservs",
clusters: "/usr/local/provisioning/cluster",
extensions: "/workspace/extensions"
}
2026-01-12 04:42:18 +00:00
```
### Path Interpolation
The system supports variable interpolation in configuration paths:
#### Supported Variables
- `{{paths.base}}` - Base provisioning path
- `{{paths.kloud}}` - Current kloud path
- `{{env.HOME}}` - User home directory
- `{{env.PWD}}` - Current working directory
- `{{now.date}}` - Current date (YYYY-MM-DD)
- `{{now.time}}` - Current time (HH:MM:SS)
- `{{git.branch}}` - Current git branch
- `{{git.commit}}` - Current git commit hash
#### `interpolate-path(template: string, context: record) -> string`
Interpolates variables in path templates.
**Parameters:**
- `template`: Path template with variables
- `context`: Variable context record
**Example:**
```nushell
let template = "{{paths.base}}/infra/{{env.USER}}/{{git.branch}}"
let result = (interpolate-path $template {
paths: { base: "/usr/local/provisioning" },
env: { USER: "admin" },
git: { branch: "main" }
})
# Returns: "/usr/local/provisioning/infra/admin/main"
2026-01-12 04:42:18 +00:00
```
## Extension Discovery API
### Provider Discovery
#### `discover-providers() -> list<record>`
Discovers all available providers.
**Returns:**
```nushell
[
{
name: "upcloud",
path: "/usr/local/provisioning/providers/upcloud",
type: "provider",
version: "1.2.0",
enabled: true,
has_schemas: true,
has_nulib: true,
has_templates: true
},
{
name: "aws",
path: "/usr/local/provisioning/providers/aws",
type: "provider",
version: "2.1.0",
enabled: true,
has_schemas: true,
has_nulib: true,
has_templates: true
}
]
2026-01-12 04:42:18 +00:00
```
#### `get-provider-config(name: string) -> record`
Gets provider-specific configuration and paths.
**Parameters:**
- `name`: Provider name
**Returns:**
```nushell
{
name: "upcloud",
base_path: "/usr/local/provisioning/providers/upcloud",
config: {
api_url: "https://api.upcloud.com/1.3",
auth_method: "basic",
interface: "API"
},
paths: {
schemas: "/usr/local/provisioning/providers/upcloud/schemas",
nulib: "/usr/local/provisioning/providers/upcloud/nulib",
templates: "/usr/local/provisioning/providers/upcloud/templates"
},
metadata: {
version: "1.2.0",
description: "UpCloud provider for server provisioning"
}
}
2026-01-12 04:42:18 +00:00
```
### Task Service Discovery
#### `discover-taskservs() -> list<record>`
Discovers all available task services.
**Returns:**
```nushell
[
{
name: "kubernetes",
path: "/usr/local/provisioning/taskservs/kubernetes",
type: "taskserv",
category: "orchestration",
version: "1.28.0",
enabled: true
},
{
name: "cilium",
path: "/usr/local/provisioning/taskservs/cilium",
type: "taskserv",
category: "networking",
version: "1.14.0",
enabled: true
}
]
2026-01-12 04:42:18 +00:00
```
#### `get-taskserv-config(name: string) -> record`
Gets task service configuration and version information.
**Parameters:**
- `name`: Task service name
**Returns:**
```nushell
{
name: "kubernetes",
path: "/usr/local/provisioning/taskservs/kubernetes",
version: {
current: "1.28.0",
available: "1.28.2",
update_available: true,
source: "github",
release_url: "https://github.com/kubernetes/kubernetes/releases"
},
config: {
category: "orchestration",
dependencies: ["containerd"],
supports_versions: ["1.26.x", "1.27.x", "1.28.x"]
}
}
2026-01-12 04:42:18 +00:00
```
### Cluster Discovery
#### `discover-clusters() -> list<record>`
Discovers all available cluster configurations.
**Returns:**
```nushell
[
{
name: "buildkit",
path: "/usr/local/provisioning/cluster/buildkit",
type: "cluster",
category: "build",
components: ["buildkit", "registry", "storage"],
enabled: true
}
]
2026-01-12 04:42:18 +00:00
```
## Environment Management API
### Environment Detection
#### `detect-environment() -> string`
Automatically detects the current environment based on:
1. `PROVISIONING_ENV` environment variable
2. Git branch patterns (main → prod, develop → dev, etc.)
3. Directory structure analysis
4. Configuration file presence
**Returns:**
- Environment name string (dev, test, prod, etc.)
#### `get-environment-config(env: string) -> record`
Gets environment-specific configuration.
**Parameters:**
- `env`: Environment name
**Returns:**
```nushell
{
name: "production",
paths: {
base: "/opt/provisioning",
kloud: "/data/kloud",
logs: "/var/log/provisioning"
},
providers: {
default: "upcloud",
allowed: ["upcloud", "aws"]
},
features: {
debug: false,
telemetry: true,
rollback: true
}
}
2026-01-12 04:42:18 +00:00
```
### Environment Switching
#### `switch-environment(env: string, validate: bool = true) -> null`
Switches to a different environment and updates path resolution.
**Parameters:**
- `env`: Target environment name
- `validate`: Whether to validate environment configuration
**Effects:**
- Updates `PROVISIONING_ENV` environment variable
- Reconfigures path resolution for new environment
- Validates environment configuration if requested
## Workspace Management API
### Workspace Discovery
#### `discover-workspaces() -> list<record>`
Discovers available workspaces and infrastructure directories.
**Returns:**
```nushell
[
{
name: "production",
path: "/workspace/infra/production",
type: "infrastructure",
provider: "upcloud",
settings: "settings.ncl",
valid: true
},
{
name: "development",
path: "/workspace/infra/development",
type: "infrastructure",
provider: "local",
settings: "dev-settings.ncl",
valid: true
}
]
2026-01-12 04:42:18 +00:00
```
#### `set-current-workspace(path: string) -> null`
Sets the current workspace for path resolution.
**Parameters:**
- `path`: Workspace directory path
**Effects:**
- Updates `CURRENT_INFRA_PATH` environment variable
- Reconfigures workspace-relative path resolution
### Project Structure Analysis
#### `analyze-project-structure(path: string = $PWD) -> record`
Analyzes project structure and identifies components.
**Parameters:**
- `path`: Project root path (defaults to current directory)
**Returns:**
```nushell
{
root: "/workspace/project",
type: "provisioning_workspace",
components: {
providers: [
{ name: "upcloud", path: "providers/upcloud" },
{ name: "aws", path: "providers/aws" }
],
taskservs: [
{ name: "kubernetes", path: "taskservs/kubernetes" },
{ name: "cilium", path: "taskservs/cilium" }
],
clusters: [
{ name: "buildkit", path: "cluster/buildkit" }
],
infrastructure: [
{ name: "production", path: "infra/production" },
{ name: "staging", path: "infra/staging" }
]
},
config_files: [
"config.defaults.toml",
"config.user.toml",
"config.prod.toml"
]
}
2026-01-12 04:42:18 +00:00
```
## Caching and Performance
### Path Caching
The path resolution system includes intelligent caching:
#### `cache-paths(duration: duration = 5 min) -> null`
Enables path caching for the specified duration.
**Parameters:**
- `duration`: Cache validity duration
#### `invalidate-path-cache() -> null`
Invalidates the path resolution cache.
#### `get-cache-stats() -> record`
Gets path resolution cache statistics.
**Returns:**
```nushell
{
enabled: true,
size: 150,
hit_rate: 0.85,
last_invalidated: "2025-09-26T10:00:00Z"
}
2026-01-12 04:42:18 +00:00
```
## Cross-Platform Compatibility
### Path Normalization
#### `normalize-path(path: string) -> string`
Normalizes paths for cross-platform compatibility.
**Parameters:**
- `path`: Input path (may contain mixed separators)
**Returns:**
- Normalized path using platform-appropriate separators
**Example:**
```nushell
# On Windows
normalize-path "path/to/file" # Returns: "path\to\file"
# On Unix
normalize-path "path\to\file" # Returns: "path/to/file"
2026-01-12 04:42:18 +00:00
```
#### `join-paths(segments: list<string>) -> string`
Safely joins path segments using platform separators.
**Parameters:**
- `segments`: List of path segments
**Returns:**
- Joined path string
## Configuration Validation API
### Path Validation
#### `validate-paths(config: record) -> record`
Validates all paths in configuration.
**Parameters:**
- `config`: Configuration record
**Returns:**
```nushell
{
valid: true,
errors: [],
warnings: [
{ path: "paths.extensions", message: "Path does not exist" }
],
checks_performed: 15
}
2026-01-12 04:42:18 +00:00
```
#### `validate-extension-structure(type: string, path: string) -> record`
Validates extension directory structure.
**Parameters:**
- `type`: Extension type (provider, taskserv, cluster)
- `path`: Extension base path
**Returns:**
```nushell
{
valid: true,
required_files: [
{ file: "manifest.toml", exists: true },
{ file: "schemas/main.ncl", exists: true },
{ file: "nulib/mod.nu", exists: true }
],
optional_files: [
{ file: "templates/server.j2", exists: false }
]
}
2026-01-12 04:42:18 +00:00
```
## Command-Line Interface
### Path Resolution Commands
The path resolution API is exposed via Nushell commands:
```bash
# Show current path configuration
provisioning show paths
# Discover available extensions
provisioning discover providers
provisioning discover taskservs
provisioning discover clusters
# Validate path configuration
provisioning validate paths
# Switch environments
provisioning env switch prod
# Set workspace
provisioning workspace set /path/to/infra
2026-01-12 04:42:18 +00:00
```
## Integration Examples
### Python Integration
```python
import subprocess
import json
class PathResolver:
def __init__(self, provisioning_path="/usr/local/bin/provisioning"):
self.cmd = provisioning_path
def get_paths(self):
result = subprocess.run([
"nu", "-c", f"use {self.cmd} *; show-config --section=paths --format=json"
], capture_output=True, text=True)
return json.loads(result.stdout)
def discover_providers(self):
result = subprocess.run([
"nu", "-c", f"use {self.cmd} *; discover providers --format=json"
], capture_output=True, text=True)
return json.loads(result.stdout)
# Usage
resolver = PathResolver()
paths = resolver.get_paths()
providers = resolver.discover_providers()
2026-01-12 04:42:18 +00:00
```
### JavaScript/Node.js Integration
```javascript
const { exec } = require('child_process');
const util = require('util');
const execAsync = util.promisify(exec);
class PathResolver {
constructor(provisioningPath = '/usr/local/bin/provisioning') {
this.cmd = provisioningPath;
}
async getPaths() {
const { stdout } = await execAsync(
`nu -c "use ${this.cmd} *; show-config --section=paths --format=json"`
);
return JSON.parse(stdout);
}
async discoverExtensions(type) {
const { stdout } = await execAsync(
`nu -c "use ${this.cmd} *; discover ${type} --format=json"`
);
return JSON.parse(stdout);
}
}
// Usage
const resolver = new PathResolver();
const paths = await resolver.getPaths();
const providers = await resolver.discoverExtensions('providers');
2026-01-12 04:42:18 +00:00
```
## Error Handling
### Common Error Scenarios
1. **Configuration File Not Found**
```nushell
Error: Configuration file not found in search paths
Searched: ["/usr/local/provisioning/config.defaults.toml", ...]
```
1. **Extension Not Found**
```nushell
Error: Provider 'missing-provider' not found
Available providers: ["upcloud", "aws", "local"]
```
2. **Invalid Path Template**
```nushell
Error: Invalid template variable: {{invalid.var}}
Valid variables: ["paths.*", "env.*", "now.*", "git.*"]
```
3. **Environment Not Found**
```nushell
Error: Environment 'staging' not configured
Available environments: ["dev", "test", "prod"]
```
### Error Recovery
The system provides graceful fallbacks:
- Missing configuration files use system defaults
- Invalid paths fall back to safe defaults
- Extension discovery continues if some paths are inaccessible
- Environment detection falls back to 'local' if detection fails
## Performance Considerations
### Best Practices
1. **Use Path Caching**: Enable caching for frequently accessed paths
2. **Batch Discovery**: Discover all extensions at once rather than individually
3. **Lazy Loading**: Load extension configurations only when needed
4. **Environment Detection**: Cache environment detection results
### Monitoring
Monitor path resolution performance:
```nushell
# Get resolution statistics
provisioning debug path-stats
# Monitor cache performance
provisioning debug cache-stats
# Profile path resolution
provisioning debug profile-paths
2026-01-12 04:42:18 +00:00
```
## Security Considerations
### Path Traversal Protection
The system includes protections against path traversal attacks:
- All paths are normalized and validated
- Relative paths are resolved within safe boundaries
- Symlinks are validated before following
### Access Control
Path resolution respects file system permissions:
- Configuration files require read access
- Extension directories require read/execute access
- Workspace directories may require write access for operations
2026-01-12 04:42:18 +00:00
This path resolution API provides a comprehensive and flexible system for managing the complex path requirements of multi-provider, multi-environment
infrastructure provisioning.