prvng_core/nulib/provisioning layer

419 lines
16 KiB
Plaintext
Raw Permalink Normal View History

2025-10-07 10:32:04 +01:00
#!/usr/bin/env nu
# Info: Script to run Provisioning Layer System Management
# Author: JesusPerezLorenzo
# Release: 1.0.0
# Date: 29-09-2025
use std log
use lib_provisioning *
use env.nu *
# - > Help on Layer
export def "main help" [
--src: string = ""
--notitles # not titles
--out: string # Print Output format: json, yaml, text (default)
]: nothing -> nothing {
if $notitles == null or not $notitles { show_titles }
^$"($env.PROVISIONING_NAME)" -mod layer --help
if ($out | is-not-empty) { $env.PROVISIONING_NO_TERMINAL = false }
print (provisioning_options $src)
if not $env.PROVISIONING_DEBUG { end_run "" }
}
# > Layer System Management
def main [
...args: string # Other options, use help to get info
-v # Show version
-i # Show Info
--version (-V) # Show version with title
--info (-I) # Show Info with title
--about (-a) # Show About
--workspace: string = "" # Workspace/infrastructure name for layer resolution
--module: string = "" # Module name to show layer information
--provider: string = "" # Provider name for layer testing
--debug (-x) # Use Debug mode
--xm # Debug with PROVISIONING_METADATA
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
--metadata # Error with metadata (-xm)
--notitles # Do not show banner titles
--helpinfo (-h) # For more details use options "help" (no dashes)
--out: string # Print Output format: json, yaml, text (default)
]: nothing -> nothing {
if ($out | is-not-empty) {
$env.PROVISIONING_OUT = $out
$env.PROVISIONING_NO_TERMINAL = true
}
provisioning_init $helpinfo "layer" $args
if $version or $v { ^$env.PROVISIONING_NAME -v ; exit }
if $info or $i { ^$env.PROVISIONING_NAME -i ; exit }
if $about {
_print (get_about_info)
exit
}
if $debug { $env.PROVISIONING_DEBUG = true }
if $metadata { $env.PROVISIONING_METADATA = true }
let task = if ($args | length) > 0 { ($args | get 0) } else { "" }
let ops = $"($env.PROVISIONING_ARGS? | default "") " | str replace $" ($task) " "" | str trim
let workspace_name = if ($ops | is-not-empty) and not ($ops | str starts-with "-") {
($ops | split row " " | get 0)
} else {
$workspace
}
let module_name = if ($ops | split row " " | length) > 1 {
($ops | split row " " | get 1)
} else {
$module
}
$env.PROVISIONING_MODULE = "layer"
match $task {
"h" | "help" => {
# Redirect to main categorized help system
exec $"($env.PROVISIONING_NAME)" help development --notitles
},
"show" => {
if ($workspace_name | is-empty) {
layer_show_all --out $out
} else {
layer_show $workspace_name --module $module_name --out $out
}
},
"test" => {
if ($module_name | is-empty) or ($workspace_name | is-empty) {
print "❌ Module name and workspace required"
print "Usage: provisioning layer test <module> <workspace> [provider]"
exit 1
}
let provider_arg = if ($ops | split row " " | length) > 2 {
($ops | split row " " | get 2)
} else {
$provider
}
layer_test $module_name $workspace_name $provider_arg
},
"explain" => {
layer_explain --out $out
},
"stats" => {
layer_stats
},
"validate" => {
layer_validate
},
_ => {
print $"❌ Unknown task: ($task)"
print "Use 'provisioning layer help' for available commands"
print ""
print "Available commands:"
print " show [workspace] [--module <name>] - Show layer information"
print " test <module> <workspace> [provider] - Test layer resolution"
print " explain - Explain the layer concept"
print " stats - Show layer statistics"
print " validate - Validate layer configuration"
exit 1
}
}
}
# Show layer information
def layer_show [
workspace: string
--module: string
--out: string
]: nothing -> nothing {
let provisioning_root = $env.PROVISIONING? | default $env.PWD
if ($module | is-not-empty) {
print $"🔍 Layer Information for Module: ($module)"
print $" Workspace: ($workspace)"
print ""
# Show layer resolution chain
print "📋 Layer Resolution Chain (Highest to Lowest Priority):"
print ""
# Layer 3: Infrastructure
print " 3⃣ Infrastructure Layer (Priority 300)"
print $" Path: workspace/infra/($workspace)/"
let workspace_root = $env.PWD
let infra_taskserv = ($workspace_root | path join "workspace" "infra" $workspace "taskservs" $"($module).k")
let infra_override = ($workspace_root | path join "workspace" "infra" $workspace "overrides" $"($module).k")
if ($infra_override | path exists) {
print $" ✅ Override: ($infra_override)"
} else if ($infra_taskserv | path exists) {
print $" ✅ Taskserv: ($infra_taskserv)"
} else {
print " ❌ No infrastructure-specific configuration"
}
print ""
# Layer 2: Workspace
print " 2⃣ Workspace Layer (Priority 200)"
print " Path: provisioning/workspace/templates/"
let workspace_template = ($provisioning_root | path join "workspace" "templates" "taskservs" $module)
if ($workspace_template | path exists) {
print $" ✅ Template: ($workspace_template)"
} else {
print " ❌ No shared template"
}
print ""
# Layer 1: Core
print " 1⃣ Core Layer (Priority 100)"
print " Path: provisioning/extensions/"
# Check if module exists in core by checking directory structure
let core_taskserv_path = ($provisioning_root | path join "extensions" "taskservs")
let core_provider_path = ($provisioning_root | path join "extensions" "providers" $module)
let core_exists = ($core_provider_path | path exists) or (
($core_taskserv_path | path exists) and
(ls $core_taskserv_path | where type == dir | get name | any {|p| ($p | path basename) == $module or ($p | str contains $module)})
)
if $core_exists {
print " ✅ Base system extension found"
} else {
print " ❌ No core extension"
}
print ""
} else {
print $"🏗️ Layer System Overview for: ($workspace)"
print ""
print "📋 Layer Resolution Order:"
print " (Higher priority overrides lower priority)"
print ""
print " 3⃣ Infrastructure Layer (Priority 300)"
print $" Path: workspace/infra/($workspace)/"
print " Description: Infrastructure-specific configurations and overrides"
print " Purpose: Customize settings for this specific environment"
print ""
print " 2⃣ Workspace Layer (Priority 200)"
print " Path: provisioning/workspace/templates/"
print " Description: Shared templates and reusable configurations"
print " Purpose: Share common patterns across infrastructures"
print ""
print " 1⃣ Core Layer (Priority 100)"
print " Path: provisioning/extensions/"
print " Description: Base provisioning system extensions"
print " Purpose: Provide default functionality and base components"
print ""
}
}
# Show all layer information
def layer_show_all [--out: string]: nothing -> nothing {
print "🏗️ Layer System Architecture"
print ""
print "The provisioning system uses a layered architecture for configuration inheritance:"
print ""
print "📋 Layer Resolution Order (Highest to Lowest Priority):"
print ""
print " 3⃣ Infrastructure Layer (Priority 300)"
print " • Path: workspace/infra/{name}/"
print " • Purpose: Infrastructure-specific configurations and overrides"
print " • Use case: Customize settings for specific environments"
print ""
print " 2⃣ Workspace Layer (Priority 200)"
print " • Path: provisioning/workspace/templates/"
print " • Purpose: Shared templates and reusable configurations"
print " • Use case: Share common patterns across infrastructures"
print ""
print " 1⃣ Core Layer (Priority 100)"
print " • Path: provisioning/extensions/"
print " • Purpose: Base provisioning system extensions"
print " • Use case: Provide default functionality and base components"
print ""
print "💡 Usage:"
print " provisioning layer show <workspace> [--module <name>]"
print " provisioning layer test <module> <workspace> [provider]"
print " provisioning layer explain"
print ""
}
# Test layer resolution
def layer_test [
module_name: string,
workspace: string,
provider: string = ""
]: nothing -> nothing {
let provisioning_root = $env.PROVISIONING? | default $env.PWD
let layer_utils = ($provisioning_root | path join "workspace" "tools" "layer-utils.nu")
if not ($layer_utils | path exists) {
print $"❌ Layer utilities not found: ($layer_utils)"
exit 1
}
# Call the test function from layer-utils.nu
nu -c $"use ($layer_utils) *; test_layer_resolution '($module_name)' '($workspace)' '($provider)'"
}
# Explain layer concept
def layer_explain [--out: string]: nothing -> nothing {
if ($out | is-not-empty) {
let layers = [
{
priority: 300
name: "Infrastructure"
path: "workspace/infra/{name}/"
description: "Infrastructure-specific configurations and overrides"
}
{
priority: 200
name: "Workspace"
path: "provisioning/workspace/templates/"
description: "Shared templates and reusable configurations"
}
{
priority: 100
name: "Core"
path: "provisioning/extensions/"
description: "Base provisioning system extensions"
}
]
if $out == "json" {
print ($layers | to json)
} else if $out == "yaml" {
print ($layers | to yaml)
} else {
print ($layers | table)
}
return
}
print "🎓 Understanding the Layer System"
print "================================="
print ""
print "The provisioning system uses a three-layer architecture for configuration"
print "inheritance and override management. Each layer has a specific priority:"
print ""
print "🏗️ LAYER ARCHITECTURE"
print ""
print "┌─────────────────────────────────────────────────────────────┐"
print "│ Layer 3: Infrastructure (Priority 300) │"
print "│ ────────────────────────────────────────── │"
print "│ Path: workspace/infra/{name}/ │"
print "│ Purpose: Environment-specific customizations │"
print "│ Example: workspace/infra/production/taskservs/ │"
print "│ kubernetes.k (production-specific K8s config) │"
print "└─────────────────────────────────────────────────────────────┘"
print " ↓ overrides ↓"
print "┌─────────────────────────────────────────────────────────────┐"
print "│ Layer 2: Workspace (Priority 200) │"
print "│ ───────────────────────────────── │"
print "│ Path: provisioning/workspace/templates/ │"
print "│ Purpose: Shared templates across infrastructures │"
print "│ Example: workspace/templates/taskservs/kubernetes/ │"
print "│ default.k (common K8s configuration) │"
print "└─────────────────────────────────────────────────────────────┘"
print " ↓ overrides ↓"
print "┌─────────────────────────────────────────────────────────────┐"
print "│ Layer 1: Core (Priority 100) │"
print "│ ──────────────────────────── │"
print "│ Path: provisioning/extensions/ │"
print "│ Purpose: Base system functionality │"
print "│ Example: extensions/taskservs/kubernetes/ │"
print "│ (base kubernetes installation logic) │"
print "└─────────────────────────────────────────────────────────────┘"
print ""
print "📖 HOW IT WORKS"
print ""
print "1. Resolution Order:"
print " When you request a module (e.g., 'kubernetes'), the system searches"
print " from highest to lowest priority:"
print " Infrastructure (300) → Workspace (200) → Core (100)"
print ""
print "2. Override Mechanism:"
print " • Infrastructure overrides Workspace and Core"
print " • Workspace overrides Core"
print " • Core provides base defaults"
print ""
print "3. Configuration Inheritance:"
print " Each layer can inherit from lower layers and override specific"
print " settings. This allows you to:"
print " • Keep common configs in Workspace"
print " • Customize per-environment in Infrastructure"
print " • Maintain base functionality in Core"
print ""
print "💡 PRACTICAL EXAMPLE"
print ""
print "Scenario: Deploying Kubernetes"
print ""
print "• Core Layer (100):"
print " Provides base kubernetes installation scripts"
print " Default version: 1.28.0"
print " Default CNI: none"
print ""
print "• Workspace Layer (200):"
print " Template with your organization's standards"
print " Version: 1.29.0"
print " CNI: Cilium"
print " Monitoring: Enabled"
print ""
print "• Infrastructure Layer (300):"
print " Production-specific overrides"
print " Version: 1.29.0 (inherited from workspace)"
print " CNI: Cilium (inherited from workspace)"
print " Monitoring: Enabled (inherited from workspace)"
print " High Availability: True (production-specific)"
print " Backup: Enabled (production-specific)"
print ""
print "Result: Production gets all workspace defaults plus specific overrides"
print ""
print "🔧 COMMANDS"
print ""
print "• Show layers for a workspace:"
print " provisioning layer show <workspace>"
print ""
print "• Show layers for specific module:"
print " provisioning layer show <workspace> --module <name>"
print ""
print "• Test layer resolution:"
print " provisioning layer test <module> <workspace> [provider]"
print ""
print "• Show layer statistics:"
print " provisioning layer stats"
print ""
print "• Validate layer configuration:"
print " provisioning layer validate"
print ""
}
# Show layer statistics
def layer_stats []: nothing -> nothing {
let provisioning_root = $env.PROVISIONING? | default $env.PWD
let layer_utils = ($provisioning_root | path join "workspace" "tools" "layer-utils.nu")
if not ($layer_utils | path exists) {
print $"❌ Layer utilities not found: ($layer_utils)"
exit 1
}
# Call the stats function from layer-utils.nu
nu -c $"use ($layer_utils) *; show_layer_stats"
}
# Validate layer configuration
def layer_validate []: nothing -> nothing {
let provisioning_root = $env.PROVISIONING? | default $env.PWD
let layer_utils = ($provisioning_root | path join "workspace" "tools" "layer-utils.nu")
if not ($layer_utils | path exists) {
print $"❌ Layer utilities not found: ($layer_utils)"
exit 1
}
# Call the validate function from layer-utils.nu
nu -c $"use ($layer_utils) *; validate_layer_config"
}