- Добавлена колонка 'Тип' во все таблицы истории сборок - Для push операций отображается registry вместо платформ - Сохранение пользователя при создании push лога - Исправлена ошибка с logger в push_docker_image endpoint - Улучшено отображение истории сборок с визуальными индикаторами
703 lines
22 KiB
Markdown
703 lines
22 KiB
Markdown
# Предложение по созданию веб-интерфейса для DevOpsLab
|
||
|
||
**Автор:** Сергей Антропов
|
||
**Сайт:** https://devops.org.ru
|
||
**Дата:** 2024
|
||
|
||
## 🎯 Цель
|
||
|
||
Создать современный веб-интерфейс на FastAPI + HTMX для управления всеми возможностями проекта DevOpsLab через браузер.
|
||
|
||
---
|
||
|
||
## 🏗️ Архитектура решения
|
||
|
||
### Технологический стек
|
||
|
||
```
|
||
Frontend:
|
||
├── HTMX - динамическое обновление контента без перезагрузки
|
||
├── Alpine.js - легковесная реактивность
|
||
├── Tailwind CSS - современный UI
|
||
├── Jinja2 Templates - серверный рендеринг
|
||
└── Chart.js - визуализация данных
|
||
|
||
Backend:
|
||
├── FastAPI - современный Python веб-фреймворк
|
||
├── Pydantic - валидация данных
|
||
├── Celery + Redis - фоновые задачи (тестирование)
|
||
├── WebSocket - real-time обновления статуса
|
||
└── SQLite/PostgreSQL - хранение истории и метрик
|
||
|
||
Интеграция:
|
||
├── Вызов Makefile команд через subprocess
|
||
├── Парсинг результатов тестов
|
||
├── Управление Docker через API
|
||
└── Работа с Git через GitPython
|
||
```
|
||
|
||
### Структура проекта
|
||
|
||
```
|
||
app/
|
||
├── api/
|
||
│ ├── v1/
|
||
│ │ ├── endpoints/
|
||
│ │ │ ├── roles.py # Управление ролями
|
||
│ │ │ ├── presets.py # Управление preset'ами
|
||
│ │ │ ├── tests.py # Запуск тестов
|
||
│ │ │ ├── docker.py # Управление Docker
|
||
│ │ │ ├── vault.py # Управление секретами
|
||
│ │ │ ├── dashboard.py # Dashboard данные
|
||
│ │ │ └── websocket.py # WebSocket для real-time
|
||
│ │ └── router.py # Роутер API
|
||
│ └── dependencies.py # Зависимости (auth, db)
|
||
├── core/
|
||
│ ├── config.py # Конфигурация
|
||
│ ├── security.py # Безопасность
|
||
│ ├── make_executor.py # Выполнение Makefile команд
|
||
│ └── docker_client.py # Docker клиент
|
||
├── models/
|
||
│ ├── role.py # Модели ролей
|
||
│ ├── test.py # Модели тестов
|
||
│ └── preset.py # Модели preset'ов
|
||
├── services/
|
||
│ ├── role_service.py # Бизнес-логика ролей
|
||
│ ├── test_service.py # Бизнес-логика тестов
|
||
│ ├── preset_service.py # Бизнес-логика preset'ов
|
||
│ └── docker_service.py # Бизнес-логика Docker
|
||
├── templates/
|
||
│ ├── base.html # Базовый шаблон
|
||
│ ├── components/
|
||
│ │ ├── navbar.html
|
||
│ │ ├── sidebar.html
|
||
│ │ ├── role_card.html
|
||
│ │ ├── test_status.html
|
||
│ │ └── preset_selector.html
|
||
│ ├── pages/
|
||
│ │ ├── dashboard.html # Главная страница
|
||
│ │ ├── roles/
|
||
│ │ │ ├── list.html # Список ролей
|
||
│ │ │ ├── create.html # Создание роли
|
||
│ │ │ ├── edit.html # Редактирование роли
|
||
│ │ │ ├── detail.html # Детали роли
|
||
│ │ │ └── test.html # Тестирование роли
|
||
│ │ ├── presets/
|
||
│ │ │ ├── list.html
|
||
│ │ │ ├── create.html
|
||
│ │ │ └── edit.html
|
||
│ │ ├── tests/
|
||
│ │ │ ├── history.html # История тестов
|
||
│ │ │ ├── results.html # Результаты теста
|
||
│ │ │ └── live.html # Live тестирование
|
||
│ │ ├── docker/
|
||
│ │ │ ├── images.html # Docker образы
|
||
│ │ │ ├── containers.html # Контейнеры
|
||
│ │ │ └── build.html # Сборка образов
|
||
│ │ └── vault/
|
||
│ │ ├── list.html
|
||
│ │ └── edit.html
|
||
│ └── partials/
|
||
│ ├── role_form.html
|
||
│ ├── preset_form.html
|
||
│ └── test_logs.html
|
||
├── static/
|
||
│ ├── css/
|
||
│ │ └── main.css # Tailwind + кастомные стили
|
||
│ ├── js/
|
||
│ │ ├── htmx.min.js
|
||
│ │ ├── alpine.js
|
||
│ │ └── app.js # Кастомный JS
|
||
│ └── images/
|
||
│ └── logo.svg
|
||
├── tasks/
|
||
│ └── celery_tasks.py # Фоновые задачи Celery
|
||
├── db/
|
||
│ ├── models.py # SQLAlchemy модели
|
||
│ ├── database.py # Подключение к БД
|
||
│ └── migrations/ # Миграции
|
||
├── main.py # Точка входа FastAPI
|
||
└── requirements.txt # Зависимости Python
|
||
```
|
||
|
||
---
|
||
|
||
## 📱 Основные страницы и функциональность
|
||
|
||
### 1. Dashboard (Главная страница)
|
||
|
||
**URL:** `/`
|
||
|
||
**Функциональность:**
|
||
- Статистика по ролям (всего, протестировано, успешно)
|
||
- График успешности тестов за период
|
||
- Последние тесты с результатами
|
||
- Быстрые действия (создать роль, запустить тест)
|
||
- Статус Docker (образы, контейнеры)
|
||
- Активные задачи (Celery)
|
||
|
||
**HTMX фичи:**
|
||
- Автообновление статистики каждые 5 секунд
|
||
- Live статус тестов через WebSocket
|
||
- Интерактивные графики
|
||
|
||
### 2. Управление ролями
|
||
|
||
#### 2.1. Список ролей (`/roles`)
|
||
|
||
**Функциональность:**
|
||
- Карточки ролей с информацией:
|
||
- Имя роли
|
||
- Описание
|
||
- Последний тест (статус, дата)
|
||
- Количество переменных
|
||
- Поддерживаемые ОС
|
||
- Фильтры:
|
||
- По статусу теста
|
||
- По ОС
|
||
- По тегам
|
||
- Поиск по имени/описанию
|
||
- Действия:
|
||
- Создать новую роль
|
||
- Редактировать
|
||
- Удалить
|
||
- Запустить тест
|
||
- Просмотреть детали
|
||
|
||
**HTMX фичи:**
|
||
- Фильтрация без перезагрузки
|
||
- Модальные окна для действий
|
||
- Inline редактирование
|
||
|
||
#### 2.2. Создание роли (`/roles/create`)
|
||
|
||
**Функциональность:**
|
||
- Мастер создания роли (шаги):
|
||
1. **Базовая информация:**
|
||
- Имя роли
|
||
- Описание
|
||
- Тип роли (service, package, config, etc.)
|
||
- Шаблон (выбор из доступных)
|
||
|
||
2. **Поддерживаемые ОС:**
|
||
- Чекбоксы для каждой ОС
|
||
- Версии ОС
|
||
|
||
3. **Переменные:**
|
||
- Динамическое добавление переменных
|
||
- Тип переменной (string, int, bool, list, dict)
|
||
- Значение по умолчанию
|
||
- Описание
|
||
|
||
4. **Зависимости:**
|
||
- Выбор зависимых ролей
|
||
- Версии зависимостей
|
||
|
||
5. **Тесты:**
|
||
- Выбор preset'а для тестирования
|
||
- Настройки тестирования
|
||
|
||
6. **Превью и создание:**
|
||
- Превью структуры роли
|
||
- Кнопка создания
|
||
|
||
**HTMX фичи:**
|
||
- Прогресс-бар шагов
|
||
- Валидация на лету
|
||
- Сохранение черновика
|
||
- Предпросмотр структуры
|
||
|
||
#### 2.3. Редактирование роли (`/roles/{role_name}/edit`)
|
||
|
||
**Функциональность:**
|
||
- Редактирование tasks/main.yml (CodeMirror)
|
||
- Редактирование defaults/main.yml (форма с переменными)
|
||
- Редактирование handlers/main.yml
|
||
- Управление templates и files
|
||
- Редактирование meta/main.yml
|
||
- Редактирование README.md (Markdown редактор)
|
||
|
||
**HTMX фичи:**
|
||
- Автосохранение
|
||
- Синтаксис-подсветка
|
||
- Предпросмотр Markdown
|
||
- Валидация YAML
|
||
|
||
#### 2.4. Детали роли (`/roles/{role_name}`)
|
||
|
||
**Функциональность:**
|
||
- Вкладки:
|
||
- **Обзор:** описание, метаданные, статистика
|
||
- **Переменные:** таблица всех переменных с описаниями
|
||
- **Задачи:** список задач с описаниями
|
||
- **Тесты:** история тестирования
|
||
- **Зависимости:** граф зависимостей
|
||
- **Документация:** README.md
|
||
|
||
**HTMX фичи:**
|
||
- Переключение вкладок без перезагрузки
|
||
- Интерактивный граф зависимостей
|
||
- Фильтрация истории тестов
|
||
|
||
#### 2.5. Тестирование роли (`/roles/{role_name}/test`)
|
||
|
||
**Функциональность:**
|
||
- Выбор preset'а
|
||
- Настройка переменных (форма)
|
||
- Параметры теста:
|
||
- Параллельность
|
||
- Verbose режим
|
||
- Только lint
|
||
- Только синтаксис
|
||
- Запуск теста
|
||
- Live логи (WebSocket)
|
||
- Прогресс выполнения
|
||
- Результаты:
|
||
- Статус (успех/ошибка)
|
||
- Время выполнения
|
||
- Детальные логи
|
||
- Сравнение с предыдущим тестом
|
||
|
||
**HTMX фичи:**
|
||
- Live обновление логов
|
||
- Прогресс-бар
|
||
- Автоматическое обновление статуса
|
||
- Скачивание логов
|
||
|
||
### 3. Управление preset'ами (`/presets`)
|
||
|
||
**Функциональность:**
|
||
- Список preset'ов
|
||
- Создание preset'а:
|
||
- Визуальный редактор хостов
|
||
- Drag & drop для изменения порядка
|
||
- Выбор образов
|
||
- Настройка сети
|
||
- Редактирование preset'а
|
||
- Копирование preset'а
|
||
- Удаление preset'а
|
||
- Предпросмотр preset'а (YAML)
|
||
|
||
**HTMX фичи:**
|
||
- Визуальный редактор
|
||
- Предпросмотр YAML
|
||
- Валидация
|
||
|
||
### 4. История тестов (`/tests`)
|
||
|
||
**Функциональность:**
|
||
- Таблица всех тестов:
|
||
- Роль
|
||
- Preset
|
||
- Статус
|
||
- Дата/время
|
||
- Длительность
|
||
- Действия (просмотр, скачать логи)
|
||
- Фильтры:
|
||
- По роли
|
||
- По статусу
|
||
- По дате
|
||
- По preset'у
|
||
- Графики:
|
||
- Успешность по времени
|
||
- Время выполнения
|
||
- Распределение по ОС
|
||
|
||
**HTMX фичи:**
|
||
- Пагинация
|
||
- Сортировка
|
||
- Экспорт в CSV/JSON
|
||
|
||
### 5. Управление Docker (`/docker`)
|
||
|
||
**Функциональность:**
|
||
- Список образов:
|
||
- Статус (локально/в registry)
|
||
- Размер
|
||
- Дата создания
|
||
- Архитектуры
|
||
- Действия (pull, push, build, delete)
|
||
- Список контейнеров:
|
||
- Статус
|
||
- Образ
|
||
- Порты
|
||
- Действия (start, stop, logs, exec)
|
||
- Сборка образов:
|
||
- Выбор образа
|
||
- Параметры сборки
|
||
- Прогресс сборки
|
||
- Registry настройки
|
||
|
||
**HTMX фичи:**
|
||
- Live обновление статуса
|
||
- Прогресс сборки
|
||
- Модальные окна для действий
|
||
|
||
### 6. Управление секретами (`/vault`)
|
||
|
||
**Функциональность:**
|
||
- Список зашифрованных файлов
|
||
- Редактирование секретов:
|
||
- Форма с полями
|
||
- Шифрование/расшифровка
|
||
- Смена пароля
|
||
- Поиск секретов в коде
|
||
- Аудит безопасности
|
||
|
||
**HTMX фичи:**
|
||
- Безопасное редактирование
|
||
- Валидация перед шифрованием
|
||
|
||
---
|
||
|
||
## 🔧 Технические детали
|
||
|
||
### FastAPI структура
|
||
|
||
```python
|
||
# app/main.py
|
||
from fastapi import FastAPI
|
||
from fastapi.staticfiles import StaticFiles
|
||
from fastapi.templating import Jinja2Templates
|
||
from app.api.v1.router import api_router
|
||
|
||
app = FastAPI(
|
||
title="DevOpsLab Web Interface",
|
||
description="Веб-интерфейс для управления Ansible ролями",
|
||
version="1.0.0"
|
||
)
|
||
|
||
# Статические файлы
|
||
app.mount("/static", StaticFiles(directory="app/static"), name="static")
|
||
|
||
# Шаблоны
|
||
templates = Jinja2Templates(directory="app/templates")
|
||
|
||
# API роуты
|
||
app.include_router(api_router, prefix="/api/v1")
|
||
|
||
# Web роуты
|
||
@app.get("/")
|
||
async def dashboard(request: Request):
|
||
return templates.TemplateResponse("pages/dashboard.html", {"request": request})
|
||
```
|
||
|
||
### Выполнение Makefile команд
|
||
|
||
```python
|
||
# app/core/make_executor.py
|
||
import subprocess
|
||
import asyncio
|
||
from typing import Optional, Dict, List
|
||
|
||
class MakeExecutor:
|
||
"""Выполнение Makefile команд с отслеживанием прогресса"""
|
||
|
||
async def execute(
|
||
self,
|
||
command: str,
|
||
args: List[str] = None,
|
||
stream: bool = False
|
||
) -> Dict:
|
||
"""Выполнение команды make"""
|
||
cmd = ["make"] + command.split() + (args or [])
|
||
|
||
if stream:
|
||
# Для live логов через WebSocket
|
||
process = await asyncio.create_subprocess_exec(
|
||
*cmd,
|
||
stdout=asyncio.subprocess.PIPE,
|
||
stderr=asyncio.subprocess.PIPE
|
||
)
|
||
return process
|
||
else:
|
||
result = subprocess.run(
|
||
cmd,
|
||
capture_output=True,
|
||
text=True,
|
||
cwd=PROJECT_ROOT
|
||
)
|
||
return {
|
||
"success": result.returncode == 0,
|
||
"stdout": result.stdout,
|
||
"stderr": result.stderr,
|
||
"returncode": result.returncode
|
||
}
|
||
```
|
||
|
||
### WebSocket для live обновлений
|
||
|
||
```python
|
||
# app/api/v1/endpoints/websocket.py
|
||
from fastapi import WebSocket
|
||
from app.core.make_executor import MakeExecutor
|
||
|
||
@app.websocket("/ws/test/{test_id}")
|
||
async def test_websocket(websocket: WebSocket, test_id: str):
|
||
await websocket.accept()
|
||
executor = MakeExecutor()
|
||
|
||
process = await executor.execute(
|
||
f"role test {test_id}",
|
||
stream=True
|
||
)
|
||
|
||
async for line in process.stdout:
|
||
await websocket.send_json({
|
||
"type": "log",
|
||
"data": line.decode()
|
||
})
|
||
|
||
await websocket.send_json({
|
||
"type": "complete",
|
||
"status": "success"
|
||
})
|
||
```
|
||
|
||
### Celery для фоновых задач
|
||
|
||
```python
|
||
# app/tasks/celery_tasks.py
|
||
from celery import Celery
|
||
from app.core.config import settings
|
||
|
||
celery_app = Celery(
|
||
"devopslab",
|
||
broker=settings.REDIS_URL,
|
||
backend=settings.REDIS_URL
|
||
)
|
||
|
||
@celery_app.task
|
||
def run_role_test(role_name: str, preset: str):
|
||
"""Запуск теста роли в фоне"""
|
||
executor = MakeExecutor()
|
||
result = executor.execute(f"role test {preset}")
|
||
return result
|
||
```
|
||
|
||
### База данных для истории
|
||
|
||
```python
|
||
# app/db/models.py
|
||
from sqlalchemy import Column, Integer, String, DateTime, Boolean, Text
|
||
from app.db.database import Base
|
||
|
||
class TestResult(Base):
|
||
__tablename__ = "test_results"
|
||
|
||
id = Column(Integer, primary_key=True)
|
||
role_name = Column(String, nullable=False)
|
||
preset = Column(String, nullable=False)
|
||
status = Column(String) # success, failed, running
|
||
started_at = Column(DateTime)
|
||
completed_at = Column(DateTime)
|
||
duration = Column(Integer) # секунды
|
||
logs = Column(Text)
|
||
stdout = Column(Text)
|
||
stderr = Column(Text)
|
||
```
|
||
|
||
---
|
||
|
||
## 🎨 UI/UX дизайн
|
||
|
||
### Цветовая схема
|
||
|
||
```css
|
||
/* Tailwind конфигурация */
|
||
colors: {
|
||
primary: '#3B82F6', // Синий
|
||
secondary: '#10B981', // Зеленый
|
||
danger: '#EF4444', // Красный
|
||
warning: '#F59E0B', // Оранжевый
|
||
dark: '#1F2937', // Темный
|
||
light: '#F9FAFB' // Светлый
|
||
}
|
||
```
|
||
|
||
### Компоненты
|
||
|
||
1. **Navbar:**
|
||
- Логотип
|
||
- Навигация (Dashboard, Roles, Presets, Tests, Docker, Vault)
|
||
- Уведомления
|
||
- Профиль пользователя
|
||
|
||
2. **Sidebar:**
|
||
- Быстрые действия
|
||
- Последние тесты
|
||
- Статистика
|
||
|
||
3. **Card компонент:**
|
||
- Заголовок
|
||
- Контент
|
||
- Действия (кнопки)
|
||
|
||
4. **Modal компонент:**
|
||
- HTMX для открытия/закрытия
|
||
- Формы внутри
|
||
|
||
5. **Table компонент:**
|
||
- Сортировка
|
||
- Фильтрация
|
||
- Пагинация
|
||
|
||
6. **Status badges:**
|
||
- Успех (зеленый)
|
||
- Ошибка (красный)
|
||
- В процессе (синий)
|
||
- Пропущен (серый)
|
||
|
||
---
|
||
|
||
## 📦 Зависимости
|
||
|
||
```txt
|
||
# app/requirements.txt
|
||
fastapi==0.104.1
|
||
uvicorn[standard]==0.24.0
|
||
jinja2==3.1.2
|
||
python-multipart==0.0.6
|
||
pydantic==2.5.0
|
||
pydantic-settings==2.1.0
|
||
|
||
# HTMX и статика
|
||
jinja2-partials==0.3.0
|
||
|
||
# База данных
|
||
sqlalchemy==2.0.23
|
||
alembic==1.12.1
|
||
asyncpg==0.29.0 # Для PostgreSQL
|
||
|
||
# Фоновые задачи
|
||
celery==5.3.4
|
||
redis==5.0.1
|
||
|
||
# WebSocket
|
||
websockets==12.0
|
||
|
||
# Docker
|
||
docker==6.1.3
|
||
|
||
# Git
|
||
GitPython==3.1.40
|
||
|
||
# Утилиты
|
||
python-dotenv==1.0.0
|
||
pyyaml==6.0.1
|
||
```
|
||
|
||
---
|
||
|
||
## 🚀 План реализации
|
||
|
||
### Фаза 1: Базовая инфраструктура (1 неделя)
|
||
- ✅ Настройка FastAPI проекта
|
||
- ✅ Базовая структура папок
|
||
- ✅ Интеграция с Makefile (MakeExecutor)
|
||
- ✅ Базовые шаблоны (base.html, navbar, sidebar)
|
||
- ✅ Dashboard страница (статичная)
|
||
|
||
### Фаза 2: Управление ролями (2 недели)
|
||
- ✅ Список ролей
|
||
- ✅ Создание роли (мастер)
|
||
- ✅ Редактирование роли
|
||
- ✅ Детали роли
|
||
- ✅ Интеграция с Git
|
||
|
||
### Фаза 3: Тестирование (2 недели)
|
||
- ✅ Запуск тестов через интерфейс
|
||
- ✅ WebSocket для live логов
|
||
- ✅ История тестов
|
||
- ✅ Результаты тестов
|
||
|
||
### Фаза 4: Preset'ы и Docker (1 неделя)
|
||
- ✅ Управление preset'ами
|
||
- ✅ Управление Docker образами
|
||
- ✅ Управление контейнерами
|
||
|
||
### Фаза 5: Полировка (1 неделя)
|
||
- ✅ Улучшение UI/UX
|
||
- ✅ Оптимизация производительности
|
||
- ✅ Документация
|
||
- ✅ Тестирование
|
||
|
||
---
|
||
|
||
## 🔐 Безопасность
|
||
|
||
1. **Аутентификация:**
|
||
- JWT токены
|
||
- Сессии
|
||
- OAuth2 (опционально)
|
||
|
||
2. **Авторизация:**
|
||
- Роли пользователей
|
||
- Права доступа
|
||
|
||
3. **Валидация:**
|
||
- Pydantic схемы
|
||
- Санитизация входных данных
|
||
|
||
4. **Защита от атак:**
|
||
- CSRF токены
|
||
- Rate limiting
|
||
- SQL injection защита
|
||
|
||
---
|
||
|
||
## 📊 Метрики и мониторинг
|
||
|
||
1. **Производительность:**
|
||
- Время ответа API
|
||
- Использование памяти
|
||
- CPU нагрузка
|
||
|
||
2. **Использование:**
|
||
- Количество пользователей
|
||
- Популярные роли
|
||
- Частота тестирования
|
||
|
||
3. **Ошибки:**
|
||
- Логирование ошибок
|
||
- Sentry интеграция (опционально)
|
||
|
||
---
|
||
|
||
## 🎯 Преимущества решения
|
||
|
||
1. **Удобство:**
|
||
- Не нужно знать команды make
|
||
- Визуальный интерфейс
|
||
- Интуитивная навигация
|
||
|
||
2. **Производительность:**
|
||
- HTMX - минимальный JS
|
||
- Серверный рендеринг
|
||
- Быстрая загрузка
|
||
|
||
3. **Расширяемость:**
|
||
- Модульная архитектура
|
||
- Легко добавлять новые функции
|
||
- API для интеграций
|
||
|
||
4. **Современность:**
|
||
- FastAPI - быстрый и современный
|
||
- HTMX - простота и мощность
|
||
- Tailwind - красивый UI
|
||
|
||
---
|
||
|
||
## 📝 Следующие шаги
|
||
|
||
1. Создать git ветку: `git checkout -b feature/web-interface`
|
||
2. Настроить структуру проекта
|
||
3. Реализовать базовую инфраструктуру
|
||
4. Постепенно добавлять функциональность
|
||
5. Тестировать и улучшать
|
||
|
||
---
|
||
|
||
**Автор:** Сергей Антропов
|
||
**Сайт:** https://devops.org.ru
|