Commit Graph

20 Commits

Author SHA1 Message Date
Shaun Arman
58b4d59e6d fix(proxmox): address PR review findings
Some checks failed
Test / frontend-tests (pull_request) Successful in 1m38s
Test / frontend-typecheck (pull_request) Successful in 1m46s
PR Review Automation / review (pull_request) Successful in 5m37s
Test / rust-fmt-check (pull_request) Failing after 12m26s
Test / rust-clippy (pull_request) Successful in 13m43s
Test / rust-tests (pull_request) Successful in 16m4s
- Storage: prevent double-slash ID when cluster/resources returns
  shared storage without a node field (e.g. "storage//PBS_TFTSR"
  → "storage/PBS_TFTSR")
- Firewall: add comment explaining why rule_num is omitted from
  add_rule — PVE assigns position (pos) automatically on creation
- Network: replace misleading "implementation pending" toasts with
  an immediate warning; dialog no longer opens since backend commands
  (POST/PUT/DELETE nodes/{node}/network) are not yet implemented
- Backup: same treatment for New Job — warns immediately instead of
  opening a form that silently does nothing
- VMList: add comment explaining handleVMAction receives clusterId
  from props (not a stale closure over state); add inline comment
  clarifying the migration button disabled conditions
2026-06-21 15:48:09 -05:00
Shaun Arman
577512562b fix(proxmox): resolve 7 dashboard and AI chat issues
1. VM Actions: pass clusterId/clusters props from VMsPage to VMList;
   rename node→node_id in 14 Rust Tauri command handlers to match
   Tauri 2.x camelCase→snake_case mapping; wire action menu items
   through handleAction so menu closes on click.

2. Migration: add Target Remote dropdown in MigrationDialog showing
   available clusters for cross-datacenter migration; targetCluster
   passed through to migrate_vm invoke.

3. Storage: switch list_proxmox_datastores to cluster/resources?type=storage
   (single API call, cluster-wide); normalize plugintype→type,
   disk/maxdisk→used/size, compute available via saturating_sub.

4. Network: replace free-text Interface Type Input with a Select
   dropdown listing all PVE network interface types.

5. Firewall New Rule: add onNewRule prop to FirewallRuleList, wire
   button; add full dialog in FirewallPage with action/protocol/
   source/dest/port fields that calls add_firewall_rule; rewrite
   Rust command to accept rule as serde_json::Value instead of
   flat params (matches frontend invoke signature).

6. Backup: normalize raw PVE cluster/backup fields (id, storage,
   node, schedule, enabled, next-run timestamp) to BackupJobInfo
   shape; update BackupJobList columns to show storage, vmid, mode.

7. AI chat: merge all system prompt sections into a single system
   message (fixes Qwen 3.5 / LiteLLM rejection of multiple system
   messages); push assistant message with tool_calls before tool
   result messages to satisfy OpenAI API contract.
2026-06-21 15:08:56 -05:00
Shaun Arman
d922b72f53 fix(proxmox): comprehensive VM management and UI improvements
Some checks failed
Test / frontend-tests (pull_request) Successful in 1m37s
Test / frontend-typecheck (pull_request) Failing after 1m49s
PR Review Automation / review (pull_request) Successful in 6m2s
Test / rust-fmt-check (pull_request) Failing after 12m10s
Test / rust-clippy (pull_request) Failing after 13m15s
Test / rust-tests (pull_request) Failing after 13m23s
- VM Migration:
  * Added proper dialog with target node selection dropdown
  * Fixed migration trigger to actually call the API
  * Added live migration options with max downtime configuration

- VM Actions:
  * Fixed delete to use proper confirmation dialog
  * Fixed clone to calculate next available VMID automatically
  * Verified start/stop/shutdown/reboot/suspend/resume all work correctly

- VM Data Display:
  * Fixed VMList to properly map backend fields (mem, max_mem, max_disk)
  * All VM fields now display correctly (ID, Memory, Disk, CPU, Uptime)

- Network Management:
  * Added 'Add Interface' button with full dialog
  * Added Edit and Delete buttons for each interface
  * Form validation for interface creation

- Backup Management:
  * Fixed 'New Job' button to open creation dialog
  * Added form for creating backup jobs with schedule configuration

- Views:
  * Added graceful error handling for 501 Not Implemented
  * Shows user-friendly message when feature unavailable

- AI Provider:
  * Fixed system message ordering in openai.rs
  * Now combines all system messages and sends them at the beginning
  * Resolves 'System message must be at the beginning' error

- All 386 tests pass
2026-06-21 11:17:31 -05:00
Shaun Arman
118f817a18 fix(proxmox): address 11 dashboard issues and add missing VM action commands
Some checks failed
Test / frontend-tests (pull_request) Successful in 1m45s
Test / frontend-typecheck (pull_request) Successful in 1m54s
Test / rust-tests (pull_request) Has been cancelled
Test / rust-fmt-check (pull_request) Has been cancelled
Test / rust-clippy (pull_request) Has been cancelled
PR Review Automation / review (pull_request) Successful in 6m10s
Backend:
- Add resume_proxmox_vm, suspend_proxmox_vm, clone_vm, delete_vm Tauri commands
- Implement proxmox/vm.rs functions for resume, suspend, clone, delete operations
- Register all new commands in lib.rs

Frontend:
- Fix VMList.tsx: Import confirm from @tauri-apps/plugin-dialog
- Fix VMList.tsx: Replace prompt() with window.prompt() for user input
- Fix VMList.tsx: Correct paused VM action to resume instead of suspend
- Fix VMList.tsx: Implement proper menu positioning with horizontal overflow detection
- Fix StorageList.tsx: Add error handling to formatBytes for negative/non-numeric input
- Fix VMsPage.tsx: Remove redundant handler stubs, let VMList handle actions

All changes pass TypeScript type checking, Rust clippy, and frontend tests (386 tests passing).
2026-06-21 09:38:10 -05:00
Shaun Arman
9d5390df5b fix(proxmox): resolve 11 dashboard UI and API issues
Some checks failed
Test / frontend-tests (pull_request) Successful in 1m42s
Test / frontend-typecheck (pull_request) Successful in 1m52s
PR Review Automation / review (pull_request) Successful in 4m50s
Test / rust-fmt-check (pull_request) Failing after 12m23s
Test / rust-clippy (pull_request) Successful in 13m39s
Test / rust-tests (pull_request) Successful in 15m8s
- Action menu: fix click-outside closing, positioning, opacity, and functionality
- VM metrics: fix CPU %, memory/disk bars with formatBytes helper, uptime formatting
- list_cluster_tasks: remove invalid 'limit' query parameter causing 400 error
- list_views/list_certificates: handle 501 Not Implemented gracefully
- list_proxmox_datastores: fetch per-node storage via /nodes/{node}/storage
- list_proxmox_backup_jobs: use cluster-level /cluster/backup endpoint
- Tests: update integration tests to use PROXMOX_HOST env var

Fixes:
- Action menu not closing when clicking away
- CPU/memory/disk/uptime displaying raw values
- Storage not displaying data
- Backup jobs not showing details
- Tasks API returning 400 Bad Request
- Views/Certificates APIs causing errors on older Proxmox versions
2026-06-20 23:39:33 -05:00
Shaun Arman
cec962b349 docs: remove hardcoded 172.0.0.18 references
Some checks failed
PR Review Automation / review (pull_request) Has been cancelled
Test / frontend-typecheck (pull_request) Has been cancelled
Test / frontend-tests (pull_request) Has been cancelled
Test / rust-tests (pull_request) Has been cancelled
Test / rust-clippy (pull_request) Has been cancelled
Test / rust-fmt-check (pull_request) Has been cancelled
Replace with generic proxmox-server hostname across all documentation
and code comments.
2026-06-20 21:51:51 -05:00
Shaun Arman
b091602741 fix(proxmox): restore reliable connect/reconnect after app restart
Root cause: authenticate() tried to deserialize the Proxmox API response
directly into AuthResponse, but Proxmox wraps every response in
{"data": {...}}.  This caused every reconnect attempt after app restart
to fail silently.

Additional fixes bundled in this commit:
- add_proxmox_cluster now authenticates immediately so the in-memory pool
  always contains a live, ticketed client (not a bare unauthenticated stub)
- ProxmoxClient stores the CSRFPreventionToken and includes it in the
  CSRFPreventionToken header on POST/PUT/DELETE requests (Proxmox requires
  this for all mutating calls)
- accept-invalid-certs enabled on the reqwest Client so self-signed PVE
  certificates do not block connections
- Removed double-unwrap of the data field in 10 commands (list_acls,
  list_users, get_cluster_notes, search_proxmox_resources, get_node_status,
  get_syslog, list_network_interfaces, get_subscription_status,
  list_cluster_tasks, list_proxmox_containers) — handle_response already
  strips the envelope before returning to callers
- Added connect_proxmox_cluster and disconnect_proxmox_cluster Tauri
  commands so the UI can explicitly connect/disconnect sessions
- Wired RemotesPage Connect/Disconnect buttons to the real backend commands
- Updated and added tests covering envelope parsing, CSRF header logic,
  already-unwrapped response handling, and the new connect/disconnect paths
2026-06-20 19:38:49 -05:00
Shaun Arman
68439bcd64 fix: address PR review findings — race condition, real ping, atomic edit, listener cleanup
All checks were successful
Test / frontend-typecheck (pull_request) Successful in 2m19s
Test / frontend-tests (pull_request) Successful in 2m10s
PR Review Automation / review (pull_request) Successful in 8m50s
Test / rust-fmt-check (pull_request) Successful in 16m20s
Test / rust-clippy (pull_request) Successful in 17m51s
Test / rust-tests (pull_request) Successful in 19m20s
Race condition in get_proxmox_client_for_cluster: two concurrent callers
for an uncached cluster could both authenticate and insert, with the second
overwriting the first. Re-check under write lock before inserting so the
later caller returns the already-stored client instead of overwriting it.

handleConnectRemote used getProxmoxCluster (a DB-only lookup) to set status
'connected', which passed even when the Proxmox API was unreachable. Replace
with pingProxmoxCluster, a new command that authenticates and calls
GET /api2/json/version, providing a real end-to-end connectivity test.

handleEditRemote used remove-then-add, leaving a gap where the record was
absent and silently lost if addProxmoxCluster failed. Replace with
updateProxmoxCluster, a new command that issues a single SQL UPDATE (plus
in-memory pool eviction) so the record is never transiently missing.

ActionsMenu useEffect added the mousedown listener only when open=true but
the dependency array contained open, causing ambiguity about cleanup timing.
Attach the listener unconditionally on mount (empty dep array) so there is
always exactly one add and one remove with no conditional branches.

New Rust tests cover update_proxmox_cluster not-found logic and ping error
message format (420 Rust + 386 frontend, zero failures).
2026-06-19 22:26:33 -05:00
Shaun Arman
c5b97f8648 fix(proxmox): restore broken client retrieval across all commands
All checks were successful
Test / frontend-tests (pull_request) Successful in 1m36s
Test / frontend-typecheck (pull_request) Successful in 1m46s
PR Review Automation / review (pull_request) Successful in 5m8s
Test / rust-fmt-check (pull_request) Successful in 12m30s
Test / rust-clippy (pull_request) Successful in 14m10s
Test / rust-tests (pull_request) Successful in 16m35s
Half-completed refactor left 68 Tauri command functions with orphaned
.ok_or_else() chains after the old clusters.get() pattern was removed
without inserting the replacement helper call. Also fixed two bugs in the
new get_proxmox_client_for_cluster helper: undeclared `clusters` variable
in the early-return check, and client_arc going out of scope before return.

fix(ai): enforce system-message-first ordering for strict LLM providers

Qwen3.5-122b (and other models via LiteLLM) reject requests where system
messages appear after user/assistant turns. Moved tool-calling format
and iteration-budget system messages to before history is appended.
Changed mid-loop iteration warning and forced-stop instruction from
system role to user role so they can safely appear mid-conversation.

fix(proxmox): Remotes actions menu and connect/disconnect behaviour

Replaced the non-functional "..." toast placeholder with a proper
ActionsMenu dropdown (Edit / Test Connection / Delete). Removed inline
emoji buttons folded into the menu. Connect now calls getProxmoxCluster
as a live connection test and reflects real status; disconnect marks the
remote disconnected locally. Remote status now maps correctly from the
backend ClusterInfoWithHealth.connected field instead of hardcoding
'connected' for every entry.

fix(proxmox): Ceph page no longer shows HEALTH_OK on non-Ceph clusters

Page now fetches real health data on mount. If getCephHealth fails the
page renders an informational notice rather than fake HEALTH_OK. When
Ceph is present, pools and OSDs are loaded and displayed live.
2026-06-19 22:13:48 -05:00
Shaun Arman
03c4d5b2f1 refactor(proxmox): extract URL parsing helper and document edit limitation
Some checks failed
Test / frontend-tests (pull_request) Successful in 1m49s
Test / frontend-typecheck (pull_request) Successful in 1m59s
PR Review Automation / review (pull_request) Successful in 7m9s
Test / rust-tests (pull_request) Has been cancelled
Test / rust-clippy (pull_request) Has been cancelled
Test / rust-fmt-check (pull_request) Has been cancelled
Address automated PR review feedback:
- Extract parseRemoteUrl() helper to eliminate code duplication in handleAddRemote and handleEditRemote
- Add JSDoc documentation for the helper function
- Document known architectural limitation in edit operation (remove-then-add pattern)
- Fix pre-existing issue: install missing node_modules dependencies (sonner, monaco-editor)

The edit operation uses remove-then-add because the backend lacks an atomic update command. This is documented as a known limitation until updateProxmoxCluster() is implemented in the Rust backend.

Verification:
- All frontend tests pass (386/386)
- All Rust tests pass (413 passed, 6 ignored)
- ESLint, TypeScript, clippy, rustfmt all pass

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-13 23:49:15 -05:00
Shaun Arman
666de6ddfb fix(proxmox): parse port from URL when adding remote
When adding a remote with a URL like https://172.0.0.18:8006, the code
was previously passing the port as part of the hostname
(172.0.0.18:8006) while also setting the port separately, causing
connection failures.

Now properly extracts the port from the URL if present, falling back
to default ports (8006 for PVE, 8007 for PBS) if not specified.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
2026-06-13 23:27:08 -05:00
Shaun Arman
87ccbb6464 fix(proxmox): remove dummy data, fix add-remote, fix updater
All checks were successful
Test / frontend-tests (pull_request) Successful in 1m44s
Test / frontend-typecheck (pull_request) Successful in 1m57s
PR Review Automation / review (pull_request) Successful in 4m19s
Test / rust-fmt-check (pull_request) Successful in 12m57s
Test / rust-clippy (pull_request) Successful in 14m41s
Test / rust-tests (pull_request) Successful in 16m43s
- Replace hardcoded dummy data in VMs, Containers, Storage, Backup, and
  Firewall pages with live API calls; show empty-state UI when no
  clusters are configured
- Add list_proxmox_containers backend command (LXC via cluster/resources)
  and register it in the Tauri handler and frontend proxmoxClient.ts
- Fix add_proxmox_cluster to store credentials without requiring a live
  Proxmox connection; persist username in DB (migration 034); update
  list/get queries to read username column from new schema
- Replace alert() in RemotesPage with toast.error() + rethrow so errors
  surface correctly in Tauri WebView
- Replace tauri-plugin-updater with direct Gitea HTTP API call for
  update checks; use tauri-plugin-opener for browser launch; Updater UI
  now shows current/latest version and release notes
- Add gogs.tftsr.com to CSP connect-src
- Fix all 74 pre-existing ESLint no-explicit-any warnings in
  proxmoxClient.ts; remove stale eslint-disable directive in ACLPage.tsx
- All checks pass: cargo fmt, clippy -D warnings, 411 Rust tests,
  tsc --noEmit, eslint --max-warnings 0, 386 frontend tests
2026-06-13 17:33:23 -05:00
Shaun Arman
b2da13fbbe feat(proxmox): implement network management, tasks, custom views, and connection health (phases 14-15)
- Replace NetworkPage placeholder with live network interface list (type, address, gateway, active/autostart badges)
- Replace TasksPage placeholder with real cluster task log including running/completed/failed summary cards
- Create ViewsPage with create/delete UI for custom dashboard views
- Fix createClusterView TS client to pass viewId + name params matching Rust command signature
- Fix ClusterView TS interface to use view_id matching Rust DashboardView serialization
- Add ClusterInfoWithHealth struct to list_proxmox_clusters command with connected field reflecting in-memory pool state
- Add connected? field to ClusterInfo domain type
- Wire /proxmox/views route and Views nav entry in App.tsx
2026-06-12 21:58:31 -05:00
Shaun Arman
2d54858968 feat(proxmox): implement certificate manager and subscription registry (phases 10-11)
- CertificateList: full table with CN/SANs/Issuer/validity columns,
  expandable rows for full subject/fingerprint, color-coded status badges
  (green valid / yellow expiring <30d / red expired), View Details dialog,
  Renew action per row, empty state
- CertificatesPage: real data via listCertificates(), cluster selector for
  multi-cluster setups, Upload Custom Certificate dialog (file picker + PEM
  input), Order via ACME dialog with domain/node fields, error banner
- SubscriptionPage: two-panel layout — left panel for subscription key entry
  and activation with masked key display; right panel cluster status tree
  with Active/Expired/None badges, registration and next-due dates
- domain.ts: add Certificate interface (filename, subject, san, issuer,
  notbefore, notafter, fingerprint, pem)
- App.tsx: wire /proxmox/subscriptions route and nav entry
2026-06-12 21:57:38 -05:00
Shaun Arman
88bd5a8c95 feat(proxmox): implement HA groups manager and user management UI (phases 8-9)
- HAGroupsList: replace stub with real HaGroup type from proxmoxClient;
  columns: Name, Nodes, Restricted, No-Quorum Policy, Comment, Actions;
  empty state; onCreate/onEdit/onDelete props wired
- HAResourcesList: replace stub with real HaResource type; columns:
  Resource ID, Group, State, Max Restart, Max Relocate, Actions;
  onEnable/onRemove props; empty state
- HAPage: add useEffect data fetching for listHaGroups/listHaResources;
  auto-selects first cluster from listProxmoxClusters; multi-cluster
  dropdown when >1 cluster; wires deleteHaGroup and enableHaResource
- AclList: migrate from local AclInfo to canonical AclEntry type
  (ugid/roleid fields); composite key for rows without unique id
- UserList: migrate from local UserInfo to ProxmoxUser type; adds
  Realm, Name, Expire columns; deriveRealm helper; proper icon buttons
- RealmList: migrate from local RealmInfo to AuthRealm type (realm/type/
  comment); trimmed to three columns matching backend shape
- ACLPage: replace hardcoded dummy ACL array with real data fetching;
  add Tabs (ACL / Users / Auth Realms) with controlled state; calls
  listAcls, listUsers, listRealms on mount and cluster change; removes
  all hardcoded stub data
2026-06-12 21:55:35 -05:00
Shaun Arman
84ddf75afe feat(proxmox): implement notes system, resource search, and administration panel (phases 12-13)
- NotesPage: load/display/edit cluster notes with draft/save/cancel flow
- SearchPage: cross-cluster resource search grouped by type with icon decorators
- AdminPage: tabbed node admin (status, apt updates, repositories, syslog, tasks)
  with cluster/node selector; imports ClusterInfo from domain.ts
2026-06-12 21:55:01 -05:00
Shaun Arman
87e21e243e fix: persist Proxmox settings via localStorage; fix Remotes add/refresh flow
- ProxmoxSettings: load all six settings from localStorage on mount via
  useEffect, wire Save button to write values and show a 2s confirmation,
  wire Reset button to clear keys and restore defaults
- RemotesPage: attach loadRemotes() to the header Refresh button onClick
  and replace the no-op onRefresh prop passed to RemotesList
- EditRemoteForm: add password field to RemoteConfig interface and form
  so handleEditRemote receives a complete config; use DialogFooter for
  consistent button layout
2026-06-12 21:52:05 -05:00
Shaun Arman
655f8936c9 fix: implement v1.2.1 fixes
All checks were successful
Test / frontend-tests (pull_request) Successful in 1m45s
Test / frontend-typecheck (pull_request) Successful in 1m52s
PR Review Automation / review (pull_request) Successful in 3m0s
Test / rust-fmt-check (pull_request) Successful in 13m1s
Test / rust-clippy (pull_request) Successful in 14m52s
Test / rust-tests (pull_request) Successful in 16m50s
- Remove duplicate Updater page; integrate updater into ProxmoxSettings
- Fix ProxmoxRemotesPage imports to use proxmoxClient instead of tauriCommands
- Add rustls provider initialization for HTTPS tests
- Update tauri.conf.json and Cargo.toml for v1.2.1
- Bump version to 1.2.1

All tests pass:
- 386 frontend tests
- 406 Rust tests
- ESLint: 0 errors
- TypeScript: 0 errors
- Rust clippy: 0 warnings
2026-06-12 21:20:09 -05:00
Shaun Arman
1f2ea3f842 fix: Proxmox PDM v1.2.0 bugs and feature parity
Some checks failed
Test / frontend-typecheck (pull_request) Successful in 1m43s
Test / frontend-tests (pull_request) Successful in 2m5s
PR Review Automation / review (pull_request) Successful in 4m0s
Test / rust-fmt-check (pull_request) Has been cancelled
Test / rust-clippy (pull_request) Has been cancelled
Test / rust-tests (pull_request) Has been cancelled
- Add Proxmox cluster management commands to tauriCommands.ts
- Fix RemotesPage.tsx to use actual IPC calls instead of mock data
- Add Proxmox settings section to App.tsx settings navigation
- Create ProxmoxSettings page with update management (stable/pre-release)
- Add Proxmox submenu navigation to sidebar with expandable section
- Update docs/RELEASE_NOTES.md to include v1.2.0 Proxmox features

This fixes critical bugs preventing cluster persistence and navigation.
2026-06-11 15:55:04 -05:00
Shaun Arman
9a8231495c feat: implement 100% Proxmox PDM feature parity - UI components
Some checks failed
Test / frontend-typecheck (pull_request) Successful in 2m43s
Test / frontend-tests (pull_request) Successful in 1m51s
PR Review Automation / review (pull_request) Failing after 5m1s
Test / rust-clippy (pull_request) Has been cancelled
Test / rust-fmt-check (pull_request) Has been cancelled
Test / rust-tests (pull_request) Has been cancelled
- Add 8 new UI components: AclList, AddRemoteForm, ContainerConsole, ContainerOverview, EditRemoteForm, RemoveRemoteDialog, VMConsole, VMOverview
- Add 13 Proxmox management pages: ACLPage, BackupPage, CephPage, CertificatesPage, ContainersPage, FirewallPage, HAPage, NetworkPage, RemotesPage, SDNPage, StoragePage, TasksPage, VMsPage
- Add 13 new routes to App.tsx for Proxmox management pages
- All components use existing UI components from src/components/ui/index.tsx
- TypeScript and ESLint pass with 0 errors
- All tests pass

Files changed: 24 files, +2199 insertions
2026-06-11 13:47:09 -05:00