prvng_core/nulib/taskservs/check_mode.nu
2025-10-07 10:32:04 +01:00

293 lines
8.7 KiB
Plaintext
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Enhanced Check Mode for Taskservs
# Provides dry-run capabilities with detailed validation and preview
use lib_provisioning *
use utils.nu *
use deps_validator.nu *
use validate.nu *
use ../lib_provisioning/config/accessor.nu *
# Preview taskserv configuration generation
def preview-config-generation [
taskserv_name: string
taskserv_profile: string
settings: record
server: record
--verbose (-v)
]: nothing -> record {
let taskservs_path = (get-taskservs-path)
let profile_path = ($taskservs_path | path join $taskserv_name $taskserv_profile)
if not ($profile_path | path exists) {
return {
valid: false
errors: [$"Profile path not found: ($profile_path)"]
warnings: []
files: []
}
}
# Find all template files
let template_files = try {
ls ($profile_path | path join "**/*.j2") | get name
} catch {
[]
}
# Find shell scripts
let script_files = try {
ls ($profile_path | path join "**/*.sh") | get name
} catch {
[]
}
# Find other config files
let config_files = try {
ls $profile_path
| where type == "file"
| where name !~ ".j2$"
| where name !~ ".sh$"
| get name
} catch {
[]
}
mut preview_files = []
# Preview templates
for tpl in $template_files {
let dest_name = ($tpl | path basename | str replace ".j2" "")
$preview_files = ($preview_files | append {
type: "template"
source: ($tpl | path relative-to $profile_path)
destination: $dest_name
action: "render and upload"
})
}
# Preview scripts
for script in $script_files {
$preview_files = ($preview_files | append {
type: "script"
source: ($script | path basename)
destination: ($script | path basename)
action: "upload and execute"
})
}
# Preview config files
for cfg in $config_files {
$preview_files = ($preview_files | append {
type: "config"
source: ($cfg | path basename)
destination: ($cfg | path basename)
action: "upload"
})
}
return {
valid: true
errors: []
warnings: []
files: $preview_files
total_files: ($preview_files | length)
}
}
# Check prerequisites on target server (without actually connecting in check mode)
def check-prerequisites [
taskserv_name: string
server: record
settings: record
check_mode: bool
]: nothing -> record {
mut checks = []
# Check if server is accessible (in check mode, just validate config)
if $check_mode {
$checks = ($checks | append {
check: "Server accessibility"
status: "skipped"
message: "Check mode - SSH not tested"
})
} else {
# In real mode, this would test SSH connection
$checks = ($checks | append {
check: "Server accessibility"
status: "pending"
message: "Would test SSH connection"
})
}
# Check if required directories exist (preview only in check mode)
let required_dirs = ["/tmp", "/etc", "/usr/local/bin"]
for dir in $required_dirs {
$checks = ($checks | append {
check: $"Directory ($dir)"
status: "info"
message: $"Would verify directory exists"
})
}
# Check if required commands are available
let required_commands = ["bash", "systemctl"]
for cmd in $required_commands {
$checks = ($checks | append {
check: $"Command ($cmd)"
status: "info"
message: $"Would verify command is available"
})
}
return {
checks: $checks
total_checks: ($checks | length)
}
}
# Enhanced check mode handler
export def run-check-mode [
taskserv_name: string
taskserv_profile: string
settings: record
server: record
--verbose (-v)
]: nothing -> record {
_print $"\n(_ansi cyan_bold)Check Mode: ($taskserv_name)(_ansi reset) on (_ansi green_bold)($server.hostname)(_ansi reset)"
mut results = {
taskserv: $taskserv_name
profile: $taskserv_profile
server: $server.hostname
validations: []
overall_valid: true
}
# 1. Static validation
_print $"\n(_ansi yellow)→ Running static validation...(_ansi reset)"
let static_validation = {
kcl: (validate-kcl-schemas $taskserv_name --verbose=$verbose)
templates: (validate-templates $taskserv_name --verbose=$verbose)
scripts: (validate-scripts $taskserv_name --verbose=$verbose)
}
let static_valid = (
$static_validation.kcl.valid and
$static_validation.templates.valid and
$static_validation.scripts.valid
)
if $static_valid {
_print $" (_ansi green)✓ Static validation passed(_ansi reset)"
} else {
_print $" (_ansi red)✗ Static validation failed(_ansi reset)"
$results.overall_valid = false
}
$results.validations = ($results.validations | append {
level: "static"
valid: $static_valid
details: $static_validation
})
# 2. Dependency validation
_print $"\n(_ansi yellow)→ Checking dependencies...(_ansi reset)"
let deps_validation = (validate-infra-dependencies $taskserv_name $settings --verbose=$verbose)
if $deps_validation.valid {
_print $" (_ansi green)✓ Dependencies OK(_ansi reset)"
if ($deps_validation.requires | default [] | length) > 0 {
_print $" Required: (($deps_validation.requires | str join ', '))"
}
} else {
_print $" (_ansi red)✗ Dependency issues found(_ansi reset)"
for err in ($deps_validation.errors | default []) {
_print $" (_ansi red)✗(_ansi reset) ($err)"
}
$results.overall_valid = false
}
$results.validations = ($results.validations | append {
level: "dependencies"
valid: $deps_validation.valid
details: $deps_validation
})
# 3. Preview configuration generation
_print $"\n(_ansi yellow)→ Previewing configuration generation...(_ansi reset)"
let config_preview = (preview-config-generation $taskserv_name $taskserv_profile $settings $server --verbose=$verbose)
if $config_preview.valid {
_print $" (_ansi green)✓ Configuration preview generated(_ansi reset)"
_print $" Files to process: ($config_preview.total_files)"
if $verbose and ($config_preview.files | length) > 0 {
_print $"\n Files to be deployed:"
for file in $config_preview.files {
_print $" ($file.type): ($file.source) → ($file.destination)"
}
}
} else {
_print $" (_ansi red)✗ Configuration preview failed(_ansi reset)"
$results.overall_valid = false
}
$results.validations = ($results.validations | append {
level: "configuration"
valid: $config_preview.valid
details: $config_preview
})
# 4. Prerequisites check
_print $"\n(_ansi yellow)→ Checking prerequisites...(_ansi reset)"
let prereq_check = (check-prerequisites $taskserv_name $server $settings true)
_print $" (_ansi blue)(_ansi reset) Prerequisite checks (preview mode):"
for check in $prereq_check.checks {
let icon = match $check.status {
"passed" => $"(_ansi green)✓(_ansi reset)"
"failed" => $"(_ansi red)✗(_ansi reset)"
"info" => $"(_ansi blue)(_ansi reset)"
"skipped" => $"(_ansi yellow)⊘(_ansi reset)"
_ => "•"
}
_print $" ($icon) ($check.check): ($check.message)"
}
$results.validations = ($results.validations | append {
level: "prerequisites"
valid: true
details: $prereq_check
})
# Summary
_print $"\n(_ansi cyan_bold)Check Mode Summary(_ansi reset)"
if $results.overall_valid {
_print $"(_ansi green_bold)✓ All validations passed(_ansi reset)"
_print $"\n💡 Taskserv can be deployed with: (_ansi cyan)provisioning taskserv create ($taskserv_name)(_ansi reset)"
} else {
_print $"(_ansi red_bold)✗ Validation failed(_ansi reset)"
_print $"\n🛑 Fix the errors above before deploying"
}
return $results
}
# Print detailed check mode report
export def print-check-report [
results: record
--format: string = "text"
]: nothing -> nothing {
match $format {
"json" => {
$results | to json
}
"yaml" => {
$results | to yaml
}
_ => {
# Text format already printed by run-check-mode
null
}
}
}