diff --git a/karpenter/src/NodePool/Details.tsx b/karpenter/src/NodePool/Details.tsx index 70ab892961..acce461627 100644 --- a/karpenter/src/NodePool/Details.tsx +++ b/karpenter/src/NodePool/Details.tsx @@ -16,6 +16,7 @@ import { DiffEditorDialog } from '../common/resourceEditor'; import { handleShowDiff } from '../helpers/handleDiff'; import { getHandleSaveHelper } from '../helpers/handleSave'; import { renderInstanceRequirements } from '../helpers/instanceRequirements'; +import { parseCpu } from '../helpers/parseCpu'; import { parseRam } from '../helpers/parseRam'; import { renderDisruptionBudgets } from '../helpers/renderBudgets'; import { nodePoolClass } from './List'; @@ -91,8 +92,8 @@ export function NodePoolDetailView(props: { name?: string }) { withEvents actions={actions()} extraInfo={item => { - const usedCPU = parseInt(item.jsonData.status?.resources?.cpu || '0'); - const CPUlimit = parseInt(item.jsonData.spec?.limits?.cpu || '0'); + const usedCPU = parseCpu(item.jsonData.status?.resources?.cpu || '0'); + const CPUlimit = parseCpu(item.jsonData.spec?.limits?.cpu || '0'); const usedMemory = parseRam(item.jsonData.status?.resources?.memory || '0'); const memoryLimit = parseRam(item.jsonData.spec?.limits?.memory || '0'); diff --git a/karpenter/src/NodePool/List.tsx b/karpenter/src/NodePool/List.tsx index 0b6640db56..102d321fae 100644 --- a/karpenter/src/NodePool/List.tsx +++ b/karpenter/src/NodePool/List.tsx @@ -3,6 +3,7 @@ import { Link, ResourceListView } from '@kinvolk/headlamp-plugin/lib/CommonCompo import { PercentageBar } from '@kinvolk/headlamp-plugin/lib/CommonComponents'; import { makeCustomResourceClass } from '@kinvolk/headlamp-plugin/lib/lib/k8s/crd'; import { getResourceStr } from '@kinvolk/headlamp-plugin/lib/Utils'; +import { parseCpu } from '../helpers/parseCpu'; import { parseRam } from '../helpers/parseRam'; import { CPUtooltip, Memorytooltip } from '../helpers/tooltip'; @@ -73,14 +74,14 @@ function NodePoolsList() { id: 'nodepool-cpu', label: t('CPU'), getValue: nodePool => { - const used = parseInt(nodePool.jsonData.status?.resources?.cpu || '0'); - const limit = parseInt(nodePool.jsonData.spec?.limits?.cpu || '0'); + const used = parseCpu(nodePool.jsonData.status?.resources?.cpu || '0'); + const limit = parseCpu(nodePool.jsonData.spec?.limits?.cpu || '0'); return limit > 0 ? `${used}/${limit}` : t('{{used}} (No limit)', { used }); }, render: nodePool => { - const used = parseInt(nodePool.jsonData.status?.resources?.cpu || 0); - const limit = parseInt(nodePool.jsonData.spec?.limits?.cpu || 0); + const used = parseCpu(nodePool.jsonData.status?.resources?.cpu || '0'); + const limit = parseCpu(nodePool.jsonData.spec?.limits?.cpu || '0'); const data: ChartDataPoint[] = [ { name: 'CPU', diff --git a/karpenter/src/helpers/parseCpu.test.ts b/karpenter/src/helpers/parseCpu.test.ts new file mode 100644 index 0000000000..76a164eca8 --- /dev/null +++ b/karpenter/src/helpers/parseCpu.test.ts @@ -0,0 +1,23 @@ +import { parseCpu } from './parseCpu'; + +describe('parseCpu', () => { + it('returns 0 for missing or unparseable values', () => { + expect(parseCpu('')).toBe(0); + expect(parseCpu('abc')).toBe(0); + }); + + it('converts milli-cores to cores', () => { + expect(parseCpu('1750m')).toBe(1.75); + expect(parseCpu('500m')).toBe(0.5); + }); + + it('converts micro-cores and nano-cores to cores', () => { + expect(parseCpu('500000u')).toBe(0.5); + expect(parseCpu('500000000n')).toBe(0.5); + }); + + it('keeps unsuffixed quantities as cores', () => { + expect(parseCpu('8')).toBe(8); + expect(parseCpu('1.5')).toBe(1.5); + }); +}); diff --git a/karpenter/src/helpers/parseCpu.tsx b/karpenter/src/helpers/parseCpu.tsx new file mode 100644 index 0000000000..f087893fac --- /dev/null +++ b/karpenter/src/helpers/parseCpu.tsx @@ -0,0 +1,18 @@ +export function parseCpu(cpuStr: string): number { + if (!cpuStr) return 0; + + const quantity = `${cpuStr}`.trim(); + const match = quantity.match(/^(\d+(?:\.\d+)?)(n|u|m)?$/); + if (!match) return 0; + + const num = parseFloat(match[1]); + const unit = match[2]; + + const perCore: Record = { + n: 1e9, + u: 1e6, + m: 1e3, + }; + + return unit ? num / perCore[unit] : num; +}