prvng_core/cli/module-loader-enhanced
2025-10-07 10:32:04 +01:00

395 lines
15 KiB
Plaintext
Executable File

#!/usr/bin/env nu
# Enhanced Module Loader CLI with Template and Layer Support
# Supports the new layered template architecture
use ../nulib/taskservs/discover.nu *
use ../nulib/taskservs/load.nu *
use ../nulib/providers/discover.nu *
use ../nulib/providers/load.nu *
use ../nulib/clusters/discover.nu *
use ../nulib/clusters/load.nu *
# Load workspace template utilities
source ../../workspace/tools/template-utils.nu
source ../../workspace/tools/layer-utils.nu
# Main module loader command with enhanced features
def main [subcommand?: string] {
if ($subcommand | is-empty) {
print_enhanced_help
return
}
match $subcommand {
"help" => print_enhanced_help
"discover" => print_discover_help
"load" => print_load_help
"list" => print_list_help
"unload" => print_unload_help
"template" => print_template_help
"layer" => print_layer_help
"override" => print_override_help
_ => {
print $"Unknown command: ($subcommand)"
print_enhanced_help
}
}
}
# === TEMPLATE COMMANDS ===
# List available templates
export def "main template list" [
--type = "all", # Template type: taskservs, providers, servers, clusters, all
--format = "table" # Output format: table, yaml, json
] {
let manifest = open ../../workspace/registry/manifest.yaml
let templates = match $type {
"taskservs" => $manifest.templates.taskservs
"providers" => $manifest.templates.providers
"servers" => $manifest.templates.servers
"clusters" => $manifest.templates.clusters
"all" => $manifest.templates
_ => {
error make {msg: $"Invalid type: ($type). Use: taskservs, providers, servers, clusters, all"}
}
}
match $format {
"json" => ($templates | to json)
"yaml" => ($templates | to yaml)
"table" => ($templates | table)
_ => ($templates | table)
}
}
# Extract infrastructure patterns to templates
export def "main template extract" [
infra_name: string, # Infrastructure to extract from (e.g., "wuji")
--to: string = "templates", # Target: templates, workspace
--type = "all", # Extract type: taskservs, providers, all
--overwrite = false # Overwrite existing templates
] {
print $"🔄 Extracting patterns from ($infra_name) infrastructure"
let infra_path = $"workspace/infra/($infra_name)"
if not ($infra_path | path exists) {
error make {msg: $"Infrastructure ($infra_name) not found at ($infra_path)"}
}
# Extract taskservs if requested
if $type in ["taskservs", "all"] {
extract_taskserv_patterns $infra_name $to $overwrite
}
# Extract provider configurations if requested
if $type in ["providers", "all"] {
extract_provider_patterns $infra_name $to $overwrite
}
print $"✅ Extraction completed for ($infra_name)"
}
# Apply template to infrastructure
export def "main template apply" [
template_name: string, # Template to apply (e.g., "kubernetes-ha")
target_infra: string, # Target infrastructure name
--provider = "upcloud", # Target provider
--customize = false # Open for customization after apply
] {
print $"🔄 Applying template ($template_name) to ($target_infra)"
let manifest = open ../../workspace/registry/manifest.yaml
let template_info = get_template_info $manifest $template_name
if ($template_info | is-empty) {
error make {msg: $"Template ($template_name) not found"}
}
# Create target directory if it doesn't exist
let target_dir = $"workspace/infra/($target_infra)"
mkdir $target_dir
apply_template_to_infra $template_info $target_infra $provider
if $customize {
print $"🔧 Opening template for customization..."
^$env.EDITOR $"($target_dir)/taskservs/($template_name).k"
}
print $"✅ Template applied successfully to ($target_infra)"
}
# === LAYER COMMANDS ===
# Show layer resolution order
export def "main layer show" [
--infra?: string # Show resolution for specific infrastructure
] {
print "📋 Layer Resolution Order:"
print "1. Core Layer (Priority: 100) - provisioning/extensions"
print "2. Workspace Layer (Priority: 200) - provisioning/workspace/templates"
if ($infra | is-not-empty) {
print $"3. Infra Layer (Priority: 300) - workspace/infra/($infra)"
} else {
print "3. Infra Layer (Priority: 300) - workspace/infra/{name}"
}
let layers = open ../../workspace/layers/core.layer.k | get core_layer
let workspace_layer = open ../../workspace/layers/workspace.layer.k | get workspace_layer
print "\n📊 Layer Details:"
print $"Core provides: (($layers.provides | str join ', '))"
print $"Workspace provides: (($workspace_layer.provides | str join ', '))"
}
# Test layer resolution for a specific module
export def "main layer test" [
module_name: string, # Module to test (e.g., "kubernetes")
--infra?: string, # Infrastructure context
--provider = "upcloud" # Provider context
] {
print $"🧪 Testing layer resolution for ($module_name)"
test_layer_resolution $module_name $infra $provider
}
# === OVERRIDE COMMANDS ===
# Create override for existing configuration
export def "main override create" [
module_type: string, # Type: taskservs, providers, servers
infra_name: string, # Target infrastructure
module_name: string, # Module to override
--from?: string, # Source template to override from
--interactive = false # Interactive override creation
] {
print $"🔧 Creating override for ($module_name) in ($infra_name)"
let override_dir = $"workspace/infra/($infra_name)/overrides"
mkdir $override_dir
if ($from | is-not-empty) {
copy_template_as_override $from $override_dir $module_name
}
if $interactive {
^$env.EDITOR $"($override_dir)/($module_name).k"
}
print $"✅ Override created for ($module_name)"
}
# === ENHANCED LOAD COMMANDS ===
# Enhanced load with layer support
export def "main load enhanced" [
type: string, # Module type: taskservs, providers, clusters
workspace: string, # Workspace path
modules: list<string>, # Module names to load
--layer = "workspace", # Layer to load from: core, workspace, templates
--force = false, # Force overwrite
--with-overrides = false # Apply infrastructure overrides
] {
print $"🔄 Loading ($type) from ($layer) layer into: ($workspace)"
match $type {
"taskservs" => {
load_taskservs_with_layer $workspace $modules $layer $force $with_overrides
}
"providers" => {
load_providers_with_layer $workspace $modules $layer $force $with_overrides
}
"clusters" => {
load_clusters_with_layer $workspace $modules $layer $force $with_overrides
}
_ => {
error make {msg: $"Invalid type: ($type). Use: taskservs, providers, clusters"}
}
}
print $"✅ Enhanced loading completed"
}
# === HELPER FUNCTIONS ===
def extract_taskserv_patterns [infra_name: string, target: string, overwrite: bool] {
let source_dir = $"workspace/infra/($infra_name)/taskservs"
let target_dir = $"provisioning/workspace/templates/taskservs"
if ($source_dir | path exists) {
print $" 📦 Extracting taskserv patterns..."
for file in (ls $source_dir | get name) {
let filename = ($file | path basename)
let target_file = $"($target_dir)/($filename)"
if ($overwrite or not ($target_file | path exists)) {
print $" ➜ Extracting ($filename)"
cp $file $target_file
} else {
print $" ⚠️ Skipping ($filename) (already exists)"
}
}
}
}
def extract_provider_patterns [infra_name: string, target: string, overwrite: bool] {
let source_dir = $"workspace/infra/($infra_name)/defs"
let target_dir = $"provisioning/workspace/templates/providers"
if ($source_dir | path exists) {
print $" 📦 Extracting provider patterns..."
for file in (ls $source_dir | where name =~ "_defaults\.k$" | get name) {
let filename = ($file | path basename)
let provider_name = ($filename | str replace "_defaults.k" "")
let target_file = $"($target_dir)/($provider_name)/defaults.k"
mkdir ($"($target_dir)/($provider_name)")
if ($overwrite or not ($target_file | path exists)) {
print $" ➜ Extracting ($provider_name) defaults"
cp $file $target_file
} else {
print $" ⚠️ Skipping ($provider_name) defaults (already exists)"
}
}
}
}
def get_template_info [manifest: record, template_name: string] -> record {
# Search through all template categories
let taskserv_templates = $manifest.templates.taskservs | items {|key, value|
if $key == $template_name {
$value | insert type "taskserv" | insert name $key
} else if ($value | describe) == "record" {
$value | items {|variant_key, variant_value|
if $variant_key == $template_name {
$variant_value | insert type "taskserv" | insert name $key | insert variant $variant_key
} else {
null
}
} | where {|x| $x != null} | first
} else {
null
}
} | where {|x| $x != null} | first
$taskserv_templates
}
def test_layer_resolution [module_name: string, infra: string, provider: string] {
print $" Layer 1 (Core): Checking provisioning/extensions/taskservs/($module_name)"
let core_exists = ("provisioning/extensions/taskservs" | path join $module_name | path exists)
print $" Core layer: ($core_exists)"
print $" Layer 2 (Workspace): Checking provisioning/workspace/templates/taskservs/($module_name)"
let workspace_exists = ("provisioning/workspace/templates/taskservs" | path join $module_name | path exists)
print $" Workspace layer: ($workspace_exists)"
if ($infra | is-not-empty) {
print $" Layer 3 (Infra): Checking workspace/infra/($infra)/taskservs/($module_name).k"
let infra_exists = ("workspace/infra" | path join $infra "taskservs" $"($module_name).k" | path exists)
print $" Infra layer: ($infra_exists)"
}
}
# === HELP FUNCTIONS ===
def print_enhanced_help [] {
print "Enhanced Module Loader CLI - Discovery, Templates, and Layers"
print ""
print "Usage: module-loader-enhanced <command> [options]"
print ""
print "Commands:"
print " discover <type> [query] [--format <fmt>] - Discover available modules"
print " load <type> <workspace> <modules...> - Load modules into workspace"
print " load enhanced <type> <workspace> <modules...> [--layer <layer>] - Enhanced load with layers"
print " list <type> <workspace> - List loaded modules"
print " unload <type> <workspace> <module> - Unload module from workspace"
print ""
print "Template Commands:"
print " template list [--type <type>] - List available templates"
print " template extract <infra> [--to <target>] - Extract patterns to templates"
print " template apply <template> <infra> - Apply template to infrastructure"
print ""
print "Layer Commands:"
print " layer show [--infra <name>] - Show layer resolution order"
print " layer test <module> [--infra <name>] - Test layer resolution"
print ""
print "Override Commands:"
print " override create <type> <infra> <module> - Create configuration override"
print ""
print "Types: taskservs, providers, clusters"
print "Layers: core, workspace, infra"
print ""
print "Examples:"
print " module-loader-enhanced template extract wuji --to templates"
print " module-loader-enhanced template apply kubernetes-ha new-infra"
print " module-loader-enhanced load enhanced taskservs workspace/infra/new-infra [kubernetes] --layer workspace"
print " module-loader-enhanced layer test kubernetes --infra new-infra"
}
def print_template_help [] {
print "Template Management Commands"
print ""
print "Usage: module-loader-enhanced template <command> [options]"
print ""
print "Commands:"
print " list [--type <type>] [--format <format>] - List available templates"
print " extract <infra> [--to <target>] - Extract infrastructure patterns to templates"
print " apply <template> <infra> [--provider] - Apply template to infrastructure"
print ""
print "Options:"
print " --type <type> Template type: taskservs, providers, servers, clusters, all"
print " --format <format> Output format: table, yaml, json"
print " --to <target> Target location: templates, workspace"
print " --provider <name> Target provider: upcloud, aws, local"
print ""
print "Examples:"
print " module-loader-enhanced template list --type taskservs"
print " module-loader-enhanced template extract wuji --type taskservs"
print " module-loader-enhanced template apply kubernetes-ha new-infra --provider upcloud"
}
def print_layer_help [] {
print "Layer Management Commands"
print ""
print "Usage: module-loader-enhanced layer <command> [options]"
print ""
print "Commands:"
print " show [--infra <name>] - Show layer resolution order"
print " test <module> [--infra <name>] - Test layer resolution for module"
print ""
print "Layer Priority Order:"
print " 1. Core (100) - provisioning/extensions"
print " 2. Workspace (200) - provisioning/workspace/templates"
print " 3. Infra (300) - workspace/infra/{name}"
print ""
print "Examples:"
print " module-loader-enhanced layer show --infra wuji"
print " module-loader-enhanced layer test kubernetes --infra wuji"
}
def print_override_help [] {
print "Override Management Commands"
print ""
print "Usage: module-loader-enhanced override <command> [options]"
print ""
print "Commands:"
print " create <type> <infra> <module> [--from <template>] - Create configuration override"
print ""
print "Options:"
print " --from <template> Source template to copy as base"
print " --interactive Open editor for customization"
print ""
print "Examples:"
print " module-loader-enhanced override create taskservs wuji kubernetes --from templates/kubernetes/ha-cluster"
}
main