@skyhook-io/k8s-ui 1.11.0 → 1.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/src/components/gitops/GitOpsStatusBadge.tsx +40 -0
- package/src/components/gitops/GitOpsTableView.tsx +22 -2
- package/src/components/gitops/ReconcilingIndicator.test.tsx +31 -0
- package/src/components/gitops/detail-helpers.ts +4 -1
- package/src/components/issues/severity.ts +1 -0
- package/src/components/resources/ResourcesView.empty-note.test.ts +41 -0
- package/src/components/resources/ResourcesView.tsx +412 -5
- package/src/components/resources/index.ts +27 -0
- package/src/components/resources/kyverno-legacy-action.test.ts +98 -0
- package/src/components/resources/renderers/AlertRenderer.tsx +4 -1
- package/src/components/resources/renderers/AnalysisRunRenderer.test.tsx +241 -0
- package/src/components/resources/renderers/AnalysisRunRenderer.tsx +166 -0
- package/src/components/resources/renderers/CNPGBackupRenderer.tsx +31 -2
- package/src/components/resources/renderers/CNPGClusterRenderer.test.tsx +33 -0
- package/src/components/resources/renderers/CNPGClusterRenderer.tsx +71 -4
- package/src/components/resources/renderers/CNPGDeclarativeRenderer.tsx +243 -0
- package/src/components/resources/renderers/CNPGObjectStoreRenderer.test.tsx +99 -0
- package/src/components/resources/renderers/CNPGObjectStoreRenderer.tsx +235 -0
- package/src/components/resources/renderers/CNPGPoolerRenderer.tsx +11 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.tsx +23 -1
- package/src/components/resources/renderers/CNPGShared.tsx +27 -0
- package/src/components/resources/renderers/CalicoHostEndpointRenderer.tsx +71 -0
- package/src/components/resources/renderers/CalicoIPPoolRenderer.tsx +32 -0
- package/src/components/resources/renderers/CalicoNetworkPolicyDiagram.test.tsx +205 -0
- package/src/components/resources/renderers/CalicoNetworkPolicyDiagram.tsx +537 -0
- package/src/components/resources/renderers/CalicoNetworkPolicyRenderer.test.tsx +223 -0
- package/src/components/resources/renderers/CalicoNetworkPolicyRenderer.tsx +670 -0
- package/src/components/resources/renderers/CalicoTierRenderer.tsx +19 -0
- package/src/components/resources/renderers/CompositeRenderer.test.tsx +81 -0
- package/src/components/resources/renderers/CompositeRenderer.tsx +67 -7
- package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +4 -1
- package/src/components/resources/renderers/GitRepositoryRenderer.tsx +4 -1
- package/src/components/resources/renderers/HelmRepositoryRenderer.tsx +4 -1
- package/src/components/resources/renderers/KustomizationRenderer.tsx +4 -1
- package/src/components/resources/renderers/KyvernoCELPolicyRenderers.tsx +13 -6
- package/src/components/resources/renderers/KyvernoExceptionRenderers.tsx +3 -2
- package/src/components/resources/renderers/KyvernoGlobalContextRenderer.test.ts +31 -0
- package/src/components/resources/renderers/KyvernoGlobalContextRenderer.tsx +124 -0
- package/src/components/resources/renderers/KyvernoPolicyReportRenderer.tsx +28 -2
- package/src/components/resources/renderers/KyvernoQueueRenderers.tsx +303 -0
- package/src/components/resources/renderers/LookupFailureNote.test.tsx +60 -0
- package/src/components/resources/renderers/LookupFailureNote.tsx +42 -0
- package/src/components/resources/renderers/NetworkPolicyDiagram.tsx +27 -26
- package/src/components/resources/renderers/NetworkPolicyRenderer.tsx +6 -3
- package/src/components/resources/renderers/OCIRepositoryRenderer.tsx +4 -1
- package/src/components/resources/renderers/PodRenderer.tsx +13 -0
- package/src/components/resources/renderers/PolicyCoverageSection.test.tsx +348 -0
- package/src/components/resources/renderers/PolicyCoverageSection.tsx +939 -0
- package/src/components/resources/renderers/PolicySection.test.tsx +159 -0
- package/src/components/resources/renderers/PolicySection.tsx +197 -0
- package/src/components/resources/renderers/RolloutRenderer.test.tsx +491 -0
- package/src/components/resources/renderers/RolloutRenderer.tsx +391 -92
- package/src/components/resources/renderers/VeleroBSLRenderer.test.tsx +374 -0
- package/src/components/resources/renderers/VeleroBSLRenderer.tsx +179 -3
- package/src/components/resources/renderers/VeleroBackupRenderer.test.tsx +221 -0
- package/src/components/resources/renderers/VeleroBackupRenderer.tsx +119 -6
- package/src/components/resources/renderers/VeleroBackupRepositoryRenderer.test.tsx +69 -0
- package/src/components/resources/renderers/VeleroBackupRepositoryRenderer.tsx +96 -0
- package/src/components/resources/renderers/VeleroRestoreRenderer.test.tsx +55 -0
- package/src/components/resources/renderers/VeleroRestoreRenderer.tsx +22 -4
- package/src/components/resources/renderers/VeleroRunMessages.test.tsx +152 -0
- package/src/components/resources/renderers/VeleroRunMessages.tsx +139 -0
- package/src/components/resources/renderers/VeleroScheduleRenderer.test.tsx +88 -0
- package/src/components/resources/renderers/VeleroScheduleRenderer.tsx +16 -6
- package/src/components/resources/renderers/WorkloadRenderer.tsx +15 -1
- package/src/components/resources/renderers/calico-cells.tsx +177 -0
- package/src/components/resources/renderers/cnpg-cells.tsx +100 -0
- package/src/components/resources/renderers/index.ts +16 -0
- package/src/components/resources/renderers/kyverno-cells.tsx +90 -0
- package/src/components/resources/renderers/network-policy-peer-styles.ts +25 -0
- package/src/components/resources/renderers/policyreport-subject.test.tsx +27 -0
- package/src/components/resources/renderers/velero-cells.tsx +29 -7
- package/src/components/resources/renderers/velero-dead-ends.test.tsx +142 -0
- package/src/components/resources/resource-utils-calico.test.ts +215 -0
- package/src/components/resources/resource-utils-calico.ts +261 -0
- package/src/components/resources/resource-utils-cnpg-declarative.test.ts +104 -0
- package/src/components/resources/resource-utils-cnpg-objectstore.test.ts +122 -0
- package/src/components/resources/resource-utils-cnpg.test.ts +117 -0
- package/src/components/resources/resource-utils-cnpg.ts +324 -3
- package/src/components/resources/resource-utils-crossplane.test.ts +68 -0
- package/src/components/resources/resource-utils-kyverno-modern.ts +24 -0
- package/src/components/resources/resource-utils-kyverno-queue.test.ts +164 -0
- package/src/components/resources/resource-utils-kyverno-queue.ts +198 -0
- package/src/components/resources/resource-utils-kyverno.ts +43 -7
- package/src/components/resources/resource-utils-velero.test.ts +26 -0
- package/src/components/resources/resource-utils-velero.ts +68 -0
- package/src/components/resources/resource-utils.ts +98 -0
- package/src/components/shared/ResourceActionsBar.tsx +101 -16
- package/src/components/shared/ResourceRendererDispatch.test.tsx +379 -3
- package/src/components/shared/ResourceRendererDispatch.tsx +199 -22
- package/src/components/shared/index.ts +1 -1
- package/src/components/shared/revision-role-badges.test.ts +120 -0
- package/src/components/topology/K8sResourceNode.test.ts +10 -0
- package/src/components/topology/K8sResourceNode.tsx +22 -0
- package/src/components/topology/TopologyFilterSidebar.test.tsx +31 -0
- package/src/components/topology/TopologyFilterSidebar.tsx +5 -0
- package/src/components/topology/TopologyGraph.tsx +6 -6
- package/src/components/topology/TopologySearch.tsx +7 -0
- package/src/components/topology/layout.ts +3 -0
- package/src/components/trace/ReachabilityView.tsx +1 -0
- package/src/components/trace/TracePanel.tsx +12 -2
- package/src/components/trace/reachFixtures.ts +26 -1
- package/src/components/trace/reachGraphModel.test.ts +20 -0
- package/src/components/trace/reachGraphModel.ts +8 -1
- package/src/components/trace/reachOrigins.test.ts +31 -0
- package/src/components/trace/reachOrigins.ts +11 -1
- package/src/components/ui/Badge.tsx +10 -0
- package/src/components/ui/ScheduleValue.test.tsx +80 -0
- package/src/components/ui/ScheduleValue.tsx +85 -0
- package/src/components/ui/drawer-components.test.tsx +17 -1
- package/src/components/ui/drawer-components.tsx +9 -2
- package/src/components/ui/index.ts +2 -0
- package/src/components/workload/WorkloadView.tsx +3 -0
- package/src/types/core.ts +29 -0
- package/src/types/gitops-flux-status.test.ts +163 -0
- package/src/types/gitops.ts +80 -24
- package/src/types/index.ts +1 -0
- package/src/types/policy.ts +193 -0
- package/src/utils/navigation.test.ts +5 -0
- package/src/utils/navigation.ts +5 -0
- package/src/utils/resource-icons.test.ts +49 -2
- package/src/utils/resource-icons.ts +29 -2
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@skyhook-io/k8s-ui",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.13.0",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "https://github.com/skyhook-io/radar",
|
|
@@ -71,7 +71,7 @@
|
|
|
71
71
|
"html-to-image": "^1.11.0",
|
|
72
72
|
"monaco-yaml": "5.5.1",
|
|
73
73
|
"react-virtuoso": "^4.18.11",
|
|
74
|
-
"shiki": "^4.2
|
|
74
|
+
"shiki": "^4.4.2"
|
|
75
75
|
},
|
|
76
76
|
"peerDependencies": {
|
|
77
77
|
"@xterm/addon-fit": ">=0.10.0",
|
|
@@ -88,7 +88,7 @@
|
|
|
88
88
|
"yaml": ">=2.0.0"
|
|
89
89
|
},
|
|
90
90
|
"devDependencies": {
|
|
91
|
-
"@types/node": "^26.
|
|
91
|
+
"@types/node": "^26.2.0",
|
|
92
92
|
"@types/react": "^19.2.18",
|
|
93
93
|
"@types/react-dom": "^19.2.3",
|
|
94
94
|
"@xterm/addon-fit": "^0.11.0",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"clsx": "^2.1.1",
|
|
99
99
|
"diff": "^9.0.0",
|
|
100
100
|
"elkjs": "^0.11.1",
|
|
101
|
-
"lucide-react": "^1.
|
|
101
|
+
"lucide-react": "^1.30.0",
|
|
102
102
|
"monaco-editor": "0.55.1",
|
|
103
103
|
"react": "^19.2.8",
|
|
104
104
|
"react-dom": "^19.2.8",
|
|
@@ -2,6 +2,8 @@ import { clsx } from 'clsx'
|
|
|
2
2
|
import { CheckCircle2, AlertCircle, Loader2, Pause, HelpCircle, XCircle } from 'lucide-react'
|
|
3
3
|
import type { GitOpsStatus, SyncStatus, GitOpsHealthStatus } from '../../types/gitops'
|
|
4
4
|
import { SEVERITY_BADGE_BORDERED, SEVERITY_BADGE } from '../../utils/badge-colors'
|
|
5
|
+
import { formatCompactAge } from '../../utils/format'
|
|
6
|
+
import { Tooltip } from '../ui/Tooltip'
|
|
5
7
|
|
|
6
8
|
interface GitOpsStatusBadgeProps {
|
|
7
9
|
status: GitOpsStatus
|
|
@@ -176,3 +178,41 @@ export function HealthStatusBadge({ health }: { health: GitOpsHealthStatus }) {
|
|
|
176
178
|
</span>
|
|
177
179
|
)
|
|
178
180
|
}
|
|
181
|
+
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* ReconcilingIndicator rides alongside the sync badge rather than replacing it,
|
|
185
|
+
* the same primary-plus-secondary shape the Velero schedule cell uses for a
|
|
186
|
+
* paused-and-rejected schedule.
|
|
187
|
+
*
|
|
188
|
+
* A pass being in flight says nothing about whether the declared state is
|
|
189
|
+
* applied, so it must not touch the sync word — but a pass that never finishes
|
|
190
|
+
* is the one fault nothing else in the product notices, and on a healthy object
|
|
191
|
+
* a real pass completes in milliseconds. In practice this only becomes visible
|
|
192
|
+
* when a controller is wedged, which is exactly when it should be.
|
|
193
|
+
*/
|
|
194
|
+
export function ReconcilingIndicator({
|
|
195
|
+
reconciling,
|
|
196
|
+
since,
|
|
197
|
+
sync,
|
|
198
|
+
}: {
|
|
199
|
+
reconciling?: boolean
|
|
200
|
+
since?: string
|
|
201
|
+
/** The sync word shown beside this. Omitted when there is no badge alongside. */
|
|
202
|
+
sync?: SyncStatus
|
|
203
|
+
}) {
|
|
204
|
+
// Suppressed when the sync badge already says Reconciling — it carries the
|
|
205
|
+
// same fact and spins for it. Showing both puts two spinners on one row for
|
|
206
|
+
// one thing. The secondary exists for the case the primary CANNOT express:
|
|
207
|
+
// an applied object whose reconcile pass never finished.
|
|
208
|
+
if (!reconciling || sync === 'Reconciling') return null
|
|
209
|
+
const age = formatCompactAge(since)
|
|
210
|
+
const tip = age
|
|
211
|
+
? `A reconcile pass has been in flight for ${age}. On a healthy resource a pass finishes in milliseconds, so a long-running one usually means the controller is stuck.`
|
|
212
|
+
: 'A reconcile pass is in flight.'
|
|
213
|
+
return (
|
|
214
|
+
<Tooltip content={tip}>
|
|
215
|
+
<Loader2 className="w-3 h-3 shrink-0 animate-spin text-theme-text-tertiary" aria-label="Reconcile pass in flight" />
|
|
216
|
+
</Tooltip>
|
|
217
|
+
)
|
|
218
|
+
}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
Zap,
|
|
25
25
|
} from 'lucide-react'
|
|
26
26
|
|
|
27
|
-
import { HealthStatusBadge, SyncStatusBadge } from './GitOpsStatusBadge'
|
|
27
|
+
import { HealthStatusBadge, ReconcilingIndicator, SyncStatusBadge } from './GitOpsStatusBadge'
|
|
28
28
|
import { Tooltip } from '../ui/Tooltip'
|
|
29
29
|
import { Input } from '../ui/Input'
|
|
30
30
|
import { PageHeader } from '../ui/PageHeader'
|
|
@@ -150,6 +150,14 @@ export interface GitOpsRow {
|
|
|
150
150
|
sync: string
|
|
151
151
|
health: string
|
|
152
152
|
suspended: boolean
|
|
153
|
+
/**
|
|
154
|
+
* A reconcile pass is executing. Deliberately separate from sync: a pass
|
|
155
|
+
* being in flight says nothing about whether the declared state is applied,
|
|
156
|
+
* but a pass that never finishes is the one fault nothing else in the
|
|
157
|
+
* product notices.
|
|
158
|
+
*/
|
|
159
|
+
reconciling?: boolean
|
|
160
|
+
reconcilingSince?: string
|
|
153
161
|
repository: string
|
|
154
162
|
targetRevision: string
|
|
155
163
|
path: string
|
|
@@ -1300,7 +1308,12 @@ function GitOpsTable({
|
|
|
1300
1308
|
<TableCell>
|
|
1301
1309
|
{row.terminating
|
|
1302
1310
|
? <span className="text-[11px] text-theme-text-tertiary">—</span>
|
|
1303
|
-
:
|
|
1311
|
+
: (
|
|
1312
|
+
<span className="inline-flex items-center gap-1 min-w-0">
|
|
1313
|
+
<SyncStatusBadge sync={row.sync as any} suspended={row.suspended} />
|
|
1314
|
+
<ReconcilingIndicator reconciling={row.reconciling} since={row.reconcilingSince} sync={row.sync as any} />
|
|
1315
|
+
</span>
|
|
1316
|
+
)}
|
|
1304
1317
|
</TableCell>
|
|
1305
1318
|
<TableCell>
|
|
1306
1319
|
{row.terminating
|
|
@@ -1529,6 +1542,7 @@ function GitOpsTile({
|
|
|
1529
1542
|
) : (
|
|
1530
1543
|
<>
|
|
1531
1544
|
<SyncStatusBadge sync={row.sync as any} suspended={row.suspended} />
|
|
1545
|
+
<ReconcilingIndicator reconciling={row.reconciling} since={row.reconcilingSince} sync={row.sync as any} />
|
|
1532
1546
|
<HealthStatusBadge health={row.health as any} />
|
|
1533
1547
|
</>
|
|
1534
1548
|
)}
|
|
@@ -1896,6 +1910,8 @@ export function normalizeArgoApplication(resource: any): GitOpsRow {
|
|
|
1896
1910
|
labels: (resource.metadata?.labels ?? {}) as Record<string, string>,
|
|
1897
1911
|
sync: status?.sync ?? 'Unknown',
|
|
1898
1912
|
health: status?.health ?? 'Unknown',
|
|
1913
|
+
reconciling: status?.reconciling,
|
|
1914
|
+
reconcilingSince: status?.reconcilingSince,
|
|
1899
1915
|
suspended: (status?.suspended ?? false) || isArgoSuspendedByRadar(resource),
|
|
1900
1916
|
repository: resource.spec?.source?.repoURL ?? '',
|
|
1901
1917
|
targetRevision: resource.spec?.source?.targetRevision ?? '',
|
|
@@ -1932,6 +1948,8 @@ export function normalizeFluxKustomization(resource: any, fluxSourceUrls?: Map<s
|
|
|
1932
1948
|
labels: (resource.metadata?.labels ?? {}) as Record<string, string>,
|
|
1933
1949
|
sync: status?.sync ?? 'Unknown',
|
|
1934
1950
|
health: status?.health ?? 'Unknown',
|
|
1951
|
+
reconciling: status?.reconciling,
|
|
1952
|
+
reconcilingSince: status?.reconcilingSince,
|
|
1935
1953
|
suspended: status?.suspended ?? resource.spec?.suspend === true,
|
|
1936
1954
|
repository,
|
|
1937
1955
|
targetRevision: resource.status?.lastAppliedRevision ?? resource.status?.lastAttemptedRevision ?? '',
|
|
@@ -1969,6 +1987,8 @@ export function normalizeFluxHelmRelease(resource: any, fluxSourceUrls?: Map<str
|
|
|
1969
1987
|
labels: (resource.metadata?.labels ?? {}) as Record<string, string>,
|
|
1970
1988
|
sync: status?.sync ?? 'Unknown',
|
|
1971
1989
|
health: status?.health ?? 'Unknown',
|
|
1990
|
+
reconciling: status?.reconciling,
|
|
1991
|
+
reconcilingSince: status?.reconcilingSince,
|
|
1972
1992
|
suspended: status?.suspended ?? resource.spec?.suspend === true,
|
|
1973
1993
|
repository,
|
|
1974
1994
|
targetRevision: chartSpec.version ?? resource.status?.lastAttemptedRevision ?? '',
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { renderToString } from 'react-dom/server'
|
|
3
|
+
import { ReconcilingIndicator } from './GitOpsStatusBadge'
|
|
4
|
+
|
|
5
|
+
const LABEL = 'Reconcile pass in flight'
|
|
6
|
+
|
|
7
|
+
// A reconcile pass in flight is worth showing only where the sync word cannot
|
|
8
|
+
// already say it. Radar's own precedent for a secondary indicator (the Velero
|
|
9
|
+
// schedule cell's paused-and-rejected case) suppresses the icon when the badge
|
|
10
|
+
// carries the same fact, and without that rule one row shows two spinners.
|
|
11
|
+
describe('ReconcilingIndicator', () => {
|
|
12
|
+
it('shows on an applied object whose pass never finished', () => {
|
|
13
|
+
// The case the sync word cannot express, and the reason this exists: a
|
|
14
|
+
// wedged controller behind a correct "Synced".
|
|
15
|
+
const html = renderToString(
|
|
16
|
+
<ReconcilingIndicator reconciling since="2026-08-11T06:05:00Z" sync="Synced" />,
|
|
17
|
+
)
|
|
18
|
+
expect(html).toContain(LABEL)
|
|
19
|
+
})
|
|
20
|
+
|
|
21
|
+
it('is suppressed when the sync badge already reports Reconciling', () => {
|
|
22
|
+
const html = renderToString(
|
|
23
|
+
<ReconcilingIndicator reconciling since="2026-08-11T06:05:00Z" sync="Reconciling" />,
|
|
24
|
+
)
|
|
25
|
+
expect(html).toBe('')
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
it('is absent when nothing is in flight', () => {
|
|
29
|
+
expect(renderToString(<ReconcilingIndicator reconciling={false} sync="Synced" />)).toBe('')
|
|
30
|
+
})
|
|
31
|
+
})
|
|
@@ -100,7 +100,10 @@ export function getGitOpsResourceStatus(kind: string, resource: any): GitOpsStat
|
|
|
100
100
|
return argoStatusToGitOpsStatus(resource?.status ?? {})
|
|
101
101
|
}
|
|
102
102
|
const conditions = (resource?.status?.conditions ?? []) as FluxCondition[]
|
|
103
|
-
return fluxConditionsToGitOpsStatus(conditions, resource?.spec?.suspend === true
|
|
103
|
+
return fluxConditionsToGitOpsStatus(conditions, resource?.spec?.suspend === true, {
|
|
104
|
+
generation: resource?.metadata?.generation,
|
|
105
|
+
observedGeneration: resource?.status?.observedGeneration,
|
|
106
|
+
})
|
|
104
107
|
}
|
|
105
108
|
|
|
106
109
|
// getGitOpsTool routes a kind+group to 'argo' or 'flux'. Same shape used
|
|
@@ -85,6 +85,7 @@ const CATEGORY_LABEL: Record<string, string> = {
|
|
|
85
85
|
volume_access_mode_conflict: 'Volume access conflict',
|
|
86
86
|
backup_failed: 'Backup failed',
|
|
87
87
|
backup_target_unavailable: 'Backup target unavailable',
|
|
88
|
+
backup_stalled: 'Backup not progressing',
|
|
88
89
|
job_failed: 'Job failed',
|
|
89
90
|
cronjob_failed: 'CronJob failed',
|
|
90
91
|
rollout_stalled: 'Rollout stalled',
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest'
|
|
2
|
+
import { emptyKindNote } from './ResourcesView'
|
|
3
|
+
|
|
4
|
+
describe('emptyKindNote', () => {
|
|
5
|
+
it('explains that no UpdateRequest is the resting state, and that it looks the same as a rule that never ran', () => {
|
|
6
|
+
const note = emptyKindNote('UpdateRequest', 'kyverno.io')
|
|
7
|
+
expect(note).toContain('deleted seconds after')
|
|
8
|
+
expect(note).toContain('never ran')
|
|
9
|
+
})
|
|
10
|
+
|
|
11
|
+
it('says an absent EphemeralReport means the scan finished, not that nothing was checked', () => {
|
|
12
|
+
expect(emptyKindNote('EphemeralReport', 'reports.kyverno.io')).toContain('scan has finished')
|
|
13
|
+
expect(emptyKindNote('ClusterEphemeralReport', 'reports.kyverno.io')).toContain('scan has finished')
|
|
14
|
+
})
|
|
15
|
+
|
|
16
|
+
it('is case-insensitive on the kind, which arrives from a URL as often as from discovery', () => {
|
|
17
|
+
expect(emptyKindNote('updaterequest', 'kyverno.io')).toBeDefined()
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// Same plural, different operator: Kyverno's group is what makes the note true.
|
|
21
|
+
it('says nothing about a kind of the same name from another group', () => {
|
|
22
|
+
expect(emptyKindNote('UpdateRequest', 'example.com')).toBeUndefined()
|
|
23
|
+
expect(emptyKindNote('EphemeralReport', '')).toBeUndefined()
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
it('says nothing about kinds with no such story', () => {
|
|
27
|
+
expect(emptyKindNote('Pod', '')).toBeUndefined()
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
// The table can be empty because the reader emptied it. Telling them none is
|
|
31
|
+
// normal then answers a question they did not ask, with their term still in
|
|
32
|
+
// the search box.
|
|
33
|
+
it('stays silent when the kind has rows and a filter is what emptied the table', () => {
|
|
34
|
+
expect(emptyKindNote('UpdateRequest', 'kyverno.io', 3)).toBeUndefined()
|
|
35
|
+
expect(emptyKindNote('EphemeralReport', 'reports.kyverno.io', 192)).toBeUndefined()
|
|
36
|
+
})
|
|
37
|
+
|
|
38
|
+
it('still speaks when the kind is genuinely empty', () => {
|
|
39
|
+
expect(emptyKindNote('UpdateRequest', 'kyverno.io', 0)).toBeDefined()
|
|
40
|
+
})
|
|
41
|
+
})
|