diff --git a/Dockerfile b/Dockerfile index f98342a..34afc73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -10,6 +10,9 @@ COPY app/app.py /app/app.py COPY app/excluded_containers.json /app/excluded_containers.json COPY ./app/templates /app/templates COPY ./app/static /app/static +COPY ./app/core /app/core +COPY ./app/api /app/api +COPY ./app/models /app/models # Создаем пользователя и добавляем в группу docker RUN useradd -m appuser && \ diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..88b5d0c --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +LogBoard+ - Основной пакет приложения +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" diff --git a/app/api/__init__.py b/app/api/__init__.py new file mode 100644 index 0000000..a83d7fe --- /dev/null +++ b/app/api/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +LogBoard+ - API модули приложения +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" diff --git a/app/api/v1/__init__.py b/app/api/v1/__init__.py new file mode 100644 index 0000000..8ac51d4 --- /dev/null +++ b/app/api/v1/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +LogBoard+ - API v1 модули приложения +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" diff --git a/app/api/v1/endpoints/__init__.py b/app/api/v1/endpoints/__init__.py new file mode 100644 index 0000000..cce566b --- /dev/null +++ b/app/api/v1/endpoints/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +LogBoard+ - API endpoints модули приложения +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" diff --git a/app/api/v1/endpoints/auth.py b/app/api/v1/endpoints/auth.py index db90e19..fe320e4 100644 --- a/app/api/v1/endpoints/auth.py +++ b/app/api/v1/endpoints/auth.py @@ -12,14 +12,14 @@ from typing import Optional from fastapi import APIRouter, Depends, HTTPException, status, Response from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials -from app.core.auth import ( +from core.auth import ( authenticate_user, create_access_token, verify_token, get_current_user, ACCESS_TOKEN_EXPIRE_MINUTES ) -from app.models.auth import UserLogin, Token +from models.auth import UserLogin, Token router = APIRouter() diff --git a/app/api/v1/endpoints/containers.py b/app/api/v1/endpoints/containers.py index e87bb97..16fc77c 100644 --- a/app/api/v1/endpoints/containers.py +++ b/app/api/v1/endpoints/containers.py @@ -11,8 +11,8 @@ from typing import List, Optional from fastapi import APIRouter, Depends, HTTPException, Query, Body from fastapi.responses import JSONResponse -from app.core.auth import get_current_user -from app.core.docker import ( +from core.auth import get_current_user +from core.docker import ( load_excluded_containers, save_excluded_containers, get_all_projects, diff --git a/app/api/v1/endpoints/logs.py b/app/api/v1/endpoints/logs.py index e4afef5..c581512 100644 --- a/app/api/v1/endpoints/logs.py +++ b/app/api/v1/endpoints/logs.py @@ -15,9 +15,9 @@ from fastapi.responses import JSONResponse import docker -from app.core.auth import get_current_user -from app.core.docker import docker_client, DEFAULT_TAIL -from app.core.logger import api_logger +from core.auth import get_current_user +from core.docker import docker_client, DEFAULT_TAIL +from core.logger import api_logger router = APIRouter() @@ -206,7 +206,7 @@ def api_snapshot( ): """Сохранить снимок логов""" import os - from app.core.config import SNAP_DIR + from core.config import SNAP_DIR # Save posted content as a snapshot file safe_service = re.sub(r"[^a-zA-Z0-9_.-]+", "_", service or container_id[:12]) diff --git a/app/api/v1/endpoints/pages.py b/app/api/v1/endpoints/pages.py index 059319b..df001db 100644 --- a/app/api/v1/endpoints/pages.py +++ b/app/api/v1/endpoints/pages.py @@ -9,8 +9,8 @@ LogBoard+ - Страницы API from fastapi import APIRouter, Request, Depends, HTTPException from fastapi.responses import HTMLResponse, RedirectResponse, PlainTextResponse -from app.core.auth import verify_token, get_current_user -from app.core.config import templates, AJAX_UPDATE_INTERVAL, DEFAULT_TAIL, SKIP_UNHEALTHY +from core.auth import verify_token, get_current_user +from core.config import templates, AJAX_UPDATE_INTERVAL, DEFAULT_TAIL, SKIP_UNHEALTHY router = APIRouter() diff --git a/app/api/v1/endpoints/settings.py b/app/api/v1/endpoints/settings.py index 1d650bd..b44a8d8 100644 --- a/app/api/v1/endpoints/settings.py +++ b/app/api/v1/endpoints/settings.py @@ -8,8 +8,8 @@ LogBoard+ - Настройки API from fastapi import APIRouter, Depends -from app.core.auth import get_current_user -from app.core.config import AJAX_UPDATE_INTERVAL, DEFAULT_TAIL, SKIP_UNHEALTHY +from core.auth import get_current_user +from core.config import AJAX_UPDATE_INTERVAL, DEFAULT_TAIL, SKIP_UNHEALTHY router = APIRouter() diff --git a/app/api/v1/endpoints/websocket.py b/app/api/v1/endpoints/websocket.py index 38b91fa..f5669af 100644 --- a/app/api/v1/endpoints/websocket.py +++ b/app/api/v1/endpoints/websocket.py @@ -12,9 +12,9 @@ from typing import Optional from fastapi import APIRouter, WebSocket, WebSocketDisconnect, Query, Depends from fastapi.responses import JSONResponse -from app.core.auth import verify_token, get_current_user -from app.core.docker import docker_client, DEFAULT_TAIL -from app.core.logger import websocket_logger +from core.auth import verify_token, get_current_user +from core.docker import docker_client, DEFAULT_TAIL +from core.logger import websocket_logger from datetime import datetime router = APIRouter() diff --git a/app/app.py b/app/app.py index 4c8108e..896e40c 100644 --- a/app/app.py +++ b/app/app.py @@ -11,9 +11,9 @@ from fastapi import FastAPI, Request, HTTPException from fastapi.staticfiles import StaticFiles from fastapi.templating import Jinja2Templates -from app.core.config import DEBUG_MODE, SNAP_DIR, STATIC_DIR, APP_PORT -from app.api.v1.router import api_router, pages_router -from app.core.logger import app_logger +from core.config import DEBUG_MODE, SNAP_DIR, STATIC_DIR, APP_PORT +from api.v1.router import api_router, pages_router +from core.logger import app_logger # Инициализация FastAPI app = FastAPI( diff --git a/app/core/__init__.py b/app/core/__init__.py new file mode 100644 index 0000000..0787d9f --- /dev/null +++ b/app/core/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +LogBoard+ - Основные модули приложения +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" diff --git a/app/core/auth.py b/app/core/auth.py index eba4529..027442a 100644 --- a/app/core/auth.py +++ b/app/core/auth.py @@ -15,7 +15,7 @@ from fastapi.security import HTTPBearer, HTTPAuthorizationCredentials from passlib.context import CryptContext import jwt -from app.core.config import ( +from core.config import ( SECRET_KEY, ALGORITHM, ACCESS_TOKEN_EXPIRE_MINUTES, diff --git a/app/core/config.py b/app/core/config.py index 55c74d2..36f3f48 100644 --- a/app/core/config.py +++ b/app/core/config.py @@ -12,16 +12,16 @@ from fastapi.templating import Jinja2Templates # Настройки приложения APP_PORT = int(os.getenv("LOGBOARD_PORT", "9001")) DEFAULT_TAIL = int(os.getenv("LOGBOARD_TAIL", "500")) -DEFAULT_PROJECT = os.getenv("COMPOSE_PROJECT_NAME") -DEFAULT_PROJECTS = os.getenv("LOGBOARD_PROJECTS") +DEFAULT_PROJECT = os.getenv("COMPOSE_PROJECT_NAME", "myproj") +DEFAULT_PROJECTS = os.getenv("LOGBOARD_PROJECTS", "") SKIP_UNHEALTHY = os.getenv("LOGBOARD_SKIP_UNHEALTHY", "true").lower() == "true" CONTAINER_LIST_TIMEOUT = int(os.getenv("LOGBOARD_CONTAINER_LIST_TIMEOUT", "10")) CONTAINER_INFO_TIMEOUT = int(os.getenv("LOGBOARD_CONTAINER_INFO_TIMEOUT", "3")) HEALTH_CHECK_TIMEOUT = int(os.getenv("LOGBOARD_HEALTH_CHECK_TIMEOUT", "2")) # Настройки безопасности -SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key-here-change-in-production") -ENCRYPTION_KEY = os.getenv("ENCRYPTION_KEY", "your-encryption-key-here-change-in-production") +SECRET_KEY = os.getenv("SECRET_KEY", "your-secret-key-here") +ENCRYPTION_KEY = os.getenv("ENCRYPTION_KEY", "your-encryption-key-here") ALGORITHM = "HS256" ACCESS_TOKEN_EXPIRE_MINUTES = int(os.getenv("SESSION_TIMEOUT", "3600")) // 60 # 1 час по умолчанию @@ -39,8 +39,8 @@ DEBUG_MODE = os.getenv("DEBUG_MODE", "false").lower() == "true" templates = Jinja2Templates(directory="app/templates") # Директории -SNAP_DIR = os.getenv("LOGBOARD_SNAPSHOT_DIR", "./snapshots") -STATIC_DIR = os.getenv("LOGBOARD_STATIC_DIR", "./app/static") +SNAP_DIR = os.getenv("LOGBOARD_SNAPSHOT_DIR", "/app/snapshots") +STATIC_DIR = os.getenv("LOGBOARD_STATIC_DIR", "/app/static") INDEX_HTML = os.getenv("LOGBOARD_INDEX_HTML", "./app/templates/index.html") # Настройки веб-интерфейса @@ -72,6 +72,7 @@ DOCKER_CERT_PATH = os.getenv("DOCKER_CERT_PATH", "") DOCKER_NETWORKS = os.getenv("DOCKER_NETWORKS", "iaas,infrastructure_iaas") # Настройки логирования +LOG_LEVEL = os.getenv("LOG_LEVEL", "INFO") LOG_FORMAT = os.getenv("LOG_FORMAT", "json") # Временная зона diff --git a/app/core/docker.py b/app/core/docker.py index bdb9346..dc6179f 100644 --- a/app/core/docker.py +++ b/app/core/docker.py @@ -12,13 +12,13 @@ from typing import List, Dict, Optional import docker -from app.core.config import ( +from core.config import ( DEFAULT_TAIL, DEFAULT_PROJECT, DEFAULT_PROJECTS, SKIP_UNHEALTHY ) -from app.core.logger import docker_logger +from core.logger import docker_logger # Инициализация Docker клиента docker_client = docker.from_env() diff --git a/app/core/logger.py b/app/core/logger.py index a540955..f302650 100644 --- a/app/core/logger.py +++ b/app/core/logger.py @@ -11,7 +11,7 @@ import sys from typing import Optional import os -from app.core.config import DEBUG_MODE +from core.config import DEBUG_MODE def setup_logger(name: str = "logboard", level: Optional[str] = None) -> logging.Logger: """ diff --git a/app/models/__init__.py b/app/models/__init__.py new file mode 100644 index 0000000..607657d --- /dev/null +++ b/app/models/__init__.py @@ -0,0 +1,7 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +LogBoard+ - Модели данных приложения +Автор: Сергей Антропов +Сайт: https://devops.org.ru +""" diff --git a/docker-compose.yml b/docker-compose.yml index d1d656f..3222731 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -9,7 +9,6 @@ services: volumes: - /var/run/docker.sock:/var/run/docker.sock:ro - ./snapshots:/app/snapshots - - ./:/app restart: unless-stopped user: 0:0 networks: diff --git a/start.sh b/start.sh index 4210a17..94a1b55 100755 --- a/start.sh +++ b/start.sh @@ -20,7 +20,7 @@ if [ "$DEBUG_MODE" = "true" ]; then echo "Swagger UI: http://0.0.0.0:$LOGBOARD_PORT/docs" echo "ReDoc: http://0.0.0.0:$LOGBOARD_PORT/redoc" - exec uvicorn app.app:app \ + exec uvicorn app:app \ --host 0.0.0.0 \ --port $LOGBOARD_PORT \ --reload \ @@ -28,7 +28,7 @@ if [ "$DEBUG_MODE" = "true" ]; then else echo "Starting in PRODUCTION mode..." - exec uvicorn app.app:app \ + exec uvicorn app:app \ --host 0.0.0.0 \ --port $LOGBOARD_PORT \ --log-level info