228 lines
9.8 KiB
Markdown
228 lines
9.8 KiB
Markdown
# Reanimator Export - Implementation Summary
|
||
|
||
## Обзор
|
||
|
||
Реализован новый формат экспорта данных LOGPile в формат Reanimator для интеграции с системами отслеживания серверных компонентов (asset tracking).
|
||
|
||
## Реализованные компоненты
|
||
|
||
### 1. Модели данных (`internal/exporter/reanimator_models.go`)
|
||
|
||
Определены структуры для формата Reanimator:
|
||
- `ReanimatorExport` - корневая структура экспорта
|
||
- `ReanimatorHardware` - контейнер для всех аппаратных компонентов
|
||
- `ReanimatorBoard` - материнская плата/сервер
|
||
- `ReanimatorCPU` - процессоры
|
||
- `ReanimatorMemory` - модули памяти (DIMM)
|
||
- `ReanimatorStorage` - накопители
|
||
- `ReanimatorPCIe` - PCIe устройства
|
||
- `ReanimatorPSU` - блоки питания
|
||
- `ReanimatorFirmware` - прошивки
|
||
|
||
### 2. Функции конвертации (`internal/exporter/reanimator_converter.go`)
|
||
|
||
Главная функция: `ConvertToReanimator(result *models.AnalysisResult) (*ReanimatorExport, error)`
|
||
|
||
Вспомогательные функции:
|
||
- `inferCPUManufacturer()` - определение производителя CPU по модели (Intel/AMD/ARM/Ampere)
|
||
- `generatePCIeSerialNumber()` - генерация серийных номеров для PCIe устройств
|
||
- `inferStorageStatus()` - определение статуса накопителей
|
||
- `convertBoard()`, `convertCPUs()`, `convertMemory()`, и т.д. - конвертация отдельных секций
|
||
|
||
**Ключевые особенности конвертации:**
|
||
- Автоматическое определение производителя CPU из модели
|
||
- Генерация серийных номеров для PCIe устройств: `{board_serial}-PCIE-{slot}`
|
||
- Объединение GPUs и NetworkAdapters в секцию pcie_devices
|
||
- Фильтрация компонентов без серийных номеров (storage, PSU)
|
||
- Нормализация статусов в допустимые значения (`OK`, `Warning`, `Critical`, `Unknown`; `Empty` только для memory)
|
||
- RFC3339 формат для collected_at
|
||
- Вывод target_host из filename (`redfish://`, `ipmi://`) если отсутствует в source
|
||
- `target_host` опционален: если определить не удалось, поле не включается в JSON
|
||
- Нормализация `board.manufacturer` и `board.product_name`: строка `"NULL"` трактуется как отсутствующее значение
|
||
- Нормализация/очистка `source_type` и `protocol`: в экспорт попадают только допустимые значения из гайда
|
||
|
||
### 3. HTTP эндпоинт
|
||
|
||
**Маршрут:** `GET /api/export/reanimator`
|
||
|
||
**Обработчик:** `handleExportReanimator()` в `internal/server/handlers.go`
|
||
|
||
**Функциональность:**
|
||
- Проверка наличия данных hardware
|
||
- Конвертация в формат Reanimator
|
||
- Возврат JSON с отступами для читаемости
|
||
- Установка заголовка Content-Disposition для скачивания
|
||
|
||
### 4. Frontend интеграция
|
||
|
||
Добавлена кнопка "Экспорт Reanimator" в веб-интерфейсе:
|
||
- Расположение: вкладка "Конфигурация"
|
||
- Использует существующую функцию `exportData('reanimator')`
|
||
|
||
### 5. Тесты
|
||
|
||
**Unit-тесты** (`reanimator_converter_test.go`):
|
||
- `TestConvertToReanimator` - основная функция конвертации
|
||
- `TestInferCPUManufacturer` - определение производителя CPU
|
||
- `TestGeneratePCIeSerialNumber` - генерация серийных номеров
|
||
- `TestInferStorageStatus` - определение статуса накопителей
|
||
- `TestConvertCPUs`, `TestConvertMemory`, и т.д. - тесты для каждого типа компонентов
|
||
|
||
**Интеграционные тесты** (`reanimator_integration_test.go`):
|
||
- `TestFullReanimatorExport` - полный экспорт с реалистичными данными
|
||
- `TestReanimatorExportWithoutTargetHost` - тест вывода target_host
|
||
|
||
**Результаты:** Все тесты проходят успешно ✓
|
||
|
||
### 6. Документация
|
||
|
||
Обновлен `CLAUDE.md`:
|
||
- Добавлен эндпоинт `/api/export/reanimator` в секцию "Export behavior"
|
||
- Описаны ключевые особенности экспорта
|
||
- Добавлена ссылка на спецификацию формата
|
||
|
||
### 7. Примеры
|
||
|
||
Создан пример экспорта: `example/docs/export-example-logpile.json`
|
||
|
||
## Формат экспорта
|
||
|
||
### Обязательные поля:
|
||
- `collected_at` (RFC3339)
|
||
- `target_host`
|
||
- `hardware.board.serial_number`
|
||
|
||
### Структура экспорта:
|
||
|
||
```json
|
||
{
|
||
"filename": "redfish://10.10.10.103",
|
||
"source_type": "api",
|
||
"protocol": "redfish",
|
||
"target_host": "10.10.10.103",
|
||
"collected_at": "2026-02-10T15:30:00Z",
|
||
"hardware": {
|
||
"board": {...},
|
||
"firmware": [...],
|
||
"cpus": [...],
|
||
"memory": [...],
|
||
"storage": [...],
|
||
"pcie_devices": [...],
|
||
"power_supplies": [...]
|
||
}
|
||
}
|
||
```
|
||
|
||
## Соответствие спецификации Reanimator
|
||
|
||
Формат полностью соответствует спецификации из `example/docs/INTEGRATION_GUIDE.md`:
|
||
|
||
✓ Все обязательные поля присутствуют
|
||
✓ Правильные типы данных
|
||
✓ RFC3339 формат времени
|
||
✓ Генерация серийных номеров для PCIe
|
||
✓ Определение производителя CPU
|
||
✓ Статусы компонентов
|
||
✓ Включение пустых слотов памяти (present=false)
|
||
|
||
## Особенности реализации
|
||
|
||
### Маппинг моделей LOGPile → Reanimator
|
||
|
||
| LOGPile | Reanimator | Примечания |
|
||
|---------|------------|------------|
|
||
| `BoardInfo` | `board` | Прямой маппинг |
|
||
| `CPU` | `cpus` | + manufacturer (выводится) + status=`Unknown` при отсутствии фактического статуса |
|
||
| `MemoryDIMM` | `memory` | Прямой маппинг |
|
||
| `Storage` | `storage` | + status=`Unknown` (статус источником не предоставляется) |
|
||
| `PCIeDevice` | `pcie_devices` | + model + status=`Unknown` |
|
||
| `GPU` | `pcie_devices` | Объединены как `device_class=DisplayController` |
|
||
| `NetworkAdapter` | `pcie_devices` | Объединены как NetworkController |
|
||
| `PSU` | `power_supplies` | Прямой маппинг |
|
||
| `FirmwareInfo` | `firmware` | Прямой маппинг |
|
||
|
||
### Фильтрация данных
|
||
|
||
**Исключаются из экспорта:**
|
||
- Storage без serial_number
|
||
- PSU без serial_number или present=false
|
||
- NetworkAdapters с present=false
|
||
|
||
**Включаются в экспорт:**
|
||
- Memory с present=false (как Empty slots)
|
||
- PCIe устройства без serial_number (генерируется)
|
||
|
||
## Использование
|
||
|
||
### Через Web UI:
|
||
1. Загрузить архив или собрать данные через API
|
||
2. Перейти на вкладку "Конфигурация"
|
||
3. Нажать "Экспорт Reanimator"
|
||
|
||
### Через API:
|
||
```bash
|
||
curl http://localhost:8082/api/export/reanimator > reanimator.json
|
||
```
|
||
|
||
### Программно:
|
||
```go
|
||
import "git.mchus.pro/mchus/logpile/internal/exporter"
|
||
|
||
result := &models.AnalysisResult{...}
|
||
reanimatorData, err := exporter.ConvertToReanimator(result)
|
||
if err != nil {
|
||
// handle error
|
||
}
|
||
|
||
jsonData, _ := json.MarshalIndent(reanimatorData, "", " ")
|
||
```
|
||
|
||
## Тестирование
|
||
|
||
Запуск тестов:
|
||
```bash
|
||
# Все тесты
|
||
go test ./internal/exporter/...
|
||
|
||
# Только тесты Reanimator
|
||
go test ./internal/exporter/... -v -run Reanimator
|
||
|
||
# С покрытием
|
||
go test ./internal/exporter/... -cover
|
||
```
|
||
|
||
## Файлы изменений
|
||
|
||
**Новые файлы:**
|
||
- `internal/exporter/reanimator_models.go` (4.6 KB)
|
||
- `internal/exporter/reanimator_converter.go` (10 KB)
|
||
- `internal/exporter/reanimator_converter_test.go` (8.0 KB)
|
||
- `internal/exporter/reanimator_integration_test.go` (7.4 KB)
|
||
- `internal/exporter/generate_example_test.go` (4.3 KB)
|
||
- `example/docs/export-example-logpile.json` (2.3 KB)
|
||
|
||
**Измененные файлы:**
|
||
- `internal/server/handlers.go` - добавлен handleExportReanimator
|
||
- `internal/server/server.go` - добавлен маршрут
|
||
- `web/templates/index.html` - добавлена кнопка экспорта
|
||
- `CLAUDE.md` - обновлена документация
|
||
|
||
## Совместимость
|
||
|
||
- ✓ Обратная совместимость: существующие экспорты (JSON/CSV/TXT) не затронуты
|
||
- ✓ Формат данных: `AnalysisResult` не изменен
|
||
- ✓ API контракты: новый эндпоинт не влияет на существующие
|
||
|
||
## Будущие улучшения
|
||
|
||
1. Поддержка статусов из реальных данных (Warning/Critical) для Storage
|
||
2. Расширенная телеметрия для компонентов
|
||
3. Валидация экспорта против JSON схемы Reanimator
|
||
4. Поддержка инкрементальных обновлений
|
||
|
||
---
|
||
|
||
**Статус:** ✅ Реализация завершена и протестирована
|
||
**Версия:** LOGPile v1.2.1+
|
||
**Дата:** 2026-02-12
|