diff --git a/frontend-modern/src/components/Alerts/Thresholds/sections/ProxmoxNodesSection.tsx b/frontend-modern/src/components/Alerts/Thresholds/sections/ProxmoxNodesSection.tsx index d278b622c..bafc28dd0 100644 --- a/frontend-modern/src/components/Alerts/Thresholds/sections/ProxmoxNodesSection.tsx +++ b/frontend-modern/src/components/Alerts/Thresholds/sections/ProxmoxNodesSection.tsx @@ -119,12 +119,23 @@ const nodeToResource = ( * Build management URL for a node */ const buildNodeUrl = (node: Node): string | undefined => { + // Prioritize guestURL if available + const guestUrlValue = node.guestURL?.trim(); + if (guestUrlValue) { + return guestUrlValue.startsWith('http') + ? guestUrlValue + : `https://${guestUrlValue}`; + } + + // Fallback to host const hostValue = node.host?.trim(); if (hostValue) { return hostValue.startsWith('http') ? hostValue : `https://${hostValue.includes(':') ? hostValue : `${hostValue}:8006`}`; } + + // Final fallback to node name if (node.name) { return `https://${node.name.includes(':') ? node.name : `${node.name}:8006`}`; } diff --git a/frontend-modern/src/components/shared/NodeSummaryTable.tsx b/frontend-modern/src/components/shared/NodeSummaryTable.tsx index 4206bafd0..b290d525e 100644 --- a/frontend-modern/src/components/shared/NodeSummaryTable.tsx +++ b/frontend-modern/src/components/shared/NodeSummaryTable.tsx @@ -499,7 +499,7 @@ export const NodeSummaryTable: Component = (props) => { href={ isPVEItem ? node!.guestURL || node!.host || `https://${node!.name}:8006` - : pbs!.host || `https://${pbs!.name}:8007` + : pbs!.guestURL || pbs!.host || `https://${pbs!.name}:8007` } target="_blank" onClick={(e) => e.stopPropagation()} diff --git a/frontend-modern/src/types/api.ts b/frontend-modern/src/types/api.ts index e081b8831..ef4209a9a 100644 --- a/frontend-modern/src/types/api.ts +++ b/frontend-modern/src/types/api.ts @@ -635,6 +635,7 @@ export interface PBSInstance { id: string; name: string; host: string; + guestURL?: string; // Optional guest-accessible URL (for navigation) status: string; version: string; cpu: number; @@ -656,6 +657,7 @@ export interface PMGInstance { id: string; name: string; host: string; + guestURL?: string; // Optional guest-accessible URL (for navigation) status: string; version: string; nodes?: PMGNodeStatus[]; diff --git a/frontend-modern/src/types/nodes.ts b/frontend-modern/src/types/nodes.ts index cf53e3896..8fcca64dd 100644 --- a/frontend-modern/src/types/nodes.ts +++ b/frontend-modern/src/types/nodes.ts @@ -50,6 +50,7 @@ export interface PBSNodeConfig { id: string; name: string; host: string; + guestURL?: string; user: string; hasPassword?: boolean; hasToken?: boolean; @@ -70,6 +71,7 @@ export interface PMGNodeConfig { id: string; name: string; host: string; + guestURL?: string; user: string; hasPassword?: boolean; hasToken?: boolean; diff --git a/internal/api/config_handlers.go b/internal/api/config_handlers.go index 0150c45f5..b15b81522 100644 --- a/internal/api/config_handlers.go +++ b/internal/api/config_handlers.go @@ -847,6 +847,7 @@ func (h *ConfigHandlers) GetAllNodesForAPI() []NodeResponse { Type: "pbs", Name: pbs.Name, Host: pbs.Host, + GuestURL: pbs.GuestURL, User: pbs.User, HasPassword: pbs.Password != "", TokenName: pbs.TokenName, @@ -878,6 +879,7 @@ func (h *ConfigHandlers) GetAllNodesForAPI() []NodeResponse { Type: "pmg", Name: pmgInst.Name, Host: pmgInst.Host, + GuestURL: pmgInst.GuestURL, User: pmgInst.User, HasPassword: pmgInst.Password != "", TokenName: pmgInst.TokenName, @@ -1486,6 +1488,7 @@ func (h *ConfigHandlers) HandleAddNode(w http.ResponseWriter, r *http.Request) { pbs := config.PBSInstance{ Name: req.Name, Host: host, + GuestURL: req.GuestURL, User: pbsUser, Password: pbsPassword, TokenName: pbsTokenName, @@ -1556,6 +1559,7 @@ func (h *ConfigHandlers) HandleAddNode(w http.ResponseWriter, r *http.Request) { pmgInstance := config.PMGInstance{ Name: req.Name, Host: host, + GuestURL: req.GuestURL, User: pmgUser, Password: pmgPassword, TokenName: pmgTokenName, @@ -2030,6 +2034,9 @@ func (h *ConfigHandlers) HandleUpdateNode(w http.ResponseWriter, r *http.Request } pbs.Host = host + // Update GuestURL if provided + pbs.GuestURL = req.GuestURL + // Handle authentication updates - only switch auth method if explicitly provided if req.TokenName != "" && req.TokenValue != "" { // Switching to token authentication @@ -2110,6 +2117,9 @@ func (h *ConfigHandlers) HandleUpdateNode(w http.ResponseWriter, r *http.Request pmgInst.Host = host } + // Update GuestURL if provided + pmgInst.GuestURL = req.GuestURL + // Handle authentication updates - only switch auth method if explicitly provided if req.TokenName != "" && req.TokenValue != "" { // Switching to token authentication diff --git a/internal/config/config.go b/internal/config/config.go index 24dd1c594..a54da55f5 100644 --- a/internal/config/config.go +++ b/internal/config/config.go @@ -462,6 +462,7 @@ type ClusterEndpoint struct { type PBSInstance struct { Name string Host string + GuestURL string // Optional guest-accessible URL (for navigation) User string Password string TokenName string @@ -485,6 +486,7 @@ type PBSInstance struct { type PMGInstance struct { Name string Host string + GuestURL string // Optional guest-accessible URL (for navigation) User string Password string TokenName string diff --git a/internal/models/models.go b/internal/models/models.go index 0a0eeca1b..c076d6140 100644 --- a/internal/models/models.go +++ b/internal/models/models.go @@ -760,6 +760,7 @@ type PBSInstance struct { ID string `json:"id"` Name string `json:"name"` Host string `json:"host"` + GuestURL string `json:"guestURL,omitempty"` // Optional guest-accessible URL (for navigation) Status string `json:"status"` Version string `json:"version"` CPU float64 `json:"cpu"` // CPU usage percentage @@ -873,6 +874,7 @@ type PMGInstance struct { ID string `json:"id"` Name string `json:"name"` Host string `json:"host"` + GuestURL string `json:"guestURL,omitempty"` // Optional guest-accessible URL (for navigation) Status string `json:"status"` Version string `json:"version"` Nodes []PMGNodeStatus `json:"nodes,omitempty"` diff --git a/internal/monitoring/monitor.go b/internal/monitoring/monitor.go index d538e811d..edbff1288 100644 --- a/internal/monitoring/monitor.go +++ b/internal/monitoring/monitor.go @@ -7006,6 +7006,7 @@ func (m *Monitor) pollPBSInstance(ctx context.Context, instanceName string, clie ID: "pbs-" + instanceName, Name: instanceName, Host: instanceCfg.Host, + GuestURL: instanceCfg.GuestURL, Status: "offline", Version: "unknown", ConnectionHealth: "unhealthy", @@ -7336,6 +7337,7 @@ func (m *Monitor) pollPMGInstance(ctx context.Context, instanceName string, clie ID: "pmg-" + instanceName, Name: instanceName, Host: instanceCfg.Host, + GuestURL: instanceCfg.GuestURL, Status: "offline", ConnectionHealth: "unhealthy", LastSeen: now,