provisioning/provisioning-validate.nu
2025-09-22 23:11:41 +01:00

300 lines
11 KiB
Plaintext
Executable File

#!/usr/bin/env nu
# Infrastructure Validation and Review Tool
# Validates KCL/YAML configurations, checks best practices, and generates reports
use core/nulib/lib_provisioning/infra_validator/validator.nu *
export def main [
infra_path?: string # Path to infrastructure configuration (default: current directory)
--fix (-f) # Auto-fix issues where possible
--report (-r): string = "md" # Report format (md|yaml|json|all)
--output (-o): string = "./validation_results" # Output directory
--severity (-s): string = "warning" # Minimum severity (info|warning|error|critical)
--ci # CI/CD mode (exit codes, no colors, minimal output)
--dry-run (-d) # Show what would be fixed without actually fixing
--rules: string # Comma-separated list of specific rules to run
--exclude: string # Comma-separated list of rules to exclude
--verbose (-v) # Verbose output (show all details)
--help (-h) # Show detailed help
]: nothing -> nothing {
if $help {
show_detailed_help
return
}
let target_path = if ($infra_path | is-empty) {
"."
} else {
$infra_path
}
if not ($target_path | path exists) {
if not $ci {
print $"🛑 Infrastructure path not found: ($target_path)"
print "Use --help for usage information"
}
exit 1
}
if not $ci {
print_banner
print $"🔍 Validating infrastructure: ($target_path | path expand)"
print ""
}
# Validate input parameters
let valid_severities = ["info", "warning", "error", "critical"]
if ($severity not-in $valid_severities) {
if not $ci {
print $"🛑 Invalid severity level: ($severity)"
print $"Valid options: ($valid_severities | str join ', ')"
}
exit 1
}
let valid_formats = ["md", "markdown", "yaml", "yml", "json", "all"]
if ($report not-in $valid_formats) {
if not $ci {
print $"🛑 Invalid report format: ($report)"
print $"Valid options: ($valid_formats | str join ', ')"
}
exit 1
}
# Set up environment
setup_validation_environment $verbose
# Run validation
try {
let result = (run_validation $target_path $fix $report $output $severity $ci $dry_run)
if not $ci {
print ""
print $"📊 Reports generated in: ($output)"
show_next_steps $result
}
} catch {|error|
if not $ci {
print $"🛑 Validation failed: ($error.msg)"
}
exit 4
}
}
def print_banner []: nothing -> nothing {
print "╔══════════════════════════════════════════════════════════════╗"
print "║ Infrastructure Validation & Review Tool ║"
print "║ Provisioning ║"
print "╚══════════════════════════════════════════════════════════════╝"
print ""
}
def show_detailed_help []: nothing -> nothing {
print "Infrastructure Validation & Review Tool"
print "========================================"
print ""
print "USAGE:"
print " nu provisioning-validate.nu [INFRA_PATH] [OPTIONS]"
print ""
print "ARGUMENTS:"
print " INFRA_PATH Path to infrastructure configuration (default: current directory)"
print ""
print "OPTIONS:"
print " -f, --fix Auto-fix issues where possible"
print " -r, --report FORMAT Report format: md, yaml, json, all (default: md)"
print " -o, --output DIR Output directory (default: ./validation_results)"
print " -s, --severity LEVEL Minimum severity: info, warning, error, critical (default: warning)"
print " --ci CI/CD mode (exit codes, no colors, minimal output)"
print " -d, --dry-run Show what would be fixed without actually fixing"
print " --rules RULES Comma-separated list of specific rules to run"
print " --exclude RULES Comma-separated list of rules to exclude"
print " -v, --verbose Verbose output"
print " -h, --help Show this help"
print ""
print "EXIT CODES:"
print " 0 All validations passed"
print " 1 Critical errors found (blocks deployment)"
print " 2 Errors found (should be fixed)"
print " 3 Only warnings found"
print " 4 Validation system error"
print ""
print "EXAMPLES:"
print ""
print " # Validate current directory, generate markdown report"
print " nu provisioning-validate.nu"
print ""
print " # Validate specific infrastructure with auto-fix"
print " nu provisioning-validate.nu klab/sgoyol --fix"
print ""
print " # CI/CD mode with YAML report"
print " nu provisioning-validate.nu klab/sgoyol --ci --report yaml"
print ""
print " # Dry run to see what would be fixed"
print " nu provisioning-validate.nu klab/sgoyol --fix --dry-run"
print ""
print " # Generate all report formats"
print " nu provisioning-validate.nu klab/sgoyol --report all --output ./reports"
print ""
print "VALIDATION RULES:"
print " VAL001 YAML Syntax Validation (critical)"
print " VAL002 KCL Compilation Check (critical)"
print " VAL003 Unquoted Variable References (error)"
print " VAL004 Required Fields Validation (error)"
print " VAL005 Resource Naming Conventions (warning)"
print " VAL006 Basic Security Checks (error)"
print " VAL007 Version Compatibility Check (warning)"
print " VAL008 Network Configuration Validation (error)"
print ""
print "INTEGRATION:"
print ""
print " GitHub Actions:"
print " ```yaml"
print " - name: Validate Infrastructure"
print " run: |"
print " nu provisioning-validate.nu klab/sgoyol \\"
print " --ci --fix --report all"
print " ```"
print ""
print " GitLab CI:"
print " ```yaml"
print " validate_infra:"
print " script:"
print " - nu provisioning-validate.nu \$INFRA_PATH --ci --report yaml"
print " artifacts:"
print " reports:"
print " junit: validation_results/validation_results.yaml"
print " ```"
print ""
}
def setup_validation_environment [verbose: bool]: nothing -> nothing {
# Check required dependencies
let dependencies = ["kcl"] # Add other required tools
for dep in $dependencies {
let check = (^bash -c $"type -P ($dep)" | complete)
if $check.exit_code != 0 {
if $verbose {
print $"⚠️ Warning: ($dep) not found in PATH"
print " Some validation rules may be skipped"
}
} else if $verbose {
print $"✅ ($dep) found"
}
}
}
def run_validation [
target_path: string
fix: bool
report: string
output: string
severity: string
ci: bool
dry_run: bool
]: nothing -> record {
# Call the validator's main function
^nu -c $"use core/nulib/lib_provisioning/infra_validator/validator.nu; main '($target_path)' --fix=($fix) --report=($report) --output=($output) --severity=($severity) --ci=($ci) --dry-run=($dry_run)"
# For now, return a basic structure - this would be improved
{
results: {
summary: { total_checks: 0, passed: 0, failed: 0, auto_fixed: 0 }
issues: []
}
exit_code: 0
}
}
def show_next_steps [result: record]: nothing -> nothing {
let exit_code = $result.exit_code
print "🎯 Next Steps:"
print "=============="
match $exit_code {
0 => {
print "✅ All validations passed! Your infrastructure is ready for deployment."
print ""
print "Recommended actions:"
print "• Review the validation report for any enhancement suggestions"
print "• Consider setting up automated validation in your CI/CD pipeline"
print "• Share the report with your team for documentation"
}
1 => {
print "🚨 Critical issues found that block deployment:"
print ""
print "Required actions:"
print "• Fix all critical issues before deployment"
print "• Review the validation report for specific fixes needed"
print "• Re-run validation after fixes: nu provisioning-validate.nu --fix"
print "• Consider using --dry-run first to preview fixes"
}
2 => {
print "❌ Errors found that should be resolved:"
print ""
print "Recommended actions:"
print "• Review and fix the errors in the validation report"
print "• Use --fix flag to auto-resolve fixable issues"
print "• Test your infrastructure after fixes"
print "• Consider the impact of proceeding with these errors"
}
3 => {
print "⚠️ Warnings found - review recommended:"
print ""
print "Suggested actions:"
print "• Review warnings for potential improvements"
print "• Consider addressing warnings for better practices"
print "• Documentation and monitoring suggestions may be included"
print "• Safe to proceed with deployment"
}
_ => {
print "❓ Unexpected validation result - please review the output"
}
}
print ""
print "For detailed information, check the generated reports in the output directory."
print "Use --help for more usage examples and CI/CD integration guidance."
}
# Quick validation function for simple use cases
export def "validate quick" [
infra_path?: string
--fix (-f)
]: nothing -> nothing {
let target = if ($infra_path | is-empty) { "." } else { $infra_path }
print "🚀 Quick Infrastructure Validation"
print "=================================="
print ""
main $target --severity="error" --report="md" --output="./quick_validation" --fix=$fix
}
# Function for CI/CD environments
export def "validate ci" [
infra_path: string
--format (-f): string = "yaml"
--fix
]: nothing -> nothing {
main $infra_path --ci --report=$format --output="./ci_validation" --fix=$fix
}
# Enhanced validation with all checks
export def "validate full" [
infra_path?: string
--output (-o): string = "./full_validation"
]: nothing -> nothing {
let target = if ($infra_path | is-empty) { "." } else { $infra_path }
print "🔍 Full Infrastructure Validation"
print "================================="
print ""
main $target --severity="info" --report="all" --output=$output --verbose
}