/**
* DriverStatusCard — reusable component showing tns-csi driver health.
* Displays controller pods, node pods, CSIDriver capabilities, and
* WebSocket connection health from Prometheus metrics.
*/
import {
NameValueTable,
SectionBox,
StatusLabel,
} from '@kinvolk/headlamp-plugin/lib/CommonComponents';
import React from 'react';
import type { CSIDriver, TnsCsiPod } from '../api/k8s';
import { formatAge, getPodImage, getPodRestarts, isPodReady } from '../api/k8s';
import type { TnsCsiMetrics } from '../api/metrics';
// ---------------------------------------------------------------------------
// Sub-components
// ---------------------------------------------------------------------------
function WebSocketStatus({ metrics }: { metrics: TnsCsiMetrics | null }) {
if (!metrics) {
return Metrics unavailable;
}
const connected = metrics.websocketConnected;
if (connected === null) {
return Unknown;
}
return (
{connected === 1 ? 'Connected' : 'Disconnected'}
);
}
function PodStatusBadge({ pod }: { pod: TnsCsiPod }) {
const ready = isPodReady(pod);
const phase = pod.status?.phase ?? 'Unknown';
return (
{phase}
);
}
function PodRow({ pod }: { pod: TnsCsiPod }) {
const name = pod.metadata.name;
const node = pod.spec?.nodeName ?? '—';
const restarts = getPodRestarts(pod);
const image = getPodImage(pod);
const age = formatAge(pod.metadata.creationTimestamp);
return (
},
{ name: 'Restarts', value: String(restarts) },
{ name: 'Image', value: image },
{ name: 'Age', value: age },
]}
/>
);
}
// ---------------------------------------------------------------------------
// Main component
// ---------------------------------------------------------------------------
interface DriverStatusCardProps {
csiDriver: CSIDriver | null;
controllerPods: TnsCsiPod[];
nodePods: TnsCsiPod[];
metrics?: TnsCsiMetrics | null;
}
export default function DriverStatusCard({
csiDriver,
controllerPods,
nodePods,
metrics,
}: DriverStatusCardProps) {
const driverInstalled = csiDriver !== null;
const allPodsReady =
controllerPods.length > 0 &&
nodePods.length > 0 &&
[...controllerPods, ...nodePods].every(isPodReady);
return (
<>
{driverInstalled ? 'tns.csi.io installed' : 'Not detected'}
),
},
{
name: 'Overall Health',
value: (
{allPodsReady ? 'Healthy' : 'Degraded'}
),
},
{
name: 'WebSocket',
value: ,
},
...(metrics?.websocketReconnectsTotal !== null && metrics?.websocketReconnectsTotal !== undefined
? [{ name: 'WS Reconnects', value: String(metrics.websocketReconnectsTotal) }]
: []),
]}
/>
{csiDriver && (
)}
{controllerPods.length > 0 && (
1 ? 's' : ''}`}>
{controllerPods.map(pod => (
))}
)}
{controllerPods.length === 0 && (
No controller pod found }]}
/>
)}
{nodePods.length > 0 && (
1 ? 's' : ''} (${nodePods.length})`}>
{nodePods.map(pod => (
))}
)}
{nodePods.length === 0 && (
No node pods found }]}
/>
)}
>
);
}