Skip to content

Commit 7d628c6

Browse files
committed
Fix cost review edge cases
1 parent b5cc97f commit 7d628c6

4 files changed

Lines changed: 59 additions & 7 deletions

File tree

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { describe, expect, it } from 'vitest'
2+
import { resourceKindForCostWorkload } from './CostView'
3+
4+
describe('resourceKindForCostWorkload', () => {
5+
it('does not link standalone aggregate rows as pods', () => {
6+
expect(resourceKindForCostWorkload('standalone')).toBeNull()
7+
})
8+
9+
it('keeps static pod rows linkable to their mirror pod', () => {
10+
expect(resourceKindForCostWorkload('staticpod')).toBe('Pod')
11+
})
12+
})

web/src/components/cost/CostView.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -614,8 +614,9 @@ function costWorkloadResource(wl: OpenCostWorkloadCost, namespace: string): Sele
614614
}
615615
}
616616

617-
function resourceKindForCostWorkload(kind: string): string | null {
618-
if (kind === 'standalone' || kind === 'staticpod') return 'Pod'
617+
export function resourceKindForCostWorkload(kind: string): string | null {
618+
if (kind === 'staticpod') return 'Pod'
619+
if (kind === 'standalone') return null
619620
if (kind === 'Deployment' || kind === 'StatefulSet' || kind === 'DaemonSet') return kind
620621
if (kind === 'Job' || kind === 'CronJob') return kind
621622
if (kind === 'Node') return kind

web/src/components/cost/WorkloadCostTab.test.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,28 @@ describe('getWorkloadCostState', () => {
103103
it('separates load failures from absent workload metrics', () => {
104104
expect(getWorkloadCostState(undefined, undefined, { currentError: true })).toBe('load_error')
105105
})
106+
107+
it('surfaces workload access and existence failures', () => {
108+
const current: OpenCostWorkloadDetailResponse = {
109+
available: false,
110+
reason: 'access_denied',
111+
namespace: 'prod',
112+
kind: 'Deployment',
113+
name: 'checkout',
114+
}
115+
116+
const missing: OpenCostWorkloadTrendResponse = {
117+
available: false,
118+
reason: 'not_found',
119+
namespace: 'prod',
120+
kind: 'Deployment',
121+
name: 'checkout',
122+
range: '24h',
123+
}
124+
125+
expect(getWorkloadCostState(current, undefined, false)).toBe('access_denied')
126+
expect(getWorkloadCostState(undefined, missing, false)).toBe('not_found')
127+
})
106128
})
107129

108130
describe('buildLineChart', () => {

web/src/components/cost/WorkloadCostTab.tsx

Lines changed: 22 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,14 @@ export function WorkloadCostTab({ kind, namespace, name }: WorkloadCostTabProps)
8383
)
8484
}
8585

86-
if (state === 'no_prometheus' || state === 'no_metrics' || state === 'query_error' || state === 'load_error') {
86+
if (
87+
state === 'no_prometheus' ||
88+
state === 'no_metrics' ||
89+
state === 'query_error' ||
90+
state === 'access_denied' ||
91+
state === 'not_found' ||
92+
state === 'load_error'
93+
) {
8794
const discoveryAgeMs = noPrometheusSince == null ? 0 : Date.now() - noPrometheusSince
8895
if (state === 'no_prometheus' && discoveryAgeMs < COST_DISCOVERY_GRACE_MS) {
8996
return (
@@ -282,7 +289,13 @@ export function getWorkloadCostState(
282289
if (loading) return 'loading'
283290

284291
const reason = current?.reason ?? trend?.reason
285-
if (reason === 'no_prometheus' || reason === 'query_error') return reason
292+
if (
293+
reason === 'no_prometheus' ||
294+
reason === 'query_error' ||
295+
reason === 'access_denied' ||
296+
reason === 'not_found'
297+
)
298+
return reason
286299
return 'no_metrics'
287300
}
288301

@@ -315,9 +328,13 @@ function WorkloadCostUnavailable({ state }: { state: CostUnavailableReason | 'lo
315328
? 'Prometheus not found. OpenCost workload cost requires Prometheus or VictoriaMetrics.'
316329
: state === 'query_error'
317330
? 'Cost data is temporarily unavailable. Prometheus was found, but workload cost queries failed.'
318-
: state === 'load_error'
319-
? 'Could not load workload cost data. Check access to this workload and try again.'
320-
: 'OpenCost workload metrics were not found for this workload.'
331+
: state === 'access_denied'
332+
? 'You do not have access to view cost for this workload.'
333+
: state === 'not_found'
334+
? 'This workload no longer exists.'
335+
: state === 'load_error'
336+
? 'Could not load workload cost data. Check access to this workload and try again.'
337+
: 'OpenCost workload metrics were not found for this workload.'
321338

322339
return (
323340
<div className="flex h-full min-h-[320px] items-center justify-center">

0 commit comments

Comments
 (0)