Spaces:
Sleeping
Sleeping
File size: 7,342 Bytes
4e9eb6a 009956c 557c4fb 4e9eb6a 2df0cf9 4e9eb6a 2df0cf9 4e9eb6a | 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 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 | """
DevOps service for script and configuration generation.
"""
from typing import Union
from fastapi import HTTPException, status
from jinja2 import Environment
from app.core.config import Settings
from app.models.schemas import ConfigState, NginxConfigRequest
class DevOpsService:
"""Service for generating DevOps scripts and configurations."""
def __init__(self, template_env: Environment, settings: Settings, logger):
self.template_env = template_env
self.settings = settings
self.logger = logger
def get_script_templates(self, config: ConfigState) -> list[str]:
"""
Determine which templates to include based on configuration.
"""
templates = []
# Stack type templates
stack_map = {
"python": "python_setup.j2",
"nodejs": "nodejs_setup.j2",
"php": "php_setup.j2",
"react": "react_setup.j2",
"vue": "vue_setup.j2",
"angular": "angular_setup.j2",
"go": "go_setup.j2",
"java": "java_setup.j2",
"dotnet": "dotnet_setup.j2",
"docker": "docker_setup.j2",
}
if config.stackType in stack_map:
templates.append(stack_map[config.stackType])
# Web server templates
web_map = {
"nginx": "nginx_setup.j2",
"apache": "apache_setup.j2",
"caddy": "caddy_setup.j2",
"litespeed": "litespeed_setup.j2",
"tomcat": "tomcat_setup.j2",
"cherokee": "cherokee_setup.j2",
"haproxy": "haproxy_setup.j2",
}
if config.webServer and config.webServer != "none":
template_name = web_map.get(config.webServer)
if template_name:
templates.append(template_name)
# Database templates
db_map = {
"postgresql": "postgresql_setup.j2",
"mysql": "mysql_setup.j2",
"mariadb": "mariadb_setup.j2",
"mongodb": "mongodb_setup.j2",
"redis": "redis_setup.j2",
}
if config.database and config.database != "none":
template_name = db_map.get(config.database)
if template_name:
templates.append(template_name)
# Process manager templates
pm_map = {
"pm2": "pm2_setup.j2",
"systemd": "systemd_setup.j2",
"docker-compose": "docker_compose_setup.j2",
}
if config.processManager and config.processManager != "none":
template_name = pm_map.get(config.processManager)
if template_name:
templates.append(template_name)
# Security templates
if config.security.ufw:
templates.append("ufw_setup.j2")
if config.security.fail2ban:
templates.append("fail2ban_setup.j2")
if config.security.disableRoot:
templates.append("disable_root_setup.j2")
if config.security.autoUpdates:
templates.append("auto_updates_setup.j2")
# Advanced templates
if config.advanced.swap:
templates.append("swap_setup.j2")
if config.advanced.sshKey:
templates.append("ssh_key_setup.j2")
if config.advanced.backups:
templates.append("backups_setup.j2")
if config.advanced.monitoring:
templates.append("monitoring_setup.j2")
# SSL template
if config.ssl:
templates.append("ssl_setup.j2")
return templates
def generate_bash_script(self, config: ConfigState, script_id: str) -> str:
"""
Generate a bash script by combining multiple modular templates.
"""
templates = self.get_script_templates(config)
script_parts = []
for template_name in templates:
try:
# Read template directly from disk to avoid caching issues
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2 Template directly
from jinja2 import Template
template = Template(
template_content,
trim_blocks=True,
lstrip_blocks=True
)
part = template.render(
config=config,
script_id=script_id
)
if part.strip(): # Only add non-empty parts
script_parts.append(part)
except Exception as e:
self.logger.warning(f"Template error for {template_name}: {e}")
combined_script = "\n\n".join(script_parts)
# Add header
header = f"""#!/bin/bash
# Generated DevOps Toolkit Script - {script_id}
# Stack: {config.stackType}
# Web Server: {config.webServer or 'None'}
# Database: {config.database or 'None'}
# Process Manager: {config.processManager or 'None'}
set -euo pipefail
echo "π Starting server setup..."
# Update system packages for security
echo "π¦ Updating system packages..."
sudo apt-get update -y
sudo apt-get upgrade -y
"""
# Add footer
footer = """
echo "β
Setup complete! Your server is ready."
echo "π Next steps:"
echo " 1. Configure your application"
echo " 2. Upload your code"
echo " 3. Start your application service"
"""
return header + combined_script + footer
def generate_nginx_config(
self, config: Union[ConfigState, NginxConfigRequest], script_id: str
) -> str:
"""
Generate nginx configuration using modular templates.
"""
stack = config.stackType
# Map stack types to nginx config templates
nginx_map = {
"python": "nginx/nginx_python.conf.j2",
"nodejs": "nginx/nginx_nodejs.conf.j2",
"php": "nginx/nginx_php.conf.j2",
"react": "nginx/nginx_static.conf.j2",
"vue": "nginx/nginx_static.conf.j2",
"angular": "nginx/nginx_static.conf.j2",
"go": "nginx/nginx_go.conf.j2",
"java": "nginx/nginx_java.conf.j2",
"dotnet": "nginx/nginx_dotnet.conf.j2",
"docker": "nginx/nginx_docker.conf.j2",
}
template_name = nginx_map.get(
stack, "nginx/nginx_static.conf.j2"
) # Default to static
try:
# Read template directly from disk to avoid caching issues
template_path = self.settings.templates_dir / template_name
with open(template_path, 'r', encoding='utf-8') as f:
template_content = f.read()
# Render using Jinja2 Template directly
from jinja2 import Template
template = Template(template_content, trim_blocks=True, lstrip_blocks=True)
return template.render(config=config, script_id=script_id)
except Exception as e:
self.logger.error(f"Nginx template error for {template_name}: {e}")
raise HTTPException(
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR,
detail=f"Required nginx template {template_name} not found",
)
|