diff --git a/src/common/k8s-api/endpoints/nodes.api.ts b/src/common/k8s-api/endpoints/nodes.api.ts index f46eaa8811..7b999b8938 100644 --- a/src/common/k8s-api/endpoints/nodes.api.ts +++ b/src/common/k8s-api/endpoints/nodes.api.ts @@ -95,17 +95,17 @@ export interface Node { status: { capacity?: { cpu: string; - ["ephemeral-storage"]: string; - ["hugepages-1Gi"]: string; - ["hugepages-2Mi"]: string; + "ephemeral-storage": string; + "hugepages-1Gi": string; + "hugepages-2Mi": string; memory: string; pods: string; }; allocatable?: { cpu: string; - ["ephemeral-storage"]: string; - ["hugepages-1Gi"]: string; - ["hugepages-2Mi"]: string; + "ephemeral-storage": string; + "hugepages-1Gi": string; + "hugepages-2Mi": string; memory: string; pods: string; }; diff --git a/src/renderer/components/+nodes/nodes.tsx b/src/renderer/components/+nodes/nodes.tsx index a2b5849611..03741e01c2 100644 --- a/src/renderer/components/+nodes/nodes.tsx +++ b/src/renderer/components/+nodes/nodes.tsx @@ -56,6 +56,15 @@ enum columnId { interface Props extends RouteComponentProps { } +type MetricsTooltipFormatter = (metrics: [number, number]) => string; + +interface UsageArgs { + node: Node; + title: string; + metricNames: [string, string]; + formatters: MetricsTooltipFormatter[]; +} + @observer export class Nodes extends React.Component { @observable.ref metrics: Partial = {}; @@ -78,18 +87,17 @@ export class Nodes extends React.Component { if (isEmpty(this.metrics)) { return []; } + const nodeName = node.getName(); return metricNames.map(metricName => { try { const metric = this.metrics[metricName]; - const result = metric.data.result.find(result => { - return [ - result.metric.node, - result.metric.instance, - result.metric.kubernetes_node, - ].includes(nodeName); - }); + const result = metric.data.result.find(({ metric: { node, instance, kubernetes_node }}) => ( + nodeName === node + || nodeName === instance + || nodeName === kubernetes_node + )); return result ? parseFloat(result.values.slice(-1)[0][1]) : 0; } catch (e) { @@ -98,74 +106,69 @@ export class Nodes extends React.Component { }); } - renderCpuUsage(node: Node) { - const metrics = this.getLastMetricValues(node, ["cpuUsage", "cpuCapacity"]); + private renderUsage({ node, title, metricNames, formatters }: UsageArgs) { + const metrics = this.getLastMetricValues(node, metricNames); - if (!metrics || !metrics[1]) return ; - const usage = metrics[0]; - const cores = metrics[1]; - const cpuUsagePercent = Math.ceil(usage * 100) / cores; - const cpuUsagePercentLabel: String = cpuUsagePercent % 1 === 0 - ? cpuUsagePercent.toString() - : cpuUsagePercent.toFixed(2); + if (!metrics || metrics.length < 2) { + return ; + } + + const [usage, capacity] = metrics; return ( formatter([usage, capacity])).join(", ")}`, }} /> ); } + renderCpuUsage(node: Node) { + return this.renderUsage({ + node, + title: "CPU", + metricNames: ["cpuUsage", "cpuCapacity"], + formatters: [ + ([usage, capacity]) => `${(usage * 100 / capacity).toFixed(2)}%`, + ([, cap]) => `cores: ${cap}`, + ], + }); + } + renderMemoryUsage(node: Node) { - const metrics = this.getLastMetricValues(node, ["workloadMemoryUsage", "memoryAllocatableCapacity"]); - - if (!metrics || !metrics[1]) return ; - const usage = metrics[0]; - const capacity = metrics[1]; - - return ( - - ); + return this.renderUsage({ + node, + title: "Memory", + metricNames: ["workloadMemoryUsage", "memoryAllocatableCapacity"], + formatters: [ + ([usage, capacity]) => `${(usage * 100 / capacity).toFixed(2)}%`, + ([usage]) => bytesToUnits(usage, 3), + ], + }); } - renderDiskUsage(node: Node): any { - const metrics = this.getLastMetricValues(node, ["fsUsage", "fsSize"]); - - if (!metrics || !metrics[1]) return ; - const usage = metrics[0]; - const capacity = metrics[1]; - - return ( - - ); + renderDiskUsage(node: Node) { + return this.renderUsage({ + node, + title: "Disk", + metricNames: ["fsUsage", "fsSize"], + formatters: [ + ([usage, capacity]) => `${(usage * 100 / capacity).toFixed(2)}%`, + ([usage]) => bytesToUnits(usage, 3), + ], + }); } renderConditions(node: Node) { if (!node.status.conditions) { return null; } - const conditions = node.getActiveConditions(); - return conditions.map(condition => { + return node.getActiveConditions().map(condition => { const { type } = condition; const tooltipId = `node-${node.getName()}-condition-${type}`; @@ -180,7 +183,8 @@ export class Nodes extends React.Component { , )} - ); + + ); }); }