143 lines
4.2 KiB
Rust
143 lines
4.2 KiB
Rust
|
|
#!/usr/bin/env -S cargo run --
|
|||
|
|
//! Simple Rust-native MCP Server for Provisioning
|
|||
|
|
//!
|
|||
|
|
//! A minimal working implementation that shows Rust feasibility
|
|||
|
|
|
|||
|
|
use anyhow::Result;
|
|||
|
|
use clap::Parser;
|
|||
|
|
use std::path::PathBuf;
|
|||
|
|
use tracing::{info, error, debug};
|
|||
|
|
use serde_json::json;
|
|||
|
|
|
|||
|
|
mod config;
|
|||
|
|
mod provisioning;
|
|||
|
|
mod tools;
|
|||
|
|
mod errors;
|
|||
|
|
|
|||
|
|
use config::Config;
|
|||
|
|
use provisioning::ProvisioningEngine;
|
|||
|
|
use tools::ProvisioningTools;
|
|||
|
|
|
|||
|
|
#[derive(Parser, Debug)]
|
|||
|
|
#[command(name = "provisioning-mcp-server")]
|
|||
|
|
#[command(about = "Rust-native MCP server for Cloud Native Provisioning")]
|
|||
|
|
#[command(version)]
|
|||
|
|
struct Args {
|
|||
|
|
/// Configuration file path
|
|||
|
|
#[arg(short, long, env = "PROVISIONING_MCP_CONFIG")]
|
|||
|
|
config: Option<PathBuf>,
|
|||
|
|
|
|||
|
|
/// Provisioning system path
|
|||
|
|
#[arg(short, long, env = "PROVISIONING_PATH")]
|
|||
|
|
provisioning_path: Option<PathBuf>,
|
|||
|
|
|
|||
|
|
/// Debug mode
|
|||
|
|
#[arg(short, long, env = "PROVISIONING_DEBUG")]
|
|||
|
|
debug: bool,
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[tokio::main]
|
|||
|
|
async fn main() -> Result<()> {
|
|||
|
|
let args = Args::parse();
|
|||
|
|
|
|||
|
|
// Initialize tracing
|
|||
|
|
tracing_subscriber::fmt()
|
|||
|
|
.with_max_level(if args.debug {
|
|||
|
|
tracing::Level::DEBUG
|
|||
|
|
} else {
|
|||
|
|
tracing::Level::INFO
|
|||
|
|
})
|
|||
|
|
.init();
|
|||
|
|
|
|||
|
|
info!("🦀 Starting Rust-native MCP Server for Provisioning");
|
|||
|
|
|
|||
|
|
// Load configuration
|
|||
|
|
let config = Config::load(
|
|||
|
|
args.config,
|
|||
|
|
args.provisioning_path,
|
|||
|
|
args.debug,
|
|||
|
|
)?;
|
|||
|
|
|
|||
|
|
info!("Configuration loaded successfully");
|
|||
|
|
info!("Provisioning path: {}", config.provisioning_path.display());
|
|||
|
|
info!("AI enabled: {}", config.is_ai_available());
|
|||
|
|
|
|||
|
|
// Initialize components
|
|||
|
|
let engine = ProvisioningEngine::new(&config)?;
|
|||
|
|
let tools = ProvisioningTools::new(&config);
|
|||
|
|
|
|||
|
|
info!("🚀 MCP Server components initialized");
|
|||
|
|
|
|||
|
|
// Run basic tests to verify functionality
|
|||
|
|
test_components(&engine, &tools).await?;
|
|||
|
|
|
|||
|
|
// Run performance tests
|
|||
|
|
info!("⚡ Running performance benchmarks...");
|
|||
|
|
let performance_results = provisioning_mcp_server::performance_test::run_performance_tests();
|
|||
|
|
println!("\n{}", performance_results);
|
|||
|
|
|
|||
|
|
info!("✅ Rust MCP Server validation complete");
|
|||
|
|
Ok(())
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
async fn test_components(engine: &ProvisioningEngine, tools: &ProvisioningTools) -> Result<()> {
|
|||
|
|
info!("🧪 Testing server components...");
|
|||
|
|
|
|||
|
|
// Test configuration parsing
|
|||
|
|
let test_description = "Create 2 servers with 4 CPU cores for kubernetes cluster on AWS";
|
|||
|
|
match tools.parse_server_description(test_description) {
|
|||
|
|
Ok(server_json) => {
|
|||
|
|
info!("✅ Server parsing test passed");
|
|||
|
|
info!(" Parsed: {} x {} servers for {}",
|
|||
|
|
server_json.get("count").and_then(|v| v.as_u64()).unwrap_or(1),
|
|||
|
|
server_json.get("instance_type").and_then(|v| v.as_str()).unwrap_or("unknown"),
|
|||
|
|
server_json.get("purpose").and_then(|v| v.as_str()).unwrap_or("general"));
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
error!("❌ Server parsing test failed: {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
// Test AI status
|
|||
|
|
let ai_status = tools.get_ai_status()?;
|
|||
|
|
info!("🤖 AI Status:\n{}", ai_status);
|
|||
|
|
|
|||
|
|
// Test basic infrastructure status
|
|||
|
|
match engine.get_status(None, false) {
|
|||
|
|
Ok(status) => {
|
|||
|
|
info!("✅ Infrastructure status test passed");
|
|||
|
|
debug!("Status: {}", status);
|
|||
|
|
}
|
|||
|
|
Err(e) => {
|
|||
|
|
info!("ℹ️ Infrastructure status (expected if no infrastructure exists): {}", e);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
Ok(())
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[cfg(test)]
|
|||
|
|
mod tests {
|
|||
|
|
use super::*;
|
|||
|
|
|
|||
|
|
#[tokio::test]
|
|||
|
|
async fn test_server_creation() {
|
|||
|
|
let config = Config::default();
|
|||
|
|
let engine = ProvisioningEngine::new(&config).expect("Failed to create engine");
|
|||
|
|
let tools = ProvisioningTools::new(&config);
|
|||
|
|
|
|||
|
|
// Test parsing
|
|||
|
|
let result = tools.parse_server_description("Create 1 server for web hosting");
|
|||
|
|
assert!(result.is_ok());
|
|||
|
|
|
|||
|
|
let server_config = result.unwrap();
|
|||
|
|
assert_eq!(server_config.count, 1);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
#[test]
|
|||
|
|
fn test_config_loading() {
|
|||
|
|
let config = Config::default();
|
|||
|
|
assert!(!config.debug);
|
|||
|
|
assert!(config.provisioning_path.exists() || !config.provisioning_path.to_string_lossy().contains("/usr/local/provisioning"));
|
|||
|
|
}
|
|||
|
|
}
|