356 lines
14 KiB
Plaintext
Raw Permalink Normal View History

# 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<int> {
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<string> {
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
}