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