2026-01-14 04:53:21 +00:00
|
|
|
# Path Resolution API
|
|
|
|
|
|
|
|
|
|
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:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
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)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Configuration Search Paths
|
|
|
|
|
|
|
|
|
|
The system searches for configuration files in these locations:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
# 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
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
use path-resolution.nu *
|
|
|
|
|
let config_path = (resolve-config-path "config.user.toml" [])
|
|
|
|
|
# Returns: "/home/user/.config/provisioning/config.user.toml"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `resolve-workspace-paths() -> record`
|
|
|
|
|
|
|
|
|
|
Gets current workspace path configuration.
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
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"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Extension Discovery API
|
|
|
|
|
|
|
|
|
|
### Provider Discovery
|
|
|
|
|
|
|
|
|
|
#### `discover-providers() -> list<record>`
|
|
|
|
|
|
|
|
|
|
Discovers all available providers.
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `get-provider-config(name: string) -> record`
|
|
|
|
|
|
|
|
|
|
Gets provider-specific configuration and paths.
|
|
|
|
|
|
|
|
|
|
**Parameters:**
|
|
|
|
|
|
|
|
|
|
- `name`: Provider name
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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"
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Task Service Discovery
|
|
|
|
|
|
|
|
|
|
#### `discover-taskservs() -> list<record>`
|
|
|
|
|
|
|
|
|
|
Discovers all available task services.
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `get-taskserv-config(name: string) -> record`
|
|
|
|
|
|
|
|
|
|
Gets task service configuration and version information.
|
|
|
|
|
|
|
|
|
|
**Parameters:**
|
|
|
|
|
|
|
|
|
|
- `name`: Task service name
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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"]
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### Cluster Discovery
|
|
|
|
|
|
|
|
|
|
#### `discover-clusters() -> list<record>`
|
|
|
|
|
|
|
|
|
|
Discovers all available cluster configurations.
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
name: "buildkit",
|
|
|
|
|
path: "/usr/local/provisioning/cluster/buildkit",
|
|
|
|
|
type: "cluster",
|
|
|
|
|
category: "build",
|
|
|
|
|
components: ["buildkit", "registry", "storage"],
|
|
|
|
|
enabled: true
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### 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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
[
|
|
|
|
|
{
|
|
|
|
|
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
|
|
|
|
|
}
|
|
|
|
|
]
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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"
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
enabled: true,
|
|
|
|
|
size: 150,
|
|
|
|
|
hit_rate: 0.85,
|
|
|
|
|
last_invalidated: "2025-09-26T10:00:00Z"
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
# On Windows
|
|
|
|
|
normalize-path "path/to/file" # Returns: "path\to\file"
|
|
|
|
|
|
|
|
|
|
# On Unix
|
|
|
|
|
normalize-path "path\to\file" # Returns: "path/to/file"
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `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:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
valid: true,
|
|
|
|
|
errors: [],
|
|
|
|
|
warnings: [
|
|
|
|
|
{ path: "paths.extensions", message: "Path does not exist" }
|
|
|
|
|
],
|
|
|
|
|
checks_performed: 15
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
#### `validate-extension-structure(type: string, path: string) -> record`
|
|
|
|
|
|
|
|
|
|
Validates extension directory structure.
|
|
|
|
|
|
|
|
|
|
**Parameters:**
|
|
|
|
|
|
|
|
|
|
- `type`: Extension type (provider, taskserv, cluster)
|
|
|
|
|
- `path`: Extension base path
|
|
|
|
|
|
|
|
|
|
**Returns:**
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
{
|
|
|
|
|
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 }
|
|
|
|
|
]
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Command-Line Interface
|
|
|
|
|
|
|
|
|
|
### Path Resolution Commands
|
|
|
|
|
|
|
|
|
|
The path resolution API is exposed via Nushell commands:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
# 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
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## Integration Examples
|
|
|
|
|
|
|
|
|
|
### Python Integration
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
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()
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
### JavaScript/Node.js Integration
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
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');
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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:
|
|
|
|
|
|
|
|
|
|
```text
|
|
|
|
|
# Get resolution statistics
|
|
|
|
|
provisioning debug path-stats
|
|
|
|
|
|
|
|
|
|
# Monitor cache performance
|
|
|
|
|
provisioning debug cache-stats
|
|
|
|
|
|
|
|
|
|
# Profile path resolution
|
|
|
|
|
provisioning debug profile-paths
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
## 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
|
|
|
|
|
|
|
|
|
|
This path resolution API provides a comprehensive and flexible system for managing the complex path requirements of multi-provider, multi-environment
|
|
|
|
|
infrastructure provisioning.
|