Spaces:
Running
Running
| """ | |
| API routes for script generation. | |
| """ | |
| import os | |
| import uuid | |
| from fastapi import APIRouter, Depends, HTTPException, Request, status | |
| from app.api.deps import get_devops_service, get_logger, get_settings | |
| from app.core.security import limiter | |
| from app.models.schemas import ConfigState, GeneratedFiles | |
| from app.services.script_validator import ScriptValidator | |
| from app.core.logging import logger as app_logger | |
| router = APIRouter() | |
| script_validator = ScriptValidator(app_logger) | |
| async def generate_script( | |
| request: Request, | |
| config: ConfigState, | |
| service=Depends(get_devops_service), | |
| settings=Depends(get_settings), | |
| logger=Depends(get_logger), | |
| ): | |
| """Generate a VPS setup script based on configuration.""" | |
| client_ip = request.client.host if request.client else "unknown" | |
| logger.info(f"Script generation request from {client_ip} for {config.stackType}") | |
| try: | |
| # Generate unique filename | |
| script_id = str(uuid.uuid4())[:8] | |
| # Generate bash script | |
| script_content = service.generate_bash_script(config, script_id) | |
| script_filename = f"setup-{script_id}.sh" | |
| script_path = settings.generated_dir / script_filename | |
| # Ensure generated directory exists | |
| script_path.parent.mkdir(exist_ok=True) | |
| # Write script file | |
| with open(script_path, "w") as f: | |
| f.write(script_content) | |
| # Make script executable | |
| os.chmod(script_path, 0o755) | |
| # Create script URL for frontend | |
| script_url = f"/download/{script_filename}" | |
| response = GeneratedFiles( | |
| script_path=str(script_path), | |
| script_url=script_url, | |
| description="VPS Setup Script for " + config.stackType + | |
| " + " + config.webServer + " + " + | |
| (config.database or "No Database"), | |
| ) | |
| # Generate nginx config if web server is selected | |
| if config.webServer and config.webServer != "none": | |
| nginx_config = service.generate_nginx_config(config, script_id) | |
| nginx_filename = f"nginx-{script_id}.conf" | |
| nginx_path = settings.generated_dir / nginx_filename | |
| with open(nginx_path, "w") as f: | |
| f.write(nginx_config) | |
| response.nginx_config_path = str(nginx_path) | |
| response.nginx_url = f"/download/{nginx_filename}" | |
| return response | |
| except Exception as e: | |
| logger.error(f"Failed to generate script: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to generate script: {str(e)}", | |
| ) | |
| async def validate_script( | |
| request: Request, | |
| file_id: str, | |
| logger=Depends(get_logger), | |
| settings=Depends(get_settings), | |
| ): | |
| """ | |
| Validate a generated bash script for syntax and best practices | |
| """ | |
| client_ip = request.client.host if request.client else "unknown" | |
| logger.info(f"Script validation request from {client_ip} for file {file_id}") | |
| try: | |
| # Find the script file | |
| script_path = settings.generated_dir / f"setup-{file_id}.sh" | |
| if not script_path.exists(): | |
| raise HTTPException( | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| detail=f"Script not found: {file_id}" | |
| ) | |
| # Read script content | |
| with open(script_path, 'r') as f: | |
| script_content = f.read() | |
| # Validate | |
| validation_result = script_validator.validate_bash_script(script_content) | |
| logger.info(f"Validation result for {file_id}: valid={validation_result['valid']}, score={validation_result['score']}") | |
| return validation_result | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error(f"Failed to validate script: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to validate script: {str(e)}" | |
| ) | |
| async def validate_nginx( | |
| request: Request, | |
| file_id: str, | |
| logger=Depends(get_logger), | |
| settings=Depends(get_settings), | |
| ): | |
| """ | |
| Validate a generated nginx configuration for syntax and best practices | |
| """ | |
| client_ip = request.client.host if request.client else "unknown" | |
| logger.info(f"Nginx validation request from {client_ip} for file {file_id}") | |
| try: | |
| # Find the nginx config file | |
| nginx_path = settings.generated_dir / f"nginx-{file_id}.conf" | |
| if not nginx_path.exists(): | |
| raise HTTPException( | |
| status_code=status.HTTP_404_NOT_FOUND, | |
| detail=f"Nginx config not found: {file_id}" | |
| ) | |
| # Read nginx content | |
| with open(nginx_path, 'r') as f: | |
| nginx_content = f.read() | |
| # Validate | |
| validation_result = script_validator.validate_nginx_config(nginx_content) | |
| logger.info(f"Validation result for {file_id}: valid={validation_result['valid']}, score={validation_result['score']}") | |
| return validation_result | |
| except HTTPException: | |
| raise | |
| except Exception as e: | |
| logger.error(f"Failed to validate nginx config: {str(e)}") | |
| raise HTTPException( | |
| status_code=status.HTTP_500_INTERNAL_SERVER_ERROR, | |
| detail=f"Failed to validate nginx config: {str(e)}" | |
| ) | |