#!/usr/bin/env nu # API Server management for Provisioning System # Provides HTTP REST API endpoints for infrastructure management use ../api/server.nu * use ../api/routes.nu * use ../lib_provisioning/utils/settings.nu * use ../lib_provisioning/config/accessor.nu * export def "main api" [ command?: string # Command: start, stop, status, docs --port (-p): int = 8080 # Port to run the API server on --host: string = "localhost" # Host to bind the server to --enable-websocket # Enable WebSocket support for real-time updates --enable-cors # Enable CORS for cross-origin requests --debug (-d) # Enable debug mode --background (-b) # Run server in background --config-file: string # Custom configuration file path --ssl # Enable SSL/TLS (requires certificates) --cert-file: string # SSL certificate file path --key-file: string # SSL private key file path --doc-format: string = "markdown" # Documentation format (markdown, json, yaml) ]: nothing -> nothing { let cmd = $command | default "start" match $cmd { "start" => { print $"πŸš€ Starting Provisioning API Server..." # Validate configuration let config_valid = validate_api_config --port $port --host $host if not $config_valid.valid { error make { msg: $"Invalid configuration: ($config_valid.errors | str join ', ')" help: "Please check your configuration and try again" } } # Check dependencies check_api_dependencies # Start the server if $background { start_api_background --port $port --host $host --enable-websocket $enable_websocket --enable-cors $enable_cors --debug $debug } else { start_api_server --port $port --host $host --enable-websocket $enable_websocket --enable-cors $enable_cors --debug $debug } } "stop" => { print "πŸ›‘ Stopping API server..." stop_api_server --port $port --host $host } "status" => { print "πŸ” Checking API server status..." let health = check_api_health --port $port --host $host print ($health | table) } "docs" => { print "πŸ“š Generating API documentation..." generate_api_documentation --format $doc_format } "routes" => { print "πŸ—ΊοΈ Listing API routes..." let routes = get_route_definitions print ($routes | select method path description | table) } "validate" => { print "βœ… Validating API configuration..." let validation = validate_routes print ($validation | table) } "spec" => { print "πŸ“‹ Generating OpenAPI specification..." let spec = generate_api_spec print ($spec | to json) } _ => { print_api_help } } } def validate_api_config [ --port: int --host: string ]: nothing -> record { mut errors = [] mut valid = true # Validate port range if $port < 1024 or $port > 65535 { $errors = ($errors | append "Port must be between 1024 and 65535") $valid = false } # Validate host format if ($host | str contains " ") { $errors = ($errors | append "Host cannot contain spaces") $valid = false } # Check if port is available if $valid { let port_available = (do -i { http listen $port --host $host --timeout 1 | ignore false } | default true) if not $port_available { $errors = ($errors | append $"Port ($port) is already in use") $valid = false } } { valid: $valid errors: $errors port: $port host: $host } } def check_api_dependencies []: nothing -> nothing { print "πŸ” Checking dependencies..." # Check Python availability let python_available = (do -i { python3 --version } | complete | get exit_code) == 0 if not $python_available { error make { msg: "Python 3 is required for the API server" help: "Please install Python 3 and ensure it's available in PATH" } } # Check required environment variables if ($env.PROVISIONING_PATH? | is-empty) { print "⚠️ Warning: PROVISIONING_PATH not set, using current directory" $env.PROVISIONING_PATH = (pwd) } print "βœ… All dependencies satisfied" } def start_api_background [ --port: int --host: string --enable-websocket --enable-cors --debug ]: nothing -> nothing { print $"πŸš€ Starting API server in background on ($host):($port)..." # Create background process let server_cmd = $"nu -c 'use ($env.PWD)/core/nulib/api/server.nu; start_api_server --port ($port) --host ($host)'" if $enable_websocket { $server_cmd = $server_cmd + " --enable-websocket" } if $enable_cors { $server_cmd = $server_cmd + " --enable-cors" } if $debug { $server_cmd = $server_cmd + " --debug" } # Save PID for later management let pid_file = $"/tmp/provisioning-api-($port).pid" bash -c $"($server_cmd) & echo $! > ($pid_file)" sleep 2sec let health = check_api_health --port $port --host $host if $health.api_server { print $"βœ… API server started successfully in background" print $"πŸ“ PID file: ($pid_file)" print $"🌐 URL: http://($host):($port)" } else { print "❌ Failed to start API server" } } def stop_api_server [ --port: int --host: string ]: nothing -> nothing { let pid_file = $"/tmp/provisioning-api-($port).pid" if ($pid_file | path exists) { let pid = (open $pid_file | str trim) print $"πŸ›‘ Stopping API server (PID: ($pid))..." try { kill $pid rm -f $pid_file print "βœ… API server stopped successfully" } catch { print "⚠️ Failed to stop server, trying force kill..." kill -9 $pid rm -f $pid_file print "βœ… Server force stopped" } } else { print "⚠️ No running API server found on port ($port)" # Try to find and kill any Python processes running the API let python_pids = (ps | where name =~ "python3" and command =~ "provisioning_api_server" | get pid) if ($python_pids | length) > 0 { print $"πŸ” Found ($python_pids | length) related processes, stopping them..." $python_pids | each { |pid| kill $pid } print "βœ… Related processes stopped" } } } def generate_api_documentation [ --format: string = "markdown" ]: nothing -> nothing { let output_file = match $format { "markdown" => "api_documentation.md" "json" => "api_spec.json" "yaml" => "api_spec.yaml" _ => "api_documentation.md" } match $format { "markdown" => { let docs = generate_route_docs $docs | save --force $output_file print $"πŸ“š Markdown documentation saved to: ($output_file)" } "json" => { let spec = generate_api_spec $spec | to json | save --force $output_file print $"πŸ“‹ OpenAPI JSON spec saved to: ($output_file)" } "yaml" => { let spec = generate_api_spec $spec | to yaml | save --force $output_file print $"πŸ“‹ OpenAPI YAML spec saved to: ($output_file)" } _ => { print $"❌ Unsupported format: ($format)" print "Supported formats: markdown, json, yaml" } } } def print_api_help []: nothing -> nothing { print " πŸš€ Provisioning API Server Management USAGE: provisioning api [COMMAND] [OPTIONS] COMMANDS: start Start the API server (default) stop Stop the API server status Check server status docs Generate API documentation routes List all available routes validate Validate API configuration spec Generate OpenAPI specification OPTIONS: -p, --port Port to run server on [default: 8080] --host Host to bind to [default: localhost] --enable-websocket Enable WebSocket support --enable-cors Enable CORS headers -d, --debug Enable debug mode -b, --background Run in background --doc-format Documentation format [default: markdown] EXAMPLES: # Start server on default port provisioning api start # Start on custom port with debugging provisioning api start --port 9090 --debug # Start in background with WebSocket support provisioning api start --background --enable-websocket # Generate API documentation provisioning api docs --doc-format json # Check server status provisioning api status # Stop running server provisioning api stop ENDPOINTS: GET /api/v1/health Health check GET /api/v1/query Query infrastructure POST /api/v1/query Complex queries GET /api/v1/metrics System metrics GET /api/v1/logs System logs GET /api/v1/dashboard Dashboard data GET /api/v1/servers List servers POST /api/v1/servers Create server GET /api/v1/ai/query AI-powered queries For more information, visit: https://docs.provisioning.dev/api " }