395 lines
15 KiB
Plaintext
Executable File
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 |