# Быстрый старт веб-интерфейса DevOpsLab **Автор:** Сергей Антропов **Сайт:** https://devops.org.ru ## 🚀 Быстрый старт ### 1. Создание git ветки ```bash git checkout -b feature/web-interface git push -u origin feature/web-interface ``` ### 2. Структура проекта ``` app/ ├── main.py # FastAPI приложение ├── api/v1/endpoints/ # API endpoints ├── templates/ # HTMX шаблоны ├── static/ # CSS, JS └── core/ # Ядро (MakeExecutor, DockerClient) ``` ### 3. Основные компоненты #### MakeExecutor - выполнение Makefile команд ```python # app/core/make_executor.py import subprocess from typing import Dict, List class MakeExecutor: def execute(self, command: str, args: List[str] = None) -> Dict: cmd = ["make"] + command.split() + (args or []) result = subprocess.run(cmd, capture_output=True, text=True) return { "success": result.returncode == 0, "stdout": result.stdout, "stderr": result.stderr } ``` #### FastAPI роуты ```python # app/api/v1/endpoints/roles.py from fastapi import APIRouter, Request from fastapi.responses import HTMLResponse from fastapi.templating import Jinja2Templates from app.core.make_executor import MakeExecutor router = APIRouter() templates = Jinja2Templates(directory="app/templates") executor = MakeExecutor() @router.get("/roles", response_class=HTMLResponse) async def list_roles(request: Request): # Получаем список ролей через make result = executor.execute("role list") roles = parse_roles(result["stdout"]) return templates.TemplateResponse( "pages/roles/list.html", {"request": request, "roles": roles} ) @router.post("/roles/{role_name}/test") async def test_role(role_name: str, preset: str = "default"): # Запуск теста result = executor.execute(f"role test {preset}") return {"status": "success" if result["success"] else "failed"} ``` #### HTMX шаблон ```html {% extends "base.html" %} {% block content %}
{% for role in roles %}

{{ role.name }}

{{ role.description }}

{% endfor %}
{% endblock %} ``` ### 4. Примеры страниц #### Dashboard ```html

Всего ролей

{{ total_roles }}

Последние тесты

``` #### Создание роли ```html

Шаг 1: Базовая информация

``` ### 5. WebSocket для live логов ```python # app/api/v1/endpoints/websocket.py from fastapi import WebSocket from app.core.make_executor import MakeExecutor @router.websocket("/ws/test/{test_id}") async def test_websocket(websocket: WebSocket, test_id: str): await websocket.accept() executor = MakeExecutor() # Запуск теста с потоковым выводом process = await executor.execute_stream(f"role test {test_id}") async for line in process.stdout: await websocket.send_json({ "type": "log", "data": line.decode() }) await websocket.send_json({"type": "complete"}) ``` ```javascript // app/static/js/test-live.js const ws = new WebSocket('ws://localhost:8000/ws/test/nginx'); const logContainer = document.getElementById('test-logs'); ws.onmessage = (event) => { const data = JSON.parse(event.data); if (data.type === 'log') { logContainer.innerHTML += `
${data.data}
`; } }; ``` ### 6. Запуск приложения ```python # app/main.py from fastapi import FastAPI from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates from app.api.v1.endpoints import roles, presets, tests app = FastAPI(title="DevOpsLab Web Interface") # Статика app.mount("/static", StaticFiles(directory="app/static"), name="static") # Шаблоны templates = Jinja2Templates(directory="app/templates") # Роуты app.include_router(roles.router, prefix="/api/v1") app.include_router(presets.router, prefix="/api/v1") app.include_router(tests.router, prefix="/api/v1") @app.get("/") async def dashboard(request: Request): return templates.TemplateResponse("pages/dashboard.html", {"request": request}) if __name__ == "__main__": import uvicorn uvicorn.run(app, host="0.0.0.0", port=8000) ``` ### 7. Docker Compose для разработки ```yaml # docker-compose.dev.yml version: '3.8' services: web: build: ./app ports: - "8000:8000" volumes: - ./app:/app - .:/workspace environment: - PROJECT_ROOT=/workspace command: uvicorn main:app --reload --host 0.0.0.0 redis: image: redis:7-alpine ports: - "6379:6379" celery: build: ./app command: celery -A tasks.celery_tasks worker --loglevel=info volumes: - ./app:/app - .:/workspace depends_on: - redis ``` ### 8. Команды для разработки ```bash # Установка зависимостей cd app pip install -r requirements.txt # Запуск в режиме разработки uvicorn main:app --reload # Запуск через Docker docker-compose -f docker-compose.dev.yml up # Запуск Celery worker celery -A tasks.celery_tasks worker --loglevel=info ``` --- ## 📋 Чек-лист реализации - [ ] Создать git ветку - [ ] Настроить структуру проекта - [ ] Реализовать MakeExecutor - [ ] Создать базовые шаблоны - [ ] Реализовать Dashboard - [ ] Реализовать список ролей - [ ] Реализовать создание роли - [ ] Реализовать тестирование роли - [ ] Добавить WebSocket для live логов - [ ] Настроить Celery для фоновых задач - [ ] Добавить базу данных для истории - [ ] Улучшить UI/UX - [ ] Добавить аутентификацию - [ ] Написать документацию --- **Полная версия:** [WEB_INTERFACE_PROPOSAL.md](WEB_INTERFACE_PROPOSAL.md)