Update core components including CLI, Nushell libraries, plugins system, and utility scripts for the provisioning system. CLI Updates: - Command implementations - CLI utilities and dispatching - Help system improvements - Command validation Library Updates: - Configuration management system - Infrastructure validation - Extension system improvements - Secrets management - Workspace operations - Cache management system Plugin System: - Interactive form plugin (inquire) - KCL integration plugin - Performance optimization plugins - Plugin registration system Utilities: - Build and distribution scripts - Installation procedures - Testing utilities - Development tools Documentation: - Library module documentation - Extension API guides - Plugin usage guides - Service management documentation All changes are backward compatible. No breaking changes.
499 lines
17 KiB
Plaintext
499 lines
17 KiB
Plaintext
# Command Dispatcher
|
|
# Central routing logic for all provisioning commands
|
|
|
|
use flags.nu *
|
|
use commands/infrastructure.nu *
|
|
use commands/orchestration.nu *
|
|
use commands/development.nu *
|
|
use commands/workspace.nu *
|
|
use commands/generation.nu *
|
|
use commands/utilities.nu *
|
|
use commands/configuration.nu *
|
|
use commands/guides.nu *
|
|
use commands/authentication.nu *
|
|
use commands/diagnostics.nu *
|
|
use commands/integrations.nu *
|
|
use commands/vm_domain.nu *
|
|
use commands/platform.nu *
|
|
use ../lib_provisioning *
|
|
use ../lib_provisioning/workspace/enforcement.nu *
|
|
use ../lib_provisioning/commands/traits.nu *
|
|
use ./flags.nu extract-workspace-infra-from-flags
|
|
use ./metadata_handler.nu *
|
|
|
|
# Helper to run module commands
|
|
def run_module [
|
|
args: string
|
|
module: string
|
|
option?: string
|
|
--exec
|
|
] {
|
|
let use_debug = if ($env.PROVISIONING_DEBUG? | default false) { "-x" } else { "" }
|
|
|
|
if $exec {
|
|
exec $"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args
|
|
} else {
|
|
^$"($env.PROVISIONING_NAME)" $use_debug -mod $module ($option | default "") $args
|
|
}
|
|
}
|
|
|
|
# Command registry with shortcuts and aliases
|
|
# Maps short forms and aliases to their canonical command domain
|
|
export def get_command_registry []: nothing -> record {
|
|
{
|
|
# Infrastructure commands (server, taskserv, cluster, infra)
|
|
"s": "infrastructure server"
|
|
"server": "infrastructure server"
|
|
"t": "infrastructure taskserv"
|
|
"task": "infrastructure taskserv"
|
|
"taskserv": "infrastructure taskserv"
|
|
"cl": "infrastructure cluster"
|
|
"cluster": "infrastructure cluster"
|
|
"i": "infrastructure infra"
|
|
"infra": "infrastructure infra"
|
|
"infras": "infrastructure infra"
|
|
|
|
# VM commands (vm, hosts, lifecycle)
|
|
"vm": "vm vm"
|
|
"vmi": "vm info"
|
|
"vmh": "vm hosts"
|
|
"vml": "vm lifecycle"
|
|
"vm-create": "vm create"
|
|
"vm-list": "vm list"
|
|
"vm-start": "vm start"
|
|
"vm-stop": "vm stop"
|
|
"vm-delete": "vm delete"
|
|
"vm-hosts-check": "vm hosts check"
|
|
"vm-hosts-prepare": "vm hosts prepare"
|
|
|
|
# Orchestration commands (workflow, batch, orchestrator)
|
|
"wf": "orchestration workflow"
|
|
"flow": "orchestration workflow"
|
|
"workflow": "orchestration workflow"
|
|
"bat": "orchestration batch"
|
|
"batch": "orchestration batch"
|
|
"orch": "orchestration orchestrator"
|
|
"orchestrator": "orchestration orchestrator"
|
|
|
|
# Development commands (module, layer, version, pack)
|
|
"mod": "development module"
|
|
"module": "development module"
|
|
"lyr": "development layer"
|
|
"layer": "development layer"
|
|
"version": "development version"
|
|
"pack": "development pack"
|
|
|
|
# Module discover shortcuts
|
|
"discover": "development module discover"
|
|
"disc": "development module discover"
|
|
"discover-taskservs": "development module discover taskservs"
|
|
"disc-t": "development module discover taskservs"
|
|
"dt": "development module discover taskservs"
|
|
"discover-providers": "development module discover providers"
|
|
"disc-p": "development module discover providers"
|
|
"dp": "development module discover providers"
|
|
"discover-clusters": "development module discover clusters"
|
|
"disc-c": "development module discover clusters"
|
|
"dc": "development module discover clusters"
|
|
|
|
# Workspace commands (workspace, template)
|
|
"ws": "workspace workspace"
|
|
"workspace": "workspace workspace"
|
|
"tpl": "workspace template"
|
|
"tmpl": "workspace template"
|
|
"template": "workspace template"
|
|
|
|
# Platform commands (platform, orchestrator, control-center)
|
|
"plat": "platform platform"
|
|
"platform": "platform platform"
|
|
|
|
# Configuration commands (env, allenv, show, init, validate)
|
|
"e": "config env"
|
|
"env": "config env"
|
|
"allenv": "config allenv"
|
|
"show": "config show"
|
|
"init": "config init"
|
|
"validate": "config validate"
|
|
"val": "config validate"
|
|
"config-template": "config config-template"
|
|
|
|
# Authentication commands (auth, login, logout, mfa) - mapped to integrations for plugin support
|
|
"login": "integrations auth login"
|
|
"logout": "integrations auth logout"
|
|
"whoami": "integrations auth verify"
|
|
"mfa": "authentication mfa"
|
|
"mfa-enroll": "authentication mfa-enroll"
|
|
"mfa-verify": "authentication mfa-verify"
|
|
|
|
# Utility commands (sed, sops, cache, providers, etc.)
|
|
"sed": "utils sed"
|
|
"sops": "utils sops"
|
|
"cache": "utils cache"
|
|
"providers": "utils providers"
|
|
"nu": "utils nu"
|
|
|
|
# Test environment commands
|
|
"test": "test"
|
|
"tst": "test"
|
|
"list": "utils list"
|
|
"l": "utils list"
|
|
"ls": "utils list"
|
|
"qr": "utils qr"
|
|
"nuinfo": "utils nuinfo"
|
|
"plugin": "utils plugin"
|
|
"plugins": "utils plugins"
|
|
"plugin-list": "utils plugin list"
|
|
"plugin-add": "utils plugin register"
|
|
"plugin-test": "utils plugin test"
|
|
|
|
# Generation and Infrastructure-from-Code commands
|
|
"g": "generation generate"
|
|
"gen": "generation generate"
|
|
"generate": "generation generate"
|
|
"detect": "generation detect"
|
|
"complete": "generation complete"
|
|
"ifc": "generation workflow"
|
|
|
|
# Guide commands (avoiding conflicts with existing infrastructure commands)
|
|
"guide": "guides guide"
|
|
"guides": "guides guide"
|
|
"sc": "guides sc"
|
|
"shortcuts": "guides sc"
|
|
"quickstart": "guides quickstart"
|
|
"quick": "guides quickstart"
|
|
"from-scratch": "guides from-scratch"
|
|
"scratch": "guides from-scratch"
|
|
"customize": "guides customize"
|
|
"custom": "guides customize"
|
|
"howto": "guides guide list"
|
|
|
|
# Diagnostics commands
|
|
"status": "diagnostics status"
|
|
"health": "diagnostics health"
|
|
"next": "diagnostics next"
|
|
"phase": "diagnostics phase"
|
|
|
|
# Plugin-powered commands (10-30x faster with native plugins)
|
|
"auth": "integrations auth"
|
|
"auth-login": "integrations auth login"
|
|
"auth-logout": "integrations auth logout"
|
|
"auth-verify": "integrations auth verify"
|
|
"kms": "integrations kms"
|
|
"kms-encrypt": "integrations kms encrypt"
|
|
"kms-decrypt": "integrations kms decrypt"
|
|
"kms-status": "integrations kms status"
|
|
"encrypt": "integrations kms encrypt"
|
|
"decrypt": "integrations kms decrypt"
|
|
"orch-status": "integrations orch status"
|
|
"orch-tasks": "integrations orch tasks"
|
|
|
|
# Integrations commands (prov-ecosystem + provctl)
|
|
"int": "integrations integrations"
|
|
"integ": "integrations integrations"
|
|
"integrations": "integrations integrations"
|
|
"runtime": "integrations runtime"
|
|
"ssh-pool": "integrations ssh"
|
|
"ssh": "integrations ssh"
|
|
"backup": "integrations backup"
|
|
"gitops": "integrations gitops"
|
|
"service": "integrations service"
|
|
|
|
# Special commands (handled separately)
|
|
"h": "help"
|
|
"c": "infrastructure create"
|
|
"create": "infrastructure create"
|
|
"d": "infrastructure delete"
|
|
"delete": "infrastructure delete"
|
|
"u": "infrastructure update"
|
|
"update": "infrastructure update"
|
|
"price": "price"
|
|
"prices": "price"
|
|
"cost": "price"
|
|
"costs": "price"
|
|
"cst": "create-server-task"
|
|
"create-server-task": "create-server-task"
|
|
"csts": "create-server-task"
|
|
"create-servers-tasks": "create-server-task"
|
|
"deploy-rm": "deploy"
|
|
"deploy-del": "deploy"
|
|
"dp-rm": "deploy"
|
|
"d-r": "deploy"
|
|
"destroy": "deploy"
|
|
"deploy-sel": "deploy-sel"
|
|
"deploy-list": "deploy-sel"
|
|
"dp-sel": "deploy-sel"
|
|
"d-s": "deploy-sel"
|
|
"deploy-sel-tree": "deploy-sel-tree"
|
|
"deploy-list-tree": "deploy-sel-tree"
|
|
"dp-sel-t": "deploy-sel-tree"
|
|
"d-st": "deploy-sel-tree"
|
|
"new": "new"
|
|
"ai": "ai"
|
|
"context": "context"
|
|
"ctx": "context"
|
|
"setup": "setup"
|
|
"st": "setup"
|
|
"config": "setup"
|
|
"control-center": "control-center"
|
|
"mcp-server": "mcp-server"
|
|
}
|
|
}
|
|
|
|
# Main command dispatcher
|
|
# Routes commands to appropriate domain handlers
|
|
export def dispatch_command [
|
|
args: list
|
|
flags: record
|
|
] {
|
|
let task = if ($args | length) > 0 { ($args | get 0) } else { "" }
|
|
let ops_list = ($args | skip 1)
|
|
let ops_str = ($ops_list | str join " ")
|
|
|
|
# Handle empty command
|
|
if ($task | is-empty) {
|
|
print "Use 'provisioning help' for available commands"
|
|
exit
|
|
}
|
|
|
|
# Handle "provisioning help <category>" directly
|
|
# This is critical for commands like "provisioning help workspace"
|
|
if $task in ["help" "h"] {
|
|
let category = if ($ops_list | length) > 0 { ($ops_list | get 0) } else { "" }
|
|
exec $"($env.PROVISIONING_NAME)" help $category --notitles
|
|
}
|
|
|
|
# Intercept bi-directional help: "provisioning <cmd> help" → "provisioning help <cmd>"
|
|
# This ensures shortcuts like "provisioning ws help" work correctly
|
|
let first_op = if ($ops_list | length) > 0 { ($ops_list | get 0) } else { "" }
|
|
if $first_op in ["help" "h"] {
|
|
# Redirect to categorized help system
|
|
exec $"($env.PROVISIONING_NAME)" help $task --notitles
|
|
}
|
|
|
|
# Resolve command through registry
|
|
let registry = get_command_registry
|
|
let resolved = if ($task in ($registry | columns)) { $registry | get $task } else { $task }
|
|
|
|
# Split into domain, command, and optional subcommand args
|
|
let parts = ($resolved | split row " ")
|
|
let domain = if ($parts | length) > 1 { ($parts | get 0) } else { "special" }
|
|
let command = if ($parts | length) > 1 { ($parts | get 1) } else { $task }
|
|
|
|
# Extract any additional parts as pre-filled ops (for compound shortcuts like "dt" → "discover taskservs")
|
|
let extra_ops = if ($parts | length) > 2 {
|
|
($parts | skip 2 | str join " ")
|
|
} else {
|
|
""
|
|
}
|
|
|
|
# Combine extra_ops with user-provided ops
|
|
let final_ops = if ($extra_ops | is-not-empty) and ($ops_str | is-not-empty) {
|
|
$"($extra_ops) ($ops_str)"
|
|
} else if ($extra_ops | is-not-empty) {
|
|
$extra_ops
|
|
} else {
|
|
$ops_str
|
|
}
|
|
|
|
# Handle workspace override from flags
|
|
let workspace_context = (extract-workspace-infra-from-flags $flags)
|
|
|
|
# Set temporary workspace context if specified
|
|
if ($workspace_context.workspace | is-not-empty) {
|
|
$env.TEMP_WORKSPACE = $workspace_context.workspace
|
|
}
|
|
|
|
# Update infra flag if parsed from workspace:infra notation
|
|
let updated_flags = if ($workspace_context.infra | is-not-empty) {
|
|
$flags | merge { infra: $workspace_context.infra }
|
|
} else {
|
|
$flags
|
|
}
|
|
|
|
# WORKSPACE ENFORCEMENT - Check workspace requirement before processing
|
|
# This enforces that most commands require an active workspace
|
|
let enforcement_allowed = (check-and-enforce $task $args)
|
|
|
|
if not $enforcement_allowed {
|
|
# Enforcement failed - error already displayed by check-and-enforce
|
|
exit 1
|
|
}
|
|
|
|
# METADATA VALIDATION - Check command requirements and handle interactive forms
|
|
# Build canonical command name for metadata lookup
|
|
let canonical_name = if ($domain == "special") {
|
|
$command
|
|
} else if ($domain != "") {
|
|
$"($domain) ($command)"
|
|
} else {
|
|
$command
|
|
}
|
|
|
|
# Validate command and prepare execution (handles interactive forms)
|
|
let prep_result = (validate-and-prepare $canonical_name $updated_flags)
|
|
|
|
if not $prep_result.proceed {
|
|
# Validation failed - error already displayed by validate-and-prepare
|
|
exit 1
|
|
}
|
|
|
|
# Set environment based on flags
|
|
set_debug_env $updated_flags
|
|
|
|
# Ensure PROVISIONING_INFRA is explicitly set if infra flag was provided
|
|
# This ensures context-aware filtering works with --infra flag
|
|
if ($updated_flags.infra | is-not-empty) {
|
|
$env.PROVISIONING_INFRA = $updated_flags.infra
|
|
}
|
|
|
|
# Dispatch to domain handler
|
|
match $domain {
|
|
"infrastructure" => { handle_infrastructure_command $command $final_ops $updated_flags }
|
|
"orchestration" => { handle_orchestration_command $command $final_ops $updated_flags }
|
|
"development" => { handle_development_command $command $final_ops $updated_flags }
|
|
"workspace" => { handle_workspace_command $command $final_ops $updated_flags }
|
|
"config" => { handle_config_command $command $final_ops $updated_flags }
|
|
"utils" => { handle_utility_command $command $final_ops $updated_flags }
|
|
"generation" => { handle_generation_command $command $final_ops $updated_flags }
|
|
"guides" => { handle_guide_command $command $final_ops $updated_flags }
|
|
"authentication" => { handle_authentication_command $command $final_ops $updated_flags }
|
|
"diagnostics" => { handle_diagnostics_command $command $final_ops $updated_flags }
|
|
"integrations" => { handle_integrations_command $command $final_ops $updated_flags }
|
|
"platform" => { handle_platform_command $command $final_ops $updated_flags }
|
|
"vm" => { handle_vm_command $command $final_ops $updated_flags }
|
|
"special" => { handle_special_command $command $final_ops $updated_flags }
|
|
"test" => { handle_test_command $command $final_ops $updated_flags }
|
|
"help" => { exec $"($env.PROVISIONING_NAME)" help $command --notitles }
|
|
_ => {
|
|
invalid_task "" $task --end
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# Clean up temporary workspace context
|
|
if ($workspace_context.workspace | is-not-empty) {
|
|
hide-env TEMP_WORKSPACE
|
|
}
|
|
}
|
|
|
|
# Integrations command handler (prov-ecosystem + provctl)
|
|
def handle_integrations_command [command: string, ops: string, flags: record] {
|
|
let args_list = if ($ops | is-not-empty) {
|
|
$ops | split row " " | where { |x| ($x | is-not-empty) }
|
|
} else {
|
|
[]
|
|
}
|
|
|
|
let check_mode = if $flags.check_mode { "--check" } else { "" }
|
|
|
|
# Parse command - could be "integrations integrations" or just the subcommand
|
|
let subcommand = if $command == "integrations" {
|
|
($args_list | get 0?)
|
|
} else {
|
|
$command
|
|
}
|
|
|
|
# Get remaining args
|
|
let remaining_args = if $command == "integrations" {
|
|
($args_list | skip 1)
|
|
} else {
|
|
$args_list
|
|
}
|
|
|
|
# Call the integrations handler with parsed arguments
|
|
if ($subcommand == null) {
|
|
cmd-integrations "help" $remaining_args --check=($check_mode | is-not-empty)
|
|
} else {
|
|
cmd-integrations $subcommand $remaining_args --check=($check_mode | is-not-empty)
|
|
}
|
|
}
|
|
|
|
# Test command handler
|
|
def handle_test_command [command: string, ops: string, flags: record] {
|
|
let args = if ($ops | is-not-empty) { $ops } else { "" }
|
|
run_module $args "test" --exec
|
|
}
|
|
|
|
# Special command handler (create, delete, update, deploy, etc.)
|
|
def handle_special_command [command: string, ops: string, flags: record] {
|
|
match $command {
|
|
"create" | "c" => {
|
|
let use_debug = if $flags.debug_mode or ($env.PROVISIONING_DEBUG? | default false) { "-x" } else { "" }
|
|
let use_check = if $flags.check_mode { "--check " } else { "" }
|
|
let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" }
|
|
let str_out = if ($flags.outfile | is-not-empty) { $"--outfile ($flags.outfile) " } else { "" }
|
|
exec $"($env.PROVISIONING_NAME)" $use_debug "create" $ops $use_check $str_infra $str_out --notitles
|
|
}
|
|
|
|
"delete" | "d" => {
|
|
let use_debug = if $flags.debug_mode { "-x" } else { "" }
|
|
let use_check = if $flags.check_mode { "--check " } else { "" }
|
|
let use_yes = if $flags.auto_confirm { "--yes " } else { "" }
|
|
let use_keepstorage = if $flags.keep_storage { "--keepstorage " } else { "" }
|
|
let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" }
|
|
exec $"($env.PROVISIONING_NAME)" "delete" $ops $use_check $use_yes $use_keepstorage $str_infra --notitles
|
|
}
|
|
|
|
"update" | "u" => {
|
|
let use_debug = if $flags.debug_mode { "-x" } else { "" }
|
|
let use_check = if $flags.check_mode { "--check " } else { "" }
|
|
let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" }
|
|
exec $"($env.PROVISIONING_NAME)" "update" $ops $use_check $str_infra --notitles
|
|
}
|
|
|
|
"price" | "prices" | "cost" | "costs" => {
|
|
handle_price_command $ops $flags
|
|
}
|
|
|
|
"create-server-task" | "cst" | "csts" | "create-servers-tasks" => {
|
|
handle_create_server_task $ops $flags
|
|
}
|
|
|
|
"new" => {
|
|
let str_new = ($flags.new_infra | default "")
|
|
print $"\n (_ansi yellow)New Infra ($str_new)(_ansi reset)"
|
|
}
|
|
|
|
"ai" => {
|
|
let str_infra = if ($flags.infra | is-not-empty) { $"--infra ($flags.infra) " } else { "" }
|
|
let str_settings = if ($flags.settings | is-not-empty) { $"--settings ($flags.settings) " } else { "" }
|
|
let str_out = if ($flags.output_format | is-not-empty) { $"--out ($flags.output_format) " } else { "" }
|
|
run_module $"($ops) ($str_infra) ($str_settings) ($str_out)" "ai" --exec
|
|
}
|
|
|
|
"context" | "ctx" => {
|
|
^$"($env.PROVISIONING_NAME)" "context" $ops --notitles
|
|
run_module $ops "" --exec
|
|
}
|
|
|
|
"setup" | "st" | "config" => {
|
|
# Route to full setup command handler
|
|
use commands/setup.nu *
|
|
|
|
let args_list = if ($ops | is-not-empty) {
|
|
$ops | split row " " | where { |x| ($x | is-not-empty) }
|
|
} else {
|
|
[]
|
|
}
|
|
|
|
let command = if ($args_list | length) > 0 { ($args_list | get 0) } else { "help" }
|
|
let remaining_args = if ($args_list | length) > 1 { ($args_list | skip 1) } else { [] }
|
|
|
|
cmd-setup $command $remaining_args --check=$flags.check_mode --verbose=$flags.debug_mode --yes=$flags.auto_confirm
|
|
}
|
|
|
|
"control-center" => {
|
|
run_module $ops "control-center" --exec
|
|
}
|
|
|
|
"mcp-server" => {
|
|
run_module $ops "mcp-server" --exec
|
|
}
|
|
|
|
_ => {
|
|
print $"❌ Unknown command: ($command)"
|
|
print "Use 'provisioning help' for available commands"
|
|
exit 1
|
|
}
|
|
}
|
|
} |