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.
328 lines
13 KiB
Plaintext
Executable File
328 lines
13 KiB
Plaintext
Executable File
#!/usr/bin/env nu
|
|
# Info: Script to run Provisioning
|
|
# Author: JesusPerezLorenzo
|
|
# Release: 1.0.4
|
|
# Date: 6-2-2024
|
|
|
|
# CRITICAL: Must be in export-env block so it runs DURING PARSING,
|
|
# not after. This sets up NU_LIB_DIRS before modules are loaded.
|
|
export-env {
|
|
# Initialize NU_LIB_DIRS, handling both string (from bash) and list (from Nushell)
|
|
let lib_dirs_raw = ($env.NU_LIB_DIRS? | default "")
|
|
let current_lib_dirs = if ($lib_dirs_raw | type) == "string" {
|
|
if ($lib_dirs_raw | is-empty) {
|
|
[]
|
|
} else {
|
|
($lib_dirs_raw | split row ":")
|
|
}
|
|
} else {
|
|
$lib_dirs_raw
|
|
}
|
|
|
|
# Ensure known provisioning paths are in NU_LIB_DIRS
|
|
let default_paths = [
|
|
"/opt/provisioning/core/nulib"
|
|
"/usr/local/provisioning/core/nulib"
|
|
]
|
|
|
|
# Combine paths: use default paths first, then add any from current
|
|
$env.NU_LIB_DIRS = ($default_paths | append $current_lib_dirs)
|
|
}
|
|
|
|
use std log
|
|
use lib_provisioning *
|
|
use env.nu *
|
|
|
|
#Load all main defs
|
|
use main_provisioning *
|
|
|
|
#module srv { use instances.nu * }
|
|
|
|
use servers/ssh.nu *
|
|
use servers/utils.nu *
|
|
use taskservs/utils.nu find_taskserv
|
|
use lib_provisioning/platform/bootstrap.nu *
|
|
|
|
# Helper: Reorder arguments to put flags before positional args
|
|
# This allows: provisioning workspace update --yes
|
|
# Instead of requiring: provisioning --yes workspace update
|
|
def reorder_args [args: list]: nothing -> list {
|
|
let flags = ($args | where {|x| ($x | str starts-with "-")})
|
|
let positionals = ($args | where {|x| not ($x | str starts-with "-")})
|
|
($flags | append $positionals)
|
|
}
|
|
|
|
# Help on provisioning commands
|
|
export def "main help" [
|
|
...args: string # Optional category: infrastructure, orchestration, development, workspace, concepts
|
|
--notitles # not titles
|
|
--out: string # Print Output format: json, yaml, text (default)
|
|
] {
|
|
if $notitles == null or not $notitles { show_titles }
|
|
if ($out | is-not-empty) { $env.PROVISIONING_NO_TERMINAL = false }
|
|
# Use only the first argument, ignore any extras (e.g., "orch status" -> "orch")
|
|
let category = if ($args | length) > 0 { ($args | get 0) } else { "" }
|
|
print (provisioning_options $category)
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
}
|
|
|
|
def main [
|
|
...args: string # Other options, use help to get info
|
|
--infra (-i): string # Cloud directory
|
|
--settings (-s): string # Settings path
|
|
--serverpos (-p): int # Server position in settings
|
|
--outfile (-o): string # Output file
|
|
--template(-t): string # Template path or name in PROVISION_KLOUDS_PATH
|
|
--check (-c) # Only check mode no servers will be created
|
|
--yes (-y) # confirm task
|
|
--wait (-w) # Wait servers to be created
|
|
--keepstorage # keep storage
|
|
--select: string # Select with task as option
|
|
--onsel: string # On selection: e (edit) | v (view) | l (list) | t (tree)
|
|
--infras: string # Infra list names separated by commas
|
|
--new (-n): string # New infrastructure name
|
|
--debug (-x) # Use Debug mode
|
|
--xm # Debug with PROVISIONING_METADATA
|
|
--xc # Debug for task and services locally PROVISIONING_DEBUG_CHECK
|
|
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
|
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
|
--nc # Not clean working settings
|
|
--metadata # Error with metadata (-xm)
|
|
--notitles # not tittles
|
|
--environment: string # Environment override (dev/test/prod)
|
|
--dep-option: string # Workspace dependency option: workspace-home, home-package, git-package, publish-repo
|
|
--dep-url: string # Dependency URL for git-package or publish-repo
|
|
--dry-run # Show what would be done without doing it (pack command)
|
|
--force (-f) # Skip confirmation prompts (pack/delete commands)
|
|
--all # Process all items (pack clean command)
|
|
--keep-latest: int # Keep N latest versions (pack clean command)
|
|
--activate # Activate workspace as default (workspace commands)
|
|
--interactive # Interactive workspace creation wizard
|
|
--org: string # Organization name (for detect/complete commands)
|
|
--apply # Apply changes (for complete command)
|
|
--verbose # Verbose output (for detect/complete/workflow commands)
|
|
--pretty # Pretty-print JSON/YAML output (for detect/complete commands)
|
|
-v # Show version
|
|
--version (-V) # Show version with title
|
|
--info # Show Info with title
|
|
--about # Show About
|
|
--helpinfo (-h) # For more details use options "help" (no dashes)
|
|
--out: string # Print Output format: json, yaml, text (default)
|
|
--view # Print with highlight
|
|
--inputfile: string # Input format: json, yaml, text (default)
|
|
--include_notuse # Include servers not use
|
|
]: nothing -> nothing {
|
|
# Reorder arguments: move flags to the beginning
|
|
# This allows: provisioning workspace update --yes
|
|
let reordered_args = (reorder_args $args)
|
|
|
|
# Extract flags from reordered args (for flags that came after positional args)
|
|
let has_yes_in_args = ($reordered_args | any {|x| $x == "--yes" or $x == "-y"})
|
|
let has_check_in_args = ($reordered_args | any {|x| $x == "--check" or $x == "-c"})
|
|
let has_force_in_args = ($reordered_args | any {|x| $x == "--force" or $x == "-f"})
|
|
let has_verbose_in_args = ($reordered_args | any {|x| $x == "--verbose" or $x == "-v"})
|
|
let has_wait_in_args = ($reordered_args | any {|x| $x == "--wait" or $x == "-w"})
|
|
|
|
# Combine with already-parsed flags (take OR - if either parsed or in args, then true)
|
|
let final_yes = ($yes or $has_yes_in_args)
|
|
let final_check = ($check or $has_check_in_args)
|
|
let final_force = ($force or $has_force_in_args)
|
|
let final_verbose = ($verbose or $has_verbose_in_args)
|
|
let final_wait = ($wait or $has_wait_in_args)
|
|
|
|
# Initialize provisioning system
|
|
provisioning_init $helpinfo "" $reordered_args
|
|
|
|
# Parse all flags into normalized structure
|
|
let parsed_flags = (parse_common_flags {
|
|
version: $version, v: $v, info: $info, about: $about,
|
|
debug: $debug, metadata: $metadata, xc: $xc, xr: $xr, xld: $xld,
|
|
check: $final_check, yes: $final_yes, wait: $final_wait, keepstorage: $keepstorage,
|
|
nc: $nc, include_notuse: $include_notuse,
|
|
out: $out, notitles: $notitles, view: $view,
|
|
infra: $infra, infras: $infras, settings: $settings, outfile: $outfile,
|
|
template: $template, select: $select, onsel: $onsel, serverpos: $serverpos,
|
|
new: $new, environment: $environment,
|
|
dep_option: $dep_option, dep_url: $dep_url,
|
|
dry_run: $dry_run, force: $final_force, all: $all, keep_latest: $keep_latest,
|
|
activate: $activate, interactive: $interactive,
|
|
org: $org, apply: $apply, verbose: $final_verbose, pretty: $pretty
|
|
})
|
|
|
|
# Handle version, info, about flags
|
|
if $parsed_flags.show_version { ^$env.PROVISIONING_NAME -v ; exit }
|
|
if $parsed_flags.show_info { ^$env.PROVISIONING_NAME -i ; exit }
|
|
if $parsed_flags.show_about { _print (get_about_info) ; exit }
|
|
|
|
# Bootstrap platform services (only if running actual commands, not help/info)
|
|
# Skip bootstrap for help-like, guide, setup, discovery/info, and utility commands
|
|
let is_help_command = (
|
|
($reordered_args | length) == 0 or
|
|
($reordered_args | get 0) in [
|
|
# Help and guides
|
|
"help", "-h", "--help",
|
|
"sc", "shortcuts", "quickstart", "quick",
|
|
"from-scratch", "scratch",
|
|
"customize", "custom",
|
|
"guide", "guides", "howto",
|
|
# Setup
|
|
"setup", "st",
|
|
# Discovery and module commands
|
|
"mod", "module", "discover", "disc",
|
|
"dt", "dp", "dc",
|
|
"discover-taskservs", "disc-t",
|
|
"discover-providers", "disc-p",
|
|
"discover-clusters", "disc-c",
|
|
# Development info
|
|
"lyr", "layer", "version", "pack",
|
|
# Utilities and info
|
|
"nuinfo", "env", "allenv",
|
|
"validate", "val", "show", "config-template",
|
|
"cache",
|
|
"list", "l", "ls",
|
|
"plugin", "plugins",
|
|
"qr", "ssh", "sops",
|
|
"providers",
|
|
"status", "health"
|
|
]
|
|
)
|
|
|
|
if not $is_help_command {
|
|
let bootstrap_result = (bootstrap-platform --auto-start --timeout=60 --verbose=($final_verbose))
|
|
if not $bootstrap_result.all_healthy {
|
|
_print ""
|
|
_print $"(_ansi red)❌ Platform services not healthy(_ansi reset)"
|
|
_print ""
|
|
_print "Failed services:"
|
|
for service in ($bootstrap_result.services | where {|s| $s.status != "healthy"}) {
|
|
_print $" - ($service.name): ($service.action)"
|
|
}
|
|
_print ""
|
|
_print "To start services manually:"
|
|
_print " cd provisioning/platform && docker-compose up -d"
|
|
_print ""
|
|
exit 1
|
|
}
|
|
}
|
|
|
|
# For info/discovery/utility commands, dispatch directly without going through workspace enforcement
|
|
# These commands don't need workspace context
|
|
if (($reordered_args | length) > 0) and (($reordered_args | get 0) in [
|
|
# Guide commands
|
|
"guide", "guides", "sc", "howto", "shortcuts", "quickstart", "quick",
|
|
"from-scratch", "scratch", "customize", "custom",
|
|
# Discovery/info commands
|
|
"mod", "module", "discover", "disc",
|
|
"dt", "dp", "dc",
|
|
"discover-taskservs", "disc-t",
|
|
"discover-providers", "disc-p",
|
|
"discover-clusters", "disc-c",
|
|
"lyr", "layer", "version",
|
|
"nuinfo", "env", "allenv",
|
|
"validate", "val", "show", "cache",
|
|
# Utility commands (these are informational)
|
|
"plugin", "plugins",
|
|
"qr", "nuinfo",
|
|
"status", "health"
|
|
]) {
|
|
dispatch_command $reordered_args $parsed_flags
|
|
if not $env.PROVISIONING_DEBUG { end_run "" }
|
|
return
|
|
}
|
|
|
|
# Dispatch command to appropriate handler
|
|
dispatch_command $reordered_args $parsed_flags
|
|
|
|
# End run if not in debug mode
|
|
if not ($env.PROVISIONING_DEBUG? | default false) { end_run "" }
|
|
}
|
|
|
|
export def get_show_info [
|
|
ops: list
|
|
curr_settings: record
|
|
out: string
|
|
]: nothing -> record {
|
|
match ($ops | get -o 0 | default "") {
|
|
"set" |"setting" | "settings" => $curr_settings,
|
|
"def" | "defs" |"defsetting" | "defsettings" => {
|
|
let src = ($curr_settings | get -o src | default "");
|
|
let src_path = ($curr_settings | get -o src_path | default "");
|
|
let def_settings = if ($src_path | path join $src | path exists) {
|
|
open -r ($src_path | path join $src)
|
|
} else { "" }
|
|
let main_path = ($env.PROVISIONING | path join "kcl" | path join "settings.k")
|
|
let src_main_settings = if ($main_path | path exists) {
|
|
open -r $main_path
|
|
} else { "" }
|
|
{
|
|
def: $src,
|
|
def_path: $src_path,
|
|
infra: ($curr_settings | get -o infra | default ""),
|
|
infra_path: ($curr_settings | get -o infra_path | default ""),
|
|
def_settings: $def_settings,
|
|
main_path: $main_path,
|
|
main_settings: $src_main_settings,
|
|
}
|
|
},
|
|
"server" |"servers" | "s" => {
|
|
let servers = ($curr_settings | get -o data | get -o servers | default {})
|
|
let item = ($ops | get -o 1 | default "")
|
|
if ($item | is-empty) {
|
|
$servers
|
|
} else {
|
|
let server = (find_server $item $servers ($out | default ""))
|
|
let def_target = ($ops | get -o 2 | default "")
|
|
match $def_target {
|
|
"t" | "task" | "taskserv" => {
|
|
let task = ($ops | get -o 3 | default "")
|
|
(find_taskserv $curr_settings $server $task ($out | default ""))
|
|
},
|
|
_ => $server,
|
|
}
|
|
}
|
|
},
|
|
"serverdefs" |"serversdefs" | "sd" => {
|
|
(find_serversdefs $curr_settings)
|
|
},
|
|
"provgendefs" |"provgendef" | "pgd" => {
|
|
(find_provgendefs)
|
|
},
|
|
"taskservs" |"taskservs" | "ts" => {
|
|
#(list_taskservs $curr_settings)
|
|
let list_taskservs = (taskservs_list)
|
|
if ($list_taskservs | length) == 0 {
|
|
_print $"🛑 no items found for (_ansi cyan)taskservs list(_ansi reset)"
|
|
return
|
|
}
|
|
$list_taskservs
|
|
},
|
|
"taskservsgendefs" |"taskservsgendef" | "tsd" => {
|
|
let defs_path = ($env.PROVISIONING_TASKSERVS_PATH | path join $env.PROVISIONING_GENERATE_DIRPATH | path join $env.PROVISIONING_GENERATE_DEFSFILE)
|
|
if ($defs_path | path exists) {
|
|
open $defs_path
|
|
}
|
|
},
|
|
"cost" | "costs" | "c" | "price" | "prices" | "p" => {
|
|
(servers_walk_by_costs $curr_settings "" false false "stdout")
|
|
},
|
|
"alldata" => ($curr_settings | get -o data | default {}
|
|
| merge { costs: (servers_walk_by_costs $curr_settings "" false false "stdout") }
|
|
),
|
|
"data" | _ => {
|
|
if ($out | is-not-empty) {
|
|
($curr_settings | get -o data | default {})
|
|
} else {
|
|
print ($" (_ansi cyan_bold)($curr_settings | get -o data | get -o main_name | default '')"
|
|
+ $"(_ansi reset): (_ansi yellow_bold)($curr_settings | get -o data | get -o main_title | default '') (_ansi reset)"
|
|
)
|
|
print ($curr_settings | get -o data | default {} | merge { servers: ''})
|
|
($curr_settings | get -o data | default {} | get -o servers | each {|item|
|
|
print $"\n server: (_ansi cyan_bold)($item.hostname | default '') (_ansi reset)"
|
|
print $item
|
|
})
|
|
""
|
|
}
|
|
},
|
|
}
|
|
}
|