diff --git a/app/app.py b/app/app.py index 2120724..6ff29f2 100644 --- a/app/app.py +++ b/app/app.py @@ -10,6 +10,7 @@ import os from fastapi import FastAPI, Request, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates +from fastapi.middleware.cors import CORSMiddleware from core.config import DEBUG_MODE, SNAP_DIR, STATIC_DIR, APP_PORT from api.v1.router import api_router, pages_router @@ -24,6 +25,15 @@ app = FastAPI( redoc_url="/redoc" if DEBUG_MODE else None ) +# Настройка CORS +app.add_middleware( + CORSMiddleware, + allow_origins=["*"], # В продакшене лучше указать конкретные домены + allow_credentials=True, + allow_methods=["*"], + allow_headers=["*"], +) + # Инициализация шаблонов from core.config import templates diff --git a/test_api.py b/test_api.py new file mode 100644 index 0000000..16d74f6 --- /dev/null +++ b/test_api.py @@ -0,0 +1,107 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Тестовый скрипт для проверки API LogBoard+ +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" + +import requests +import json + +def test_api(): + """Тестирование API endpoints""" + + base_url = "http://localhost:9001" + + # 1. Проверяем health endpoint + print("🔍 Проверка health endpoint...") + try: + response = requests.get(f"{base_url}/healthz") + print(f" Health: {response.status_code} - {response.text}") + except Exception as e: + print(f" ❌ Ошибка health: {e}") + return + + # 2. Проверяем API без токена + print("\n🔍 Проверка API без токена...") + try: + response = requests.get(f"{base_url}/api/containers/services") + print(f" API без токена: {response.status_code}") + if response.status_code == 401: + print(" ✅ Правильно - требует аутентификации") + else: + print(" ⚠️ Неожиданный статус") + except Exception as e: + print(f" ❌ Ошибка API без токена: {e}") + + # 3. Вход в систему + print("\n🔐 Вход в систему...") + login_data = {"username": "admin", "password": "admin"} + try: + response = requests.post(f"{base_url}/api/auth/login", json=login_data) + if response.status_code != 200: + print(f" ❌ Ошибка входа: {response.status_code}") + return + + token = response.json()["access_token"] + headers = {"Authorization": f"Bearer {token}"} + print(" ✅ Вход выполнен успешно") + except Exception as e: + print(f" ❌ Ошибка входа: {e}") + return + + # 4. Проверяем API с токеном + print("\n🔍 Проверка API с токеном...") + try: + response = requests.get(f"{base_url}/api/containers/services", headers=headers) + print(f" API с токеном: {response.status_code}") + if response.status_code == 200: + containers = response.json() + print(f" ✅ Получено контейнеров: {len(containers)}") + + # Показываем первые 3 контейнера + for i, container in enumerate(containers[:3]): + print(f" {i+1}. {container.get('name', 'N/A')} ({container.get('status', 'N/A')})") + else: + print(f" ❌ Ошибка API: {response.text}") + except Exception as e: + print(f" ❌ Ошибка API с токеном: {e}") + + # 5. Проверяем WebSocket status + print("\n🔍 Проверка WebSocket status...") + try: + response = requests.get(f"{base_url}/api/websocket/status", headers=headers) + print(f" WebSocket status: {response.status_code}") + if response.status_code == 200: + status = response.json() + print(f" ✅ WebSocket статус: {status}") + else: + print(f" ❌ Ошибка WebSocket status: {response.text}") + except Exception as e: + print(f" ❌ Ошибка WebSocket status: {e}") + + # 6. Проверяем логи для первого контейнера + try: + response = requests.get(f"{base_url}/api/containers/services", headers=headers) + if response.status_code == 200: + containers = response.json() + if containers: + first_container = containers[0] + container_id = first_container.get('id') + print(f"\n🔍 Проверка логов для контейнера {first_container.get('name')}...") + try: + response = requests.get(f"{base_url}/api/logs/{container_id}?tail=5", headers=headers) + print(f" Логи: {response.status_code}") + if response.status_code == 200: + logs = response.json() + print(f" ✅ Получено строк логов: {len(logs.get('logs', []))}") + else: + print(f" ❌ Ошибка логов: {response.text}") + except Exception as e: + print(f" ❌ Ошибка логов: {e}") + except Exception as e: + print(f" ❌ Ошибка получения контейнеров: {e}") + +if __name__ == "__main__": + test_api() diff --git a/test_browser.html b/test_browser.html new file mode 100644 index 0000000..1446e34 --- /dev/null +++ b/test_browser.html @@ -0,0 +1,199 @@ + + + + + + Тест LogBoard+ API + + + +

Тест LogBoard+ API

+ +
+

1. Проверка токена в localStorage

+ +
+
+ +
+

2. Тест входа в систему

+ +
+
+ +
+

3. Тест получения контейнеров

+ +
+
+ +
+

4. Тест WebSocket

+ +
+
+ +
+

5. Очистка

+ +
+
+ + + + diff --git a/test_websocket.py b/test_websocket.py new file mode 100644 index 0000000..15ba8c1 --- /dev/null +++ b/test_websocket.py @@ -0,0 +1,87 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Тестовый скрипт для проверки WebSocket соединений LogBoard+ +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" + +import asyncio +import websockets +import json +import requests + +async def test_websocket(): + """Тестирование WebSocket соединений""" + + base_url = "http://localhost:9001" + + # 1. Получаем токен + print("🔐 Получение токена...") + login_data = {"username": "admin", "password": "admin"} + try: + response = requests.post(f"{base_url}/api/auth/login", json=login_data) + if response.status_code != 200: + print(f" ❌ Ошибка входа: {response.status_code}") + return + + token = response.json()["access_token"] + print(" ✅ Токен получен") + except Exception as e: + print(f" ❌ Ошибка входа: {e}") + return + + # 2. Получаем список контейнеров + print("\n🔍 Получение контейнеров...") + headers = {"Authorization": f"Bearer {token}"} + try: + response = requests.get(f"{base_url}/api/containers/services", headers=headers) + if response.status_code != 200: + print(f" ❌ Ошибка получения контейнеров: {response.status_code}") + return + + containers = response.json() + print(f" ✅ Получено контейнеров: {len(containers)}") + + if not containers: + print(" ❌ Нет контейнеров для тестирования") + return + + first_container = containers[0] + container_id = first_container.get('id') + container_name = first_container.get('name') + print(f" 📦 Тестируем контейнер: {container_name} ({container_id})") + + except Exception as e: + print(f" ❌ Ошибка получения контейнеров: {e}") + return + + # 3. Тестируем WebSocket соединение + print(f"\n🔌 Тестирование WebSocket для {container_name}...") + + # Формируем WebSocket URL + ws_url = f"ws://localhost:9001/api/websocket/logs/{container_id}?tail=10&token={token}&service={container_name}" + print(f" 🔗 WebSocket URL: {ws_url}") + + try: + async with websockets.connect(ws_url) as websocket: + print(" ✅ WebSocket соединение установлено") + + # Ждем сообщения + print(" 📡 Ожидание сообщений...") + message_count = 0 + max_messages = 5 + + async for message in websocket: + message_count += 1 + print(f" 📨 Сообщение {message_count}: {message[:100]}...") + + if message_count >= max_messages: + print(f" ✅ Получено {message_count} сообщений") + break + + except Exception as e: + print(f" ❌ Ошибка WebSocket: {e}") + +if __name__ == "__main__": + asyncio.run(test_websocket())