mirror of
https://github.com/rcourtman/Pulse.git
synced 2026-05-19 07:54:10 +00:00
Hide cluster deploy banner for offline PVE nodes
The "N nodes unmonitored" banner gated purely on absence of a Pulse Unified Agent (r.agent?.agentId). Offline cluster members (status 'offline') were counted as deploy candidates, which is wrong on two fronts: those nodes are typically still covered by the cluster's PVE API token (so they aren't truly unmonitored, just unreachable), and an offline host is precisely the case where deploying an agent cannot succeed. Exclude status === 'offline' from the unmonitored count.
This commit is contained in:
parent
9329258f8b
commit
07d73843f0
2 changed files with 35 additions and 5 deletions
|
|
@ -17,7 +17,11 @@ export const ClusterDeployBanner: Component<ClusterDeployBannerProps> = (props)
|
|||
// 1. Non-empty cluster name (not Standalone)
|
||||
// 2. At least one resource has platformType === 'proxmox-pve'
|
||||
// 3. At least one resource has agent?.agentId (source agent exists)
|
||||
// 4. At least one PVE node does NOT have an agent (unmonitored)
|
||||
// 4. At least one *reachable* PVE node does NOT have an agent
|
||||
//
|
||||
// Offline nodes are excluded: we can't deploy a Pulse Unified Agent to
|
||||
// a node we can't reach, and a node going temporarily offline is not
|
||||
// the same situation as a never-onboarded cluster peer.
|
||||
const deployInfo = createMemo(() => {
|
||||
const resources = props.group.resources;
|
||||
const cluster = props.group.cluster;
|
||||
|
|
@ -33,7 +37,9 @@ export const ClusterDeployBanner: Component<ClusterDeployBannerProps> = (props)
|
|||
const hasSourceAgent = pveNodes.some((r) => r.agent?.agentId);
|
||||
if (!hasSourceAgent) return null;
|
||||
|
||||
const unmonitoredCount = pveNodes.filter((r) => !r.agent?.agentId).length;
|
||||
const unmonitoredCount = pveNodes.filter(
|
||||
(r) => !r.agent?.agentId && r.status !== 'offline',
|
||||
).length;
|
||||
if (unmonitoredCount === 0) return null;
|
||||
|
||||
return { cluster, unmonitoredCount };
|
||||
|
|
|
|||
|
|
@ -17,8 +17,12 @@ import type { Resource } from '@/types/resource';
|
|||
|
||||
/* ── helpers ──────────────────────────────────────────────────── */
|
||||
|
||||
/** Minimal PVE node resource with optional agent */
|
||||
function makePveNode(id: string, agentId?: string): Resource {
|
||||
/** Minimal PVE node resource with optional agent and overridable status */
|
||||
function makePveNode(
|
||||
id: string,
|
||||
agentId?: string,
|
||||
status: Resource['status'] = 'online',
|
||||
): Resource {
|
||||
return {
|
||||
id,
|
||||
type: 'agent',
|
||||
|
|
@ -27,7 +31,7 @@ function makePveNode(id: string, agentId?: string): Resource {
|
|||
platformId: 'pve1',
|
||||
platformType: 'proxmox-pve',
|
||||
sourceType: 'api',
|
||||
status: 'online',
|
||||
status,
|
||||
agent: agentId ? { agentId } : undefined,
|
||||
} as Resource;
|
||||
}
|
||||
|
|
@ -116,6 +120,26 @@ describe('ClusterDeployBanner', () => {
|
|||
expect(screen.getByText('1 node unmonitored')).toBeInTheDocument();
|
||||
expect(screen.getByText('Review & Deploy')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('does not count offline no-agent nodes (cannot deploy to an unreachable host)', () => {
|
||||
const group = makeGroup('my-cluster', [
|
||||
makePveNode('node1', 'agent-1'), // source agent
|
||||
makePveNode('offline-node', undefined, 'offline'), // offline, no agent
|
||||
]);
|
||||
render(() => <ClusterDeployBanner group={group} onDeploy={vi.fn()} />);
|
||||
expect(screen.queryByText(/unmonitored/)).not.toBeInTheDocument();
|
||||
expect(screen.queryByText('Review & Deploy')).not.toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('still counts online no-agent nodes when other no-agent nodes are offline', () => {
|
||||
const group = makeGroup('my-cluster', [
|
||||
makePveNode('node1', 'agent-1'),
|
||||
makePveNode('online-no-agent'),
|
||||
makePveNode('offline-no-agent', undefined, 'offline'),
|
||||
]);
|
||||
render(() => <ClusterDeployBanner group={group} onDeploy={vi.fn()} />);
|
||||
expect(screen.getByText('1 node unmonitored')).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
|
||||
describe('unmonitored count display', () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue