deploymate / app /api /routes /scripts.py
shakauthossain's picture
V2.0.0
2df0cf9 verified
"""
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)}"
)