Commit Graph

12 Commits

Author SHA1 Message Date
6796903712 feat(ipam): several IP addresses per instance
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 1m46s
Deploy to Production / Trigger production update (push) Failing after 10s
SonarCloud / SonarCloud Analysis (push) Failing after 3m7s
A guest was implicitly limited to a single allocation: lookups were
"(server, vmid) -> one row", release_ip_by_vmid freed one address, and
the link tool skipped guests that already had one. An instance can now
hold a primary address plus any number of aliases, managed from the
Network tab of the instance and visible on the IPAM pages.

Schema and service:
- ipam_allocations gains is_primary, assignment_kind, target_interface
  and apply_* columns; migration 43 marks existing rows as primary
- find_allocations_by_resource/set_primary; release_ip_by_vmid now frees
  every address of a deleted guest instead of just the first one
- next-available search may scan the whole subnet when a network has no
  auto-assign pool, skipping node and cached guest addresses so it never
  hands out an address that is already live

Applying to the guest (services/guest_ip_service.py):
- reuses script_engine, so LXC goes through pct exec and VMs through the
  guest agent; the shell script synchronises the whole alias list of an
  interface, which makes add, remove and retry the same code path
- persists via ifupdown, netplan, NetworkManager or sysconfig and never
  restarts guest networking; an unknown stack degrades to runtime_only
  and an unreachable guest keeps the allocation as pending

API and UI:
- /ipam/api/guests/{server_id}/{vmid}/addresses: list, add, apply,
  primary, delete; allocations list accepts guest filters
- instance list exposes ips[] alongside the primary ip
- addresses card on the Network tab, "+N" badge in the IP column,
  primary badge in the allocations table

Fixes found along the way:
- link-allocations registers every address of a guest, carries the MAC
  over, refuses to take an address away from another live guest and no
  longer matches allocations by resource name (which leaked an address
  between same-named guests on different servers)
- IPAM history no longer fails to serialise datetime values, which used
  to abort re-linking with a 500
2026-08-21 23:48:20 +05:00
markmorado
633f1a424c feat(appstore): кастомный порт при установке + мгновенная чистка инстанса
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 57s
Deploy to Production / Trigger production update (push) Successful in 7s
App Store:
- поле кастомного порта в мастере установки (переопределяет порт каталога)
- валидация диапазона порта 1..65535 (Pydantic Field + EngineError)
- APP_PORT в окружении синхронизируется с выбранным портом
- при удалении приложения инстанс сразу помечается deleted в кэше
  vm_instances (soft_delete_vm_instance), не дожидаясь фонового воркера

Также включены правки IPAM (привязка сетей к рабочей области, UI
WorkspaceSelect) и синхронизации каталога App Store.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-09 01:20:28 +05:00
4feb802c4f fix(ipam): filter unlinked allocations to VMs with IPs inside active IPAM networks
All checks were successful
Backend Tests / pytest (Python 3.12) (push) Successful in 46s
Deploy to Production / Trigger production update (push) Successful in 8s
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-06-20 02:53:50 +05:00
de967c35e0 refactor(rbac): migrate API permission checks to resource:action format
Replace all legacy dotted permission codes (vms.view, proxmox.manage, ...)
in PermissionChecker/has_permission across app/api with the new
resource:action format (vm:view, server:manage, ...), per LEGACY_PERMISSION_MAP.
All 33 codes used by the API are now registered in the permission registry.

Also switch the /api/auth/me admin branch to get_all_permissions_v2 so the
endpoint emits permissions in the new format only.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-20 02:07:48 +05:00
d66928ee78 refactor(proxmox): unify ProxmoxClient construction via from_server
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 48s
Deploy to Production / Trigger production update (push) Successful in 8s
Collapse four duplicated host+auth client-building blocks into a single
ProxmoxClient.from_server() classmethod (the canonical source of truth):

- _helpers._get_proxmox_client now delegates to from_server (107 callers
  untouched)
- ipam._build_proxmox_client removed; its one call site uses from_server
- task_queue_service keeps its per-server cache pool, builds via from_server
- monitoring_worker keeps its ValueError-on-missing-auth contract, builds
  via from_server

Behaviour preserved (token-first, then password; non-default port appended).
Verified: containers rebuild healthy, smoke test of both auth paths passes.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 22:30:57 +05:00
bfd92102cf Refactor backend: Split models and proxmox_client into modules, add alembic
Some checks failed
Backend Tests / pytest (Python 3.12) (push) Failing after 2m27s
2026-06-13 03:53:27 +05:00
markmorado
1d08c815a7 fix: frontend-backend integration — 14 issues resolved
- nginx: add proxy routes for /settings/, /templates/, /ipam/, /logs/, /admin/, /health
- dashboard: fix data format mismatch (servers[] not nodes[]/vms[])
- dashboard: add WebSocket subscription to dashboard_metrics for real-time updates
- dashboard: connect activity feed to /logs/api/logs endpoint
- dashboard: reduce polling to 15s with WS as primary update source
- graphs: fix rrddata response unwrap (backend returns {data:[],timeframe:''})
- graphs: add i18n translations for chart titles
- console: add xterm.js CSS import for proper terminal rendering
- console: add i18n translations (connecting, reconnect)
- workspace: add switcher dropdown in TopBar
- workspace: add edit dialog in WorkspacesPage
- workspace: create Zustand store with localStorage persistence
- workspace: add X-Active-Workspace header to API client
- sidebar: replace generic icon with actual favicon.svg logo
- instances: translate RowActionMenu and InstanceDetailPage strings
- locales: add graphs, console, workspace, instance tab keys to en/ru
2026-04-07 00:46:04 +02:00
markmorado
91dbf0b81c feat: IPAM improvements - server/node subnet binding, theme color fixes
- IPAM link-allocations: filter networks by proxmox_server_id and proxmox_node
  to prevent cross-server/cross-node IP assignment
- IPAM link-allocations: add manual server+network selection modal before linking
- IPAM add-network forms: add Proxmox server and node selectors with dynamic
  cluster-info loading (ipam_dashboard.html, ipam_networks.html)
- models.py / schemas.py: add proxmox_node field to IPAMNetwork
- migrations: migration #16 adds proxmox_node column to ipam_networks table
- Theme fixes: replace all hardcoded rgba/color:#fff/color:white with CSS vars
  across base.html, virtual_machines.html, instance_detail.html,
  os_templates.html, proxmox_vms.html, ipam_network_detail.html,
  ipam_allocations.html
- i18n: add proxmox_node, node selector, link-allocations modal keys (ru/en)
- Version bump: 1.0.4 -> 1.0.5
2026-03-08 14:17:54 +01:00
Claude
7c42de11a3 fix: repair two runtime bugs missed in Q2/Q3
- proxmox/__init__.py: re-export get_next_vmid, save_vm_instance,
  get_vm_instance so templates.py import doesn't raise ImportError
  (regression introduced in Q3 split)
- ipam.py:791: remove erroneous await on non-async get_orphan_allocations()
  (missed in Q2 async cleanup)

https://claude.ai/code/session_019rK2wvaWg5zXFwmAPPEB7R
2026-03-07 18:29:33 +00:00
Claude
7bd2dd5b8f refactor: remove spurious async defs in ipam.py, deduplicate ProxmoxClient instantiation
- api/ipam.py: convert 30 async def handlers that had no await to plain def,
  letting FastAPI run them in its thread pool (correct for sync SQLAlchemy I/O);
  cleanup_orphan_allocations kept async (it has await)
- api/proxmox.py: add _get_proxmox_client(server) helper that encapsulates the
  use_password/token branching, replace 58 duplicated 10-line blocks with a
  single call; get_proxmox_resources() call sites left unchanged (different sig)

https://claude.ai/code/session_019rK2wvaWg5zXFwmAPPEB7R
2026-03-07 11:57:44 +00:00
Claude
e05650cc9b perf: async Proxmox API, optimized IPAM queries, log cleanup scheduling, background template import
- proxmox_client.py: add ThreadPoolExecutor(max_workers=20) + async wrapper
  methods (async_get_nodes, async_get_vms, async_get_containers,
  async_get_node_status, async_get_vm_status, async_get_container_status,
  async_get_storages, async_get_all_resources) to avoid blocking event loop
- ipam_service.py: replace full-network allocation scan + Python IP loop with
  per-pool targeted SQL query — only loads IPs for the specific pool being searched
- api/ipam.py: fix N+1 full-table scans on GET /api/allocations — use IN-filtered
  queries on only the network/pool IDs present in the result set
- monitoring_worker.py: wire LoggingService.cleanup_old_logs(days=30) into the
  existing run_cleanup_expired() job so audit logs don't grow unboundedly
- api/templates.py: convert auto_import_templates to async endpoint using
  BackgroundTasks — returns immediately, heavy Proxmox I/O runs in background

https://claude.ai/code/session_019rK2wvaWg5zXFwmAPPEB7R
2026-03-07 11:48:53 +00:00
f5a3903f5d Add complete project structure and all files 2025-12-15 13:03:29 +05:00