Spaces:
Sleeping
Sleeping
File size: 5,711 Bytes
4e9eb6a 2df0cf9 4e9eb6a 2df0cf9 4e9eb6a 2df0cf9 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 | """
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)
@router.post("/generate-script", response_model=GeneratedFiles)
@limiter.limit("10/minute")
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)}",
)
@router.get("/validate-script/{file_id}")
@limiter.limit("20/minute")
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)}"
)
@router.get("/validate-nginx/{file_id}")
@limiter.limit("20/minute")
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)}"
)
|