mirror of
https://github.com/lensapp/lens.git
synced 2025-05-20 05:10:56 +00:00
Add back commented functionality to cluster pie charts clusteroverview UI block
Signed-off-by: Juho Heikka <juho.heikka@gmail.com>
This commit is contained in:
parent
6a870fa68a
commit
a59fd52948
@ -3,312 +3,302 @@
|
|||||||
* Licensed under MIT License. See LICENSE in root directory for more information.
|
* Licensed under MIT License. See LICENSE in root directory for more information.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// import styles from "./cluster-pie-charts.module.scss";
|
import styles from "./cluster-pie-charts.module.scss";
|
||||||
|
|
||||||
import React from "react";
|
import React from "react";
|
||||||
// import { observer } from "mobx-react";
|
import { observer } from "mobx-react";
|
||||||
// import type { ClusterOverviewStore } from "../cluster-overview-store/cluster-overview-store";
|
import { Spinner } from "../components/spinner";
|
||||||
// import { MetricNodeRole } from "../cluster-overview-store/cluster-overview-store";
|
import { Icon } from "../components/icon";
|
||||||
// import { Spinner } from "../../spinner";
|
import { PieChart, PieChartData } from "../components/chart";
|
||||||
// import { Icon } from "../../icon";
|
import { ClusterNoMetrics } from "../components/cluster-no-metrics";
|
||||||
// import type { NodeStore } from "../../+nodes/store";
|
import { bytesToUnits, cssNames } from "@k8slens/utilities";
|
||||||
// import type { PieChartData } from "../../chart";
|
import type { LensTheme } from "../components/chart/lens-theme";
|
||||||
// import { PieChart } from "../../chart";
|
import { withInjectables } from "@ogre-tools/injectable-react";
|
||||||
// import { ClusterNoMetrics } from "../cluster-no-metrics";
|
import type { IComputedValue } from "mobx";
|
||||||
// import { bytesToUnits, cssNames } from "@k8slens/utilities";
|
import { ClusterMetricData, getMetricLastPoints } from "../metrics.api";
|
||||||
// import type { LensTheme } from "../../../themes/lens-theme";
|
|
||||||
// import { getMetricLastPoints } from "../../../../common/k8s-api/endpoints/metrics.api";
|
|
||||||
// import { withInjectables } from "@ogre-tools/injectable-react";
|
|
||||||
// import clusterOverviewStoreInjectable from "../cluster-overview-store/cluster-overview-store.injectable";
|
|
||||||
// import nodeStoreInjectable from "../../+nodes/store.injectable";
|
|
||||||
// import type { IComputedValue } from "mobx";
|
|
||||||
// import activeThemeInjectable from "../../../themes/active.injectable";
|
|
||||||
// import type { ClusterMetricData } from "../../../../common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable";
|
|
||||||
import { getInjectable } from "@ogre-tools/injectable";
|
import { getInjectable } from "@ogre-tools/injectable";
|
||||||
import { clusterOverviewUIBlockInjectionToken } from "../injection-tokens";
|
import { activeThemeInjectionToken, ClusterOverviewStore, clusterOverviewStoreInjectionToken, clusterOverviewUIBlockInjectionToken, MetricNodeRole, NodeStore, nodeStoreInjectionToken } from "../injection-tokens";
|
||||||
|
|
||||||
// function createLabels(rawLabelData: [string, number | undefined][]): string[] {
|
function createLabels(rawLabelData: [string, number | undefined][]): string[] {
|
||||||
// return rawLabelData.map(
|
return rawLabelData.map(
|
||||||
// ([key, value]) => `${key}: ${value?.toFixed(2) || "N/A"}`
|
([key, value]) => `${key}: ${value?.toFixed(2) || "N/A"}`
|
||||||
// );
|
);
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// const checkedBytesToUnits = (value: number | undefined) =>
|
|
||||||
// typeof value === "number" ? bytesToUnits(value) : "N/A";
|
|
||||||
//
|
|
||||||
// interface Dependencies {
|
|
||||||
// clusterOverviewStore: ClusterOverviewStore;
|
|
||||||
// nodeStore: NodeStore;
|
|
||||||
// activeTheme: IComputedValue<LensTheme>;
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const NonInjectedClusterPieCharts = observer(
|
const checkedBytesToUnits = (value: number | undefined) =>
|
||||||
// ({ clusterOverviewStore, nodeStore, activeTheme }: Dependencies) => {
|
typeof value === "number" ? bytesToUnits(value) : "N/A";
|
||||||
// const renderLimitWarning = () => {
|
|
||||||
// return (
|
|
||||||
// <div className="node-warning flex gaps align-center">
|
|
||||||
// <Icon material="info" />
|
|
||||||
// <p>Specified limits are higher than node capacity!</p>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const renderCharts = (
|
|
||||||
// lastPoints: Partial<Record<keyof ClusterMetricData, number>>
|
|
||||||
// ) => {
|
|
||||||
// const {
|
|
||||||
// memoryUsage,
|
|
||||||
// memoryRequests,
|
|
||||||
// memoryAllocatableCapacity,
|
|
||||||
// memoryCapacity,
|
|
||||||
// memoryLimits,
|
|
||||||
// cpuUsage,
|
|
||||||
// cpuRequests,
|
|
||||||
// cpuAllocatableCapacity,
|
|
||||||
// cpuCapacity,
|
|
||||||
// cpuLimits,
|
|
||||||
// podUsage,
|
|
||||||
// podAllocatableCapacity,
|
|
||||||
// podCapacity,
|
|
||||||
// } = lastPoints;
|
|
||||||
//
|
|
||||||
// if (
|
|
||||||
// typeof cpuCapacity !== "number" ||
|
|
||||||
// typeof cpuAllocatableCapacity !== "number" ||
|
|
||||||
// typeof podCapacity !== "number" ||
|
|
||||||
// typeof podAllocatableCapacity !== "number" ||
|
|
||||||
// typeof memoryAllocatableCapacity !== "number" ||
|
|
||||||
// typeof memoryCapacity !== "number" ||
|
|
||||||
// typeof memoryUsage !== "number" ||
|
|
||||||
// typeof memoryRequests !== "number"
|
|
||||||
// ) {
|
|
||||||
// return null;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const defaultColor = activeTheme.get().colors.pieChartDefaultColor;
|
|
||||||
//
|
|
||||||
// const cpuData: PieChartData = {
|
|
||||||
// datasets: [
|
|
||||||
// {
|
|
||||||
// data: [cpuUsage, cpuUsage ? cpuAllocatableCapacity - cpuUsage : 1],
|
|
||||||
// backgroundColor: ["#c93dce", defaultColor],
|
|
||||||
// id: "cpuUsage",
|
|
||||||
// label: "Usage",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// data: [
|
|
||||||
// cpuRequests,
|
|
||||||
// cpuRequests ? cpuAllocatableCapacity - cpuRequests : 1,
|
|
||||||
// ],
|
|
||||||
// backgroundColor: ["#4caf50", defaultColor],
|
|
||||||
// id: "cpuRequests",
|
|
||||||
// label: "Requests",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// data: [
|
|
||||||
// cpuLimits,
|
|
||||||
// Math.max(
|
|
||||||
// 0,
|
|
||||||
// cpuAllocatableCapacity - (cpuLimits ?? cpuAllocatableCapacity)
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// backgroundColor: ["#3d90ce", defaultColor],
|
|
||||||
// id: "cpuLimits",
|
|
||||||
// label: "Limits",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// labels: createLabels([
|
|
||||||
// ["Usage", cpuUsage],
|
|
||||||
// ["Requests", cpuRequests],
|
|
||||||
// ["Limits", cpuLimits],
|
|
||||||
// ["Allocatable Capacity", cpuAllocatableCapacity],
|
|
||||||
// ["Capacity", cpuCapacity],
|
|
||||||
// ]),
|
|
||||||
// };
|
|
||||||
// const memoryData: PieChartData = {
|
|
||||||
// datasets: [
|
|
||||||
// {
|
|
||||||
// data: [
|
|
||||||
// memoryUsage,
|
|
||||||
// memoryUsage ? memoryAllocatableCapacity - memoryUsage : 1,
|
|
||||||
// ],
|
|
||||||
// backgroundColor: ["#c93dce", defaultColor],
|
|
||||||
// id: "memoryUsage",
|
|
||||||
// label: "Usage",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// data: [
|
|
||||||
// memoryRequests,
|
|
||||||
// memoryRequests ? memoryAllocatableCapacity - memoryRequests : 1,
|
|
||||||
// ],
|
|
||||||
// backgroundColor: ["#4caf50", defaultColor],
|
|
||||||
// id: "memoryRequests",
|
|
||||||
// label: "Requests",
|
|
||||||
// },
|
|
||||||
// {
|
|
||||||
// data: [
|
|
||||||
// memoryLimits,
|
|
||||||
// Math.max(
|
|
||||||
// 0,
|
|
||||||
// memoryAllocatableCapacity -
|
|
||||||
// (memoryLimits ?? memoryAllocatableCapacity)
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// backgroundColor: ["#3d90ce", defaultColor],
|
|
||||||
// id: "memoryLimits",
|
|
||||||
// label: "Limits",
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// labels: [
|
|
||||||
// `Usage: ${bytesToUnits(memoryUsage)}`,
|
|
||||||
// `Requests: ${bytesToUnits(memoryRequests)}`,
|
|
||||||
// `Limits: ${checkedBytesToUnits(memoryLimits)}`,
|
|
||||||
// `Allocatable Capacity: ${bytesToUnits(memoryAllocatableCapacity)}`,
|
|
||||||
// `Capacity: ${bytesToUnits(memoryCapacity)}`,
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
// const podsData: PieChartData = {
|
|
||||||
// datasets: [
|
|
||||||
// {
|
|
||||||
// data: [podUsage, podUsage ? podAllocatableCapacity - podUsage : 1],
|
|
||||||
// backgroundColor: ["#4caf50", defaultColor],
|
|
||||||
// id: "podUsage",
|
|
||||||
// label: "Usage",
|
|
||||||
// tooltipLabels: [
|
|
||||||
// (percent) => `Usage: ${percent}`,
|
|
||||||
// (percent) => `Available: ${percent}`,
|
|
||||||
// ],
|
|
||||||
// },
|
|
||||||
// ],
|
|
||||||
// labels: [
|
|
||||||
// `Usage: ${podUsage || 0}`,
|
|
||||||
// `Capacity: ${podAllocatableCapacity}`,
|
|
||||||
// ],
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// return (
|
|
||||||
// <div className="flex justify-center box grow gaps">
|
|
||||||
// <div
|
|
||||||
// className={cssNames(
|
|
||||||
// styles.chart,
|
|
||||||
// "flex column align-center box grow"
|
|
||||||
// )}
|
|
||||||
// >
|
|
||||||
// <PieChart
|
|
||||||
// data={cpuData}
|
|
||||||
// title="CPU"
|
|
||||||
// legendColors={[
|
|
||||||
// "#c93dce",
|
|
||||||
// "#4caf50",
|
|
||||||
// "#3d90ce",
|
|
||||||
// "#032b4d",
|
|
||||||
// defaultColor,
|
|
||||||
// ]}
|
|
||||||
// />
|
|
||||||
// {(cpuLimits ?? cpuAllocatableCapacity) > cpuAllocatableCapacity &&
|
|
||||||
// renderLimitWarning()}
|
|
||||||
// </div>
|
|
||||||
// <div
|
|
||||||
// className={cssNames(
|
|
||||||
// styles.chart,
|
|
||||||
// "flex column align-center box grow"
|
|
||||||
// )}
|
|
||||||
// >
|
|
||||||
// <PieChart
|
|
||||||
// data={memoryData}
|
|
||||||
// title="Memory"
|
|
||||||
// legendColors={[
|
|
||||||
// "#c93dce",
|
|
||||||
// "#4caf50",
|
|
||||||
// "#3d90ce",
|
|
||||||
// "#032b4d",
|
|
||||||
// defaultColor,
|
|
||||||
// ]}
|
|
||||||
// />
|
|
||||||
// {(memoryLimits ?? memoryAllocatableCapacity) >
|
|
||||||
// memoryAllocatableCapacity && renderLimitWarning()}
|
|
||||||
// </div>
|
|
||||||
// <div
|
|
||||||
// className={cssNames(
|
|
||||||
// styles.chart,
|
|
||||||
// "flex column align-center box grow"
|
|
||||||
// )}
|
|
||||||
// >
|
|
||||||
// <PieChart
|
|
||||||
// data={podsData}
|
|
||||||
// title="Pods"
|
|
||||||
// legendColors={["#4caf50", defaultColor]}
|
|
||||||
// />
|
|
||||||
// </div>
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// const renderContent = ({
|
|
||||||
// metricNodeRole,
|
|
||||||
// metrics,
|
|
||||||
// }: ClusterOverviewStore) => {
|
|
||||||
// const { masterNodes, workerNodes } = nodeStore;
|
|
||||||
// const nodes =
|
|
||||||
// metricNodeRole === MetricNodeRole.MASTER ? masterNodes : workerNodes;
|
|
||||||
//
|
|
||||||
// if (!nodes.length) {
|
|
||||||
// return (
|
|
||||||
// <div
|
|
||||||
// className={cssNames(
|
|
||||||
// styles.empty,
|
|
||||||
// "flex column box grow align-center justify-center"
|
|
||||||
// )}
|
|
||||||
// >
|
|
||||||
// <Icon material="info" />
|
|
||||||
// No Nodes Available.
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (!metrics) {
|
|
||||||
// return (
|
|
||||||
// <div
|
|
||||||
// className={cssNames(
|
|
||||||
// styles.empty,
|
|
||||||
// "flex justify-center align-center box grow"
|
|
||||||
// )}
|
|
||||||
// >
|
|
||||||
// <Spinner />
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// const lastPoints = getMetricLastPoints(metrics);
|
|
||||||
// const { memoryCapacity, cpuCapacity, podCapacity } = lastPoints;
|
|
||||||
//
|
|
||||||
// if (!memoryCapacity || !cpuCapacity || !podCapacity) {
|
|
||||||
// return (
|
|
||||||
// <div className={styles.noMetrics}>
|
|
||||||
// <ClusterNoMetrics className={styles.empty} />
|
|
||||||
// </div>
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return renderCharts(lastPoints);
|
|
||||||
// };
|
|
||||||
//
|
|
||||||
// return <div className="flex">{renderContent(clusterOverviewStore)}</div>;
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
// const ClusterPieCharts = withInjectables<Dependencies>(
|
interface Dependencies {
|
||||||
// NonInjectedClusterPieCharts,
|
clusterOverviewStore: ClusterOverviewStore;
|
||||||
// {
|
nodeStore: NodeStore;
|
||||||
// getProps: (di) => ({
|
activeTheme: IComputedValue<LensTheme>;
|
||||||
// clusterOverviewStore: di.inject(clusterOverviewStoreInjectable),
|
}
|
||||||
// nodeStore: di.inject(nodeStoreInjectable),
|
|
||||||
// activeTheme: di.inject(activeThemeInjectable),
|
|
||||||
// }),
|
|
||||||
// }
|
|
||||||
// );
|
|
||||||
|
|
||||||
const ClusterPieCharts = () => <div>cluster-pie-charts.injectable</div>;
|
const NonInjectedClusterPieCharts = observer(
|
||||||
|
({ clusterOverviewStore, nodeStore, activeTheme }: Dependencies) => {
|
||||||
|
const renderLimitWarning = () => {
|
||||||
|
return (
|
||||||
|
<div className="node-warning flex gaps align-center">
|
||||||
|
<Icon material="info" />
|
||||||
|
<p>Specified limits are higher than node capacity!</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderCharts = (
|
||||||
|
lastPoints: Partial<Record<keyof ClusterMetricData, number>>
|
||||||
|
) => {
|
||||||
|
const {
|
||||||
|
memoryUsage,
|
||||||
|
memoryRequests,
|
||||||
|
memoryAllocatableCapacity,
|
||||||
|
memoryCapacity,
|
||||||
|
memoryLimits,
|
||||||
|
cpuUsage,
|
||||||
|
cpuRequests,
|
||||||
|
cpuAllocatableCapacity,
|
||||||
|
cpuCapacity,
|
||||||
|
cpuLimits,
|
||||||
|
podUsage,
|
||||||
|
podAllocatableCapacity,
|
||||||
|
podCapacity,
|
||||||
|
} = lastPoints;
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof cpuCapacity !== "number" ||
|
||||||
|
typeof cpuAllocatableCapacity !== "number" ||
|
||||||
|
typeof podCapacity !== "number" ||
|
||||||
|
typeof podAllocatableCapacity !== "number" ||
|
||||||
|
typeof memoryAllocatableCapacity !== "number" ||
|
||||||
|
typeof memoryCapacity !== "number" ||
|
||||||
|
typeof memoryUsage !== "number" ||
|
||||||
|
typeof memoryRequests !== "number"
|
||||||
|
) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const defaultColor = activeTheme.get().colors.pieChartDefaultColor;
|
||||||
|
|
||||||
|
const cpuData: PieChartData = {
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [cpuUsage, cpuUsage ? cpuAllocatableCapacity - cpuUsage : 1],
|
||||||
|
backgroundColor: ["#c93dce", defaultColor],
|
||||||
|
id: "cpuUsage",
|
||||||
|
label: "Usage",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
cpuRequests,
|
||||||
|
cpuRequests ? cpuAllocatableCapacity - cpuRequests : 1,
|
||||||
|
],
|
||||||
|
backgroundColor: ["#4caf50", defaultColor],
|
||||||
|
id: "cpuRequests",
|
||||||
|
label: "Requests",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
cpuLimits,
|
||||||
|
Math.max(
|
||||||
|
0,
|
||||||
|
cpuAllocatableCapacity - (cpuLimits ?? cpuAllocatableCapacity)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
backgroundColor: ["#3d90ce", defaultColor],
|
||||||
|
id: "cpuLimits",
|
||||||
|
label: "Limits",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
labels: createLabels([
|
||||||
|
["Usage", cpuUsage],
|
||||||
|
["Requests", cpuRequests],
|
||||||
|
["Limits", cpuLimits],
|
||||||
|
["Allocatable Capacity", cpuAllocatableCapacity],
|
||||||
|
["Capacity", cpuCapacity],
|
||||||
|
]),
|
||||||
|
};
|
||||||
|
const memoryData: PieChartData = {
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
memoryUsage,
|
||||||
|
memoryUsage ? memoryAllocatableCapacity - memoryUsage : 1,
|
||||||
|
],
|
||||||
|
backgroundColor: ["#c93dce", defaultColor],
|
||||||
|
id: "memoryUsage",
|
||||||
|
label: "Usage",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
memoryRequests,
|
||||||
|
memoryRequests ? memoryAllocatableCapacity - memoryRequests : 1,
|
||||||
|
],
|
||||||
|
backgroundColor: ["#4caf50", defaultColor],
|
||||||
|
id: "memoryRequests",
|
||||||
|
label: "Requests",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
data: [
|
||||||
|
memoryLimits,
|
||||||
|
Math.max(
|
||||||
|
0,
|
||||||
|
memoryAllocatableCapacity -
|
||||||
|
(memoryLimits ?? memoryAllocatableCapacity)
|
||||||
|
),
|
||||||
|
],
|
||||||
|
backgroundColor: ["#3d90ce", defaultColor],
|
||||||
|
id: "memoryLimits",
|
||||||
|
label: "Limits",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
labels: [
|
||||||
|
`Usage: ${bytesToUnits(memoryUsage)}`,
|
||||||
|
`Requests: ${bytesToUnits(memoryRequests)}`,
|
||||||
|
`Limits: ${checkedBytesToUnits(memoryLimits)}`,
|
||||||
|
`Allocatable Capacity: ${bytesToUnits(memoryAllocatableCapacity)}`,
|
||||||
|
`Capacity: ${bytesToUnits(memoryCapacity)}`,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
const podsData: PieChartData = {
|
||||||
|
datasets: [
|
||||||
|
{
|
||||||
|
data: [podUsage, podUsage ? podAllocatableCapacity - podUsage : 1],
|
||||||
|
backgroundColor: ["#4caf50", defaultColor],
|
||||||
|
id: "podUsage",
|
||||||
|
label: "Usage",
|
||||||
|
tooltipLabels: [
|
||||||
|
(percent) => `Usage: ${percent}`,
|
||||||
|
(percent) => `Available: ${percent}`,
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
labels: [
|
||||||
|
`Usage: ${podUsage || 0}`,
|
||||||
|
`Capacity: ${podAllocatableCapacity}`,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="flex justify-center box grow gaps">
|
||||||
|
<div
|
||||||
|
className={cssNames(
|
||||||
|
styles.chart,
|
||||||
|
"flex column align-center box grow"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<PieChart
|
||||||
|
data={cpuData}
|
||||||
|
title="CPU"
|
||||||
|
legendColors={[
|
||||||
|
"#c93dce",
|
||||||
|
"#4caf50",
|
||||||
|
"#3d90ce",
|
||||||
|
"#032b4d",
|
||||||
|
defaultColor,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
{(cpuLimits ?? cpuAllocatableCapacity) > cpuAllocatableCapacity &&
|
||||||
|
renderLimitWarning()}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cssNames(
|
||||||
|
styles.chart,
|
||||||
|
"flex column align-center box grow"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<PieChart
|
||||||
|
data={memoryData}
|
||||||
|
title="Memory"
|
||||||
|
legendColors={[
|
||||||
|
"#c93dce",
|
||||||
|
"#4caf50",
|
||||||
|
"#3d90ce",
|
||||||
|
"#032b4d",
|
||||||
|
defaultColor,
|
||||||
|
]}
|
||||||
|
/>
|
||||||
|
{(memoryLimits ?? memoryAllocatableCapacity) >
|
||||||
|
memoryAllocatableCapacity && renderLimitWarning()}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
className={cssNames(
|
||||||
|
styles.chart,
|
||||||
|
"flex column align-center box grow"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<PieChart
|
||||||
|
data={podsData}
|
||||||
|
title="Pods"
|
||||||
|
legendColors={["#4caf50", defaultColor]}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
const renderContent = ({
|
||||||
|
metricNodeRole,
|
||||||
|
metrics,
|
||||||
|
}: ClusterOverviewStore) => {
|
||||||
|
const { masterNodes, workerNodes } = nodeStore;
|
||||||
|
const nodes =
|
||||||
|
metricNodeRole === MetricNodeRole.MASTER ? masterNodes : workerNodes;
|
||||||
|
|
||||||
|
if (!nodes.length) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cssNames(
|
||||||
|
styles.empty,
|
||||||
|
"flex column box grow align-center justify-center"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Icon material="info" />
|
||||||
|
No Nodes Available.
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!metrics) {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className={cssNames(
|
||||||
|
styles.empty,
|
||||||
|
"flex justify-center align-center box grow"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<Spinner />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const lastPoints = getMetricLastPoints(metrics);
|
||||||
|
const { memoryCapacity, cpuCapacity, podCapacity } = lastPoints;
|
||||||
|
|
||||||
|
if (!memoryCapacity || !cpuCapacity || !podCapacity) {
|
||||||
|
return (
|
||||||
|
<div className={styles.noMetrics}>
|
||||||
|
<ClusterNoMetrics className={styles.empty} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return renderCharts(lastPoints);
|
||||||
|
};
|
||||||
|
|
||||||
|
return <div className="flex">{renderContent(clusterOverviewStore)}</div>;
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const ClusterPieCharts = withInjectables<Dependencies>(
|
||||||
|
NonInjectedClusterPieCharts,
|
||||||
|
{
|
||||||
|
getProps: (di) => ({
|
||||||
|
clusterOverviewStore: di.inject(clusterOverviewStoreInjectionToken),
|
||||||
|
nodeStore: di.inject(nodeStoreInjectionToken),
|
||||||
|
activeTheme: di.inject(activeThemeInjectionToken),
|
||||||
|
}),
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
const clusterPieChartsClusterOverviewInjectable = getInjectable({
|
const clusterPieChartsClusterOverviewInjectable = getInjectable({
|
||||||
id: "cluster-pie-charts-cluster-overview",
|
id: "cluster-pie-charts-cluster-overview",
|
||||||
|
|||||||
@ -68,4 +68,3 @@ export enum MetricNodeRole {
|
|||||||
MASTER = "master",
|
MASTER = "master",
|
||||||
WORKER = "worker",
|
WORKER = "worker",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,27 @@
|
|||||||
import moment from "moment";
|
import moment from "moment";
|
||||||
import { isDefined, object } from "@k8slens/utilities";
|
import { isDefined, object } from "@k8slens/utilities";
|
||||||
|
|
||||||
|
// hack, copied from:
|
||||||
|
// packages/core/src/common/k8s-api/endpoints/metrics.api/request-cluster-metrics-by-node-names.injectable.ts
|
||||||
|
|
||||||
|
export interface ClusterMetricData {
|
||||||
|
memoryUsage: MetricData;
|
||||||
|
memoryRequests: MetricData;
|
||||||
|
memoryLimits: MetricData;
|
||||||
|
memoryCapacity: MetricData;
|
||||||
|
memoryAllocatableCapacity: MetricData;
|
||||||
|
cpuUsage: MetricData;
|
||||||
|
cpuRequests: MetricData;
|
||||||
|
cpuLimits: MetricData;
|
||||||
|
cpuCapacity: MetricData;
|
||||||
|
cpuAllocatableCapacity: MetricData;
|
||||||
|
podUsage: MetricData;
|
||||||
|
podCapacity: MetricData;
|
||||||
|
podAllocatableCapacity: MetricData;
|
||||||
|
fsSize: MetricData;
|
||||||
|
fsUsage: MetricData;
|
||||||
|
}
|
||||||
|
|
||||||
export interface MetricData {
|
export interface MetricData {
|
||||||
status: string;
|
status: string;
|
||||||
data: {
|
data: {
|
||||||
@ -34,10 +55,12 @@ export function normalizeMetrics(metrics: MetricData | undefined | null, frames
|
|||||||
return {
|
return {
|
||||||
data: {
|
data: {
|
||||||
resultType: "",
|
resultType: "",
|
||||||
result: [{
|
result: [
|
||||||
metric: {},
|
{
|
||||||
values: [],
|
metric: {},
|
||||||
}],
|
values: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
},
|
},
|
||||||
status: "",
|
status: "",
|
||||||
};
|
};
|
||||||
@ -48,8 +71,10 @@ export function normalizeMetrics(metrics: MetricData | undefined | null, frames
|
|||||||
if (result.length) {
|
if (result.length) {
|
||||||
if (frames > 0) {
|
if (frames > 0) {
|
||||||
// fill the gaps
|
// fill the gaps
|
||||||
result.forEach(res => {
|
result.forEach((res) => {
|
||||||
if (!res.values || !res.values.length) return;
|
if (!res.values || !res.values.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
let now = moment().startOf("minute").subtract(1, "minute").unix();
|
let now = moment().startOf("minute").subtract(1, "minute").unix();
|
||||||
let timestamp = res.values[0][0];
|
let timestamp = res.values[0][0];
|
||||||
@ -72,8 +97,7 @@ export function normalizeMetrics(metrics: MetricData | undefined | null, frames
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// always return at least empty values array
|
// always return at least empty values array
|
||||||
result.push({
|
result.push({
|
||||||
metric: {},
|
metric: {},
|
||||||
@ -85,10 +109,13 @@ export function normalizeMetrics(metrics: MetricData | undefined | null, frames
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function isMetricsEmpty(metrics: Partial<Record<string, MetricData>>) {
|
export function isMetricsEmpty(metrics: Partial<Record<string, MetricData>>) {
|
||||||
return Object.values(metrics).every(metric => !metric?.data?.result?.length);
|
return Object.values(metrics).every((metric) => !metric?.data?.result?.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getItemMetrics<Keys extends string>(metrics: Partial<Record<Keys, MetricData>> | null | undefined, itemName: string): Partial<Record<Keys, MetricData>> | undefined {
|
export function getItemMetrics<Keys extends string>(
|
||||||
|
metrics: Partial<Record<Keys, MetricData>> | null | undefined,
|
||||||
|
itemName: string,
|
||||||
|
): Partial<Record<Keys, MetricData>> | undefined {
|
||||||
if (!metrics) {
|
if (!metrics) {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
@ -100,7 +127,7 @@ export function getItemMetrics<Keys extends string>(metrics: Partial<Record<Keys
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
const results = metrics[metric]?.data.result;
|
const results = metrics[metric]?.data.result;
|
||||||
const result = results?.find(res => Object.values(res.metric)[0] == itemName);
|
const result = results?.find((res) => Object.values(res.metric)[0] == itemName);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||||
itemMetrics[metric]!.data.result = result ? [result] : [];
|
itemMetrics[metric]!.data.result = result ? [result] : [];
|
||||||
@ -109,9 +136,12 @@ export function getItemMetrics<Keys extends string>(metrics: Partial<Record<Keys
|
|||||||
return itemMetrics;
|
return itemMetrics;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getMetricLastPoints<Keys extends string>(metrics: Partial<Record<Keys, MetricData>>): Partial<Record<Keys, number>> {
|
export function getMetricLastPoints<Keys extends string>(
|
||||||
|
metrics: Partial<Record<Keys, MetricData>>,
|
||||||
|
): Partial<Record<Keys, number>> {
|
||||||
return object.fromEntries(
|
return object.fromEntries(
|
||||||
object.entries(metrics)
|
object
|
||||||
|
.entries(metrics)
|
||||||
.map(([metricName, metric]) => {
|
.map(([metricName, metric]) => {
|
||||||
try {
|
try {
|
||||||
return [metricName, +metric.data.result[0].values.slice(-1)[0][1]] as const;
|
return [metricName, +metric.data.result[0].values.slice(-1)[0][1]] as const;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user