chore: add current provisioning state before migration
This commit is contained in:
parent
a9703b4748
commit
50745b0f22
660 changed files with 88126 additions and 0 deletions
431
core/nulib/main_provisioning/ai.nu
Normal file
431
core/nulib/main_provisioning/ai.nu
Normal file
|
|
@ -0,0 +1,431 @@
|
|||
# AI Module for Provisioning CLI
|
||||
# Enhanced natural language interface with intelligent agents
|
||||
|
||||
use std
|
||||
use ../lib_provisioning/ai/lib.nu *
|
||||
use ../lib_provisioning/utils/settings.nu load_settings
|
||||
use ../lib_provisioning/plugins_defs.nu render_template
|
||||
use ../ai/query_processor.nu *
|
||||
|
||||
# Main AI command dispatcher
|
||||
export def main [
|
||||
action: string
|
||||
...args: string
|
||||
--prompt: string
|
||||
--template-type: string = "server"
|
||||
--context: string
|
||||
--provider: string
|
||||
--model: string
|
||||
--max-tokens: int
|
||||
--temperature: float
|
||||
--test
|
||||
--config
|
||||
--enable
|
||||
--disable
|
||||
]: nothing -> any {
|
||||
match $action {
|
||||
"template" => { ai_template_command $args $prompt $template_type }
|
||||
"query" => {
|
||||
if ($prompt | is-not-empty) {
|
||||
enhanced_query_command $prompt $context
|
||||
} else {
|
||||
ai_query_command $args $prompt $context
|
||||
}
|
||||
}
|
||||
"chat" => { start_interactive_chat }
|
||||
"capabilities" => { show_ai_capabilities }
|
||||
"examples" => { show_query_examples }
|
||||
"batch" => {
|
||||
if ($args | length) > 0 {
|
||||
process_batch_file $args.0
|
||||
} else {
|
||||
print "❌ Batch processing requires a file path"
|
||||
}
|
||||
}
|
||||
"performance" => { run_ai_benchmark }
|
||||
"webhook" => { ai_webhook_command $args $prompt }
|
||||
"test" => { ai_test_command }
|
||||
"config" => { ai_config_command }
|
||||
"enable" => { ai_enable_command }
|
||||
"disable" => { ai_disable_command }
|
||||
"help" => { enhanced_ai_help_command }
|
||||
_ => {
|
||||
print $"Unknown AI action: ($action)"
|
||||
enhanced_ai_help_command
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Generate infrastructure templates using AI
|
||||
def ai_template_command [
|
||||
args: list<string>
|
||||
prompt: string
|
||||
template_type: string
|
||||
] {
|
||||
if ($prompt | is-empty) {
|
||||
error make {msg: "AI template generation requires --prompt"}
|
||||
}
|
||||
|
||||
let result = (ai_generate_template $prompt $template_type)
|
||||
print $"# AI Generated ($template_type) Template"
|
||||
print $"# Prompt: ($prompt)"
|
||||
print ""
|
||||
print $result
|
||||
}
|
||||
|
||||
# Process natural language queries about infrastructure
|
||||
def ai_query_command [
|
||||
args: list<string>
|
||||
prompt: string
|
||||
context: string
|
||||
] {
|
||||
if ($prompt | is-empty) {
|
||||
error make {msg: "AI query requires --prompt"}
|
||||
}
|
||||
|
||||
let context_data = if ($context | is-empty) {
|
||||
{}
|
||||
} else {
|
||||
if ($context | str starts-with "{") {
|
||||
($context | from json)
|
||||
} else {
|
||||
{raw_context: $context}
|
||||
}
|
||||
}
|
||||
|
||||
let result = (ai_process_query $prompt $context_data)
|
||||
print $result
|
||||
}
|
||||
|
||||
# Process webhook/chat messages
|
||||
def ai_webhook_command [
|
||||
args: list<string>
|
||||
prompt: string
|
||||
] {
|
||||
if ($prompt | is-empty) {
|
||||
error make {msg: "AI webhook processing requires --prompt"}
|
||||
}
|
||||
|
||||
let user_id = if ($args | length) > 0 { $args.0 } else { "cli" }
|
||||
let channel = if ($args | length) > 1 { $args.1 } else { "direct" }
|
||||
|
||||
let result = (ai_process_webhook $prompt $user_id $channel)
|
||||
print $result
|
||||
}
|
||||
|
||||
# Test AI connectivity and configuration
|
||||
def ai_test_command [] {
|
||||
print "Testing AI configuration..."
|
||||
|
||||
let validation = (validate_ai_config)
|
||||
if not $validation.valid {
|
||||
print "❌ AI configuration issues found:"
|
||||
for issue in $validation.issues {
|
||||
print $" - ($issue)"
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
print "✅ AI configuration is valid"
|
||||
|
||||
let test_result = (test_ai_connection)
|
||||
if $test_result.success {
|
||||
print $"✅ ($test_result.message)"
|
||||
if "response" in $test_result {
|
||||
print $" Response: ($test_result.response)"
|
||||
}
|
||||
} else {
|
||||
print $"❌ ($test_result.message)"
|
||||
}
|
||||
}
|
||||
|
||||
# Show AI configuration
|
||||
def ai_config_command [] {
|
||||
let config = (get_ai_config)
|
||||
|
||||
print "🤖 AI Configuration:"
|
||||
print $" Enabled: ($config.enabled)"
|
||||
print $" Provider: ($config.provider)"
|
||||
print $" Model: ($config.model? // 'default')"
|
||||
print $" Max Tokens: ($config.max_tokens)"
|
||||
print $" Temperature: ($config.temperature)"
|
||||
print $" Timeout: ($config.timeout)s"
|
||||
print ""
|
||||
print "Feature Flags:"
|
||||
print $" Template AI: ($config.enable_template_ai)"
|
||||
print $" Query AI: ($config.enable_query_ai)"
|
||||
print $" Webhook AI: ($config.enable_webhook_ai)"
|
||||
|
||||
if $config.enabled and ($config.api_key? == null) {
|
||||
print ""
|
||||
print "⚠️ API key not configured"
|
||||
print " Set environment variable based on provider:"
|
||||
print " - OpenAI: OPENAI_API_KEY"
|
||||
print " - Claude: ANTHROPIC_API_KEY"
|
||||
print " - Generic: LLM_API_KEY"
|
||||
}
|
||||
}
|
||||
|
||||
# Enable AI functionality
|
||||
def ai_enable_command [] {
|
||||
print "AI functionality can be enabled by setting ai.enabled = true in your KCL settings"
|
||||
print "Example configuration:"
|
||||
print ""
|
||||
print "ai: AIProvider {"
|
||||
print " enabled: true"
|
||||
print " provider: \"openai\" # or \"claude\" or \"generic\""
|
||||
print " api_key: env(\"OPENAI_API_KEY\")"
|
||||
print " model: \"gpt-4\""
|
||||
print " max_tokens: 2048"
|
||||
print " temperature: 0.3"
|
||||
print " enable_template_ai: true"
|
||||
print " enable_query_ai: true"
|
||||
print " enable_webhook_ai: false"
|
||||
print "}"
|
||||
}
|
||||
|
||||
# Disable AI functionality
|
||||
def ai_disable_command [] {
|
||||
print "AI functionality can be disabled by setting ai.enabled = false in your KCL settings"
|
||||
print "This will disable all AI features while preserving configuration."
|
||||
}
|
||||
|
||||
# Show AI help
|
||||
def ai_help_command [] {
|
||||
print "🤖 AI-Powered Provisioning Commands"
|
||||
print ""
|
||||
print "USAGE:"
|
||||
print " ./core/nulib/provisioning ai <ACTION> [OPTIONS]"
|
||||
print ""
|
||||
print "ACTIONS:"
|
||||
print " template Generate infrastructure templates from natural language"
|
||||
print " query Process natural language queries about infrastructure"
|
||||
print " webhook Process webhook/chat messages"
|
||||
print " test Test AI connectivity and configuration"
|
||||
print " config Show current AI configuration"
|
||||
print " enable Show how to enable AI functionality"
|
||||
print " disable Show how to disable AI functionality"
|
||||
print " help Show this help message"
|
||||
print ""
|
||||
print "TEMPLATE OPTIONS:"
|
||||
print " --prompt <text> Natural language description"
|
||||
print " --template-type <type> Type of template (server, cluster, taskserv)"
|
||||
print ""
|
||||
print "QUERY OPTIONS:"
|
||||
print " --prompt <text> Natural language query"
|
||||
print " --context <json> Additional context as JSON"
|
||||
print ""
|
||||
print "WEBHOOK OPTIONS:"
|
||||
print " --prompt <text> Message to process"
|
||||
print " <user_id> User ID for context"
|
||||
print " <channel> Channel for context"
|
||||
print ""
|
||||
print "EXAMPLES:"
|
||||
print " # Generate a Kubernetes cluster template"
|
||||
print " ./core/nulib/provisioning ai template --prompt \"3-node Kubernetes cluster with Ceph storage\""
|
||||
print ""
|
||||
print " # Query infrastructure status"
|
||||
print " ./core/nulib/provisioning ai query --prompt \"show all running servers with high CPU\""
|
||||
print ""
|
||||
print " # Process chat message"
|
||||
print " ./core/nulib/provisioning ai webhook --prompt \"deploy redis cluster\" user123 slack"
|
||||
print ""
|
||||
print " # Test AI configuration"
|
||||
print " ./core/nulib/provisioning ai test"
|
||||
}
|
||||
|
||||
# AI-enhanced generate command
|
||||
export def ai_generate [
|
||||
type: string
|
||||
--prompt: string
|
||||
--template-type: string = "server"
|
||||
--output: string
|
||||
]: nothing -> any {
|
||||
if ($prompt | is-empty) {
|
||||
error make {msg: "AI generation requires --prompt"}
|
||||
}
|
||||
|
||||
let result = (ai_generate_template $prompt $template_type)
|
||||
|
||||
if ($output | is-empty) {
|
||||
print $result
|
||||
} else {
|
||||
$result | save $output
|
||||
print $"AI generated ($template_type) saved to: ($output)"
|
||||
}
|
||||
}
|
||||
|
||||
# AI-enhanced query with provisioning context
|
||||
export def ai_query_infra [
|
||||
query: string
|
||||
--infra: string
|
||||
--provider: string
|
||||
--output-format: string = "human"
|
||||
]: nothing -> any {
|
||||
let context = {
|
||||
infra: ($infra | default "")
|
||||
provider: ($provider | default "")
|
||||
output_format: $output_format
|
||||
}
|
||||
|
||||
let result = (ai_process_query $query $context)
|
||||
|
||||
match $output_format {
|
||||
"json" => { {query: $query, response: $result} | to json }
|
||||
"yaml" => { {query: $query, response: $result} | to yaml }
|
||||
_ => { print $result }
|
||||
}
|
||||
}
|
||||
|
||||
# Enhanced AI query command with intelligent agents
|
||||
def enhanced_query_command [
|
||||
prompt: string
|
||||
context: string
|
||||
] {
|
||||
print $"🤖 Enhanced AI Query: ($prompt)"
|
||||
|
||||
let result = process_query $prompt --format "summary"
|
||||
print $result
|
||||
}
|
||||
|
||||
# Show AI system capabilities
|
||||
def show_ai_capabilities [] {
|
||||
let caps = get_query_capabilities
|
||||
|
||||
print "🤖 Enhanced AI System Capabilities"
|
||||
print ""
|
||||
print "📋 Supported Query Types:"
|
||||
$caps.supported_types | each { |type| print $" • ($type)" }
|
||||
|
||||
print ""
|
||||
print "🤖 Available AI Agents:"
|
||||
$caps.agents | each { |agent| print $" • ($agent)" }
|
||||
|
||||
print ""
|
||||
print "📊 Output Formats:"
|
||||
$caps.output_formats | each { |format| print $" • ($format)" }
|
||||
|
||||
print ""
|
||||
print "🚀 Features:"
|
||||
$caps.features | each { |feature| print $" • ($feature)" }
|
||||
}
|
||||
|
||||
# Show query examples
|
||||
def show_query_examples [] {
|
||||
print "💡 Enhanced AI Query Examples"
|
||||
print ""
|
||||
|
||||
print "🏗️ Infrastructure Status:"
|
||||
print " • \"What servers are currently running?\""
|
||||
print " • \"Show me the health status of all services\""
|
||||
print " • \"Which containers are consuming the most resources?\""
|
||||
print ""
|
||||
|
||||
print "⚡ Performance Analysis:"
|
||||
print " • \"Which services have high CPU usage?\""
|
||||
print " • \"What's causing slow response times?\""
|
||||
print " • \"Show me memory usage trends over the last hour\""
|
||||
print ""
|
||||
|
||||
print "💰 Cost Optimization:"
|
||||
print " • \"How can I reduce my AWS costs?\""
|
||||
print " • \"Which instances are underutilized?\""
|
||||
print " • \"Show me the most expensive resources\""
|
||||
print ""
|
||||
|
||||
print "🛡️ Security Analysis:"
|
||||
print " • \"Are there any security threats detected?\""
|
||||
print " • \"Show me recent failed login attempts\""
|
||||
print " • \"What vulnerabilities exist in the system?\""
|
||||
print ""
|
||||
|
||||
print "🔮 Predictive Analysis:"
|
||||
print " • \"When will I need to scale the database?\""
|
||||
print " • \"Predict disk space usage for next month\""
|
||||
print " • \"What failures are likely to occur soon?\""
|
||||
}
|
||||
|
||||
# Process batch queries from file
|
||||
def process_batch_file [file_path: string] {
|
||||
if not ($file_path | path exists) {
|
||||
print $"❌ File not found: ($file_path)"
|
||||
return
|
||||
}
|
||||
|
||||
let queries = (open $file_path | lines | where { |line| not ($line | is-empty) and not ($line | str starts-with "#") })
|
||||
|
||||
print $"📋 Processing ($queries | length) queries from: ($file_path)"
|
||||
|
||||
let results = process_batch_queries $queries --format "summary"
|
||||
|
||||
$results | enumerate | each { |item|
|
||||
print $"--- Query ($item.index + 1) ---"
|
||||
print $item.item
|
||||
print ""
|
||||
}
|
||||
}
|
||||
|
||||
# Run AI performance benchmark
|
||||
def run_ai_benchmark [] {
|
||||
let benchmark_queries = [
|
||||
"What's the current CPU usage?"
|
||||
"Show me error logs from the last hour"
|
||||
"Which services are consuming high memory?"
|
||||
"Are there any security alerts?"
|
||||
"Predict when we'll need more storage"
|
||||
]
|
||||
|
||||
let results = analyze_query_performance $benchmark_queries
|
||||
|
||||
print "📊 AI Query Performance Benchmark"
|
||||
print $"Total Queries: ($results.total_queries)"
|
||||
print $"Average Duration: ($results.average_duration_ms) ms"
|
||||
print $"Queries per Second: ($results.queries_per_second | math round -p 2)"
|
||||
}
|
||||
|
||||
# Enhanced AI help command
|
||||
def enhanced_ai_help_command [] {
|
||||
print "🤖 Enhanced AI-Powered Provisioning Commands"
|
||||
print ""
|
||||
print "USAGE:"
|
||||
print " ./core/nulib/provisioning ai <ACTION> [OPTIONS]"
|
||||
print ""
|
||||
print "ENHANCED ACTIONS:"
|
||||
print " query Process natural language queries with intelligent agents"
|
||||
print " chat Interactive AI chat mode"
|
||||
print " capabilities Show AI system capabilities"
|
||||
print " examples Show example queries"
|
||||
print " batch Process batch queries from file"
|
||||
print " performance Run performance benchmarks"
|
||||
print ""
|
||||
print "LEGACY ACTIONS:"
|
||||
print " template Generate infrastructure templates"
|
||||
print " webhook Process webhook/chat messages"
|
||||
print " test Test AI connectivity"
|
||||
print " config Show AI configuration"
|
||||
print " enable Enable AI functionality"
|
||||
print " disable Disable AI functionality"
|
||||
print ""
|
||||
print "ENHANCED QUERY EXAMPLES:"
|
||||
print " # Natural language infrastructure queries"
|
||||
print " ./core/nulib/provisioning ai query --prompt \"What servers are using high CPU?\""
|
||||
print " ./core/nulib/provisioning ai query --prompt \"How can I reduce AWS costs?\""
|
||||
print " ./core/nulib/provisioning ai query --prompt \"Are there any security threats?\""
|
||||
print ""
|
||||
print " # Interactive chat mode"
|
||||
print " ./core/nulib/provisioning ai chat"
|
||||
print ""
|
||||
print " # Batch processing"
|
||||
print " ./core/nulib/provisioning ai batch queries.txt"
|
||||
print ""
|
||||
print " # Performance analysis"
|
||||
print " ./core/nulib/provisioning ai performance"
|
||||
print ""
|
||||
print "🚀 New Features:"
|
||||
print " • Intelligent agent selection"
|
||||
print " • Natural language processing"
|
||||
print " • Real-time data integration"
|
||||
print " • Predictive analytics"
|
||||
print " • Interactive chat mode"
|
||||
print " • Batch query processing"
|
||||
}
|
||||
318
core/nulib/main_provisioning/api.nu
Normal file
318
core/nulib/main_provisioning/api.nu
Normal file
|
|
@ -0,0 +1,318 @@
|
|||
#!/usr/bin/env nu
|
||||
|
||||
# API Server management for Provisioning System
|
||||
# Provides HTTP REST API endpoints for infrastructure management
|
||||
|
||||
use ../api/server.nu *
|
||||
use ../api/routes.nu *
|
||||
use ../lib_provisioning/utils/settings.nu *
|
||||
|
||||
export def "main api" [
|
||||
command?: string # Command: start, stop, status, docs
|
||||
--port (-p): int = 8080 # Port to run the API server on
|
||||
--host: string = "localhost" # Host to bind the server to
|
||||
--enable-websocket # Enable WebSocket support for real-time updates
|
||||
--enable-cors # Enable CORS for cross-origin requests
|
||||
--debug (-d) # Enable debug mode
|
||||
--background (-b) # Run server in background
|
||||
--config-file: string # Custom configuration file path
|
||||
--ssl # Enable SSL/TLS (requires certificates)
|
||||
--cert-file: string # SSL certificate file path
|
||||
--key-file: string # SSL private key file path
|
||||
--doc-format: string = "markdown" # Documentation format (markdown, json, yaml)
|
||||
]: nothing -> nothing {
|
||||
|
||||
let cmd = $command | default "start"
|
||||
|
||||
match $cmd {
|
||||
"start" => {
|
||||
print $"🚀 Starting Provisioning API Server..."
|
||||
|
||||
# Validate configuration
|
||||
let config_valid = validate_api_config --port $port --host $host
|
||||
if not $config_valid.valid {
|
||||
error make {
|
||||
msg: $"Invalid configuration: ($config_valid.errors | str join ', ')"
|
||||
help: "Please check your configuration and try again"
|
||||
}
|
||||
}
|
||||
|
||||
# Check dependencies
|
||||
check_api_dependencies
|
||||
|
||||
# Start the server
|
||||
if $background {
|
||||
start_api_background --port $port --host $host --enable-websocket $enable_websocket --enable-cors $enable_cors --debug $debug
|
||||
} else {
|
||||
start_api_server --port $port --host $host --enable-websocket $enable_websocket --enable-cors $enable_cors --debug $debug
|
||||
}
|
||||
}
|
||||
|
||||
"stop" => {
|
||||
print "🛑 Stopping API server..."
|
||||
stop_api_server --port $port --host $host
|
||||
}
|
||||
|
||||
"status" => {
|
||||
print "🔍 Checking API server status..."
|
||||
let health = check_api_health --port $port --host $host
|
||||
print ($health | table)
|
||||
}
|
||||
|
||||
"docs" => {
|
||||
print "📚 Generating API documentation..."
|
||||
generate_api_documentation --format $doc_format
|
||||
}
|
||||
|
||||
"routes" => {
|
||||
print "🗺️ Listing API routes..."
|
||||
let routes = get_route_definitions
|
||||
print ($routes | select method path description | table)
|
||||
}
|
||||
|
||||
"validate" => {
|
||||
print "✅ Validating API configuration..."
|
||||
let validation = validate_routes
|
||||
print ($validation | table)
|
||||
}
|
||||
|
||||
"spec" => {
|
||||
print "📋 Generating OpenAPI specification..."
|
||||
let spec = generate_api_spec
|
||||
print ($spec | to json)
|
||||
}
|
||||
|
||||
_ => {
|
||||
print_api_help
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def validate_api_config [
|
||||
--port: int
|
||||
--host: string
|
||||
]: nothing -> record {
|
||||
mut errors = []
|
||||
mut valid = true
|
||||
|
||||
# Validate port range
|
||||
if $port < 1024 or $port > 65535 {
|
||||
$errors = ($errors | append "Port must be between 1024 and 65535")
|
||||
$valid = false
|
||||
}
|
||||
|
||||
# Validate host format
|
||||
if ($host | str contains " ") {
|
||||
$errors = ($errors | append "Host cannot contain spaces")
|
||||
$valid = false
|
||||
}
|
||||
|
||||
# Check if port is available
|
||||
if $valid {
|
||||
let port_available = (do -i {
|
||||
http listen $port --host $host --timeout 1 | ignore
|
||||
false
|
||||
} | default true)
|
||||
|
||||
if not $port_available {
|
||||
$errors = ($errors | append $"Port ($port) is already in use")
|
||||
$valid = false
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
valid: $valid
|
||||
errors: $errors
|
||||
port: $port
|
||||
host: $host
|
||||
}
|
||||
}
|
||||
|
||||
def check_api_dependencies []: nothing -> nothing {
|
||||
print "🔍 Checking dependencies..."
|
||||
|
||||
# Check Python availability
|
||||
let python_available = (do -i { python3 --version } | complete | get exit_code) == 0
|
||||
if not $python_available {
|
||||
error make {
|
||||
msg: "Python 3 is required for the API server"
|
||||
help: "Please install Python 3 and ensure it's available in PATH"
|
||||
}
|
||||
}
|
||||
|
||||
# Check required environment variables
|
||||
if ($env.PROVISIONING_PATH? | is-empty) {
|
||||
print "⚠️ Warning: PROVISIONING_PATH not set, using current directory"
|
||||
$env.PROVISIONING_PATH = (pwd)
|
||||
}
|
||||
|
||||
print "✅ All dependencies satisfied"
|
||||
}
|
||||
|
||||
def start_api_background [
|
||||
--port: int
|
||||
--host: string
|
||||
--enable-websocket
|
||||
--enable-cors
|
||||
--debug
|
||||
]: nothing -> nothing {
|
||||
print $"🚀 Starting API server in background on ($host):($port)..."
|
||||
|
||||
# Create background process
|
||||
let server_cmd = $"nu -c 'use ($env.PWD)/core/nulib/api/server.nu; start_api_server --port ($port) --host ($host)'"
|
||||
|
||||
if $enable_websocket {
|
||||
$server_cmd = $server_cmd + " --enable-websocket"
|
||||
}
|
||||
if $enable_cors {
|
||||
$server_cmd = $server_cmd + " --enable-cors"
|
||||
}
|
||||
if $debug {
|
||||
$server_cmd = $server_cmd + " --debug"
|
||||
}
|
||||
|
||||
# Save PID for later management
|
||||
let pid_file = $"/tmp/provisioning-api-($port).pid"
|
||||
|
||||
bash -c $"($server_cmd) & echo $! > ($pid_file)"
|
||||
|
||||
sleep 2sec
|
||||
let health = check_api_health --port $port --host $host
|
||||
|
||||
if $health.api_server {
|
||||
print $"✅ API server started successfully in background"
|
||||
print $"📍 PID file: ($pid_file)"
|
||||
print $"🌐 URL: http://($host):($port)"
|
||||
} else {
|
||||
print "❌ Failed to start API server"
|
||||
}
|
||||
}
|
||||
|
||||
def stop_api_server [
|
||||
--port: int
|
||||
--host: string
|
||||
]: nothing -> nothing {
|
||||
let pid_file = $"/tmp/provisioning-api-($port).pid"
|
||||
|
||||
if ($pid_file | path exists) {
|
||||
let pid = (open $pid_file | str trim)
|
||||
print $"🛑 Stopping API server (PID: ($pid))..."
|
||||
|
||||
try {
|
||||
kill $pid
|
||||
rm -f $pid_file
|
||||
print "✅ API server stopped successfully"
|
||||
} catch {
|
||||
print "⚠️ Failed to stop server, trying force kill..."
|
||||
kill -9 $pid
|
||||
rm -f $pid_file
|
||||
print "✅ Server force stopped"
|
||||
}
|
||||
} else {
|
||||
print "⚠️ No running API server found on port ($port)"
|
||||
|
||||
# Try to find and kill any Python processes running the API
|
||||
let python_pids = (ps | where name =~ "python3" and command =~ "provisioning_api_server" | get pid)
|
||||
|
||||
if ($python_pids | length) > 0 {
|
||||
print $"🔍 Found ($python_pids | length) related processes, stopping them..."
|
||||
$python_pids | each { |pid| kill $pid }
|
||||
print "✅ Related processes stopped"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def generate_api_documentation [
|
||||
--format: string = "markdown"
|
||||
]: nothing -> nothing {
|
||||
let output_file = match $format {
|
||||
"markdown" => "api_documentation.md"
|
||||
"json" => "api_spec.json"
|
||||
"yaml" => "api_spec.yaml"
|
||||
_ => "api_documentation.md"
|
||||
}
|
||||
|
||||
match $format {
|
||||
"markdown" => {
|
||||
let docs = generate_route_docs
|
||||
$docs | save --force $output_file
|
||||
print $"📚 Markdown documentation saved to: ($output_file)"
|
||||
}
|
||||
|
||||
"json" => {
|
||||
let spec = generate_api_spec
|
||||
$spec | to json | save --force $output_file
|
||||
print $"📋 OpenAPI JSON spec saved to: ($output_file)"
|
||||
}
|
||||
|
||||
"yaml" => {
|
||||
let spec = generate_api_spec
|
||||
$spec | to yaml | save --force $output_file
|
||||
print $"📋 OpenAPI YAML spec saved to: ($output_file)"
|
||||
}
|
||||
|
||||
_ => {
|
||||
print $"❌ Unsupported format: ($format)"
|
||||
print "Supported formats: markdown, json, yaml"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
def print_api_help []: nothing -> nothing {
|
||||
print "
|
||||
🚀 Provisioning API Server Management
|
||||
|
||||
USAGE:
|
||||
provisioning api [COMMAND] [OPTIONS]
|
||||
|
||||
COMMANDS:
|
||||
start Start the API server (default)
|
||||
stop Stop the API server
|
||||
status Check server status
|
||||
docs Generate API documentation
|
||||
routes List all available routes
|
||||
validate Validate API configuration
|
||||
spec Generate OpenAPI specification
|
||||
|
||||
OPTIONS:
|
||||
-p, --port <PORT> Port to run server on [default: 8080]
|
||||
--host <HOST> Host to bind to [default: localhost]
|
||||
--enable-websocket Enable WebSocket support
|
||||
--enable-cors Enable CORS headers
|
||||
-d, --debug Enable debug mode
|
||||
-b, --background Run in background
|
||||
--doc-format <FORMAT> Documentation format [default: markdown]
|
||||
|
||||
EXAMPLES:
|
||||
# Start server on default port
|
||||
provisioning api start
|
||||
|
||||
# Start on custom port with debugging
|
||||
provisioning api start --port 9090 --debug
|
||||
|
||||
# Start in background with WebSocket support
|
||||
provisioning api start --background --enable-websocket
|
||||
|
||||
# Generate API documentation
|
||||
provisioning api docs --doc-format json
|
||||
|
||||
# Check server status
|
||||
provisioning api status
|
||||
|
||||
# Stop running server
|
||||
provisioning api stop
|
||||
|
||||
ENDPOINTS:
|
||||
GET /api/v1/health Health check
|
||||
GET /api/v1/query Query infrastructure
|
||||
POST /api/v1/query Complex queries
|
||||
GET /api/v1/metrics System metrics
|
||||
GET /api/v1/logs System logs
|
||||
GET /api/v1/dashboard Dashboard data
|
||||
GET /api/v1/servers List servers
|
||||
POST /api/v1/servers Create server
|
||||
GET /api/v1/ai/query AI-powered queries
|
||||
|
||||
For more information, visit: https://docs.provisioning.dev/api
|
||||
"
|
||||
}
|
||||
120
core/nulib/main_provisioning/contexts.nu
Normal file
120
core/nulib/main_provisioning/contexts.nu
Normal file
|
|
@ -0,0 +1,120 @@
|
|||
|
||||
use ops.nu provisioning_context_options
|
||||
|
||||
use ../lib_provisioning/setup *
|
||||
|
||||
#> Manage contexts settings
|
||||
export def "main context" [
|
||||
task?: string # server (s) | task (t) | service (sv)
|
||||
name?: string # server (s) | task (t) | service (sv)
|
||||
--key (-k): string
|
||||
--value (-v): string
|
||||
...args # Args for create command
|
||||
--reset (-r) # Restore defaults
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--wait (-w) # Wait servers to be created
|
||||
--settings (-s): string # Settings path
|
||||
--outfile (-o): string # Output file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
] {
|
||||
parse_help_command "context" --task {provisioning_context_options} --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
let config_path = (setup_config_path)
|
||||
let default_context_path = ($config_path | path join "default_context.yaml")
|
||||
let name_context_path = ($config_path | path join $"($name).yaml")
|
||||
let context_path = ($config_path | path join "context.yaml")
|
||||
let set_as_default = {
|
||||
rm -f $context_path
|
||||
^ln -s $name_context_path $context_path
|
||||
_print (
|
||||
$"(_ansi blue_bold)($name)(_ansi reset) set as (_ansi green)default context(_ansi reset)" +
|
||||
$" in (_ansi default_dimmed)($config_path)(_ansi reset)"
|
||||
)
|
||||
}
|
||||
match $task {
|
||||
"h" => {
|
||||
^$"($env.PROVISIONING_NAME)" context --help
|
||||
_print (provisioning_context_options)
|
||||
}
|
||||
"create" | "c" | "new" => {
|
||||
if $name == null or $name == "" {
|
||||
_print $"🛑 No (_ansi red)name(_ansi reset) value "
|
||||
}
|
||||
if ($name_context_path |path exists) {
|
||||
_print $"(_ansi blue_bold)($name)(_ansi reset) already in (_ansi default_dimmed)($config_path)(_ansi reset)"
|
||||
} else {
|
||||
^cp $default_context_path $name_context_path
|
||||
open -r $name_context_path | str replace "infra: " $"infra: ($name)" | save -f $name_context_path
|
||||
_print $"(_ansi blue_bold)($name)(_ansi reset) created in (_ansi default_dimmed)($config_path)(_ansi reset)"
|
||||
}
|
||||
do $set_as_default
|
||||
},
|
||||
"default" | "d" => {
|
||||
if $name == null or $name == "" {
|
||||
_print $"🛑 No (_ansi red)name(_ansi reset) value "
|
||||
exit 1
|
||||
}
|
||||
if not ($name_context_path | path exists) {
|
||||
_print $"🛑 No (_ansi red)($name)(_ansi reset) found in (_ansi default_dimmed)($config_path)(_ansi reset) "
|
||||
exit 1
|
||||
}
|
||||
do $set_as_default
|
||||
},
|
||||
"remove" | "r" => {
|
||||
if $name == null {
|
||||
_print $"🛑 No (_ansi red)name(_ansi reset) value "
|
||||
exit 1
|
||||
}
|
||||
if $name == "" or not ( $name_context_path | path exists) {
|
||||
_print $"🛑 context path (_ansi blue_bold)($name)(_ansi reset) not found "
|
||||
exit 1
|
||||
}
|
||||
let context = (setup_user_context $name)
|
||||
let curr_infra = ($context | get -o "infra")
|
||||
if $curr_infra == $name {
|
||||
_print (
|
||||
$"(_ansi blue_bold)($name)(_ansi reset) removed as (_ansi green)default context(_ansi reset) " +
|
||||
$" in (_ansi default_dimmed)($config_path)(_ansi reset)"
|
||||
)
|
||||
}
|
||||
rm -f $name_context_path $context_path
|
||||
_print $"(_ansi blue_bold)($name)(_ansi reset) context removed "
|
||||
},
|
||||
"edit" | "e" => {
|
||||
let editor = ($env | get -o EDITOR | default "vi")
|
||||
let config_path = (setup_user_context_path $name)
|
||||
^$editor $config_path
|
||||
},
|
||||
"view" | "v" => {
|
||||
_print ((setup_user_context $name) | table -e)
|
||||
},
|
||||
"set" | "s" => {
|
||||
let context = (setup_user_context $name)
|
||||
let curr_value = ($context | get -o $key)
|
||||
if $curr_value == null {
|
||||
_print $"🛑 invalid ($key) in setup "
|
||||
exit 1
|
||||
}
|
||||
if $curr_value == $value {
|
||||
_print $"🛑 ($key) ($value) already set "
|
||||
exit 1
|
||||
}
|
||||
# if $context != null and ( $context.infra | path exists) { return $context.infra }
|
||||
let new_context = ($context | update $key $value)
|
||||
setup_save_context $new_context
|
||||
},
|
||||
"i" | "install" => {
|
||||
install_config $reset --context
|
||||
},
|
||||
_ => {
|
||||
invalid_task "context" ($task | default "") --end
|
||||
},
|
||||
}
|
||||
end_run $" create ($task) "
|
||||
}
|
||||
47
core/nulib/main_provisioning/create.nu
Normal file
47
core/nulib/main_provisioning/create.nu
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
|
||||
# -> Create infrastructure and services (see TARGETS)
|
||||
export def "main create" [
|
||||
target?: string # server (s) | taskserv (t) | cluster (c)
|
||||
name?: string # Target name in settings
|
||||
...args # Args for create command
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--check (-c) # Only check mode no servers will be created
|
||||
--wait (-w) # Wait servers to be created
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--outfile (-o): string # Output file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
parse_help_command "create" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
let use_debug = if $debug or $env.PROVISIONING_DEBUG { "-x" } else { "" }
|
||||
|
||||
match $target {
|
||||
"server"| "servers" | "s" => {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" ($env.PROVISIONING_ARGS | str replace $target '') --notitles
|
||||
},
|
||||
"taskserv" | "taskservs" | "task" | "tasks" | "t" => {
|
||||
let ops = ($env.PROVISIONING_ARGS | split row " ")
|
||||
let task = ($ops | get -o 0 | default "")
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "taskserv" $task ($env.PROVISIONING_ARGS | str replace $"($task) ($target)" '') --notitles
|
||||
},
|
||||
"clusters"| "clusters" | "cl" => {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "cluster" ($env.PROVISIONING_ARGS | str replace $target '') --notitles
|
||||
},
|
||||
_ => {
|
||||
invalid_task "create" ($target | default "") --end
|
||||
exit
|
||||
},
|
||||
}
|
||||
}
|
||||
152
core/nulib/main_provisioning/create_enhanced.nu
Normal file
152
core/nulib/main_provisioning/create_enhanced.nu
Normal file
|
|
@ -0,0 +1,152 @@
|
|||
# Enhanced create command with better validation and logging
|
||||
|
||||
export def "main create enhanced" [
|
||||
target?: string # server (s) | taskserv (t) | cluster (c)
|
||||
name?: string # Target name in settings
|
||||
...args # Args for create command
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--check (-c) # Only check mode no servers will be created
|
||||
--wait (-w) # Wait servers to be created
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--outfile (-o): string # Output file
|
||||
--debug (-x) # Use Debug mode
|
||||
--dry-run # Show what would be done without executing
|
||||
--verbose (-v) # Verbose output
|
||||
]: nothing -> nothing {
|
||||
|
||||
# Set debug mode
|
||||
if $debug {
|
||||
$env.PROVISIONING_DEBUG = true
|
||||
print $"🐛 Debug mode enabled"
|
||||
}
|
||||
|
||||
# Set output format
|
||||
if ($outfile | is-not-empty) {
|
||||
$env.PROVISIONING_OUT = $outfile
|
||||
$env.PROVISIONING_NO_TERMINAL = true
|
||||
}
|
||||
|
||||
# Validate target parameter
|
||||
if ($target | is-empty) {
|
||||
print $"🛑 Target parameter is required"
|
||||
print "💡 Valid targets: server(s), taskserv(t), cluster(cl)"
|
||||
print "💡 Example: provisioning create enhanced server my-server"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Validate target value
|
||||
let valid_targets = ["server", "servers", "s", "taskserv", "taskservs", "task", "tasks", "t", "clusters", "cl"]
|
||||
let is_valid_target = ($valid_targets | where {|t| $t == $target} | length) > 0
|
||||
|
||||
if not $is_valid_target {
|
||||
print $"🛑 Invalid target: ($target)"
|
||||
print $"💡 Valid targets: ($valid_targets | str join ', ')"
|
||||
exit 1
|
||||
}
|
||||
|
||||
# Log operation start
|
||||
print $""
|
||||
print $"📋 Creating ($target)"
|
||||
print $"─────────────────────────────────────────────────────────────"
|
||||
print $"ℹ️ Target: ($target)"
|
||||
print $"ℹ️ Name: ($name | default 'default')"
|
||||
|
||||
if $dry_run {
|
||||
print $"⚠️ DRY RUN MODE - No actual changes will be made"
|
||||
}
|
||||
|
||||
# Validate settings path if provided
|
||||
if ($settings | is-not-empty) {
|
||||
if not ($settings | path exists) {
|
||||
print $"🛑 Settings file not found: ($settings)"
|
||||
exit 1
|
||||
}
|
||||
print $"ℹ️ Using settings: ($settings)"
|
||||
}
|
||||
|
||||
# Validate infra path if provided
|
||||
if ($infra | is-not-empty) {
|
||||
if not ($infra | path exists) {
|
||||
print $"🛑 Infra path not found: ($infra)"
|
||||
exit 1
|
||||
}
|
||||
print $"ℹ️ Using infra: ($infra)"
|
||||
}
|
||||
|
||||
# Execute the appropriate creation command
|
||||
let use_debug = if $debug { "-x" } else { "" }
|
||||
|
||||
try {
|
||||
match $target {
|
||||
"server"| "servers" | "s" => {
|
||||
print $" 📌 Creating server"
|
||||
if $dry_run {
|
||||
print $"ℹ️ Would execute: server creation command"
|
||||
} else {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" ($env.PROVISIONING_ARGS | str replace $target '') --notitles
|
||||
}
|
||||
},
|
||||
"taskserv" | "taskservs" | "task" | "tasks" | "t" => {
|
||||
print $" 📌 Creating taskserv"
|
||||
let ops = ($env.PROVISIONING_ARGS | split row " ")
|
||||
let task = ($ops | get -o 0 | default "")
|
||||
if $dry_run {
|
||||
print $"ℹ️ Would execute: taskserv creation for task ($task)"
|
||||
} else {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "taskserv" $task ($env.PROVISIONING_ARGS | str replace $"($task) ($target)" '') --notitles
|
||||
}
|
||||
},
|
||||
"clusters"| "clusters" | "cl" => {
|
||||
print $" 📌 Creating cluster"
|
||||
if $dry_run {
|
||||
print $"ℹ️ Would execute: cluster creation command"
|
||||
} else {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "cluster" ($env.PROVISIONING_ARGS | str replace $target '') --notitles
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if not $dry_run {
|
||||
print $"✅ Successfully created ($target)"
|
||||
} else {
|
||||
print $"✅ Dry run completed successfully"
|
||||
}
|
||||
|
||||
} catch {|err|
|
||||
print $"🛑 Failed to create ($target)"
|
||||
print $" Details: ($err.msg)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
# Helper function to validate server configuration
|
||||
export def validate-server-config [
|
||||
server_config: record
|
||||
]: bool {
|
||||
let required_fields = ["hostname", "ip", "provider"]
|
||||
let missing_fields = ($required_fields | where {|field|
|
||||
($server_config | get -o $field | is-empty)
|
||||
})
|
||||
|
||||
if ($missing_fields | length) > 0 {
|
||||
print $"🛑 Missing required server configuration fields"
|
||||
$missing_fields | each {|field|
|
||||
print $" - ($field)"
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
print $"✅ Server configuration is valid"
|
||||
true
|
||||
}
|
||||
|
||||
# Helper function to show creation progress
|
||||
export def show-creation-progress [
|
||||
current: int
|
||||
total: int
|
||||
operation: string
|
||||
] {
|
||||
let percent = (($current * 100) / $total)
|
||||
print $"📊 ($operation) ($percent)%"
|
||||
}
|
||||
157
core/nulib/main_provisioning/dashboard.nu
Normal file
157
core/nulib/main_provisioning/dashboard.nu
Normal file
|
|
@ -0,0 +1,157 @@
|
|||
#!/usr/bin/env nu
|
||||
|
||||
# Dashboard Management Commands
|
||||
# Interactive dashboards and data visualization
|
||||
|
||||
use ../dashboard/marimo_integration.nu *
|
||||
|
||||
# Main dashboard command
|
||||
export def main [
|
||||
subcommand?: string
|
||||
...args: string
|
||||
]: [string, ...string] -> nothing {
|
||||
|
||||
if ($subcommand | is-empty) {
|
||||
print "📊 Systems Provisioning Dashboard"
|
||||
print ""
|
||||
print "Interactive dashboards for infrastructure monitoring and analytics"
|
||||
print ""
|
||||
print "Usage: provisioning dashboard <subcommand> [args...]"
|
||||
print ""
|
||||
print "Subcommands:"
|
||||
print " create [template] [name] - Create interactive dashboard"
|
||||
print " start <name> [port] - Start dashboard server"
|
||||
print " list - List available dashboards"
|
||||
print " export <name> [output] - Export dashboard to HTML"
|
||||
print " demo - Create and start demo dashboard"
|
||||
print " status - Show dashboard system status"
|
||||
print ""
|
||||
print "Templates:"
|
||||
print " monitoring - Real-time logs and metrics"
|
||||
print " infrastructure - Server and cluster overview"
|
||||
print " full - Complete observability dashboard"
|
||||
print " ai-insights - AI-powered analytics and predictions"
|
||||
print ""
|
||||
print "Examples:"
|
||||
print " provisioning dashboard demo"
|
||||
print " provisioning dashboard create monitoring my-dashboard"
|
||||
print " provisioning dashboard start my-dashboard 8080"
|
||||
print ""
|
||||
return
|
||||
}
|
||||
|
||||
match $subcommand {
|
||||
"create" => {
|
||||
marimo_integration create ...$args
|
||||
}
|
||||
"start" => {
|
||||
marimo_integration start ...$args
|
||||
}
|
||||
"list" => {
|
||||
marimo_integration list
|
||||
}
|
||||
"export" => {
|
||||
marimo_integration export ...$args
|
||||
}
|
||||
"demo" => {
|
||||
create_demo_dashboard
|
||||
}
|
||||
"status" => {
|
||||
show_dashboard_status
|
||||
}
|
||||
_ => {
|
||||
print $"❌ Unknown subcommand: ($subcommand)"
|
||||
print "Run 'provisioning dashboard' for help"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Create and start a demo dashboard
|
||||
def create_demo_dashboard []: nothing -> nothing {
|
||||
print "🚀 Creating demo dashboard with live data..."
|
||||
|
||||
# Check if API server is running
|
||||
let api_status = check_api_server_status
|
||||
|
||||
if not $api_status {
|
||||
print "⚠️ API server not running. Starting API server..."
|
||||
start_api_server --port 3000 --background
|
||||
sleep 3sec
|
||||
}
|
||||
|
||||
# Create AI insights dashboard
|
||||
marimo_integration create ai-insights demo-dashboard
|
||||
|
||||
print ""
|
||||
print "🎉 Demo dashboard created and started!"
|
||||
print "📊 Open your browser to: http://localhost:8080"
|
||||
print ""
|
||||
print "Features available:"
|
||||
print " 🔍 Real-time log analysis"
|
||||
print " 📈 System metrics visualization"
|
||||
print " 🏗️ Infrastructure topology"
|
||||
print " 🤖 AI-powered insights and predictions"
|
||||
print " 📊 Interactive charts and tables"
|
||||
print ""
|
||||
}
|
||||
|
||||
# Check API server status
|
||||
def check_api_server_status []: nothing -> bool {
|
||||
try {
|
||||
http get "http://localhost:3000/health" | get status == "healthy"
|
||||
} catch {
|
||||
false
|
||||
}
|
||||
}
|
||||
|
||||
# Start API server in background
|
||||
def start_api_server [--port: int = 3000, --background = false]: nothing -> nothing {
|
||||
if $background {
|
||||
nu -c "use ../api/server.nu *; start_api_server --port $port" &
|
||||
} else {
|
||||
use ../api/server.nu *
|
||||
start_api_server --port $port
|
||||
}
|
||||
}
|
||||
|
||||
# Show dashboard system status
|
||||
def show_dashboard_status []: nothing -> nothing {
|
||||
print "📊 Dashboard System Status"
|
||||
print ""
|
||||
|
||||
# Check Marimo installation
|
||||
let marimo_available = check_marimo_available
|
||||
let marimo_status = if $marimo_available { "✅ Installed" } else { "❌ Not installed" }
|
||||
print $"Marimo: ($marimo_status)"
|
||||
|
||||
# Check API server
|
||||
let api_status = check_api_server_status
|
||||
let api_display = if $api_status { "✅ Running" } else { "❌ Stopped" }
|
||||
print $"API Server: ($api_display)"
|
||||
|
||||
# List dashboards
|
||||
let dashboards = list_dashboards
|
||||
print $"Dashboards: ($dashboards | length) available"
|
||||
|
||||
if ($dashboards | length) > 0 {
|
||||
print ""
|
||||
print "Available dashboards:"
|
||||
$dashboards | select name modified | table
|
||||
}
|
||||
|
||||
# System resources
|
||||
print ""
|
||||
print "System Resources:"
|
||||
let mem_info = (sys mem)
|
||||
print $"Memory: ($mem_info.used | into string) / ($mem_info.total | into string) used"
|
||||
|
||||
print ""
|
||||
print "Quick start:"
|
||||
if not $marimo_available {
|
||||
print "1. Install Marimo: provisioning dashboard create install"
|
||||
}
|
||||
if not $api_status {
|
||||
print "2. Start API: provisioning api start"
|
||||
}
|
||||
print "3. Create dashboard: provisioning dashboard demo"
|
||||
}
|
||||
79
core/nulib/main_provisioning/delete.nu
Normal file
79
core/nulib/main_provisioning/delete.nu
Normal file
|
|
@ -0,0 +1,79 @@
|
|||
|
||||
def prompt_delete [
|
||||
target: string
|
||||
target_name: string
|
||||
yes: bool
|
||||
name?: string
|
||||
]: nothing -> string {
|
||||
match $name {
|
||||
"h" | "help" => {
|
||||
^($env.PROVISIONING_NAME) "-mod" $target "--help"
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
if not $yes or not (($env.PROVISIONING_ARGS? | default "") | str contains "--yes") {
|
||||
_print ( $"To (_ansi red_bold)delete ($target_name) (_ansi reset) " +
|
||||
$" (_ansi green_bold)($name)(_ansi reset) type (_ansi green_bold)yes(_ansi reset) ? "
|
||||
)
|
||||
let user_input = (input --numchar 3)
|
||||
if $user_input != "yes" and $user_input != "YES" {
|
||||
exit 1
|
||||
}
|
||||
$name
|
||||
} else {
|
||||
$env.PROVISIONING_ARGS = ($env.PROVISIONING_ARGS? | find -v "yes")
|
||||
($name | default "" | str replace "yes" "")
|
||||
}
|
||||
}
|
||||
|
||||
# -> Delete infrastructure and services
|
||||
export def "main delete" [
|
||||
target?: string # server (s) | task (t) | service (sv)
|
||||
name?: string # target name in settings
|
||||
...args # Args for create command
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--keepstorage # Keep storage
|
||||
--yes (-y) # confirm delete
|
||||
--wait (-w) # Wait servers to be created
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--outfile (-o): string # Output file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
parse_help_command "delete" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
let use_debug = if $debug or $env.PROVISIONING_DEBUG { "-x" } else { "" }
|
||||
match $target {
|
||||
"server"| "servers" | "s" => {
|
||||
prompt_delete "server" "servers" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" ($env.PROVISIONING_ARGS | str replace $target '') --yes --notitles
|
||||
},
|
||||
"storage" => {
|
||||
prompt_delete "server" "storage" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" $env.PROVISIONING_ARGS --yes --notitles
|
||||
},
|
||||
"taskserv" | "taskservs" | "t" => {
|
||||
prompt_delete "taskserv" "tasks/services" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "tasksrv" ($env.PROVISIONING_ARGS | str replace $target '') --yes --notitles
|
||||
},
|
||||
"clusters"| "clusters" | "cl" => {
|
||||
prompt_delete "cluster" "cluster" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "cluster" ($env.PROVISIONING_ARGS | str replace $target '') --yes --notitles
|
||||
},
|
||||
_ => {
|
||||
invalid_task "delete" ($target | default "") --end
|
||||
exit
|
||||
},
|
||||
}
|
||||
}
|
||||
94
core/nulib/main_provisioning/extensions.nu
Normal file
94
core/nulib/main_provisioning/extensions.nu
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
# Extensions Management Commands
|
||||
|
||||
use ../lib_provisioning/extensions *
|
||||
|
||||
# List available extensions
|
||||
export def "main extensions list" [
|
||||
--type: string = "" # Filter by type: provider, taskserv, or all
|
||||
--helpinfo (-h) # Show help
|
||||
]: nothing -> nothing {
|
||||
if $helpinfo {
|
||||
print "List available extensions"
|
||||
return
|
||||
}
|
||||
|
||||
match $type {
|
||||
"provider" => {
|
||||
print "Available Provider Extensions:"
|
||||
list-providers
|
||||
}
|
||||
"taskserv" => {
|
||||
print "Available TaskServ Extensions:"
|
||||
list-taskservs
|
||||
}
|
||||
_ => {
|
||||
print "Available Extensions:"
|
||||
print "\nProviders:"
|
||||
list-providers
|
||||
|
||||
print "\nTaskServs:"
|
||||
list-taskservs
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Show extension details
|
||||
export def "main extensions show" [
|
||||
name: string # Extension name
|
||||
--helpinfo (-h) # Show help
|
||||
]: nothing -> nothing {
|
||||
if $helpinfo {
|
||||
print "Show details for a specific extension"
|
||||
return
|
||||
}
|
||||
|
||||
let provider = (get-provider $name)
|
||||
let taskserv = (get-taskserv $name)
|
||||
|
||||
if ($provider | is-not-empty) {
|
||||
print $"Provider Extension: ($name)"
|
||||
$provider
|
||||
} else if ($taskserv | is-not-empty) {
|
||||
print $"TaskServ Extension: ($name)"
|
||||
$taskserv
|
||||
} else {
|
||||
print $"Extension '($name)' not found"
|
||||
}
|
||||
}
|
||||
|
||||
# Initialize extensions
|
||||
export def "main extensions init" [
|
||||
--helpinfo (-h) # Show help
|
||||
]: nothing -> nothing {
|
||||
if $helpinfo {
|
||||
print "Initialize extension registry"
|
||||
return
|
||||
}
|
||||
|
||||
init-registry
|
||||
print "Extension registry initialized"
|
||||
}
|
||||
|
||||
# Show current profile
|
||||
export def "main profile show" [
|
||||
--helpinfo (-h) # Show help
|
||||
]: nothing -> nothing {
|
||||
if $helpinfo {
|
||||
print "Show current access profile"
|
||||
return
|
||||
}
|
||||
|
||||
show-profile | table
|
||||
}
|
||||
|
||||
# Create example profiles
|
||||
export def "main profile create-examples" [
|
||||
--helpinfo (-h) # Show help
|
||||
]: nothing -> nothing {
|
||||
if $helpinfo {
|
||||
print "Create example profile files"
|
||||
return
|
||||
}
|
||||
|
||||
create-example-profiles
|
||||
}
|
||||
209
core/nulib/main_provisioning/generate.nu
Normal file
209
core/nulib/main_provisioning/generate.nu
Normal file
|
|
@ -0,0 +1,209 @@
|
|||
|
||||
#use utils *
|
||||
#use defs *
|
||||
use lib_provisioning *
|
||||
|
||||
# - > Query infrastructure and services
|
||||
export def "main generate" [
|
||||
#hostname?: string # Server hostname in settings
|
||||
...args # Args for create command
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--check (-c) # Only check mode no servers will be created
|
||||
--wait (-w) # Wait servers to be created
|
||||
--outfile: string # Optional output format: json | yaml | csv | text | md | nuon
|
||||
--find (-f): string # Optional generate find a value (empty if no value found)
|
||||
--cols (-l): string # Optional generate columns list separated with comma
|
||||
--template(-t): string # Template path or name in PROVISION_KLOUDS_PATH
|
||||
--ips # Optional generate get IPS only for target "servers-info"
|
||||
--prov: string # Optional provider name to filter generate
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
if $helpinfo {
|
||||
_print (provisioning_generate_options)
|
||||
if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
}
|
||||
parse_help_command "generate" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
#use defs [ load_settings ]
|
||||
let curr_settings = if $infra != null {
|
||||
if $settings != null {
|
||||
(load_settings --infra $infra --settings $settings)
|
||||
} else {
|
||||
(load_settings --infra $infra)
|
||||
}
|
||||
} else {
|
||||
if $settings != null {
|
||||
(load_settings --settings $settings)
|
||||
} else {
|
||||
(load_settings false true)
|
||||
}
|
||||
}
|
||||
#let cmd_template = if ($template | is-empty ) {
|
||||
# ($args | get -o 0 | default "")
|
||||
#} else { $template }
|
||||
#let str_out = if $outfile == null { "none" } else { $outfile }
|
||||
let str_out = if $out == null { "" } else { $out }
|
||||
let str_cols = if $cols == null { "" } else { $cols }
|
||||
let str_find = if $find == null { "" } else { $find }
|
||||
let str_template = if $template == null { "" } else { $template }
|
||||
let cmd_target = if ($args | length) > 0 { ($args| get 0) } else { "" }
|
||||
$env.PROVISIONING_MODULE = "generate"
|
||||
let ops = $"($env.PROVISIONING_ARGS? | default "") " | str replace $env.PROVISIONING_MODULE "" | str replace $" ($cmd_target) " "" | str trim
|
||||
#generate_provision $args $curr_settings $str_template
|
||||
match $cmd_target {
|
||||
"new" | "n" => {
|
||||
let args_list = if ($args | length) > 0 {
|
||||
($args| skip 1)
|
||||
} else { [] }
|
||||
generate_provision $args_list $curr_settings $str_template
|
||||
},
|
||||
"server" | "servers" => {
|
||||
#use utils/format.nu datalist_to_format
|
||||
_print (datalist_to_format $str_out
|
||||
(mw_generate_servers $curr_settings $str_find $cols --prov $prov --serverpos $serverpos)
|
||||
)
|
||||
},
|
||||
"server-status" | "servers-status" | "server-info" | "servers-info" => {
|
||||
let list_cols = if ($cmd_target | str contains "status") {
|
||||
if ($str_cols | str contains "state") { $str_cols } else { $str_cols + ",state" }
|
||||
} else {
|
||||
$str_cols
|
||||
}
|
||||
# not use $str_cols to filter previous $ips selection
|
||||
(out_data_generate_info
|
||||
$curr_settings
|
||||
(mw_servers_info $curr_settings $str_find --prov $prov --serverpos $serverpos)
|
||||
#(mw_servers_info $curr_settings $find $cols --prov $prov --serverpos $serverpos)
|
||||
$list_cols
|
||||
$str_out
|
||||
$ips
|
||||
)
|
||||
},
|
||||
"servers-def" | "server-def" => {
|
||||
let data = if $str_find != "" { ($curr_settings.data.servers | find $find) } else { $curr_settings.data.servers}
|
||||
(out_data_generate_info
|
||||
$curr_settings
|
||||
$data
|
||||
$str_cols
|
||||
$str_out
|
||||
false
|
||||
)
|
||||
},
|
||||
"def" | "defs" => {
|
||||
let data = if $str_find != "" { ($curr_settings.data | find $find) } else { $curr_settings.data}
|
||||
(out_data_generate_info
|
||||
$curr_settings
|
||||
[ $data ]
|
||||
$str_cols
|
||||
$str_out
|
||||
false
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
(throw-error $"🛑 ($env.PROVISIONING_NAME) generate " $"Invalid option (_ansi red)($cmd_target)(_ansi reset)"
|
||||
$"($env.PROVISIONING_NAME) generate --target ($cmd_target)" --span (metadata $cmd_target).span
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup ($curr_settings | get -o wk_path | default "")
|
||||
if $outfile == null { end_run "generate" }
|
||||
}
|
||||
|
||||
export def generate_new_infra [
|
||||
args: list
|
||||
template: string
|
||||
]: nothing -> record {
|
||||
let infra_path = ($args | get -o 0 | default "")
|
||||
let infra_name = ($infra_path | path basename)
|
||||
let target_path = if ($infra_path | str contains "/") {
|
||||
$infra_path
|
||||
} else if ($env.PROVISIONING_INFRA_PATH | path exists) and not ($env.PROVISIONING_INFRA_PATH | path join $infra_path | path exists) {
|
||||
($env.PROVISIONING_INFRA_PATH | path join $infra_path)
|
||||
} else {
|
||||
$infra_path
|
||||
}
|
||||
if ($target_path | path exists) {
|
||||
_print $"🛑 Path (_ansi yellow_bold)($target_path)(_ansi reset) already exits"
|
||||
return
|
||||
}
|
||||
^mkdir -p $target_path
|
||||
_print $"(_ansi green)($infra_name)(_ansi reset) created in (_ansi green)($target_path | path dirname)(_ansi reset)"
|
||||
_print $"(_ansi green)($infra_name)(_ansi reset) ... "
|
||||
let template_path = if ($template | is-empty) {
|
||||
($env.PROVISIONING | path join $env.PROVISIONING_GENERATE_DIRPATH | path join "default")
|
||||
} else if ($template | str contains "/") and ($template | path exists) {
|
||||
$template
|
||||
} else if ($env.PROVISIONING_INFRA_PATH | path join $template | path exists) {
|
||||
($env.PROVISIONING_INFRA_PATH | path join $template)
|
||||
}
|
||||
let new_created = if not ($target_path | path join "settings.k" | path exists) {
|
||||
^cp -pr ...(glob ($template_path | path join "*")) ($target_path)
|
||||
_print $"copy (_ansi green)($template)(_ansi reset) to (_ansi green)($infra_name)(_ansi reset)"
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
{ path: $target_path, name: $infra_name, created: $new_created }
|
||||
}
|
||||
export def generate_provision [
|
||||
args: list
|
||||
settings: record
|
||||
template: string
|
||||
]: nothing -> nothing {
|
||||
let generated_infra = if ($settings | is-empty) {
|
||||
if ($args | is-empty) {
|
||||
(throw-error $"🛑 ($env.PROVISIONING_NAME) generate " $"Invalid option (_ansi red)no settings and path found(_ansi reset)"
|
||||
$"($env.PROVISIONING_NAME) generate " --span (metadata $settings).span
|
||||
)
|
||||
} else {
|
||||
generate_new_infra $args $template
|
||||
}
|
||||
}
|
||||
if ($generated_infra | is-empty) {
|
||||
(throw-error $"🛑 ($env.PROVISIONING_NAME) generate " $"Invalid option (_ansi red)no settings and path found(_ansi reset)"
|
||||
$"($env.PROVISIONING_NAME) generate " --span (metadata $settings).span
|
||||
)
|
||||
}
|
||||
generate_data_def $env.PROVISIONING $generated_infra.name $generated_infra.path $generated_infra.created
|
||||
}
|
||||
def out_data_generate_info [
|
||||
settings: record
|
||||
data: list
|
||||
cols: string
|
||||
outfile: string
|
||||
ips: bool
|
||||
]: nothing -> nothing {
|
||||
if ($data | get -o 0 | is-empty) {
|
||||
if $env.PROVISIONING_DEBUG { print $"🛑 ($env.PROVISIONING_NAME) generate (_ansi red)no data found(_ansi reset)" }
|
||||
_print ""
|
||||
return
|
||||
}
|
||||
let sel_data = if ($cols | is-not-empty) {
|
||||
$data | select -o ($cols | split row ",")
|
||||
} else {
|
||||
$data
|
||||
}
|
||||
#use ../../../providers/prov_lib/middleware.nu mw_servers_ips
|
||||
#use utils/format.nu datalist_to_format
|
||||
print (datalist_to_format $outfile $sel_data)
|
||||
# let data_ips = (($data).ip_addresses? | flatten | find "public")
|
||||
if $ips {
|
||||
let ips_result = (mw_servers_ips $settings $data)
|
||||
print $ips_result
|
||||
}
|
||||
}
|
||||
24
core/nulib/main_provisioning/mod.nu
Normal file
24
core/nulib/main_provisioning/mod.nu
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
export use ops.nu *
|
||||
|
||||
export use query.nu *
|
||||
|
||||
export use create.nu *
|
||||
export use delete.nu *
|
||||
export use status.nu *
|
||||
export use update.nu *
|
||||
export use generate.nu *
|
||||
|
||||
export use tools.nu *
|
||||
export use sops.nu *
|
||||
export use secrets.nu *
|
||||
export use ai.nu *
|
||||
export use contexts.nu *
|
||||
export use extensions.nu *
|
||||
#export use main.nu *
|
||||
|
||||
# export use server.nu *
|
||||
#export use task.nu *
|
||||
|
||||
#export use server/server_delete.nu *
|
||||
|
||||
#export module instances.nu
|
||||
207
core/nulib/main_provisioning/ops.nu
Normal file
207
core/nulib/main_provisioning/ops.nu
Normal file
|
|
@ -0,0 +1,207 @@
|
|||
|
||||
export def provisioning_options [
|
||||
]: nothing -> string {
|
||||
let target_items = $"(_ansi blue)server(_ansi reset) | (_ansi yellow)tasks(_ansi reset) | (_ansi purple)cluster(_ansi reset)"
|
||||
(
|
||||
$"(_ansi green_bold)Options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) sed - to edit content from a SOPS file \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) ssh - to config and get SSH settings for servers\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) list [items] - to list items: " +
|
||||
$"[ (_ansi green)providers(_ansi reset) p | (_ansi green)tasks(_ansi reset) t | (_ansi green)nfra(_ansi reset) k ]\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) nu - to run a nushell in ($env.PROVISIONING) path\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) qr - to get ($env.PROVISIONING_URL) QR code\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) context - to change (_ansi blue)context(_ansi reset) settings. " +
|
||||
$"(_ansi default_dimmed)use context -h for help(_ansi reset)\n" +
|
||||
$"\n(_ansi green_bold)Targets(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) generate - to generate (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) use one option: (_ansi green)provision(_ansi reset) " +
|
||||
$"| ($target_items)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) create - to create use one option: ($target_items)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) delete - to delete use one option: ($target_items)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) cst - to create (_ansi blue)Servers(_ansi reset) and (_ansi yellow)Tasks(_ansi reset). " +
|
||||
$"Alias from (_ansi blue_bold)create-servers-tasks(_ansi reset)\n" +
|
||||
$"\n(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) deploy-sel - to sel (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) " +
|
||||
$"(_ansi cyan_bold)deployments info(_ansi reset) --onsel [ (_ansi yellow_bold)e(_ansi reset)dit | " +
|
||||
$"(_ansi yellow_bold)v(_ansi reset)iew | (_ansi yellow_bold)l(_ansi reset)ist | (_ansi yellow_bold)t(_ansi reset)ree " +
|
||||
$"(_ansi yellow_bold)c(_ansi reset)ode | (_ansi yellow_bold)s(_ansi reset)hell | (_ansi yellow_bold)n(_ansi reset)u ]\n" +
|
||||
$"\n(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) deploy-rm - to remove (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) " +
|
||||
$"(_ansi cyan_bold)deployments infos(_ansi reset)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) destroy - to remove (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) " +
|
||||
$"(_ansi cyan_bold)deployments infos(_ansi reset) and (_ansi green_bold)servers(_ansi reset) with confirmation or add '--yes'\n" +
|
||||
$"\n(_ansi green_bold)Targets(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) server - On Servers or instances \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) taskserv - On Task Services for servers: settings, services\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) cluster - On Cluster for provisioning\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) infra - On Infrastructures for provisioning\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) validate - Infrastructure validation and review tool\n" +
|
||||
$"\n(_ansi green_bold)Others(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) show - To show (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) settings and data \n" +
|
||||
$"(_ansi default_dimmed)Options:(_ansi reset) (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) show [ settings | defsettings | servers | serverdefs | costs | alldata | data ] \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) new - To create a new (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) Infrastructure \n" +
|
||||
$"\n(_ansi default_dimmed)To get help on Targets use:(_ansi reset) (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) [target-name] help\n" +
|
||||
$"\n(_ansi default_dimmed)NOTICE: Most of Options and Targets have a shortcut by using a single dash and a letter(_ansi reset)\n" +
|
||||
$"(_ansi default_dimmed)example(_ansi reset) -h (_ansi default_dimmed)for(_ansi reset)" +
|
||||
$" --helpinfo (_ansi default_dimmed)or(_ansi reset) help" +
|
||||
$" (_ansi default_dimmed)even it can simply be used as(_ansi reset) h \n"
|
||||
)
|
||||
}
|
||||
export def provisioning_context_options [
|
||||
]: nothing -> string {
|
||||
(
|
||||
$"(_ansi green_bold)Context options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) install - to install (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)context(_ansi reset) \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) view - to view (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)context(_ansi reset)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) default [name] - to set default as [name] \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) remove [name] - to remove [name] from (_ansi yellow)context(_ansi reset)\n" +
|
||||
$"\n(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) set [name] -k [key] -v [value] - to set (_ansi green)[key] = [value](_ansi reset) in [name] (_ansi yellow)context(_ansi reset)"
|
||||
)
|
||||
}
|
||||
export def provisioning_setup_options [
|
||||
]: nothing -> string {
|
||||
(
|
||||
$"(_ansi green_bold)Setup options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) providers - to view (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)context(_ansi reset) use 'check' or 'help'\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) tools - to install (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools(_ansi reset) use 'check' or 'help'\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) versions - to generate (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools versions file (_ansi reset)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) midddleware - to generate (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)providers middleware library(_ansi reset)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) context - to create (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)context file(_ansi reset)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) defaults - to create (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)defaults file(_ansi reset)"
|
||||
)
|
||||
}
|
||||
export def provisioning_infra_options [
|
||||
]: nothing -> string {
|
||||
(
|
||||
$"(_ansi green_bold)Cloud options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) view - to view (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)context(_ansi reset)"
|
||||
)
|
||||
}
|
||||
export def provisioning_tools_options [
|
||||
]: nothing -> string {
|
||||
(
|
||||
$"(_ansi green_bold)Tools options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) - to check (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools(_ansi reset) and versions\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) check - to check (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools(_ansi reset) and versions\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) install - to install(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools(_ansi reset)\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) show - to show (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools(_ansi reset) info \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) show providers - to show (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)providers (_ansi reset) info \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) show all - to show (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)tools and providers (_ansi reset) info \n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) info - alias (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi cyan)tools show(_ansi reset) \n" +
|
||||
$"\n(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) (_ansi cyan)[install | check | show](_ansi reset) commmands support to add specifict (_ansi green)'tool-name'(_ansi reset) at the end, " +
|
||||
$"\n(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) (_ansi cyan)show or info(_ansi reset) commmands support to add specifict (_ansi green)'provider-name'(_ansi reset) at the end, " +
|
||||
$"by default uses (_ansi green)'all'(_ansi reset)" +
|
||||
$"\n(_ansi blue)($env.PROVISIONING_NAME) tools(_ansi reset) (_ansi green)'tool-name'(_ansi reset) to check tool installation and version"
|
||||
)
|
||||
}
|
||||
export def provisioning_generate_options [
|
||||
]: nothing -> string {
|
||||
(
|
||||
$"(_ansi green_bold)Generate options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)generate new [name-or-path](_ansi reset) - to create a new (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)directory(_ansi reset)" +
|
||||
$"\nif '[name-or-path]' is not relative or full path it will be created in (_ansi blue)($env.PROVISIONING_INFRA_PATH | default "")(_ansi reset) " +
|
||||
$"\nadd (_ansi blue)--template [name](_ansi reset) to (_ansi cyan)copy(_ansi reset) from existing (_ansi green)template 'name'(_ansi reset) " +
|
||||
$"\ndefault (_ansi blue)template(_ansi reset) to use (_ansi cyan)($env.PROVISIONING | path join $env.PROVISIONING_GENERATE_DIRPATH | path join "default")(_ansi reset)"
|
||||
)
|
||||
}
|
||||
export def provisioning_show_options [
|
||||
]: nothing -> string {
|
||||
(
|
||||
$"(_ansi green_bold)Show options(_ansi reset):\n" +
|
||||
$"(_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) (_ansi yellow)show [options](_ansi reset) - To show (_ansi blue)($env.PROVISIONING_NAME)(_ansi reset) settings and data (_ansi yellow)(_ansi reset)" +
|
||||
$"\n(_ansi blue)settings (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green)settings(_ansi reset) " +
|
||||
$"\n(_ansi blue)defsettings (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green)def settings content (_ansi reset) " +
|
||||
$"\n(_ansi blue)servers (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green)servers(_ansi reset) " +
|
||||
$"\n(_ansi blue)defservers (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green)def servers content (_ansi reset) " +
|
||||
$"\n(_ansi blue)costs (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green) prices or costs (_ansi reset) " +
|
||||
$"\n(_ansi blue)alldata (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green) all data settings and prices or costs (_ansi reset) " +
|
||||
$"\n(_ansi blue)data (_ansi reset) to (_ansi cyan)get(_ansi reset) (_ansi green) data settings (_ansi reset) " +
|
||||
$"\nby adding (_ansi blue)--out(_ansi reset) (_ansi cyan)[ json | yaml | toml ](_ansi reset) it can be used ad a kind of API source" +
|
||||
$"\nby adding (_ansi blue)--view(_ansi reset) with (_ansi blue)--out(_ansi reset) option, content is formated with highlight"
|
||||
)
|
||||
}
|
||||
|
||||
export def provisioning_validate_options [
|
||||
]: nothing -> string {
|
||||
print "Infrastructure Validation & Review Tool"
|
||||
print "========================================"
|
||||
print ""
|
||||
print "Validates KCL/YAML configurations, checks best practices, and generates reports"
|
||||
print ""
|
||||
|
||||
print "USAGE:"
|
||||
print $" ($env.PROVISIONING_NAME) validate [SUBCOMMAND] [INFRA_PATH] [OPTIONS]"
|
||||
print ""
|
||||
|
||||
print "SUBCOMMANDS:"
|
||||
print " (none) Full validation with customizable options"
|
||||
print " quick Quick validation focusing on errors and critical issues"
|
||||
print " ci CI/CD optimized validation with structured output"
|
||||
print " full Comprehensive validation including info-level checks"
|
||||
print " agent Agent/automation interface with JSON output"
|
||||
print " rules List all available validation rules"
|
||||
print " test Run validation system self-tests"
|
||||
print " help Show detailed help information"
|
||||
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 (show all details)"
|
||||
print " -h, --help Show detailed 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 "VALIDATION RULES:"
|
||||
print " VAL001 YAML Syntax Validation (critical)"
|
||||
print " VAL002 KCL Compilation Check (critical)"
|
||||
print " VAL003 Unquoted Variable References (error, auto-fixable)"
|
||||
print " VAL004 Required Fields Validation (error)"
|
||||
print " VAL005 Resource Naming Conventions (warning, auto-fixable)"
|
||||
print " VAL006 Basic Security Checks (error)"
|
||||
print " VAL007 Version Compatibility Check (warning)"
|
||||
print " VAL008 Network Configuration Validation (error)"
|
||||
print ""
|
||||
print "Legend: Auto-fixable rules can be automatically corrected with --fix"
|
||||
print ""
|
||||
|
||||
print "EXAMPLES:"
|
||||
print ""
|
||||
print " # Validate current directory"
|
||||
print $" ($env.PROVISIONING_NAME) validate"
|
||||
print ""
|
||||
print " # Quick validation with auto-fix"
|
||||
print $" ($env.PROVISIONING_NAME) validate quick klab/sgoyol --fix"
|
||||
print ""
|
||||
print " # CI/CD validation"
|
||||
print $" ($env.PROVISIONING_NAME) validate ci klab/sgoyol --report yaml"
|
||||
print ""
|
||||
print " # Dry run to see what would be fixed"
|
||||
print $" ($env.PROVISIONING_NAME) validate klab/sgoyol --fix --dry-run"
|
||||
print ""
|
||||
print " # Generate all report formats"
|
||||
print $" ($env.PROVISIONING_NAME) validate klab/sgoyol --report all --output ./reports"
|
||||
print ""
|
||||
print " # List available rules"
|
||||
print $" ($env.PROVISIONING_NAME) validate rules"
|
||||
print ""
|
||||
print " # Test the validation system"
|
||||
print $" ($env.PROVISIONING_NAME) validate test"
|
||||
print ""
|
||||
|
||||
""
|
||||
}
|
||||
171
core/nulib/main_provisioning/query.nu
Normal file
171
core/nulib/main_provisioning/query.nu
Normal file
|
|
@ -0,0 +1,171 @@
|
|||
|
||||
#use utils *
|
||||
#use defs *
|
||||
use lib_provisioning *
|
||||
|
||||
# - > Query infrastructure and services
|
||||
export def "main query" [
|
||||
#hostname?: string # Server hostname in settings
|
||||
...args # Args for create command
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--check (-c) # Only check mode no servers will be created
|
||||
--wait (-w) # Wait servers to be created
|
||||
--outfile: string # Optional output format: json | yaml | csv | text | md | nuon
|
||||
--find (-f): string # Optional query find a value (empty if no value found)
|
||||
--cols (-l): string # Optional query columns list separated with comma
|
||||
--target(-t): string # Target element for query: servers-status | servers | servers-info | servers-def | defs
|
||||
--ips # Optional query get IPS only for target "servers-info"
|
||||
--prov: string # Optional provider name to filter query
|
||||
--ai_query: string # Natural language query using AI
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
# Handle AI query first if provided
|
||||
if ($ai_query | is-not-empty) {
|
||||
use ../lib_provisioning/ai/lib.nu *
|
||||
if (is_ai_enabled) and (get_ai_config).enable_query_ai {
|
||||
# Get current infrastructure context for AI
|
||||
let curr_settings = if $infra != null {
|
||||
if $settings != null {
|
||||
(load_settings --infra $infra --settings $settings)
|
||||
} else {
|
||||
(load_settings --infra $infra)
|
||||
}
|
||||
} else {
|
||||
if $settings != null {
|
||||
(load_settings --settings $settings)
|
||||
} else {
|
||||
(load_settings)
|
||||
}
|
||||
}
|
||||
|
||||
let context = {
|
||||
infra: ($infra | default "")
|
||||
provider: ($prov | default "")
|
||||
available_targets: ["servers", "servers-status", "servers-info", "servers-def", "defs"]
|
||||
output_format: ($out | default "text")
|
||||
}
|
||||
|
||||
let ai_response = (ai_process_query $ai_query $context)
|
||||
print $ai_response
|
||||
return
|
||||
} else {
|
||||
print "AI query processing is disabled or not configured"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
parse_help_command "query" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
#use defs [ load_settings ]
|
||||
let curr_settings = if $infra != null {
|
||||
if $settings != null {
|
||||
(load_settings --infra $infra --settings $settings)
|
||||
} else {
|
||||
(load_settings --infra $infra)
|
||||
}
|
||||
} else {
|
||||
if $settings != null {
|
||||
(load_settings --settings $settings)
|
||||
} else {
|
||||
(load_settings)
|
||||
}
|
||||
}
|
||||
let cmd_target = if ($target | is-empty ) {
|
||||
($args | get -o 0 | default "")
|
||||
} else { $target }
|
||||
#let str_out = if $outfile == null { "none" } else { $outfile }
|
||||
let str_out = if $out == null { "" } else { $out }
|
||||
let str_cols = if $cols == null { "" } else { $cols }
|
||||
let str_find = if $find == null { "" } else { $find }
|
||||
#use lib_provisioning *
|
||||
match $cmd_target {
|
||||
"server" | "servers" => {
|
||||
#use utils/format.nu datalist_to_format
|
||||
_print (datalist_to_format $str_out
|
||||
(mw_query_servers $curr_settings $str_find $cols --prov $prov --serverpos $serverpos)
|
||||
)
|
||||
},
|
||||
"server-status" | "servers-status" | "server-info" | "servers-info" => {
|
||||
let list_cols = if ($cmd_target | str contains "status") {
|
||||
if ($str_cols | str contains "state") { $str_cols } else { $str_cols + ",state" }
|
||||
} else {
|
||||
$str_cols
|
||||
}
|
||||
# not use $str_cols to filter previous $ips selection
|
||||
(out_data_query_info
|
||||
$curr_settings
|
||||
(mw_servers_info $curr_settings $str_find --prov $prov --serverpos $serverpos)
|
||||
#(mw_servers_info $curr_settings $find $cols --prov $prov --serverpos $serverpos)
|
||||
$list_cols
|
||||
$str_out
|
||||
$ips
|
||||
)
|
||||
},
|
||||
"servers-def" | "server-def" => {
|
||||
let data = if $str_find != "" { ($curr_settings.data.servers | find $find) } else { $curr_settings.data.servers}
|
||||
(out_data_query_info
|
||||
$curr_settings
|
||||
$data
|
||||
$str_cols
|
||||
$str_out
|
||||
false
|
||||
)
|
||||
},
|
||||
"def" | "defs" => {
|
||||
let data = if $str_find != "" { ($curr_settings.data | find $find) } else { $curr_settings.data}
|
||||
(out_data_query_info
|
||||
$curr_settings
|
||||
[ $data ]
|
||||
$str_cols
|
||||
$str_out
|
||||
false
|
||||
)
|
||||
}
|
||||
_ => {
|
||||
(throw-error $"🛑 ($env.PROVISIONING_NAME) query " $"Invalid option (_ansi red)($cmd_target)(_ansi reset)"
|
||||
$"($env.PROVISIONING_NAME) query --target ($cmd_target)" --span (metadata $cmd_target).span
|
||||
)
|
||||
}
|
||||
}
|
||||
cleanup $curr_settings.wk_path
|
||||
if $outfile == null { end_run "query" }
|
||||
}
|
||||
def out_data_query_info [
|
||||
settings: record
|
||||
data: list
|
||||
cols: string
|
||||
outfile: string
|
||||
ips: bool
|
||||
]: nothing -> nothing {
|
||||
if ($data | get -o 0 | is-empty) {
|
||||
if $env.PROVISIONING_DEBUG { print $"🛑 ($env.PROVISIONING_NAME) query (_ansi red)no data found(_ansi reset)" }
|
||||
_print ""
|
||||
return
|
||||
}
|
||||
let sel_data = if ($cols | is-not-empty) {
|
||||
$data | select -o ($cols | split row ",")
|
||||
} else {
|
||||
$data
|
||||
}
|
||||
#use (prov-middleware) mw_servers_ips
|
||||
#use utils/format.nu datalist_to_format
|
||||
print (datalist_to_format $outfile $sel_data)
|
||||
# let data_ips = (($data).ip_addresses? | flatten | find "public")
|
||||
if $ips {
|
||||
let ips_result = (mw_servers_ips $settings $data)
|
||||
print $ips_result
|
||||
}
|
||||
}
|
||||
82
core/nulib/main_provisioning/secrets.nu
Normal file
82
core/nulib/main_provisioning/secrets.nu
Normal file
|
|
@ -0,0 +1,82 @@
|
|||
# Import will be handled by parent context
|
||||
|
||||
# - > Secrets management with infrastructure and services (SOPS or KMS)
|
||||
export def "main secrets" [
|
||||
sourcefile?: string # source file for secrets command
|
||||
targetfile?: string # target file for secrets command
|
||||
--provider (-p): string # secret provider: sops or kms
|
||||
--encrypt (-e) # Encrypt file
|
||||
--decrypt (-d) # Decrypt file
|
||||
--gen (-g) # Generate encrypted files
|
||||
--sed # Edit encrypted file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debug for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
|
||||
# Set secret provider if specified
|
||||
if ($provider | is-not-empty) {
|
||||
$env.PROVISIONING_SECRET_PROVIDER = $provider
|
||||
}
|
||||
|
||||
parse_help_command "secrets" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
|
||||
if $sourcefile == "sed" or $sourcefile == "ed" {
|
||||
on_secrets "sed" $targetfile
|
||||
end_run "secrets"
|
||||
return true
|
||||
}
|
||||
|
||||
if $sed and $sourcefile != null and ($sourcefile | path exists) {
|
||||
on_secrets sed $sourcefile
|
||||
exit
|
||||
}
|
||||
|
||||
if $encrypt {
|
||||
if $sourcefile == null or not ($sourcefile | path exists) {
|
||||
print $"🛑 Error on_secrets encrypt 'sourcefile' ($sourcefile) not found "
|
||||
exit 1
|
||||
}
|
||||
if ($targetfile | is-not-empty) {
|
||||
print $"on_secrets encrypt ($sourcefile) ($targetfile)"
|
||||
on_secrets "encrypt" $sourcefile $targetfile
|
||||
exit
|
||||
} else {
|
||||
print $"on_secrets encrypt ($sourcefile) "
|
||||
print (on_secrets "encrypt" $sourcefile)
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
if $decrypt {
|
||||
if $sourcefile == null or not ($sourcefile | path exists) {
|
||||
print $"🛑 Error on_secrets decrypt 'sourcefile' ($sourcefile) not found "
|
||||
return false
|
||||
}
|
||||
if ($targetfile | is-not-empty) {
|
||||
on_secrets decrypt $sourcefile $targetfile
|
||||
exit
|
||||
} else {
|
||||
print (on_secrets decrypt $sourcefile)
|
||||
exit
|
||||
}
|
||||
}
|
||||
|
||||
if $gen and $sourcefile != null {
|
||||
on_secrets generate $sourcefile $targetfile
|
||||
exit
|
||||
}
|
||||
|
||||
option_undefined "secrets" ""
|
||||
end_run "secrets"
|
||||
}
|
||||
70
core/nulib/main_provisioning/sops.nu
Normal file
70
core/nulib/main_provisioning/sops.nu
Normal file
|
|
@ -0,0 +1,70 @@
|
|||
#use sops/lib.nu on_sops
|
||||
|
||||
# - > SOPS with infrastructure and services
|
||||
export def "main sops" [
|
||||
sourcefile?: string # source file for sops command
|
||||
targetfile?: string # target file for sops command
|
||||
--encrypt (-e) # SOPS encrypt file
|
||||
--decrypt (-d) # SOPS decrypt file
|
||||
--gen (-g) # SOPS generate encrypted files
|
||||
--sed # Edit sops encrypted file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
parse_help_command "sops" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
if $sourcefile == "sed" or $sourcefile == "ed" {
|
||||
on_sops "sed" $targetfile
|
||||
end_run "sops"
|
||||
return true
|
||||
}
|
||||
if $sed and $sourcefile != null and ($sourcefile | path exists) {
|
||||
on_sops sed $sourcefile
|
||||
exit
|
||||
}
|
||||
if $encrypt {
|
||||
if $sourcefile == null or not ($sourcefile | path exists) {
|
||||
print $"🛑 Error on_sops encrypt 'sourcefile' ($sourcefile) not found "
|
||||
exit 1
|
||||
}
|
||||
if ($targetfile | is-not-empty) {
|
||||
print $"on_sops encrypt ($sourcefile) ($targetfile)"
|
||||
on_sops "encrypt" $sourcefile $targetfile
|
||||
exit
|
||||
} else {
|
||||
print $"on_sops encrypt ($sourcefile) "
|
||||
print (on_sops "encrypt" $sourcefile)
|
||||
exit
|
||||
}
|
||||
}
|
||||
if $decrypt {
|
||||
if $sourcefile == null or not ($sourcefile | path exists) {
|
||||
print $"🛑 Error on_sops decrypt 'sourcefile' ($sourcefile) not found "
|
||||
return false
|
||||
}
|
||||
if ($targetfile | is-not-empty) {
|
||||
on_sops decrypt $sourcefile $targetfile
|
||||
exit
|
||||
} else {
|
||||
print (on_sops decrypt $sourcefile)
|
||||
exit
|
||||
}
|
||||
}
|
||||
if $gen and $sourcefile != null {
|
||||
on_sops generate $sourcefile $targetfile
|
||||
exit
|
||||
}
|
||||
option_undefined "sops" ""
|
||||
#cleanup $settings.wk_path
|
||||
end_run "sops"
|
||||
}
|
||||
48
core/nulib/main_provisioning/status.nu
Normal file
48
core/nulib/main_provisioning/status.nu
Normal file
|
|
@ -0,0 +1,48 @@
|
|||
# -> Manage provisioning Servers or instances
|
||||
export def "main status" [
|
||||
target?: string # server (s) | taskserv (t) | cluster (c)
|
||||
name?: string # Target name in settings
|
||||
...args # Args for create command
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--check (-c) # Only check mode no servers will be created
|
||||
--wait (-w) # Wait servers to be created
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--outfile (-o): string # Output file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--out: string # Print Output format: json, yaml, text (default)
|
||||
]: nothing -> nothing {
|
||||
let str_out = if ($out | is-not-empty) {
|
||||
$env.PROVISIONING_OUT = $out
|
||||
$env.PROVISIONING_NO_TERMINAL = true
|
||||
$"--out ($out)"
|
||||
} else {
|
||||
""
|
||||
}
|
||||
parse_help_command "status" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
let use_debug = if $debug or $env.PROVISIONING_DEBUG { "-x" } else { "" }
|
||||
match ($target | default "") {
|
||||
"server"| "servers" | "s" => {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" ($env.PROVISIONING_ARGS | str replace $target '') $str_out --yes --notitles
|
||||
},
|
||||
"taskserv" | "taskservs" | "t" => {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "tasksrv" ($env.PROVISIONING_ARGS | str replace $target '') _out --yes --notitles
|
||||
},
|
||||
"clusters"| "clusters" | "c" => {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "cluster" ($env.PROVISIONING_ARGS | str replace $target '') $str_out --yes --notitles
|
||||
},
|
||||
"" => {
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" ($env.PROVISIONING_ARGS) $str_out
|
||||
},
|
||||
_ => {
|
||||
invalid_task "status" ($target | default "") --end
|
||||
},
|
||||
}
|
||||
}
|
||||
272
core/nulib/main_provisioning/tools.nu
Normal file
272
core/nulib/main_provisioning/tools.nu
Normal file
|
|
@ -0,0 +1,272 @@
|
|||
#!/usr/bin/env nu
|
||||
# Info: Script to run Provisioning
|
||||
# Author: JesusPerezLorenzo
|
||||
# Release: 1.0.4
|
||||
# Date: 30-4-2024
|
||||
|
||||
use std log
|
||||
#use lib_provisioning *
|
||||
use ../env.nu *
|
||||
use ../lib_provisioning/utils/interface.nu *
|
||||
use ../lib_provisioning/utils/init.nu *
|
||||
use ../lib_provisioning/utils/error.nu *
|
||||
use ../lib_provisioning/utils/version_manager.nu *
|
||||
use ../lib_provisioning/utils/version_formatter.nu *
|
||||
use ../lib_provisioning/utils/version_loader.nu *
|
||||
use ../lib_provisioning/utils/version_registry.nu *
|
||||
use ../lib_provisioning/utils/version_taskserv.nu *
|
||||
|
||||
# - > Tools management
|
||||
export def "main tools" [
|
||||
task?: string # tools tasks for tools command
|
||||
...args # tools options
|
||||
--update (-u) # Update tools
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--helpinfo (-h) # For more details use options "help" (no dashes)
|
||||
--out: string # Print Output format: json, yaml, text (default)
|
||||
--dry-run (-n) # Dry run mode for update operations
|
||||
--force (-f) # Force updates even if fixed
|
||||
]: nothing -> nothing {
|
||||
if ($out | is-not-empty) {
|
||||
$env.PROVISIONING_OUT = $out
|
||||
$env.PROVISIONING_NO_TERMINAL = true
|
||||
}
|
||||
if (use_titles) { show_titles }
|
||||
if $helpinfo {
|
||||
_print (provisioning_tools_options)
|
||||
# if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
}
|
||||
let tools_task = if $task == null { "" } else { $task }
|
||||
let tools_args = if ($args | length) == 0 { ["all"] } else { $args }
|
||||
let core_bin = ($env.PROVISIONING | path join "core" | path join "bin")
|
||||
match $tools_task {
|
||||
"install" => {
|
||||
let update_tools = if $update { "--update" } else { "" }
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools_install (_ansi green_bold)($tools_args | str join ' ') ($update_tools)(_ansi reset) "
|
||||
^$"($core_bin)/tools-install" ...$tools_args $update_tools
|
||||
},
|
||||
"show" | "s" | "info" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let target = ($args | get -o 0 | default "")
|
||||
let match = ($args | get -o 1 | default "")
|
||||
match $target {
|
||||
"a" | "all" => {
|
||||
(show_tools_info $target)
|
||||
(show_provs_info $match)
|
||||
},
|
||||
"p" | "prov" | "provider" | "providers" => (show_provs_info $match),
|
||||
_ => (show_tools_info $target),
|
||||
}
|
||||
},
|
||||
"" | "check" | "c" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools check (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
|
||||
# Get all results first
|
||||
let all_results = (check-versions --fetch-latest=false)
|
||||
let all_configs = (discover-configurations)
|
||||
|
||||
# Filter based on arguments
|
||||
let filtered_results = if ($args | length) == 0 {
|
||||
# No args - show all
|
||||
$all_results
|
||||
} else if ($args | length) == 1 {
|
||||
let arg = ($args | get 0)
|
||||
# Handle special cases for providers
|
||||
if $arg == "providers" {
|
||||
# Show all provider components
|
||||
$all_results | where type == "provider"
|
||||
} else {
|
||||
# Check if it's a type or component ID
|
||||
let by_type = ($all_results | where type == $arg)
|
||||
let by_id = ($all_results | where id == $arg)
|
||||
if ($by_type | length) > 0 { $by_type } else { $by_id }
|
||||
}
|
||||
} else {
|
||||
# Multiple args - "provider upcloud" format
|
||||
let type_filter = ($args | get 0)
|
||||
let category_filter = ($args | get 1)
|
||||
|
||||
if $type_filter == "provider" {
|
||||
# Filter by provider category
|
||||
let configs_by_category = ($all_configs | where type == "provider" and category == $category_filter)
|
||||
let ids_by_category = ($configs_by_category | get id)
|
||||
$all_results | where id in $ids_by_category
|
||||
} else {
|
||||
# Fallback to ID filtering
|
||||
let id_filter = $category_filter
|
||||
$all_results | where type == $type_filter and id == $id_filter
|
||||
}
|
||||
}
|
||||
|
||||
_print ($filtered_results | select id type configured status | table)
|
||||
},
|
||||
"versions" | "v" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools versions (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
|
||||
# Get all results first
|
||||
let all_results = (check-versions --fetch-latest=false)
|
||||
let all_configs = (discover-configurations)
|
||||
|
||||
# Filter based on arguments (same logic as check command)
|
||||
let filtered_results = if ($args | length) == 0 {
|
||||
# No args - show all
|
||||
$all_results
|
||||
} else if ($args | length) == 1 {
|
||||
let arg = ($args | get 0)
|
||||
# Handle special cases for providers
|
||||
if $arg == "providers" {
|
||||
# Show all provider components
|
||||
$all_results | where type == "provider"
|
||||
} else {
|
||||
# Check if it's a type or component ID
|
||||
let by_type = ($all_results | where type == $arg)
|
||||
let by_id = ($all_results | where id == $arg)
|
||||
if ($by_type | length) > 0 { $by_type } else { $by_id }
|
||||
}
|
||||
} else {
|
||||
# Multiple args - "provider upcloud" format
|
||||
let type_filter = ($args | get 0)
|
||||
let category_filter = ($args | get 1)
|
||||
|
||||
if $type_filter == "provider" {
|
||||
# Filter by provider category
|
||||
let configs_by_category = ($all_configs | where type == "provider" and category == $category_filter)
|
||||
let ids_by_category = ($configs_by_category | get id)
|
||||
$all_results | where id in $ids_by_category
|
||||
} else {
|
||||
# Fallback to ID filtering
|
||||
let id_filter = $category_filter
|
||||
$all_results | where type == $type_filter and id == $id_filter
|
||||
}
|
||||
}
|
||||
|
||||
_print ($filtered_results | select id type configured status | table)
|
||||
_print "\nNote: Run 'tools check-updates' to fetch latest versions from remote sources"
|
||||
return
|
||||
},
|
||||
"check-updates" | "cu" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools check-updates (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let types = if ($args | length) > 0 { $args } else { [] }
|
||||
check-available-updates --types=$types
|
||||
return
|
||||
},
|
||||
"apply-updates" | "au" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools apply-updates (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let types = if ($args | length) > 0 { $args } else { [] }
|
||||
apply-config-updates --types=$types --dry-run=$dry_run --force=$force
|
||||
return
|
||||
},
|
||||
"pin" => {
|
||||
let component = ($args | get -o 0)
|
||||
if ($component | is-empty) {
|
||||
_print "❌ Please specify a component ID"
|
||||
return
|
||||
}
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools pin (_ansi green_bold)($component)(_ansi reset) "
|
||||
set-fixed $component true
|
||||
return
|
||||
},
|
||||
"unpin" => {
|
||||
let component = ($args | get -o 0)
|
||||
if ($component | is-empty) {
|
||||
_print "❌ Please specify a component ID"
|
||||
return
|
||||
}
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools unpin (_ansi green_bold)($component)(_ansi reset) "
|
||||
set-fixed $component false
|
||||
return
|
||||
},
|
||||
"taskserv-versions" | "tv" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) taskserv versions (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let format = ($args | get -o 0 | default "table")
|
||||
let taskservs_path = if ($args | length) > 1 { ($args | get 1) } else { "" }
|
||||
show-version-status --taskservs-path=$taskservs_path --format=$format
|
||||
return
|
||||
},
|
||||
"taskserv-check" | "tc" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) taskserv check (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let taskservs_path = if ($args | length) > 0 { ($args | get 0) } else { "" }
|
||||
let configs = (discover-taskserv-configurations --base-path=$taskservs_path)
|
||||
_print ($configs | select id version kcl_file | table)
|
||||
return
|
||||
},
|
||||
"taskserv-update" | "tu" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) taskserv update (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let components = if ($args | length) > 0 { $args } else { [] }
|
||||
update-registry-versions --components=$components --dry-run=$dry_run
|
||||
return
|
||||
},
|
||||
"taskserv-sync" | "ts" => {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) taskserv sync (_ansi green_bold)($tools_args | str join ' ')(_ansi reset) "
|
||||
let taskservs_path = if ($args | length) > 0 { ($args | get 0) } else { "" }
|
||||
let component = if ($args | length) > 1 { ($args | get 1) } else { "" }
|
||||
taskserv-sync-versions --taskservs-path=$taskservs_path --component=$component --dry-run=$dry_run
|
||||
return
|
||||
},
|
||||
"help" | "helpinfo" | "h" => {
|
||||
provisioning_tools_options
|
||||
},
|
||||
_ => {
|
||||
on_tools_task $core_bin $tools_task
|
||||
let text = $"expected to be one of [install, show, info, check, versions, check-updates, update-versions, pin, unpin], got ($tools_task)"
|
||||
(throw-error
|
||||
"🛑 invalid_option"
|
||||
$text
|
||||
#--span (metadata $pkg_dir | get span)
|
||||
)
|
||||
},
|
||||
}
|
||||
if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
}
|
||||
|
||||
export def show_tools_info [
|
||||
match: string
|
||||
]: nothing -> nothing {
|
||||
let tools_data = (open $env.PROVISIONING_REQ_VERSIONS)
|
||||
if ($match | is-empty) {
|
||||
_print ($tools_data | table -e)
|
||||
} else {
|
||||
_print ($tools_data | get -o $match | table -e)
|
||||
}
|
||||
}
|
||||
export def show_provs_info [
|
||||
match: string
|
||||
]: nothing -> nothing {
|
||||
if not ($env.PROVISIONING_PROVIDERS_PATH| path exists) {
|
||||
_print $"❗Error providers path (_ansi red)($env.PROVISIONING_PROVIDERS_PATH)(_ansi reset) not found"
|
||||
return
|
||||
}
|
||||
^ls $env.PROVISIONING_PROVIDERS_PATH | each {|prv|
|
||||
if ($match | is-empty) or $match == ($prv | str trim) {
|
||||
let prv_path = ($env.PROVISIONING_PROVIDERS_PATH | path join ($prv | str trim) | path join "provisioning.yaml")
|
||||
if ($prv_path | path exists) {
|
||||
_print $"(_ansi magenta_bold)($prv | str trim | str upcase)(_ansi reset)"
|
||||
_print (open $prv_path | table -e)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
export def on_tools_task [
|
||||
core_bin: string
|
||||
tools_task: string
|
||||
]: nothing -> nothing {
|
||||
if not ($env.PROVISIONING_REQ_VERSIONS | path exists) {
|
||||
_print $"❗Error tools path (_ansi red)($env.PROVISIONING_REQ_VERSIONS)(_ansi reset) not found"
|
||||
return
|
||||
}
|
||||
let tools_data = (open $env.PROVISIONING_REQ_VERSIONS)
|
||||
let tool_name = ($tools_data | get -o $tools_task)
|
||||
if ($tool_name | is-not-empty) {
|
||||
_print $"(_ansi blue_bold)($env.PROVISIONING_NAME)(_ansi reset) tools check (_ansi green_bold)($tools_task)(_ansi reset) "
|
||||
^$"($core_bin)/tools-install" check $tools_task
|
||||
# if not $env.PROVISIONING_DEBUG { end_run "" }
|
||||
exit
|
||||
}
|
||||
}
|
||||
75
core/nulib/main_provisioning/update.nu
Normal file
75
core/nulib/main_provisioning/update.nu
Normal file
|
|
@ -0,0 +1,75 @@
|
|||
|
||||
def prompt_update [
|
||||
target: string
|
||||
target_name: string
|
||||
yes: bool
|
||||
name?: string
|
||||
]: nothing -> string {
|
||||
match $name {
|
||||
"h" | "help" => {
|
||||
^($env.PROVISIONING_NAME) "-mod" $target "--help"
|
||||
exit 0
|
||||
}
|
||||
}
|
||||
if not $yes or not (($env.PROVISIONING_ARGS? | default "") | str contains "--yes") {
|
||||
_print ( $"To (_ansi red_bold)update ($target_name) (_ansi reset) " +
|
||||
$" (_ansi green_bold)($name)(_ansi reset) type (_ansi green_bold)yes(_ansi reset) ? "
|
||||
)
|
||||
let user_input = (input --numchar 3)
|
||||
if $user_input != "yes" and $user_input != "YES" {
|
||||
exit 1
|
||||
}
|
||||
$name
|
||||
} else {
|
||||
$env.PROVISIONING_ARGS = ($env.PROVISIONING_ARGS? | find -v "yes")
|
||||
($name | default "" | str replace "yes" "")
|
||||
}
|
||||
}
|
||||
# -> Update infrastructure and services
|
||||
export def "main update" [
|
||||
target?: string # server (s) | task (t) | service (sv)
|
||||
name?: string # target name in settings
|
||||
...args # Args for create command
|
||||
--serverpos (-p): int # Server position in settings
|
||||
--keepstorage # Keep storage
|
||||
--yes (-y) # confirm update
|
||||
--wait (-w) # Wait servers to be created
|
||||
--infra (-i): string # Infra path
|
||||
--settings (-s): string # Settings path
|
||||
--outfile (-o): string # Output file
|
||||
--debug (-x) # Use Debug mode
|
||||
--xm # Debug with PROVISIONING_METADATA
|
||||
--xc # Debuc for task and services locally PROVISIONING_DEBUG_CHECK
|
||||
--xr # Debug for remote servers PROVISIONING_DEBUG_REMOTE
|
||||
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||||
--metadata # Error with metadata (-xm)
|
||||
--notitles # not tittles
|
||||
--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
|
||||
}
|
||||
parse_help_command "update" --end
|
||||
if $debug { $env.PROVISIONING_DEBUG = true }
|
||||
let use_debug = if $debug or $env.PROVISIONING_DEBUG { "-x" } else { "" }
|
||||
match $target {
|
||||
"server"| "servers" | "s" => {
|
||||
let use_keepstorage = if $keepstorage { "--keepstorage "} else { "" }
|
||||
prompt_update "server" "servers" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "server" ($env.PROVISIONING_ARGS | str replace $target '') --yes --notitles $use_keepstorage
|
||||
},
|
||||
"taskserv" | "taskservs" | "t" => {
|
||||
prompt_update "taskserv" "tasks/services" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "tasksrv" ($env.PROVISIONING_ARGS | str replace $target '') --yes --notitles
|
||||
},
|
||||
"clusters"| "clusters" | "cl" => {
|
||||
prompt_update "cluster" "cluster" $yes $name
|
||||
^$"($env.PROVISIONING_NAME)" $use_debug -mod "cluster" ($env.PROVISIONING_ARGS | str replace $target '') --yes --notitles
|
||||
},
|
||||
_ => {
|
||||
invalid_task "update" ($target | default "") --end
|
||||
exit
|
||||
},
|
||||
}
|
||||
}
|
||||
343
core/nulib/main_provisioning/validate.nu
Normal file
343
core/nulib/main_provisioning/validate.nu
Normal file
|
|
@ -0,0 +1,343 @@
|
|||
# Infrastructure Validation Commands
|
||||
# Integrates validation system into the main provisioning CLI
|
||||
|
||||
# Import validation functions
|
||||
use ../lib_provisioning/infra_validator/validator.nu *
|
||||
use ../lib_provisioning/infra_validator/agent_interface.nu *
|
||||
|
||||
# Main validation command
|
||||
export def "main validate" [
|
||||
infra_path?: string # Path to infrastructure configuration (default: current directory)
|
||||
...args # Additional arguments
|
||||
--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_validation_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_validation_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 using the validator engine
|
||||
try {
|
||||
let result = (main $target_path
|
||||
--fix=$fix
|
||||
--report=$report
|
||||
--output=$output
|
||||
--severity=$severity
|
||||
--ci=$ci
|
||||
--dry-run=$dry_run
|
||||
)
|
||||
|
||||
if not $ci {
|
||||
print ""
|
||||
print $"📊 Reports generated in: ($output)"
|
||||
show_validation_next_steps $result
|
||||
}
|
||||
|
||||
} catch {|error|
|
||||
if not $ci {
|
||||
print $"🛑 Validation failed: ($error.msg)"
|
||||
}
|
||||
exit 4
|
||||
}
|
||||
}
|
||||
|
||||
# Quick validation subcommand
|
||||
export def "main 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 validate $target --severity="error" --report="md" --output="./quick_validation" --fix=$fix
|
||||
}
|
||||
|
||||
# CI validation subcommand
|
||||
export def "main validate ci" [
|
||||
infra_path: string
|
||||
--format (-f): string = "yaml"
|
||||
--fix
|
||||
]: nothing -> nothing {
|
||||
main validate $infra_path --ci --report=$format --output="./ci_validation" --fix=$fix
|
||||
}
|
||||
|
||||
# Full validation subcommand
|
||||
export def "main 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 validate $target --severity="info" --report="all" --output=$output --verbose
|
||||
}
|
||||
|
||||
# Agent interface for automation
|
||||
export def "main validate agent" [
|
||||
infra_path: string
|
||||
--auto_fix: bool = false
|
||||
--severity_threshold: string = "warning"
|
||||
--format: string = "json"
|
||||
]: nothing -> nothing {
|
||||
|
||||
print "🤖 Agent Validation Mode"
|
||||
print "========================"
|
||||
print ""
|
||||
|
||||
let result = (validate_for_agent $infra_path --auto_fix=$auto_fix --severity_threshold=$severity_threshold)
|
||||
|
||||
match $format {
|
||||
"json" => { $result | to json },
|
||||
"yaml" => { $result | to yaml },
|
||||
_ => { $result }
|
||||
}
|
||||
}
|
||||
|
||||
# List available rules
|
||||
export def "main validate rules" []: nothing -> nothing {
|
||||
print "📋 Available Validation Rules"
|
||||
print "============================"
|
||||
print ""
|
||||
|
||||
let rules = [
|
||||
{id: "VAL001", category: "syntax", severity: "critical", name: "YAML Syntax Validation", auto_fix: false}
|
||||
{id: "VAL002", category: "compilation", severity: "critical", name: "KCL Compilation Check", auto_fix: false}
|
||||
{id: "VAL003", category: "syntax", severity: "error", name: "Unquoted Variable References", auto_fix: true}
|
||||
{id: "VAL004", category: "schema", severity: "error", name: "Required Fields Validation", auto_fix: false}
|
||||
{id: "VAL005", category: "best_practices", severity: "warning", name: "Resource Naming Conventions", auto_fix: true}
|
||||
{id: "VAL006", category: "security", severity: "error", name: "Basic Security Checks", auto_fix: false}
|
||||
{id: "VAL007", category: "compatibility", severity: "warning", name: "Version Compatibility Check", auto_fix: false}
|
||||
{id: "VAL008", category: "networking", severity: "error", name: "Network Configuration Validation", auto_fix: false}
|
||||
]
|
||||
|
||||
for rule in $rules {
|
||||
let auto_fix_indicator = if $rule.auto_fix { "🔧" } else { "👁️" }
|
||||
let severity_color = match $rule.severity {
|
||||
"critical" => "🚨"
|
||||
"error" => "❌"
|
||||
"warning" => "⚠️"
|
||||
_ => "ℹ️"
|
||||
}
|
||||
|
||||
print $"($auto_fix_indicator) ($severity_color) ($rule.id): ($rule.name)"
|
||||
print $" Category: ($rule.category) | Severity: ($rule.severity) | Auto-fix: ($rule.auto_fix)"
|
||||
print ""
|
||||
}
|
||||
|
||||
print "Legend:"
|
||||
print "🔧 = Auto-fixable | 👁️ = Manual fix required"
|
||||
print "🚨 = Critical | ❌ = Error | ⚠️ = Warning | ℹ️ = Info"
|
||||
}
|
||||
|
||||
# Test validation system
|
||||
export def "main validate test" []: nothing -> nothing {
|
||||
print "🧪 Testing Validation System"
|
||||
print "============================="
|
||||
print ""
|
||||
|
||||
# Run the test script
|
||||
try {
|
||||
^nu test_validation.nu
|
||||
} catch {|error|
|
||||
print $"❌ Test failed: ($error.msg)"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
def print_validation_banner []: nothing -> nothing {
|
||||
print "╔══════════════════════════════════════════════════════════════╗"
|
||||
print "║ Infrastructure Validation & Review Tool ║"
|
||||
print "║ Cloud Native Provisioning ║"
|
||||
print "╚══════════════════════════════════════════════════════════════╝"
|
||||
print ""
|
||||
}
|
||||
|
||||
def show_validation_help []: nothing -> nothing {
|
||||
print "Infrastructure Validation & Review Tool"
|
||||
print "========================================"
|
||||
print ""
|
||||
print "USAGE:"
|
||||
print " ./core/nulib/provisioning validate [SUBCOMMAND] [INFRA_PATH] [OPTIONS]"
|
||||
print ""
|
||||
print "SUBCOMMANDS:"
|
||||
print " (none) Full validation with customizable options"
|
||||
print " quick Quick validation focusing on errors and critical issues"
|
||||
print " ci CI/CD optimized validation with structured output"
|
||||
print " full Comprehensive validation including info-level checks"
|
||||
print " agent Agent/automation interface with JSON output"
|
||||
print " rules List all available validation rules"
|
||||
print " test Run validation system self-tests"
|
||||
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"
|
||||
print " ./core/nulib/provisioning validate"
|
||||
print ""
|
||||
print " # Quick validation with auto-fix"
|
||||
print " ./core/nulib/provisioning validate quick klab/sgoyol --fix"
|
||||
print ""
|
||||
print " # CI/CD validation"
|
||||
print " ./core/nulib/provisioning validate ci klab/sgoyol --format yaml"
|
||||
print ""
|
||||
print " # Full validation with all reports"
|
||||
print " ./core/nulib/provisioning validate full klab/sgoyol --output ./reports"
|
||||
print ""
|
||||
print " # Agent mode for automation"
|
||||
print " ./core/nulib/provisioning validate agent klab/sgoyol --auto_fix"
|
||||
print ""
|
||||
print " # List available rules"
|
||||
print " ./core/nulib/provisioning validate rules"
|
||||
print ""
|
||||
print " # Test the validation system"
|
||||
print " ./core/nulib/provisioning validate test"
|
||||
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 show_validation_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: ./core/nulib/provisioning validate --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."
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue