#!/usr/bin/env nu # Port Management Script for Provisioning Platform # Centralizes port configuration and updates across all services const DEFAULT_PORTS = { orchestrator: 9090, control_center: 9080, api_gateway: 9083, mcp_server: 9082, oci_registry: 5000, coredns: 5353, gitea: 3000, frontend: 3001, surrealdb: 8000, redis: 6379, postgresql: 5432 } # Show current port configuration export def "main show" [] { print "šŸ“Š Current Port Configuration\n" let config = load_current_config $config | each {|service| print $" ($service.name | fill -a right -c ' ' -w 20): ($service.port) \(($service.status)\)" } } # Check if ports are in use export def "main check" [] { print "šŸ” Checking port availability\n" for service in ($DEFAULT_PORTS | transpose key value) { let port = $service.value let in_use = (is_port_in_use $port) if $in_use { let process = (get_process_on_port $port) print $" āš ļø ($service.key | fill -a right -c ' ' -w 20): Port ($port) IN USE by ($process)" } else { print $" āœ… ($service.key | fill -a right -c ' ' -w 20): Port ($port) available" } } } # Update port configuration across all files export def "main update" [ service: string # Service name (orchestrator, control_center, etc) new_port: int # New port number --apply # Apply changes (default is dry-run) ] { if $service not-in ($DEFAULT_PORTS | columns) { error make {msg: $"Unknown service: ($service). Available: ($DEFAULT_PORTS | columns | str join ', ')"} } let old_port = ($DEFAULT_PORTS | get $service) print $"šŸ“ Updating ($service) port: ($old_port) → ($new_port)\n" # Get files to update let files = (get_files_for_service $service) if ($files | is-empty) { print " ā„¹ļø No configuration files found for this service" return } print $" Found ($files | length) files to update:\n" for file in $files { let changes = (preview_changes $file $old_port $new_port) if ($changes | length) > 0 { print $" šŸ“„ ($file)" print $" Changes: ($changes | length) line\(s\)" if $apply { update_file $file $old_port $new_port $service print " āœ… Applied" } else { print " ā­ļø Dry-run \(use --apply to apply\)" } } } if not $apply { print $"\nšŸ’” Run with --apply to apply changes" } else { print $"\nāœ… Port updated. Remember to rebuild and restart the service!" } } # Verify port configuration is consistent export def "main verify" [] { print "šŸ”Ž Verifying port configuration consistency\n" let issues = [] for service in ($DEFAULT_PORTS | transpose key value) { let service_name = $service.key let expected_port = $service.value let files = (get_files_for_service $service_name) for file in $files { if ($file | path exists) { let content = (open $file) let found_ports = (extract_ports_from_file $file $service_name) for port in $found_ports { if $port != $expected_port { print $" āš ļø ($service_name) in ($file): Found port ($port), expected ($expected_port)" } } } } } print "\nāœ… Verification complete" } # Migrate from old ports to new ports export def "main migrate" [ --orchestrator: int = 9090 # New orchestrator port --control_center: int = 9080 # New control center port --apply # Apply changes ] { print "šŸ”„ Port Migration Tool\n" print "Migration plan:" print $" Orchestrator: 8080 → ($orchestrator)" print $" Control Center: 8081 → ($control_center)" print "" if not $apply { print "āš ļø DRY RUN MODE - No changes will be made" print " Use --apply to apply changes\n" } # Orchestrator if $orchestrator != 8080 { main update orchestrator $orchestrator --apply=$apply } # Control Center if $control_center != 8081 { main update control_center $control_center --apply=$apply } if $apply { print "\nāœ… Migration complete!" print "\nšŸ“‹ Next steps:" print " 1. Rebuild services: cd provisioning/platform/orchestrator && cargo build --release" print " 2. Rebuild services: cd provisioning/platform/control-center && cargo build --release" print " 3. Restart services" } } # Helper: Load current configuration def load_current_config [] { [ {name: "orchestrator", port: (get_port_from_file "provisioning/platform/orchestrator/config.defaults.toml" "port"), status: "configured"}, {name: "control_center", port: (get_port_from_file "provisioning/platform/control-center/config.defaults.toml" "port"), status: "configured"}, {name: "oci_registry", port: 5000, status: "static"}, {name: "coredns", port: 5353, status: "static"}, {name: "gitea", port: 3000, status: "static"}, {name: "surrealdb", port: 8000, status: "static"} ] } # Helper: Check if port is in use def is_port_in_use [port: int] { let result = (do { lsof -i $":($port)" | complete } | get exit_code) $result == 0 } # Helper: Get process using port def get_process_on_port [port: int] { try { let output = (lsof -i $":($port)" | lines | get 1 | split row -r '\s+') $"($output.0) \(PID: ($output.1)\)" } catch { "unknown" } } # Helper: Get files for a service def get_files_for_service [service: string] { let base = "/Users/Akasha/project-provisioning" match $service { "orchestrator" => [ $"($base)/provisioning/platform/orchestrator/src/lib.rs", $"($base)/provisioning/platform/orchestrator/config.defaults.toml", $"($base)/provisioning/platform/orchestrator/scripts/start-orchestrator.nu" ], "control_center" => [ $"($base)/provisioning/platform/control-center/src/simple_config.rs", $"($base)/provisioning/platform/control-center/config.defaults.toml" ], _ => [] } } # Helper: Preview changes in a file def preview_changes [file: string, old_port: int, new_port: int] { if not ($file | path exists) { return [] } let content = (open $file) let lines = ($content | lines) $lines | enumerate | where {|it| ($it.item | str contains $"($old_port)") } | get index } # Helper: Update file def update_file [file: string, old_port: int, new_port: int, service: string] { let content = (open $file) # Different update strategies based on file type let updated = if ($file | str ends-with ".rs") { # Rust file - careful replacement $content | str replace -a $"port = ($old_port)" $"port = ($new_port)" | str replace -a $"default_value = \"($old_port)\"" $"default_value = \"($new_port)\"" } else if ($file | str ends-with ".toml") { # TOML file $content | str replace -a $"port = ($old_port)" $"port = ($new_port)" } else if ($file | str ends-with ".nu") { # Nushell file $content | str replace -a $"= ($old_port)" $"= ($new_port)" | str replace -a $": int = ($old_port)" $": int = ($new_port)" } else { $content } $updated | save -f $file } # Helper: Get port from TOML file def get_port_from_file [file: string, key: string] { try { let full_path = $"/Users/Akasha/project-provisioning/($file)" if ($full_path | path exists) { let content = (open $full_path) let match = ($content | lines | find -r $"($key)\\s*=\\s*(\\d+)" | first) if ($match | is-empty) { return 0 } ($match | parse -r $"($key)\\s*=\\s*(?\\d+)" | get port.0 | into int) } else { 0 } } catch { 0 } } # Helper: Extract ports from file for service def extract_ports_from_file [file: string, service: string] { try { let content = (open $file) let matches = ($content | lines | find -r '\d{4,5}' | parse -r '(?\d{4,5})') $matches | get port | into int | uniq } catch { [] } } # Main help export def main [] { print "Port Management for Provisioning Platform\n" print "Usage:" print " manage-ports.nu show - Show current port configuration" print " manage-ports.nu check - Check if ports are available" print " manage-ports.nu update [--apply] - Update service port" print " manage-ports.nu verify - Verify configuration consistency" print " manage-ports.nu migrate [--apply] - Migrate from old to new ports" print "" print "Examples:" print " manage-ports.nu check" print " manage-ports.nu update orchestrator 9090 --apply" print " manage-ports.nu migrate --orchestrator 9090 --control_center 9080 --apply" }