# Environment Detection Module # Detects system capabilities, available tools, network configuration, and existing setup # Follows Nushell guidelines: explicit types, single purpose, no try-catch use ./mod.nu * # ============================================================================ # SYSTEM CAPABILITY DETECTION # ============================================================================ # Check if Docker is installed and running export def has-docker []: nothing -> bool { let which_check = (bash -c "which docker > /dev/null 2>&1; echo $?" | str trim | into int) if ($which_check != 0) { return false } let docker_check = (bash -c "docker ps > /dev/null 2>&1; echo $?" | str trim | into int) ($docker_check == 0) } # Check if Kubernetes (kubectl) is installed export def has-kubectl []: nothing -> bool { let kubectl_check = (bash -c "which kubectl > /dev/null 2>&1; echo $?" | str trim | into int) ($kubectl_check == 0) } # Check if Docker Compose is installed export def has-docker-compose []: nothing -> bool { let compose_check = (bash -c "docker compose version > /dev/null 2>&1; echo $?" | str trim | into int) ($compose_check == 0) } # Check if Podman is installed export def has-podman []: nothing -> bool { let podman_check = (bash -c "which podman > /dev/null 2>&1; echo $?" | str trim | into int) ($podman_check == 0) } # Check if systemd is available export def has-systemd []: nothing -> bool { let systemctl_check = (bash -c "systemctl --version > /dev/null 2>&1; echo $?" | str trim | into int) ($systemctl_check == 0) } # Check if SSH is available export def has-ssh []: nothing -> bool { let ssh_check = (bash -c "which ssh > /dev/null 2>&1; echo $?" | str trim | into int) ($ssh_check == 0) } # Check if KCL is installed export def has-kcl []: nothing -> bool { let kcl_check = (bash -c "which kcl > /dev/null 2>&1; echo $?" | str trim | into int) ($kcl_check == 0) } # Check if SOPS is installed export def has-sops []: nothing -> bool { let sops_check = (bash -c "which sops > /dev/null 2>&1; echo $?" | str trim | into int) ($sops_check == 0) } # Check if Age is installed export def has-age []: nothing -> bool { let age_check = (bash -c "which age > /dev/null 2>&1; echo $?" | str trim | into int) ($age_check == 0) } # Get detailed deployment capabilities export def get-deployment-capabilities []: nothing -> record { { docker_available: (has-docker) docker_compose_available: (has-docker-compose) podman_available: (has-podman) kubectl_available: (has-kubectl) systemd_available: (has-systemd) ssh_available: (has-ssh) kcl_available: (has-kcl) sops_available: (has-sops) age_available: (has-age) } } # ============================================================================ # NETWORK DETECTION # ============================================================================ # Check if port is available export def is-port-available [ port: int ]: nothing -> bool { let os_type = (detect-os) let port_check = if $os_type == "macos" { bash -c $"lsof -i :($port) > /dev/null 2>&1; echo $?" | str trim | into int } else { bash -c $"netstat -tuln 2>/dev/null | grep -q :($port); echo $?" | str trim | into int } ($port_check != 0) # Port is available if check returns non-zero } # Get available ports in range export def get-available-ports [ start_port: int end_port: int ]: nothing -> list { mut available = [] for port in ($start_port..$end_port) { if (is-port-available $port) { $available = ($available | append $port) } } $available } # Check internet connectivity export def has-internet-connectivity []: nothing -> bool { let curl_check = (bash -c "curl -s -I --max-time 3 https://www.google.com > /dev/null 2>&1; echo $?" | str trim | into int) ($curl_check == 0) } # ============================================================================ # EXISTING CONFIGURATION DETECTION # ============================================================================ # Check if provisioning is already configured export def is-provisioning-configured []: nothing -> bool { let config_base = (get-config-base-path) let system_config = $"($config_base)/system.toml" ($system_config | path exists) } # Get existing provisioning configuration summary export def get-existing-config-summary []: nothing -> record { let config_base = (get-config-base-path) let system_config_exists = ($"($config_base)/system.toml" | path exists) let workspaces_exists = ($"($config_base)/workspaces" | path exists) let user_prefs_exists = ($"($config_base)/user_preferences.toml" | path exists) { config_path: $config_base has_system_config: $system_config_exists has_workspaces: $workspaces_exists has_user_prefs: $user_prefs_exists } } # ============================================================================ # PLATFORM SERVICES DETECTION # ============================================================================ # Check if orchestrator is running export def is-orchestrator-running []: nothing -> bool { let endpoint = "http://localhost:9090/health" let result = (do { curl -s -f --max-time 2 $endpoint o> /dev/null e> /dev/null } | complete) ($result.exit_code == 0) } # Check if control-center is running export def is-control-center-running []: nothing -> bool { let endpoint = "http://localhost:3000/health" let result = (do { curl -s -f --max-time 2 $endpoint o> /dev/null e> /dev/null } | complete) ($result.exit_code == 0) } # Check if KMS service is running export def is-kms-running []: nothing -> bool { let endpoint = "http://localhost:3001/health" let result = (do { curl -s -f --max-time 2 $endpoint o> /dev/null e> /dev/null } | complete) ($result.exit_code == 0) } # Get platform services status export def get-platform-services-status []: nothing -> record { { orchestrator_running: (is-orchestrator-running) orchestrator_endpoint: "http://localhost:9090/health" control_center_running: (is-control-center-running) control_center_endpoint: "http://localhost:3000/health" kms_running: (is-kms-running) kms_endpoint: "http://localhost:3001/health" } } # ============================================================================ # ENVIRONMENT ANALYSIS REPORT # ============================================================================ # Generate comprehensive environment detection report export def generate-detection-report []: nothing -> record { { system: { os: (detect-os) architecture: (detect-architecture) hostname: (get-system-hostname) current_user: (get-current-user) cpu_count: (get-cpu-count) memory_gb: (get-system-memory-gb) disk_gb: (get-system-disk-gb) } capabilities: (get-deployment-capabilities) network: { internet_connected: (has-internet-connectivity) docker_port_available: (is-port-available 2375) orchestrator_port_available: (is-port-available 9090) control_center_port_available: (is-port-available 3000) kms_port_available: (is-port-available 3001) } existing_config: (get-existing-config-summary) platform_services: (get-platform-services-status) timestamp: (date now) } } # Print detection report in readable format export def print-detection-report [ report: record ]: nothing -> nothing { print "" print "╔═══════════════════════════════════════════════════════════════╗" print "║ ENVIRONMENT DETECTION REPORT ║" print "╚═══════════════════════════════════════════════════════════════╝" print "" print "📊 SYSTEM INFORMATION" print "─────────────────────────────────────────────────────────────" print $" OS: ($report.system.os)" print $" Architecture: ($report.system.architecture)" print $" Hostname: ($report.system.hostname)" print $" User: ($report.system.current_user)" print $" CPU Cores: ($report.system.cpu_count)" print $" Memory: ($report.system.memory_gb) GB" print $" Disk Space: ($report.system.disk_gb) GB" print "" print "🛠️ AVAILABLE TOOLS" print "─────────────────────────────────────────────────────────────" print $" Docker: (if $report.capabilities.docker_available { '✅' } else { '❌' })" print $" Docker Compose: (if $report.capabilities.docker_compose_available { '✅' } else { '❌' })" print $" Podman: (if $report.capabilities.podman_available { '✅' } else { '❌' })" print $" Kubernetes: (if $report.capabilities.kubectl_available { '✅' } else { '❌' })" print $" Systemd: (if $report.capabilities.systemd_available { '✅' } else { '❌' })" print $" SSH: (if $report.capabilities.ssh_available { '✅' } else { '❌' })" print $" KCL: (if $report.capabilities.kcl_available { '✅' } else { '❌' })" print $" SOPS: (if $report.capabilities.sops_available { '✅' } else { '❌' })" print $" Age: (if $report.capabilities.age_available { '✅' } else { '❌' })" print "" print "🌐 NETWORK STATUS" print "─────────────────────────────────────────────────────────────" print $" Internet: (if $report.network.internet_connected { '✅' } else { '❌' })" print $" Docker Port: (if $report.network.docker_port_available { '✅ Available' } else { '❌ In Use' })" print $" Orchestrator: (if $report.network.orchestrator_port_available { '✅ Available' } else { '❌ In Use' })" print $" Control Center: (if $report.network.control_center_port_available { '✅ Available' } else { '❌ In Use' })" print $" KMS Service: (if $report.network.kms_port_available { '✅ Available' } else { '❌ In Use' })" print "" print "📁 EXISTING CONFIGURATION" print "─────────────────────────────────────────────────────────────" print $" Config Path: ($report.existing_config.config_path)" print $" Configured: (if $report.existing_config.has_system_config { '✅ Yes' } else { '❌ No' })" print $" Workspaces: (if $report.existing_config.has_workspaces { '✅ Yes' } else { '❌ No' })" print $" Preferences: (if $report.existing_config.has_user_prefs { '✅ Yes' } else { '❌ No' })" print "" print "⚙️ PLATFORM SERVICES" print "─────────────────────────────────────────────────────────────" print $" Orchestrator: (if $report.platform_services.orchestrator_running { '✅ Running' } else { '❌ Not Running' })" print $" Control Center: (if $report.platform_services.control_center_running { '✅ Running' } else { '❌ Not Running' })" print $" KMS Service: (if $report.platform_services.kms_running { '✅ Running' } else { '❌ Not Running' })" print "" print "═══════════════════════════════════════════════════════════════" print "" } # Recommend deployment mode based on available capabilities export def recommend-deployment-mode [ report: record ]: nothing -> string { let caps = $report.capabilities if ($caps.docker_available and $caps.docker_compose_available) { "docker-compose" } else if ($caps.kubectl_available) { "kubernetes" } else if ($caps.ssh_available) { "remote-ssh" } else if ($caps.systemd_available) { "systemd" } else { "unknown" } } # Get recommended deployment configuration export def get-recommended-config [ report: record ]: nothing -> record { let deployment_mode = (recommend-deployment-mode $report) let caps = $report.capabilities { deployment_mode: $deployment_mode supported_modes: { docker_compose: ($caps.docker_available and $caps.docker_compose_available) kubernetes: ($caps.kubectl_available) remote_ssh: ($caps.ssh_available) systemd: ($caps.systemd_available) } recommended_os_paths: { config_base: (get-config-base-path) workspaces: $"(get-config-base-path)/workspaces" cache: $"(get-config-base-path)/cache" } required_tools_missing: (get-missing-required-tools $report) } } # Get list of missing required tools export def get-missing-required-tools [ report: record ]: nothing -> list { mut missing = [] if not $report.capabilities.kcl_available { $missing = ($missing | append "kcl") } if not $report.capabilities.sops_available { $missing = ($missing | append "sops") } if not $report.capabilities.age_available { $missing = ($missing | append "age") } # At least one deployment method is required let has_deployment = ( ($report.capabilities.docker_available) or ($report.capabilities.kubectl_available) or ($report.capabilities.ssh_available) or ($report.capabilities.systemd_available) ) if not $has_deployment { $missing = ($missing | append "deployment-method (docker/kubernetes/ssh/systemd)") } $missing }