432 lines
16 KiB
Plaintext
432 lines
16 KiB
Plaintext
|
|
#!/usr/bin/env nu
|
||
|
|
# Info: Script to run Provisioning Batch Workflow Management
|
||
|
|
# Author: JesusPerezLorenzo
|
||
|
|
# Release: 1.0.0
|
||
|
|
# Date: 29-09-2025
|
||
|
|
|
||
|
|
use std log
|
||
|
|
|
||
|
|
use lib_provisioning *
|
||
|
|
use env.nu *
|
||
|
|
use workflows/batch.nu *
|
||
|
|
|
||
|
|
# - > Help on Batch Workflows
|
||
|
|
export def "main help" [
|
||
|
|
--src: string = ""
|
||
|
|
--notitles # not titles
|
||
|
|
--out: string # Print Output format: json, yaml, text (default)
|
||
|
|
]: nothing -> nothing {
|
||
|
|
if $notitles == null or not $notitles {
|
||
|
|
if (which show_titles | is-not-empty) {
|
||
|
|
show_titles
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
print ""
|
||
|
|
print "Batch Workflow Management - Comprehensive batch operations for infrastructure provisioning"
|
||
|
|
print "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||
|
|
print ""
|
||
|
|
print "USAGE:"
|
||
|
|
print " provisioning batch <command> [arguments] [flags]"
|
||
|
|
print ""
|
||
|
|
print "COMMANDS:"
|
||
|
|
print " validate <workflow_file> Validate KCL workflow definition"
|
||
|
|
print " --check-syntax Check syntax only"
|
||
|
|
print " --check-dependencies Validate dependencies"
|
||
|
|
print ""
|
||
|
|
print " submit <workflow_file> Submit batch workflow to orchestrator"
|
||
|
|
print " --name <name> Custom workflow name"
|
||
|
|
print " --priority <1-10> Workflow priority (default: 5)"
|
||
|
|
print " --environment <dev|test|prod> Target environment"
|
||
|
|
print " --wait Wait for completion"
|
||
|
|
print " --timeout <duration> Timeout (default: 30min)"
|
||
|
|
print ""
|
||
|
|
print " status <workflow_id> Get batch workflow status"
|
||
|
|
print " --format <table|json|compact> Output format (default: table)"
|
||
|
|
print ""
|
||
|
|
print " monitor <workflow_id> Real-time workflow monitoring"
|
||
|
|
print " --interval <duration> Refresh interval (default: 3sec)"
|
||
|
|
print " --timeout <duration> Maximum monitoring time (default: 30min)"
|
||
|
|
print " --quiet Minimal output"
|
||
|
|
print ""
|
||
|
|
print " rollback <workflow_id> Rollback failed workflow"
|
||
|
|
print " --checkpoint <name> Rollback to specific checkpoint"
|
||
|
|
print " --force Force without confirmation"
|
||
|
|
print ""
|
||
|
|
print " list List batch workflows"
|
||
|
|
print " --status <status> Filter by status (Running, Failed, Completed)"
|
||
|
|
print " --environment <env> Filter by environment"
|
||
|
|
print " --name <pattern> Filter by name pattern"
|
||
|
|
print " --limit <number> Maximum results (default: 50)"
|
||
|
|
print " --format <table|json|compact> Output format"
|
||
|
|
print ""
|
||
|
|
print " cancel <workflow_id> Cancel running workflow"
|
||
|
|
print " --reason <text> Cancellation reason"
|
||
|
|
print " --force Force cancellation"
|
||
|
|
print ""
|
||
|
|
print " template <action> [name] Manage workflow templates"
|
||
|
|
print " Actions: list, create, delete, show"
|
||
|
|
print " --from-file <path> Create template from file"
|
||
|
|
print " --description <text> Template description"
|
||
|
|
print ""
|
||
|
|
print " stats Show batch statistics"
|
||
|
|
print " --period <1h|24h|7d|30d> Time period (default: 24h)"
|
||
|
|
print " --environment <env> Filter by environment"
|
||
|
|
print " --detailed Show detailed statistics"
|
||
|
|
print ""
|
||
|
|
print " health Check batch system health"
|
||
|
|
print ""
|
||
|
|
print "GLOBAL FLAGS:"
|
||
|
|
print " --check Check mode, no actual changes"
|
||
|
|
print " --yes Auto-confirm operations"
|
||
|
|
print " --debug Enable debug mode"
|
||
|
|
print " --out <json|yaml|table> Output format"
|
||
|
|
print ""
|
||
|
|
print "EXAMPLES:"
|
||
|
|
print " # Validate a workflow"
|
||
|
|
print " provisioning batch validate workflows/example.k --check-syntax --check-dependencies"
|
||
|
|
print ""
|
||
|
|
print " # Submit and wait for completion"
|
||
|
|
print " provisioning batch submit workflows/deploy.k --wait --environment prod"
|
||
|
|
print ""
|
||
|
|
print " # Monitor workflow in real-time"
|
||
|
|
print " provisioning batch monitor abc123-def456"
|
||
|
|
print ""
|
||
|
|
print " # List all running workflows"
|
||
|
|
print " provisioning batch list --status Running"
|
||
|
|
print ""
|
||
|
|
print " # Check system health"
|
||
|
|
print " provisioning batch health"
|
||
|
|
print ""
|
||
|
|
}
|
||
|
|
|
||
|
|
# > Batch Workflow Management
|
||
|
|
def main [
|
||
|
|
...args: string # Other options, use help to get info
|
||
|
|
-v # Show version
|
||
|
|
-i # Show Info
|
||
|
|
--version (-V) # Show version with title
|
||
|
|
--info (-I) # Show Info with title
|
||
|
|
--about (-a) # Show About
|
||
|
|
--interval: duration = 3sec # Monitoring refresh interval
|
||
|
|
--timeout: duration = 30min # Timeout for wait/monitor operations
|
||
|
|
--status: string = "" # Filter status (Running, Failed, Completed, etc)
|
||
|
|
--format: string = "table" # Output format: table, json, compact
|
||
|
|
--priority: int = 5 # Workflow priority (1-10)
|
||
|
|
--environment: string = "" # Target environment (dev/test/prod)
|
||
|
|
--checkpoint: string = "" # Rollback checkpoint
|
||
|
|
--reason: string = "" # Cancellation reason
|
||
|
|
--period: string = "24h" # Statistics period (1h, 24h, 7d, 30d)
|
||
|
|
--template: string = "" # Template type or name
|
||
|
|
--from-file: string = "" # Source file for template creation
|
||
|
|
--description: string = "" # Template description
|
||
|
|
--name: string = "" # Custom workflow or template name
|
||
|
|
--limit: int = 50 # Maximum results for list
|
||
|
|
--check-syntax (-s) # Check syntax only
|
||
|
|
--check-dependencies (-d) # Validate dependencies
|
||
|
|
--wait (-w) # Wait for completion
|
||
|
|
--check (-c) # Only check mode, no actual changes
|
||
|
|
--yes (-y) # Confirm task
|
||
|
|
--force (-f) # Force operation without confirmation
|
||
|
|
--quiet (-q) # Minimal output
|
||
|
|
--detailed # Show detailed information
|
||
|
|
--debug (-x) # Use Debug mode
|
||
|
|
--xm # Debug with PROVISIONING_METADATA
|
||
|
|
--xld # Log level with DEBUG PROVISIONING_LOG_LEVEL=debug
|
||
|
|
--metadata # Error with metadata (-xm)
|
||
|
|
--notitles # Do not show banner titles
|
||
|
|
--helpinfo (-h) # For more details use options "help" (no dashes)
|
||
|
|
--out: string # Print Output format: json, yaml, text (default)
|
||
|
|
]: nothing -> nothing {
|
||
|
|
if ($out | is-not-empty) {
|
||
|
|
$env.PROVISIONING_OUT = $out
|
||
|
|
$env.PROVISIONING_NO_TERMINAL = true
|
||
|
|
}
|
||
|
|
provisioning_init $helpinfo "batch" $args
|
||
|
|
if $version or $v { ^$env.PROVISIONING_NAME -v ; exit }
|
||
|
|
if $info or $i { ^$env.PROVISIONING_NAME -i ; exit }
|
||
|
|
if $about {
|
||
|
|
_print (get_about_info)
|
||
|
|
exit
|
||
|
|
}
|
||
|
|
if $debug { $env.PROVISIONING_DEBUG = true }
|
||
|
|
if $metadata { $env.PROVISIONING_METADATA = true }
|
||
|
|
|
||
|
|
let task = if ($args | length) > 0 { ($args | get 0) } else { "" }
|
||
|
|
let ops = $"($env.PROVISIONING_ARGS? | default "") " | str replace $" ($task) " "" | str trim
|
||
|
|
let workflow_param = if ($ops | is-not-empty) and not ($ops | str starts-with "-") {
|
||
|
|
($ops | split row " " | get 0)
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
|
||
|
|
$env.PROVISIONING_MODULE = "batch"
|
||
|
|
|
||
|
|
match $task {
|
||
|
|
"h" | "help" => {
|
||
|
|
# Redirect to main categorized help system
|
||
|
|
exec $"($env.PROVISIONING_NAME)" help orchestration --notitles
|
||
|
|
},
|
||
|
|
"validate" => {
|
||
|
|
if ($workflow_param | is-empty) {
|
||
|
|
print "❌ Workflow file path is required"
|
||
|
|
print "Usage: provisioning batch validate <workflow_file> [--check-syntax] [--check-dependencies]"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"🔍 Validating workflow: ($workflow_param)"
|
||
|
|
let result = if $check_syntax and $check_dependencies {
|
||
|
|
batch validate $workflow_param --check-syntax --check-dependencies
|
||
|
|
} else if $check_syntax {
|
||
|
|
batch validate $workflow_param --check-syntax
|
||
|
|
} else if $check_dependencies {
|
||
|
|
batch validate $workflow_param --check-dependencies
|
||
|
|
} else {
|
||
|
|
batch validate $workflow_param
|
||
|
|
}
|
||
|
|
|
||
|
|
if $result.valid {
|
||
|
|
print "✅ Workflow is valid"
|
||
|
|
} else {
|
||
|
|
print "❌ Workflow validation failed"
|
||
|
|
print $"Errors: ($result.errors | str join '\n ')"
|
||
|
|
}
|
||
|
|
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"submit" => {
|
||
|
|
if ($workflow_param | is-empty) {
|
||
|
|
print "❌ Workflow file path is required"
|
||
|
|
print "Usage: provisioning batch submit <workflow_file> [--wait] [--check]"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "🔍 CHECK MODE: Would submit workflow but --check flag is set"
|
||
|
|
let validation = batch validate $workflow_param --check-syntax --check-dependencies
|
||
|
|
if $validation.valid {
|
||
|
|
print "✅ Workflow is valid and ready to submit"
|
||
|
|
} else {
|
||
|
|
print "❌ Workflow validation failed"
|
||
|
|
print $"Errors: ($validation.errors | str join '\n ')"
|
||
|
|
}
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"📤 Submitting workflow: ($workflow_param)"
|
||
|
|
let result = if $wait {
|
||
|
|
batch submit $workflow_param --name $name --priority $priority --environment $environment --wait --timeout $timeout
|
||
|
|
} else {
|
||
|
|
batch submit $workflow_param --name $name --priority $priority --environment $environment
|
||
|
|
}
|
||
|
|
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"status" => {
|
||
|
|
if ($workflow_param | is-empty) {
|
||
|
|
print "❌ Workflow ID is required"
|
||
|
|
print "Usage: provisioning batch status <workflow_id>"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
let result = batch status $workflow_param --format $format
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"monitor" => {
|
||
|
|
if ($workflow_param | is-empty) {
|
||
|
|
print "❌ Workflow ID is required"
|
||
|
|
print "Usage: provisioning batch monitor <workflow_id> [--interval 2sec]"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if $quiet {
|
||
|
|
batch monitor $workflow_param --interval $interval --timeout $timeout --quiet
|
||
|
|
} else {
|
||
|
|
batch monitor $workflow_param --interval $interval --timeout $timeout
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"rollback" => {
|
||
|
|
if ($workflow_param | is-empty) {
|
||
|
|
print "❌ Workflow ID is required"
|
||
|
|
print "Usage: provisioning batch rollback <workflow_id> [--checkpoint <name>] [--force]"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "🔍 CHECK MODE: Would rollback workflow but --check flag is set"
|
||
|
|
print $"Workflow ID: ($workflow_param)"
|
||
|
|
if ($checkpoint | is-not-empty) {
|
||
|
|
print $"Checkpoint: ($checkpoint)"
|
||
|
|
}
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
if not $force and not $yes {
|
||
|
|
let confirm = (input $"⚠️ Rollback workflow ($workflow_param)? This cannot be undone. [y/N]: ")
|
||
|
|
if $confirm != "y" and $confirm != "Y" {
|
||
|
|
print "🚫 Rollback cancelled"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"🔄 Rolling back workflow: ($workflow_param)"
|
||
|
|
let result = if ($checkpoint | is-not-empty) {
|
||
|
|
batch rollback $workflow_param --checkpoint $checkpoint --force
|
||
|
|
} else if $force or $yes {
|
||
|
|
batch rollback $workflow_param --force
|
||
|
|
} else {
|
||
|
|
batch rollback $workflow_param
|
||
|
|
}
|
||
|
|
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"list" => {
|
||
|
|
let result = batch list --status $status --environment $environment --name $name --limit $limit --format $format
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"cancel" => {
|
||
|
|
if ($workflow_param | is-empty) {
|
||
|
|
print "❌ Workflow ID is required"
|
||
|
|
print "Usage: provisioning batch cancel <workflow_id> [--reason <text>] [--force]"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if $check {
|
||
|
|
print "🔍 CHECK MODE: Would cancel workflow but --check flag is set"
|
||
|
|
print $"Workflow ID: ($workflow_param)"
|
||
|
|
if ($reason | is-not-empty) {
|
||
|
|
print $"Reason: ($reason)"
|
||
|
|
}
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
|
||
|
|
if not $force and not $yes {
|
||
|
|
let confirm = (input $"⚠️ Cancel workflow ($workflow_param)? [y/N]: ")
|
||
|
|
if $confirm != "y" and $confirm != "Y" {
|
||
|
|
print "🚫 Cancellation aborted"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
print $"🚫 Cancelling workflow: ($workflow_param)"
|
||
|
|
let result = if ($reason | is-not-empty) and ($force or $yes) {
|
||
|
|
batch cancel $workflow_param --reason $reason --force
|
||
|
|
} else if ($reason | is-not-empty) {
|
||
|
|
batch cancel $workflow_param --reason $reason
|
||
|
|
} else if ($force or $yes) {
|
||
|
|
batch cancel $workflow_param --force
|
||
|
|
} else {
|
||
|
|
batch cancel $workflow_param
|
||
|
|
}
|
||
|
|
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"template" => {
|
||
|
|
let action = if ($workflow_param | is-not-empty) {
|
||
|
|
$workflow_param
|
||
|
|
} else {
|
||
|
|
"list"
|
||
|
|
}
|
||
|
|
|
||
|
|
let template_name_param = if ($ops | is-not-empty) {
|
||
|
|
let parts = ($ops | split row " ")
|
||
|
|
if ($parts | length) > 1 and not (($parts | get 1) | str starts-with "-") {
|
||
|
|
($parts | get 1)
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
""
|
||
|
|
}
|
||
|
|
|
||
|
|
let result = match $action {
|
||
|
|
"list" => {
|
||
|
|
batch template "list"
|
||
|
|
},
|
||
|
|
"create" => {
|
||
|
|
if ($template_name_param | is-empty) or ($from_file | is-empty) {
|
||
|
|
print "❌ Template name and --from-file are required"
|
||
|
|
print "Usage: provisioning batch template create <name> --from-file <path> [--description <text>]"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
batch template "create" $template_name_param --from-file $from_file --description $description
|
||
|
|
},
|
||
|
|
"delete" => {
|
||
|
|
if ($template_name_param | is-empty) {
|
||
|
|
print "❌ Template name is required"
|
||
|
|
print "Usage: provisioning batch template delete <name>"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
|
||
|
|
if not $force and not $yes {
|
||
|
|
let confirm = (input $"⚠️ Delete template ($template_name_param)? [y/N]: ")
|
||
|
|
if $confirm != "y" and $confirm != "Y" {
|
||
|
|
print "🚫 Deletion cancelled"
|
||
|
|
exit 0
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
batch template "delete" $template_name_param
|
||
|
|
},
|
||
|
|
"show" => {
|
||
|
|
if ($template_name_param | is-empty) {
|
||
|
|
print "❌ Template name is required"
|
||
|
|
print "Usage: provisioning batch template show <name>"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
batch template "show" $template_name_param
|
||
|
|
},
|
||
|
|
_ => {
|
||
|
|
print $"❌ Unknown template action: ($action)"
|
||
|
|
print "Available actions: list, create, delete, show"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"stats" => {
|
||
|
|
let result = if $detailed {
|
||
|
|
batch stats --period $period --environment $environment --detailed
|
||
|
|
} else {
|
||
|
|
batch stats --period $period --environment $environment
|
||
|
|
}
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
"health" => {
|
||
|
|
let result = batch health
|
||
|
|
output_result $result $out
|
||
|
|
},
|
||
|
|
_ => {
|
||
|
|
print $"❌ Unknown task: ($task)"
|
||
|
|
print ""
|
||
|
|
print "Available commands:"
|
||
|
|
print " validate <workflow_file> - Validate KCL workflow definition"
|
||
|
|
print " submit <workflow_file> - Submit batch workflow to orchestrator"
|
||
|
|
print " status <workflow_id> - Get batch workflow status"
|
||
|
|
print " monitor <workflow_id> - Real-time workflow monitoring"
|
||
|
|
print " rollback <workflow_id> - Rollback failed workflow"
|
||
|
|
print " list - List batch workflows"
|
||
|
|
print " cancel <workflow_id> - Cancel running workflow"
|
||
|
|
print " template <action> [name] - Manage workflow templates"
|
||
|
|
print " stats - Show batch statistics"
|
||
|
|
print " health - Check batch system health"
|
||
|
|
print ""
|
||
|
|
print "Use 'provisioning batch help' for detailed information"
|
||
|
|
exit 1
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
# Helper function to output results in various formats
|
||
|
|
def output_result [result: any, format: string]: nothing -> nothing {
|
||
|
|
if ($format | is-not-empty) {
|
||
|
|
if $format == "json" {
|
||
|
|
print ($result | to json)
|
||
|
|
} else if $format == "yaml" {
|
||
|
|
print ($result | to yaml)
|
||
|
|
} else {
|
||
|
|
print ($result | table)
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|