101 lines
3.8 KiB
TypeScript
101 lines
3.8 KiB
TypeScript
import type { Container } from "../types/appops.ts";
|
|
|
|
export type ContainerFocusFilter =
|
|
| "all"
|
|
| "attention"
|
|
| "running"
|
|
| "unhealthy"
|
|
| "unmapped"
|
|
| "unknown"
|
|
| "protected"
|
|
| "managed"
|
|
| "connector_available"
|
|
| "no_connector"
|
|
| "missing_metrics";
|
|
|
|
export interface ContainerFocusSummary {
|
|
total: number;
|
|
attention: number;
|
|
unhealthy: number;
|
|
unmapped: number;
|
|
unknown: number;
|
|
protected: number;
|
|
missingMetrics: number;
|
|
measuredMetrics: number;
|
|
noConnector: number;
|
|
}
|
|
|
|
const statusValue = (value: unknown): string => String(value || "").toLowerCase();
|
|
|
|
export const hasMissingContainerMetrics = (container: Container): boolean => (
|
|
container.state === "running"
|
|
&& statusValue(container.metricsStatus) !== "measured"
|
|
&& (!container.cpu
|
|
|| !container.ram
|
|
|| statusValue(container.cpu) === "n/a"
|
|
|| statusValue(container.ram) === "n/a")
|
|
);
|
|
|
|
export const hasMeasuredContainerMetrics = (container: Container): boolean => (
|
|
statusValue(container.metricsStatus) === "measured"
|
|
|| (
|
|
Boolean(container.cpu)
|
|
&& Boolean(container.ram)
|
|
&& statusValue(container.cpu) !== "n/a"
|
|
&& statusValue(container.ram) !== "n/a"
|
|
)
|
|
);
|
|
|
|
export const isUnmappedContainer = (container: Container): boolean => {
|
|
const importStatus = statusValue(container.importStatus);
|
|
return ["unmapped", "changed", "missing"].includes(importStatus);
|
|
};
|
|
|
|
export const containerNeedsOperatorAttention = (container: Container): boolean => (
|
|
container.health === "unhealthy"
|
|
|| container.health === "critical"
|
|
|| isUnmappedContainer(container)
|
|
);
|
|
|
|
export const buildContainerFocusSummary = (containers: Container[]): ContainerFocusSummary => {
|
|
const summary: ContainerFocusSummary = {
|
|
total: containers.length,
|
|
attention: 0,
|
|
unhealthy: 0,
|
|
unmapped: 0,
|
|
unknown: 0,
|
|
protected: 0,
|
|
missingMetrics: 0,
|
|
measuredMetrics: 0,
|
|
noConnector: 0,
|
|
};
|
|
|
|
for (const container of containers) {
|
|
if (containerNeedsOperatorAttention(container)) summary.attention += 1;
|
|
if (container.health === "unhealthy" || container.health === "critical") summary.unhealthy += 1;
|
|
if (isUnmappedContainer(container)) summary.unmapped += 1;
|
|
if (statusValue(container.appType) === "unknown") summary.unknown += 1;
|
|
if (container.protected) summary.protected += 1;
|
|
if (hasMissingContainerMetrics(container)) summary.missingMetrics += 1;
|
|
if (hasMeasuredContainerMetrics(container)) summary.measuredMetrics += 1;
|
|
if (!container.connectorType || statusValue(container.connectorType) === "none") summary.noConnector += 1;
|
|
}
|
|
|
|
return summary;
|
|
};
|
|
|
|
export const filterContainersByFocus = (containers: Container[], focus: ContainerFocusFilter): Container[] => {
|
|
if (focus === "all") return containers;
|
|
if (focus === "attention") return containers.filter(containerNeedsOperatorAttention);
|
|
if (focus === "running") return containers.filter(container => container.state === "running");
|
|
if (focus === "unhealthy") return containers.filter(container => container.health === "unhealthy" || container.health === "critical");
|
|
if (focus === "unmapped") return containers.filter(isUnmappedContainer);
|
|
if (focus === "unknown") return containers.filter(container => statusValue(container.appType) === "unknown");
|
|
if (focus === "protected") return containers.filter(container => container.protected === true);
|
|
if (focus === "managed") return containers.filter(container => container.isManaged === true || container.importStatus === "managed");
|
|
if (focus === "connector_available") return containers.filter(container => Boolean(container.connectorType) && statusValue(container.connectorType) !== "none");
|
|
if (focus === "no_connector") return containers.filter(container => !container.connectorType || statusValue(container.connectorType) === "none");
|
|
if (focus === "missing_metrics") return containers.filter(hasMissingContainerMetrics);
|
|
return containers;
|
|
};
|