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)}"
        )