Skip to main content
Glama
moimran
by moimran
verify_production_ready.py13.6 kB
#!/usr/bin/env python3 """ Production Readiness Verification Script Verifies that the EVE-NG MCP Server is ready for production deployment """ import json import os import subprocess import sys from pathlib import Path from typing import Dict, List, Tuple class ProductionReadinessChecker: def __init__(self): self.project_root = Path(__file__).parent.parent self.checks = [] self.passed = 0 self.failed = 0 def check(self, name: str, condition: bool, details: str = "") -> bool: """Record a check result""" status = "✅ PASS" if condition else "❌ FAIL" self.checks.append({ "name": name, "status": status, "condition": condition, "details": details }) if condition: self.passed += 1 else: self.failed += 1 print(f"{status} {name}") if details and not condition: print(f" 📝 {details}") return condition def check_file_exists(self, file_path: str, description: str) -> bool: """Check if a file exists""" path = self.project_root / file_path exists = path.exists() details = f"Missing: {file_path}" if not exists else "" return self.check(description, exists, details) def check_directory_exists(self, dir_path: str, description: str) -> bool: """Check if a directory exists""" path = self.project_root / dir_path exists = path.exists() and path.is_dir() details = f"Missing directory: {dir_path}" if not exists else "" return self.check(description, exists, details) def check_python_syntax(self, file_path: str) -> bool: """Check Python file syntax""" try: with open(self.project_root / file_path, 'r') as f: compile(f.read(), file_path, 'exec') return True except SyntaxError as e: return False def run_command(self, command: List[str], cwd: Path = None) -> Tuple[bool, str]: """Run a command and return success status and output""" try: result = subprocess.run( command, cwd=cwd or self.project_root, capture_output=True, text=True, timeout=30 ) return result.returncode == 0, result.stdout + result.stderr except Exception as e: return False, str(e) def check_documentation(self): """Check documentation completeness""" print("\n📚 Checking Documentation") print("=" * 40) # Main documentation files self.check_file_exists("README.md", "Main README exists") self.check_file_exists("docs/README.md", "Documentation hub exists") self.check_file_exists("docs/api/README.md", "API documentation exists") self.check_file_exists("docs/deployment/README.md", "Deployment guide exists") self.check_file_exists("docs/troubleshooting/README.md", "Troubleshooting guide exists") self.check_file_exists("docs/integrations/README.md", "Integration guide exists") self.check_file_exists("docs/integrations/claude-desktop.md", "Claude Desktop guide exists") self.check_file_exists("docs/integrations/vscode.md", "VS Code guide exists") # Integration examples self.check_directory_exists("examples/integrations", "Integration examples directory exists") self.check_file_exists("examples/integrations/claude-desktop-config.json", "Claude Desktop config example exists") self.check_file_exists("examples/integrations/vscode-workspace.json", "VS Code workspace example exists") self.check_file_exists("examples/integrations/deploy_lab.py", "Lab deployment script exists") self.check_file_exists("examples/integrations/sample-lab.json", "Sample lab configuration exists") # Check README content readme_path = self.project_root / "README.md" if readme_path.exists(): content = readme_path.read_text() self.check("README has installation instructions", "installation" in content.lower()) self.check("README has usage examples", "usage" in content.lower()) self.check("README has API reference", "api" in content.lower()) self.check("README has integration information", "integration" in content.lower()) def check_testing_framework(self): """Check testing framework completeness""" print("\n🧪 Checking Testing Framework") print("=" * 40) # Test structure self.check_directory_exists("tests", "Tests directory exists") self.check_directory_exists("tests/unit", "Unit tests directory exists") self.check_directory_exists("tests/integration", "Integration tests directory exists") self.check_directory_exists("tests/e2e", "E2E tests directory exists") self.check_directory_exists("tests/performance", "Performance tests directory exists") self.check_directory_exists("tests/fixtures", "Test fixtures directory exists") # Test configuration self.check_file_exists("tests/conftest.py", "Pytest configuration exists") self.check_file_exists("tests/requirements.txt", "Test requirements exist") self.check_file_exists("tests/run_tests.py", "Test runner exists") self.check_file_exists("tests/README.md", "Testing guide exists") # Sample tests self.check_file_exists("tests/unit/test_client.py", "Sample unit test exists") # Check test runner syntax test_runner_path = "tests/run_tests.py" if (self.project_root / test_runner_path).exists(): syntax_ok = self.check_python_syntax(test_runner_path) self.check("Test runner has valid syntax", syntax_ok) def check_deployment_configuration(self): """Check deployment configuration""" print("\n🚀 Checking Deployment Configuration") print("=" * 40) # Docker self.check_file_exists("Dockerfile", "Dockerfile exists") # Configuration self.check_directory_exists("config", "Config directory exists") self.check_file_exists("config/production.json", "Production config exists") # Systemd self.check_directory_exists("deployment", "Deployment directory exists") self.check_file_exists("deployment/systemd/eveng-mcp-server.service", "Systemd service file exists") # Check production config prod_config_path = self.project_root / "config/production.json" if prod_config_path.exists(): try: with open(prod_config_path) as f: config = json.load(f) self.check("Production config is valid JSON", True) self.check("Production config has EVE-NG settings", "eveng" in config) self.check("Production config has MCP settings", "mcp" in config) self.check("Production config has security settings", "security" in config) except json.JSONDecodeError: self.check("Production config is valid JSON", False, "Invalid JSON format") def check_code_quality(self): """Check code quality configuration""" print("\n🔧 Checking Code Quality") print("=" * 40) # Project configuration self.check_file_exists("pyproject.toml", "Project configuration exists") self.check_file_exists(".gitignore", "Gitignore exists") # Check pyproject.toml pyproject_path = self.project_root / "pyproject.toml" if pyproject_path.exists(): content = pyproject_path.read_text() self.check("Project has proper metadata", "[project]" in content) self.check("Project has dependencies", "dependencies" in content) self.check("Project has dev dependencies", "[project.optional-dependencies]" in content) self.check("Project has test configuration", "[tool.pytest.ini_options]" in content) self.check("Project has coverage configuration", "[tool.coverage" in content) def check_core_functionality(self): """Check core functionality""" print("\n⚙️ Checking Core Functionality") print("=" * 40) # Core modules self.check_directory_exists("eveng_mcp_server", "Main package exists") self.check_file_exists("eveng_mcp_server/__init__.py", "Package init exists") self.check_file_exists("eveng_mcp_server/cli.py", "CLI module exists") self.check_file_exists("eveng_mcp_server/server.py", "Server module exists") # Sub-packages self.check_directory_exists("eveng_mcp_server/tools", "Tools package exists") self.check_directory_exists("eveng_mcp_server/resources", "Resources package exists") self.check_directory_exists("eveng_mcp_server/prompts", "Prompts package exists") self.check_directory_exists("eveng_mcp_server/config", "Config package exists") # Check syntax of main modules for module in ["eveng_mcp_server/cli.py", "eveng_mcp_server/server.py"]: if (self.project_root / module).exists(): syntax_ok = self.check_python_syntax(module) self.check(f"{module} has valid syntax", syntax_ok) def check_dependencies(self): """Check dependencies and installation""" print("\n📦 Checking Dependencies") print("=" * 40) # Check if UV is available uv_available, _ = self.run_command(["uv", "--version"]) self.check("UV package manager available", uv_available, "Install UV: curl -LsSf https://astral.sh/uv/install.sh | sh") # Check if dependencies can be resolved if uv_available: deps_ok, output = self.run_command(["uv", "sync", "--dry-run"]) self.check("Dependencies can be resolved", deps_ok, "Run 'uv sync' to install dependencies") # Check lock file self.check_file_exists("uv.lock", "Lock file exists") def check_security(self): """Check security configuration""" print("\n🔐 Checking Security Configuration") print("=" * 40) # Check .gitignore for sensitive files gitignore_path = self.project_root / ".gitignore" if gitignore_path.exists(): content = gitignore_path.read_text() self.check("Gitignore excludes .env files", ".env" in content) self.check("Gitignore excludes logs", "*.log" in content) self.check("Gitignore excludes secrets", "secrets" in content) # Check for hardcoded secrets (basic check) sensitive_patterns = ["password", "secret", "key", "token"] config_files = ["config/production.json"] for config_file in config_files: config_path = self.project_root / config_file if config_path.exists(): content = config_path.read_text().lower() has_env_vars = "${" in content or "env" in content self.check(f"{config_file} uses environment variables", has_env_vars) def generate_report(self): """Generate final report""" print("\n📊 Production Readiness Report") print("=" * 60) total_checks = self.passed + self.failed success_rate = (self.passed / total_checks) * 100 if total_checks > 0 else 0 print(f"Total Checks: {total_checks}") print(f"✅ Passed: {self.passed}") print(f"❌ Failed: {self.failed}") print(f"📈 Success Rate: {success_rate:.1f}%") if self.failed > 0: print(f"\n❌ Failed Checks:") for check in self.checks: if not check["condition"]: print(f" - {check['name']}") if check["details"]: print(f" {check['details']}") print(f"\n🎯 Production Readiness Status:") if success_rate >= 95: print("✅ READY FOR PRODUCTION") print("All critical checks passed. The project is production-ready!") elif success_rate >= 80: print("⚠️ MOSTLY READY") print("Most checks passed. Address failed checks before production deployment.") else: print("❌ NOT READY") print("Multiple critical issues found. Address all failed checks before deployment.") return success_rate >= 95 def run_all_checks(self): """Run all production readiness checks""" print("🚀 EVE-NG MCP Server - Production Readiness Check") print("=" * 60) self.check_documentation() self.check_testing_framework() self.check_deployment_configuration() self.check_code_quality() self.check_core_functionality() self.check_dependencies() self.check_security() return self.generate_report() def main(): """Main entry point""" checker = ProductionReadinessChecker() is_ready = checker.run_all_checks() # Exit with appropriate code sys.exit(0 if is_ready else 1) if __name__ == "__main__": main()

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/moimran/eveng-mcp'

If you have feedback or need assistance with the MCP directory API, please join our Discord server