fix: correct relative imports in proxmox subpackage and CSP headers
- Fix all `from ..` → `from ...` in app/api/proxmox/*.py after the proxmox.py split (PR #6) placed modules one level deeper, causing ModuleNotFoundError on startup - Broaden Content-Security-Policy to allow CDN sources used in templates: cdnjs.cloudflare.com (Font Awesome), cdn.jsdelivr.net (Bootstrap, Chart.js, xterm), fonts.googleapis.com/gstatic.com (Google Fonts), esm.sh (noVNC) — the overly-strict CSP was blocking all icons and charts from loading in the browser Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -10,14 +10,14 @@ import asyncio
|
|||||||
import httpx
|
import httpx
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from ..db import get_db
|
from ...db import get_db
|
||||||
from ..models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
from ...models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
||||||
from ..schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
from ...schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
||||||
from ..proxmox_client import ProxmoxClient, get_proxmox_resources
|
from ...proxmox_client import ProxmoxClient, get_proxmox_resources
|
||||||
from ..auth import get_current_user, PermissionChecker, require_permission, check_permission
|
from ...auth import get_current_user, PermissionChecker, require_permission, check_permission
|
||||||
from ..logging_service import LoggingService
|
from ...logging_service import LoggingService
|
||||||
from ..template_helpers import add_i18n_context
|
from ...template_helpers import add_i18n_context
|
||||||
from ..ipam_service import IPAMService
|
from ...ipam_service import IPAMService
|
||||||
|
|
||||||
templates = Jinja2Templates(directory="app/templates")
|
templates = Jinja2Templates(directory="app/templates")
|
||||||
|
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import asyncio
|
|||||||
import httpx
|
import httpx
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from ..db import get_db
|
from ...db import get_db
|
||||||
from ..models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
from ...models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
||||||
from ..schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
from ...schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
||||||
from ..proxmox_client import ProxmoxClient, get_proxmox_resources
|
from ...proxmox_client import ProxmoxClient, get_proxmox_resources
|
||||||
from ..auth import get_current_user, PermissionChecker, require_permission, check_permission
|
from ...auth import get_current_user, PermissionChecker, require_permission, check_permission
|
||||||
from ..logging_service import LoggingService
|
from ...logging_service import LoggingService
|
||||||
from ..template_helpers import add_i18n_context
|
from ...template_helpers import add_i18n_context
|
||||||
from ..ipam_service import IPAMService
|
from ...ipam_service import IPAMService
|
||||||
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
||||||
get_next_vmid, archive_and_delete_snapshots,
|
get_next_vmid, archive_and_delete_snapshots,
|
||||||
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import asyncio
|
|||||||
import httpx
|
import httpx
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from ..db import get_db
|
from ...db import get_db
|
||||||
from ..models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
from ...models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
||||||
from ..schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
from ...schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
||||||
from ..proxmox_client import ProxmoxClient, get_proxmox_resources
|
from ...proxmox_client import ProxmoxClient, get_proxmox_resources
|
||||||
from ..auth import get_current_user, PermissionChecker, require_permission, check_permission
|
from ...auth import get_current_user, PermissionChecker, require_permission, check_permission
|
||||||
from ..logging_service import LoggingService
|
from ...logging_service import LoggingService
|
||||||
from ..template_helpers import add_i18n_context
|
from ...template_helpers import add_i18n_context
|
||||||
from ..ipam_service import IPAMService
|
from ...ipam_service import IPAMService
|
||||||
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
||||||
get_next_vmid, archive_and_delete_snapshots,
|
get_next_vmid, archive_and_delete_snapshots,
|
||||||
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
||||||
@@ -31,7 +31,7 @@ router = APIRouter()
|
|||||||
@router.get("/vms", response_class=HTMLResponse, include_in_schema=False)
|
@router.get("/vms", response_class=HTMLResponse, include_in_schema=False)
|
||||||
def vms_page(request: Request, db: Session = Depends(get_db)):
|
def vms_page(request: Request, db: Session = Depends(get_db)):
|
||||||
"""Страница управления Proxmox серверами, VM и LXC"""
|
"""Страница управления Proxmox серверами, VM и LXC"""
|
||||||
from ..i18n import t
|
from ...i18n import t
|
||||||
lang = request.cookies.get("language", "en")
|
lang = request.cookies.get("language", "en")
|
||||||
|
|
||||||
proxmox_servers = db.query(ProxmoxServer).all()
|
proxmox_servers = db.query(ProxmoxServer).all()
|
||||||
@@ -430,7 +430,7 @@ def update_proxmox_server(
|
|||||||
current_user: User = Depends(PermissionChecker("proxmox.servers.edit"))
|
current_user: User = Depends(PermissionChecker("proxmox.servers.edit"))
|
||||||
):
|
):
|
||||||
"""Обновить Proxmox сервер"""
|
"""Обновить Proxmox сервер"""
|
||||||
from ..proxmox_client import clear_server_cache
|
from ...proxmox_client import clear_server_cache
|
||||||
|
|
||||||
server = db.query(ProxmoxServer).filter(ProxmoxServer.id == server_id).first()
|
server = db.query(ProxmoxServer).filter(ProxmoxServer.id == server_id).first()
|
||||||
if not server:
|
if not server:
|
||||||
@@ -460,8 +460,8 @@ def delete_proxmox_server(
|
|||||||
current_user: User = Depends(PermissionChecker("proxmox.servers.delete"))
|
current_user: User = Depends(PermissionChecker("proxmox.servers.delete"))
|
||||||
):
|
):
|
||||||
"""Удалить Proxmox сервер и связанные OS Templates"""
|
"""Удалить Proxmox сервер и связанные OS Templates"""
|
||||||
from ..proxmox_client import clear_server_cache
|
from ...proxmox_client import clear_server_cache
|
||||||
from ..models import OSTemplate, OSTemplateGroup, VMInstance
|
from ...models import OSTemplate, OSTemplateGroup, VMInstance
|
||||||
|
|
||||||
server = db.query(ProxmoxServer).filter(ProxmoxServer.id == server_id).first()
|
server = db.query(ProxmoxServer).filter(ProxmoxServer.id == server_id).first()
|
||||||
if not server:
|
if not server:
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import asyncio
|
|||||||
import httpx
|
import httpx
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from ..db import get_db
|
from ...db import get_db
|
||||||
from ..models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
from ...models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
||||||
from ..schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
from ...schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
||||||
from ..proxmox_client import ProxmoxClient, get_proxmox_resources
|
from ...proxmox_client import ProxmoxClient, get_proxmox_resources
|
||||||
from ..auth import get_current_user, PermissionChecker, require_permission, check_permission
|
from ...auth import get_current_user, PermissionChecker, require_permission, check_permission
|
||||||
from ..logging_service import LoggingService
|
from ...logging_service import LoggingService
|
||||||
from ..template_helpers import add_i18n_context
|
from ...template_helpers import add_i18n_context
|
||||||
from ..ipam_service import IPAMService
|
from ...ipam_service import IPAMService
|
||||||
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
||||||
get_next_vmid, archive_and_delete_snapshots,
|
get_next_vmid, archive_and_delete_snapshots,
|
||||||
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
||||||
|
|||||||
@@ -10,16 +10,16 @@ import asyncio
|
|||||||
import httpx
|
import httpx
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from ..db import get_db
|
from ...db import get_db
|
||||||
from ..models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
from ...models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
||||||
from ..schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
from ...schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
||||||
from ..proxmox_client import ProxmoxClient, get_proxmox_resources
|
from ...proxmox_client import ProxmoxClient, get_proxmox_resources
|
||||||
from ..auth import get_current_user, PermissionChecker, require_permission, check_permission
|
from ...auth import get_current_user, PermissionChecker, require_permission, check_permission
|
||||||
from ..logging_service import LoggingService
|
from ...logging_service import LoggingService
|
||||||
from ..template_helpers import add_i18n_context
|
from ...template_helpers import add_i18n_context
|
||||||
from ..ipam_service import IPAMService
|
from ...ipam_service import IPAMService
|
||||||
from ..models import TaskQueue
|
from ...models import TaskQueue
|
||||||
from ..services.task_queue_service import TaskQueueService, process_task_queue
|
from ...services.task_queue_service import TaskQueueService, process_task_queue
|
||||||
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
||||||
get_next_vmid, archive_and_delete_snapshots,
|
get_next_vmid, archive_and_delete_snapshots,
|
||||||
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
||||||
|
|||||||
@@ -10,14 +10,14 @@ import asyncio
|
|||||||
import httpx
|
import httpx
|
||||||
import websockets
|
import websockets
|
||||||
|
|
||||||
from ..db import get_db
|
from ...db import get_db
|
||||||
from ..models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
from ...models import ProxmoxServer, VMInstance, User, IPAMAllocation, IPAMNetwork, VMSnapshotArchive
|
||||||
from ..schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
from ...schemas import ProxmoxServerCreate, ProxmoxServerUpdate, ProxmoxServerResponse
|
||||||
from ..proxmox_client import ProxmoxClient, get_proxmox_resources
|
from ...proxmox_client import ProxmoxClient, get_proxmox_resources
|
||||||
from ..auth import get_current_user, PermissionChecker, require_permission, check_permission
|
from ...auth import get_current_user, PermissionChecker, require_permission, check_permission
|
||||||
from ..logging_service import LoggingService
|
from ...logging_service import LoggingService
|
||||||
from ..template_helpers import add_i18n_context
|
from ...template_helpers import add_i18n_context
|
||||||
from ..ipam_service import IPAMService
|
from ...ipam_service import IPAMService
|
||||||
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
||||||
get_next_vmid, archive_and_delete_snapshots,
|
get_next_vmid, archive_and_delete_snapshots,
|
||||||
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
save_vm_instance, get_vm_instance, soft_delete_vm_instance,
|
||||||
@@ -25,8 +25,8 @@ from ._helpers import (check_vm_access, require_vm_access, _get_proxmox_client,
|
|||||||
|
|
||||||
router = APIRouter()
|
router = APIRouter()
|
||||||
|
|
||||||
from ..models import TaskQueue
|
from ...models import TaskQueue
|
||||||
from ..services.task_queue_service import TaskQueueService, process_task_queue
|
from ...services.task_queue_service import TaskQueueService, process_task_queue
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel
|
||||||
from typing import List as TypingList, Optional
|
from typing import List as TypingList, Optional
|
||||||
|
|
||||||
@@ -54,7 +54,7 @@ def sync_vms_now(
|
|||||||
Useful when you create VMs directly in Proxmox and want them to appear in the panel immediately.
|
Useful when you create VMs directly in Proxmox and want them to appear in the panel immediately.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
from ..workers.monitoring_worker import MonitoringWorker
|
from ...workers.monitoring_worker import MonitoringWorker
|
||||||
|
|
||||||
worker = MonitoringWorker()
|
worker = MonitoringWorker()
|
||||||
worker.sync_vm_cache()
|
worker.sync_vm_cache()
|
||||||
@@ -86,7 +86,7 @@ def get_all_virtual_machines(
|
|||||||
|
|
||||||
Для пользователей с ролью 'user' возвращаются только их собственные инстансы.
|
Для пользователей с ролью 'user' возвращаются только их собственные инстансы.
|
||||||
"""
|
"""
|
||||||
from ..models import VMInstance
|
from ...models import VMInstance
|
||||||
|
|
||||||
# Get servers for name lookup
|
# Get servers for name lookup
|
||||||
servers = db.query(ProxmoxServer).all()
|
servers = db.query(ProxmoxServer).all()
|
||||||
@@ -403,7 +403,7 @@ async def delete_vm(
|
|||||||
current_user: User = Depends(PermissionChecker("vms.delete"))
|
current_user: User = Depends(PermissionChecker("vms.delete"))
|
||||||
):
|
):
|
||||||
"""Удалить VM"""
|
"""Удалить VM"""
|
||||||
from ..i18n import t
|
from ...i18n import t
|
||||||
lang = request.cookies.get("language", "en")
|
lang = request.cookies.get("language", "en")
|
||||||
|
|
||||||
# VPS-style user isolation: check VM ownership for limited users
|
# VPS-style user isolation: check VM ownership for limited users
|
||||||
@@ -784,7 +784,7 @@ async def delete_container(
|
|||||||
current_user: User = Depends(PermissionChecker("vms.delete"))
|
current_user: User = Depends(PermissionChecker("vms.delete"))
|
||||||
):
|
):
|
||||||
"""Удалить LXC контейнер"""
|
"""Удалить LXC контейнер"""
|
||||||
from ..i18n import t
|
from ...i18n import t
|
||||||
lang = request.cookies.get("language", "en")
|
lang = request.cookies.get("language", "en")
|
||||||
|
|
||||||
# VPS-style user isolation: check container ownership for limited users
|
# VPS-style user isolation: check container ownership for limited users
|
||||||
@@ -2116,7 +2116,7 @@ async def create_lxc_container_smart(
|
|||||||
# Update IPAM allocation with VMID and server info
|
# Update IPAM allocation with VMID and server info
|
||||||
if ipam_allocation_id:
|
if ipam_allocation_id:
|
||||||
try:
|
try:
|
||||||
from ..models import IPAMAllocation
|
from ...models import IPAMAllocation
|
||||||
allocation = db.query(IPAMAllocation).filter(IPAMAllocation.id == ipam_allocation_id).first()
|
allocation = db.query(IPAMAllocation).filter(IPAMAllocation.id == ipam_allocation_id).first()
|
||||||
if allocation:
|
if allocation:
|
||||||
allocation.resource_id = vmid
|
allocation.resource_id = vmid
|
||||||
|
|||||||
@@ -178,11 +178,11 @@ def create_app() -> FastAPI:
|
|||||||
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
|
response.headers["Referrer-Policy"] = "strict-origin-when-cross-origin"
|
||||||
response.headers["Content-Security-Policy"] = (
|
response.headers["Content-Security-Policy"] = (
|
||||||
"default-src 'self'; "
|
"default-src 'self'; "
|
||||||
"script-src 'self' 'unsafe-inline' 'unsafe-eval'; "
|
"script-src 'self' 'unsafe-inline' 'unsafe-eval' https://cdn.jsdelivr.net https://esm.sh; "
|
||||||
"style-src 'self' 'unsafe-inline'; "
|
"style-src 'self' 'unsafe-inline' https://cdnjs.cloudflare.com https://cdn.jsdelivr.net https://fonts.googleapis.com; "
|
||||||
"img-src 'self' data: blob:; "
|
"img-src 'self' data: blob:; "
|
||||||
"connect-src 'self' wss: ws:; "
|
"connect-src 'self' wss: ws: https://esm.sh; "
|
||||||
"font-src 'self' data:; "
|
"font-src 'self' data: https://cdnjs.cloudflare.com https://fonts.gstatic.com; "
|
||||||
"frame-ancestors 'self';"
|
"frame-ancestors 'self';"
|
||||||
)
|
)
|
||||||
if not settings.DEBUG:
|
if not settings.DEBUG:
|
||||||
|
|||||||
Reference in New Issue
Block a user