642 lines
20 KiB
Plaintext
642 lines
20 KiB
Plaintext
|
|
# Interactive Setup Wizard Module
|
|||
|
|
# Provides step-by-step interactive guidance for system setup
|
|||
|
|
# Follows Nushell guidelines: explicit types, single purpose, no try-catch
|
|||
|
|
# [command]
|
|||
|
|
# name = "setup wizard"
|
|||
|
|
# group = "configuration"
|
|||
|
|
# tags = ["setup", "interactive", "wizard"]
|
|||
|
|
# version = "2.0.0"
|
|||
|
|
# requires = ["forminquire.nu:1.0.0", "nushell:0.109.0"]
|
|||
|
|
# note = "Migrated to FormInquire with fallback to prompt-* functions"
|
|||
|
|
|
|||
|
|
use ./mod.nu *
|
|||
|
|
use ./detection.nu *
|
|||
|
|
use ./validation.nu *
|
|||
|
|
use ../../forminquire/nulib/forminquire.nu *
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# INPUT HELPERS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Helper to read one line of input in Nushell 0.109.1
|
|||
|
|
# Reads directly from /dev/tty for TTY mode, handles piped input gracefully
|
|||
|
|
def read-input-line []: string -> string {
|
|||
|
|
# Try to read from /dev/tty first (TTY/interactive mode)
|
|||
|
|
let tty_result = (try {
|
|||
|
|
open /dev/tty | lines | first | str trim
|
|||
|
|
} catch {
|
|||
|
|
null
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
# If /dev/tty worked, return the line
|
|||
|
|
if $tty_result != null {
|
|||
|
|
$tty_result
|
|||
|
|
} else {
|
|||
|
|
# No /dev/tty (Windows, containers, or piped mode)
|
|||
|
|
# Return empty string - this will use defaults in calling code
|
|||
|
|
""
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Prompt user for simple yes/no question
|
|||
|
|
export def prompt-yes-no [
|
|||
|
|
question: string
|
|||
|
|
]: nothing -> bool {
|
|||
|
|
print ""
|
|||
|
|
print -n ($question + " (y/n): ")
|
|||
|
|
let response = (read-input-line)
|
|||
|
|
if ($response | is-empty) { false } else { ($response == "y" or $response == "Y") }
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Prompt user for text input
|
|||
|
|
export def prompt-text [
|
|||
|
|
question: string
|
|||
|
|
default_value: string = ""
|
|||
|
|
]: nothing -> string {
|
|||
|
|
print ""
|
|||
|
|
if ($default_value != "") {
|
|||
|
|
print ($question + " [" + $default_value + "]: ")
|
|||
|
|
} else {
|
|||
|
|
print ($question + ": ")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let response = (read-input-line)
|
|||
|
|
if ($response == "") {
|
|||
|
|
$default_value
|
|||
|
|
} else {
|
|||
|
|
$response
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Prompt user for selection from list
|
|||
|
|
export def prompt-select [
|
|||
|
|
question: string
|
|||
|
|
options: list<string>
|
|||
|
|
]: nothing -> string {
|
|||
|
|
print ""
|
|||
|
|
print $question
|
|||
|
|
let option_count = ($options | length)
|
|||
|
|
for i in (0..($option_count - 1)) {
|
|||
|
|
let option = ($options | get $i)
|
|||
|
|
let num = (($i + 1) | into string)
|
|||
|
|
print (" " + $num + ") " + $option)
|
|||
|
|
}
|
|||
|
|
print ""
|
|||
|
|
let count_str = ($option_count | into string)
|
|||
|
|
print ("Select option (1-" + $count_str + "): ")
|
|||
|
|
|
|||
|
|
let choice_str = (read-input-line)
|
|||
|
|
let choice = ($choice_str | into int | default 1)
|
|||
|
|
|
|||
|
|
if ($choice >= 1 and $choice <= $option_count) {
|
|||
|
|
$options | get ($choice - 1)
|
|||
|
|
} else {
|
|||
|
|
$options | get 0
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Prompt user for number with validation
|
|||
|
|
export def prompt-number [
|
|||
|
|
question: string
|
|||
|
|
min_value: int = 1
|
|||
|
|
max_value: int = 1000
|
|||
|
|
default_value: int = 0
|
|||
|
|
]: nothing -> int {
|
|||
|
|
mut result = $default_value
|
|||
|
|
mut valid = false
|
|||
|
|
|
|||
|
|
while (not $valid) {
|
|||
|
|
print ""
|
|||
|
|
if ($default_value != 0) {
|
|||
|
|
print $"$question [$default_value]: "
|
|||
|
|
} else {
|
|||
|
|
print $"$question: "
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let input_value = (read-input-line)
|
|||
|
|
|
|||
|
|
if ($input_value == "") {
|
|||
|
|
$result = $default_value
|
|||
|
|
$valid = true
|
|||
|
|
} else {
|
|||
|
|
let parsed = (do { $input_value | into int } | complete)
|
|||
|
|
if ($parsed.exit_code == 0) {
|
|||
|
|
let num = ($parsed.stdout | str trim | into int)
|
|||
|
|
if ($num >= $min_value and $num <= $max_value) {
|
|||
|
|
$result = $num
|
|||
|
|
$valid = true
|
|||
|
|
} else {
|
|||
|
|
print-setup-warning $"Please enter a number between ($min_value) and ($max_value)"
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
print-setup-warning "Please enter a valid number"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
$result
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SYSTEM CONFIGURATION PROMPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Prompt for system configuration details
|
|||
|
|
export def prompt-system-config []: nothing -> record {
|
|||
|
|
print-setup-header "System Configuration"
|
|||
|
|
print ""
|
|||
|
|
print "Let's configure your provisioning system. This will set up the base configuration."
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let config_path = (get-config-base-path)
|
|||
|
|
print-setup-info $"Configuration will be stored in: ($config_path)"
|
|||
|
|
|
|||
|
|
let use_defaults = (prompt-yes-no "Use recommended paths for your OS?")
|
|||
|
|
|
|||
|
|
let confirmed_path = if $use_defaults {
|
|||
|
|
config_path
|
|||
|
|
} else {
|
|||
|
|
(prompt-text "Configuration base path" $config_path)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
config_path: $confirmed_path
|
|||
|
|
os_name: (detect-os)
|
|||
|
|
cpu_count: (get-cpu-count)
|
|||
|
|
memory_gb: (get-system-memory-gb)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# DEPLOYMENT MODE PROMPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Prompt for deployment mode selection
|
|||
|
|
export def prompt-deployment-mode [
|
|||
|
|
detection_report: record
|
|||
|
|
]: nothing -> string {
|
|||
|
|
print-setup-header "Deployment Mode Selection"
|
|||
|
|
print ""
|
|||
|
|
print "Choose how platform services will be deployed:"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
mut options = []
|
|||
|
|
let caps = $detection_report.capabilities
|
|||
|
|
|
|||
|
|
if ($caps.docker_available and $caps.docker_compose_available) {
|
|||
|
|
$options = ($options | append "docker-compose (Local Docker)")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if $caps.kubectl_available {
|
|||
|
|
$options = ($options | append "kubernetes (Kubernetes cluster)")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if $caps.ssh_available {
|
|||
|
|
$options = ($options | append "remote-ssh (Remote SSH)")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if $caps.systemd_available {
|
|||
|
|
$options = ($options | append "systemd (System services)")
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($options | length) == 0 {
|
|||
|
|
print-setup-error "No deployment methods available"
|
|||
|
|
return "unknown"
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let recommended = (recommend-deployment-mode $detection_report)
|
|||
|
|
print ("Recommended: " + $recommended)
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let selected = (prompt-select "Select deployment mode" $options)
|
|||
|
|
match $selected {
|
|||
|
|
"docker-compose (Local Docker)" => { "docker-compose" }
|
|||
|
|
"kubernetes (Kubernetes cluster)" => { "kubernetes" }
|
|||
|
|
"remote-ssh (Remote SSH)" => { "remote-ssh" }
|
|||
|
|
"systemd (System services)" => { "systemd" }
|
|||
|
|
_ => { "docker-compose" }
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# PROVIDER CONFIGURATION PROMPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Prompt for provider selection
|
|||
|
|
export def prompt-providers []: nothing -> list<string> {
|
|||
|
|
print-setup-header "Provider Selection"
|
|||
|
|
print ""
|
|||
|
|
print "Which infrastructure providers do you want to use?"
|
|||
|
|
print "(Select at least one)"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let available_providers = ["upcloud", "aws", "hetzner", "local"]
|
|||
|
|
mut selected = []
|
|||
|
|
|
|||
|
|
for provider in $available_providers {
|
|||
|
|
let use_provider = (prompt-yes-no $"Use ($provider)?")
|
|||
|
|
if $use_provider {
|
|||
|
|
$selected = ($selected | append $provider)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if ($selected | length) == 0 {
|
|||
|
|
print-setup-info "At least 'local' provider is required"
|
|||
|
|
["local"]
|
|||
|
|
} else {
|
|||
|
|
$selected
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# RESOURCE CONFIGURATION PROMPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Prompt for resource allocation
|
|||
|
|
export def prompt-resource-allocation [
|
|||
|
|
detection_report: record
|
|||
|
|
]: nothing -> record {
|
|||
|
|
print-setup-header "Resource Allocation"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let current_cpus = $detection_report.system.cpu_count
|
|||
|
|
let current_memory = $detection_report.system.memory_gb
|
|||
|
|
|
|||
|
|
let cpu_count = (prompt-number "Number of CPUs to allocate" 1 $current_cpus $current_cpus)
|
|||
|
|
let memory_gb = (prompt-number "Memory in GB to allocate" 1 $current_memory $current_memory)
|
|||
|
|
|
|||
|
|
print ""
|
|||
|
|
print $"✅ Allocated ($cpu_count) CPUs and ($memory_gb) GB memory"
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
cpu_count: $cpu_count
|
|||
|
|
memory_gb: $memory_gb
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# SECURITY CONFIGURATION PROMPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Prompt for security settings
|
|||
|
|
export def prompt-security-config []: nothing -> record {
|
|||
|
|
print-setup-header "Security Configuration"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let enable_mfa = (prompt-yes-no "Enable Multi-Factor Authentication (MFA)?")
|
|||
|
|
let enable_audit = (prompt-yes-no "Enable audit logging for all operations?")
|
|||
|
|
let require_approval = (prompt-yes-no "Require approval for destructive operations?")
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
enable_mfa: $enable_mfa
|
|||
|
|
enable_audit: $enable_audit
|
|||
|
|
require_approval_for_destructive: $require_approval
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# WORKSPACE CONFIGURATION PROMPTS
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Prompt for initial workspace creation
|
|||
|
|
export def prompt-initial-workspace []: nothing -> record {
|
|||
|
|
print-setup-header "Initial Workspace"
|
|||
|
|
print ""
|
|||
|
|
print "Create an initial workspace for your infrastructure?"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let create_workspace = (prompt-yes-no "Create workspace now?")
|
|||
|
|
|
|||
|
|
if not $create_workspace {
|
|||
|
|
return {
|
|||
|
|
create_workspace: false
|
|||
|
|
name: ""
|
|||
|
|
description: ""
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
let workspace_name = (prompt-text "Workspace name" "default")
|
|||
|
|
let workspace_description = (prompt-text "Workspace description (optional)" "")
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
create_workspace: true
|
|||
|
|
name: $workspace_name
|
|||
|
|
description: $workspace_description
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# COMPLETE SETUP WIZARD
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Run complete interactive setup wizard
|
|||
|
|
export def run-setup-wizard [
|
|||
|
|
--verbose = false
|
|||
|
|
]: nothing -> record {
|
|||
|
|
# Check if running in TTY or piped mode
|
|||
|
|
let is_interactive = (try {
|
|||
|
|
open /dev/tty | null
|
|||
|
|
true
|
|||
|
|
} catch {
|
|||
|
|
false
|
|||
|
|
})
|
|||
|
|
|
|||
|
|
if not $is_interactive {
|
|||
|
|
# In non-TTY mode, switch to defaults automatically
|
|||
|
|
print "ℹ️ Non-interactive mode detected. Using recommended defaults..."
|
|||
|
|
print ""
|
|||
|
|
return (run-setup-with-defaults)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Force immediate output
|
|||
|
|
print ""
|
|||
|
|
print "╔═══════════════════════════════════════════════════════════════╗"
|
|||
|
|
print "║ PROVISIONING SYSTEM SETUP WIZARD ║"
|
|||
|
|
print "║ ║"
|
|||
|
|
print "║ This wizard will guide you through setting up provisioning ║"
|
|||
|
|
print "║ for your infrastructure automation needs. ║"
|
|||
|
|
print "╚═══════════════════════════════════════════════════════════════╝"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
# Step 1: Environment Detection
|
|||
|
|
print-setup-header "Step 1: Environment Detection"
|
|||
|
|
print "Analyzing your system configuration..."
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
# Use simplified detection to avoid hangs
|
|||
|
|
let detection_report = {
|
|||
|
|
system: {
|
|||
|
|
os: (detect-os)
|
|||
|
|
architecture: (detect-architecture)
|
|||
|
|
hostname: "localhost"
|
|||
|
|
current_user: (get-current-user)
|
|||
|
|
cpu_count: 4
|
|||
|
|
memory_gb: 8
|
|||
|
|
disk_gb: 100
|
|||
|
|
}
|
|||
|
|
capabilities: (get-deployment-capabilities)
|
|||
|
|
network: {
|
|||
|
|
internet_connected: true
|
|||
|
|
docker_port_available: true
|
|||
|
|
orchestrator_port_available: true
|
|||
|
|
control_center_port_available: true
|
|||
|
|
kms_port_available: true
|
|||
|
|
}
|
|||
|
|
existing_config: (get-existing-config-summary)
|
|||
|
|
platform_services: {
|
|||
|
|
orchestrator_running: false
|
|||
|
|
control_center_running: false
|
|||
|
|
kms_running: false
|
|||
|
|
}
|
|||
|
|
timestamp: (date now)
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if $verbose {
|
|||
|
|
print-detection-report $detection_report
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Step 2: System Configuration
|
|||
|
|
let system_config = (prompt-system-config)
|
|||
|
|
|
|||
|
|
# Step 3: Deployment Mode
|
|||
|
|
let deployment_mode = (prompt-deployment-mode $detection_report)
|
|||
|
|
print-setup-success $"Selected deployment mode: ($deployment_mode)"
|
|||
|
|
|
|||
|
|
# Step 4: Provider Selection
|
|||
|
|
let providers = (prompt-providers)
|
|||
|
|
print-setup-success $"Selected providers: ($providers | str join ', ')"
|
|||
|
|
|
|||
|
|
# Step 5: Resource Allocation
|
|||
|
|
let resources = (prompt-resource-allocation $detection_report)
|
|||
|
|
|
|||
|
|
# Step 6: Security Settings
|
|||
|
|
let security = (prompt-security-config)
|
|||
|
|
|
|||
|
|
# Step 7: Initial Workspace
|
|||
|
|
let workspace = (prompt-initial-workspace)
|
|||
|
|
|
|||
|
|
# Summary
|
|||
|
|
print ""
|
|||
|
|
print-setup-header "Setup Summary"
|
|||
|
|
print ""
|
|||
|
|
print "Configuration Details:"
|
|||
|
|
print $" Config Path: ($system_config.config_path)"
|
|||
|
|
print $" OS: ($system_config.os_name)"
|
|||
|
|
print $" Deployment Mode: ($deployment_mode)"
|
|||
|
|
print $" Providers: ($providers | str join ', ')"
|
|||
|
|
print $" CPUs: ($resources.cpu_count)"
|
|||
|
|
print $" Memory: ($resources.memory_gb) GB"
|
|||
|
|
print $" MFA Enabled: (if $security.enable_mfa { 'Yes' } else { 'No' })"
|
|||
|
|
print $" Audit Logging: (if $security.enable_audit { 'Yes' } else { 'No' })"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
let confirm = (prompt-yes-no "Proceed with this configuration?")
|
|||
|
|
|
|||
|
|
if not $confirm {
|
|||
|
|
print-setup-warning "Setup cancelled"
|
|||
|
|
return {
|
|||
|
|
completed: false
|
|||
|
|
system_config: {}
|
|||
|
|
deployment_mode: ""
|
|||
|
|
providers: []
|
|||
|
|
resources: {}
|
|||
|
|
security: {}
|
|||
|
|
workspace: {}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
print ""
|
|||
|
|
print-setup-success "Configuration confirmed!"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
completed: true
|
|||
|
|
system_config: $system_config
|
|||
|
|
deployment_mode: $deployment_mode
|
|||
|
|
providers: $providers
|
|||
|
|
resources: $resources
|
|||
|
|
security: $security
|
|||
|
|
workspace: $workspace
|
|||
|
|
timestamp: (date now)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# QUICK SETUP (AUTOMATED WITH DEFAULTS)
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Run setup with recommended defaults (no interaction)
|
|||
|
|
export def run-setup-with-defaults []: nothing -> record {
|
|||
|
|
print-setup-header "Quick Setup (Recommended Defaults)"
|
|||
|
|
print ""
|
|||
|
|
print "Configuring with system-recommended defaults..."
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
completed: true
|
|||
|
|
system_config: {
|
|||
|
|
config_path: (get-config-base-path)
|
|||
|
|
os_name: (detect-os)
|
|||
|
|
cpu_count: (get-cpu-count)
|
|||
|
|
memory_gb: (get-system-memory-gb)
|
|||
|
|
}
|
|||
|
|
deployment_mode: "docker-compose"
|
|||
|
|
providers: ["local"]
|
|||
|
|
resources: {
|
|||
|
|
cpu_count: (get-cpu-count)
|
|||
|
|
memory_gb: (get-system-memory-gb)
|
|||
|
|
}
|
|||
|
|
security: {
|
|||
|
|
enable_mfa: true
|
|||
|
|
enable_audit: true
|
|||
|
|
require_approval_for_destructive: true
|
|||
|
|
}
|
|||
|
|
workspace: {
|
|||
|
|
create_workspace: true
|
|||
|
|
name: "default"
|
|||
|
|
description: "Default workspace"
|
|||
|
|
}
|
|||
|
|
timestamp: (date now)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Run minimal setup (only required settings)
|
|||
|
|
export def run-minimal-setup []: nothing -> record {
|
|||
|
|
print-setup-header "Minimal Setup"
|
|||
|
|
print ""
|
|||
|
|
print "Configuring with minimal required settings..."
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
completed: true
|
|||
|
|
system_config: {
|
|||
|
|
config_path: (get-config-base-path)
|
|||
|
|
os_name: (detect-os)
|
|||
|
|
}
|
|||
|
|
deployment_mode: "docker-compose"
|
|||
|
|
providers: ["local"]
|
|||
|
|
resources: {}
|
|||
|
|
security: {
|
|||
|
|
enable_mfa: false
|
|||
|
|
enable_audit: true
|
|||
|
|
require_approval_for_destructive: false
|
|||
|
|
}
|
|||
|
|
workspace: {
|
|||
|
|
create_workspace: false
|
|||
|
|
}
|
|||
|
|
timestamp: (date now)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# ============================================================================
|
|||
|
|
# INTERACTIVE SETUP USING FORMINQUIRE (NEW)
|
|||
|
|
# ============================================================================
|
|||
|
|
|
|||
|
|
# Run setup wizard using FormInquire - modern TUI experience
|
|||
|
|
export def run-setup-wizard-interactive []: nothing -> record {
|
|||
|
|
print ""
|
|||
|
|
print "╔═══════════════════════════════════════════════════════════════╗"
|
|||
|
|
print "║ PROVISIONING SYSTEM SETUP WIZARD (FormInquire) ║"
|
|||
|
|
print "║ ║"
|
|||
|
|
print "║ This wizard will guide you through setting up provisioning ║"
|
|||
|
|
print "║ for your infrastructure automation needs. ║"
|
|||
|
|
print "╚═══════════════════════════════════════════════════════════════╝"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
# Prepare context with system information for form defaults
|
|||
|
|
let context = {
|
|||
|
|
config_path: (get-config-base-path)
|
|||
|
|
cpu_count: (get-cpu-count)
|
|||
|
|
memory_gb: (get-system-memory-gb)
|
|||
|
|
disk_gb: 100
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Run the FormInquire-based wizard
|
|||
|
|
let form_result = (setup-wizard-form)
|
|||
|
|
|
|||
|
|
if not $form_result.success {
|
|||
|
|
print-setup-warning "Setup cancelled or failed"
|
|||
|
|
return {
|
|||
|
|
completed: false
|
|||
|
|
system_config: {}
|
|||
|
|
deployment_mode: ""
|
|||
|
|
providers: []
|
|||
|
|
resources: {}
|
|||
|
|
security: {}
|
|||
|
|
workspace: {}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
# Extract values from form results
|
|||
|
|
let values = $form_result.values
|
|||
|
|
|
|||
|
|
# Collect selected providers
|
|||
|
|
let providers = (
|
|||
|
|
[]
|
|||
|
|
| if ($values.provider_upcloud? | default false) { append "upcloud" } else { . }
|
|||
|
|
| if ($values.provider_aws? | default false) { append "aws" } else { . }
|
|||
|
|
| if ($values.provider_hetzner? | default false) { append "hetzner" } else { . }
|
|||
|
|
| if ($values.provider_local? | default false) { append "local" } else { . }
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Ensure at least one provider
|
|||
|
|
let providers_final = if ($providers | length) == 0 { ["local"] } else { $providers }
|
|||
|
|
|
|||
|
|
# Create workspace config if requested
|
|||
|
|
let workspace_final = (
|
|||
|
|
if ($values.create_workspace? | default false) {
|
|||
|
|
{
|
|||
|
|
create_workspace: true
|
|||
|
|
name: ($values.workspace_name? | default "default")
|
|||
|
|
description: ($values.workspace_description? | default "")
|
|||
|
|
}
|
|||
|
|
} else {
|
|||
|
|
{
|
|||
|
|
create_workspace: false
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
# Display summary
|
|||
|
|
print ""
|
|||
|
|
print-setup-header "Setup Summary"
|
|||
|
|
print ""
|
|||
|
|
print "Configuration Details:"
|
|||
|
|
print $" Config Path: ($values.config_path)"
|
|||
|
|
print $" Deployment Mode: ($values.deployment_mode)"
|
|||
|
|
print $" Providers: ($providers_final | str join ', ')"
|
|||
|
|
print $" CPUs: ($values.cpu_count)"
|
|||
|
|
print $" Memory: ($values.memory_gb) GB"
|
|||
|
|
print $" Disk: ($values.disk_gb) GB"
|
|||
|
|
print $" MFA Enabled: (if ($values.enable_mfa? | default false) { 'Yes' } else { 'No' })"
|
|||
|
|
print $" Audit Logging: (if ($values.enable_audit_logging? | default false) { 'Yes' } else { 'No' })"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
print-setup-success "Configuration confirmed!"
|
|||
|
|
print ""
|
|||
|
|
|
|||
|
|
{
|
|||
|
|
completed: true
|
|||
|
|
system_config: {
|
|||
|
|
config_path: ($values.config_path)
|
|||
|
|
os_name: (detect-os)
|
|||
|
|
cpu_count: ($values.cpu_count | into int)
|
|||
|
|
memory_gb: ($values.memory_gb | into int)
|
|||
|
|
}
|
|||
|
|
deployment_mode: ($values.deployment_mode)
|
|||
|
|
providers: $providers_final
|
|||
|
|
resources: {
|
|||
|
|
cpu_count: ($values.cpu_count | into int)
|
|||
|
|
memory_gb: ($values.memory_gb | into int)
|
|||
|
|
disk_gb: ($values.disk_gb | into int)
|
|||
|
|
}
|
|||
|
|
security: {
|
|||
|
|
enable_mfa: ($values.enable_mfa? | default false)
|
|||
|
|
enable_audit: ($values.enable_audit_logging? | default false)
|
|||
|
|
require_approval_for_destructive: ($values.require_approval? | default false)
|
|||
|
|
}
|
|||
|
|
workspace: $workspace_final
|
|||
|
|
timestamp: (date now)
|
|||
|
|
}
|
|||
|
|
}
|