@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
|
@@ -79,6 +79,8 @@ import {
|
|
|
79
79
|
getPVCCapacity,
|
|
80
80
|
getPVCAccessModes,
|
|
81
81
|
getRolloutStatus,
|
|
82
|
+
getAnalysisRunStatus,
|
|
83
|
+
summarizeAnalysisMetrics,
|
|
82
84
|
getRolloutStrategy,
|
|
83
85
|
getRolloutReady,
|
|
84
86
|
getRolloutStep,
|
|
@@ -152,14 +154,17 @@ import { ScaledObjectCell, ScaledJobCell, TriggerAuthenticationCell, ClusterTrig
|
|
|
152
154
|
import { ResourceClaimCell, ResourceClaimTemplateCell, DeviceClassCell, ResourceSliceCell } from './renderers/dra-cells'
|
|
153
155
|
import { NvidiaClusterPolicyCell, NvidiaDriverCell } from './renderers/nvidia-cells'
|
|
154
156
|
import { ServiceMonitorCell, PrometheusRuleCell, PodMonitorCell } from './renderers/prometheus-cells'
|
|
155
|
-
import { PolicyReportCell, ClusterPolicyReportCell, KyvernoPolicyCell, ClusterPolicyCell
|
|
157
|
+
import { PolicyReportCell, ClusterPolicyReportCell, KyvernoPolicyCell, ClusterPolicyCell,
|
|
158
|
+
KyvernoUpdateRequestCell,
|
|
159
|
+
KyvernoEphemeralReportCell,
|
|
160
|
+
} from './renderers/kyverno-cells'
|
|
156
161
|
import { KyvernoModernPolicyCell, KyvernoPolicyExceptionCell, KyvernoCleanupPolicyCell } from './renderers/kyverno-modern-cells'
|
|
157
162
|
import { KYVERNO_MODERN_PLURALS, isModernKyvernoPolicy } from './resource-utils-kyverno-modern'
|
|
158
163
|
import { isAnyKyvernoPolicyException } from './resource-utils-kyverno-exceptions'
|
|
159
164
|
import { ExternalSecretCell, ClusterExternalSecretCell, SecretStoreCell, ClusterSecretStoreCell } from './renderers/eso-cells'
|
|
160
165
|
import { BackupCell, RestoreCell, ScheduleCell, BackupStorageLocationCell, VolumeSnapshotLocationCell, BackupRepositoryCell } from './renderers/velero-cells'
|
|
161
166
|
import { isVeleroResource } from './resource-utils-velero'
|
|
162
|
-
import { CNPGClusterCell, CNPGBackupCell, CNPGScheduledBackupCell, CNPGPoolerCell } from './renderers/cnpg-cells'
|
|
167
|
+
import { CNPGClusterCell, CNPGBackupCell, CNPGScheduledBackupCell, CNPGPoolerCell, CNPGObjectStoreCell, CNPGDeclarativeCell, CNPGImageCatalogCell } from './renderers/cnpg-cells'
|
|
163
168
|
import { isApiGroup, CNPG_GROUP } from './resource-utils-cnpg'
|
|
164
169
|
import { ManagedResourceCell, CompositeResourceCell, CrossplaneProviderCell, CrossplaneProviderConfigCell, CompositionCell, XRDCell } from './renderers/crossplane-cells'
|
|
165
170
|
import { isManagedResource, isComposite } from './resource-utils-crossplane'
|
|
@@ -171,6 +176,8 @@ import { CAPIClusterCell, CAPIMachineCell, CAPIMachineDeploymentCell, CAPIMachin
|
|
|
171
176
|
import { AWSManagedControlPlaneCell, AWSManagedMachinePoolCell, AWSMachineCell, AWSMachineTemplateCell, AWSManagedClusterCell } from './renderers/aws-capi-cells'
|
|
172
177
|
import { GCPManagedControlPlaneCell, GCPManagedMachinePoolCell, GCPMachineCell, GCPMachineTemplateCell, GCPManagedClusterCell } from './renderers/gcp-capi-cells'
|
|
173
178
|
import { AzureManagedControlPlaneCell, AzureManagedMachinePoolCell, AzureMachineCell, AzureMachineTemplateCell, AzureManagedClusterCell } from './renderers/azure-capi-cells'
|
|
179
|
+
import { CalicoInfraCell, CalicoPolicyCell } from './renderers/calico-cells'
|
|
180
|
+
import { isCalicoPolicyResource, isCoreNetworkPolicyKind } from './resource-utils-calico'
|
|
174
181
|
import { useRegisterShortcut, useRegisterShortcuts } from '../../hooks/useKeyboardShortcuts'
|
|
175
182
|
import { ResourcesSidebar } from './ResourcesSidebar'
|
|
176
183
|
import type { SelectedKindInfo } from './ResourcesSidebar'
|
|
@@ -274,10 +281,14 @@ function buildCustomColumn(d: CustomColumnDef): ExtraColumn {
|
|
|
274
281
|
}
|
|
275
282
|
|
|
276
283
|
// Tailwind width class → pixel minimum mapping for CSS Grid column sizing
|
|
284
|
+
// A width class missing from this map falls back to 80px, and nothing says so —
|
|
285
|
+
// the column just renders narrow enough to truncate its header. Keep the whole
|
|
286
|
+
// Tailwind step range present rather than only the sizes in use today.
|
|
277
287
|
const TAILWIND_WIDTH_TO_PX: Record<string, number> = {
|
|
278
288
|
'w-12': 48, 'w-14': 56, 'w-16': 64, 'w-20': 80, 'w-24': 96,
|
|
279
289
|
'w-28': 112, 'w-32': 128, 'w-36': 144, 'w-40': 160, 'w-44': 176,
|
|
280
|
-
'w-48': 192, 'w-56': 224, 'w-64': 256,
|
|
290
|
+
'w-48': 192, 'w-52': 208, 'w-56': 224, 'w-60': 240, 'w-64': 256,
|
|
291
|
+
'w-72': 288, 'w-80': 320, 'w-96': 384,
|
|
281
292
|
}
|
|
282
293
|
|
|
283
294
|
const COMPARE_COLUMN_WIDTH = 36
|
|
@@ -296,6 +307,30 @@ function getColumnMinWidth(col: Column): number {
|
|
|
296
307
|
}
|
|
297
308
|
|
|
298
309
|
// Default columns for unknown resource types (CRDs)
|
|
310
|
+
/**
|
|
311
|
+
* Why a list of this kind being empty is not the answer it looks like.
|
|
312
|
+
*
|
|
313
|
+
* Kyverno's two working records are garbage-collected within seconds of
|
|
314
|
+
* finishing, so "none" is the resting state of a healthy cluster — and for
|
|
315
|
+
* UpdateRequest it is ALSO what you see when a generate rule never fired at
|
|
316
|
+
* all. Those are opposite conclusions and a bare "No X found" renders them
|
|
317
|
+
* identically.
|
|
318
|
+
*/
|
|
319
|
+
export function emptyKindNote(kind: string, group?: string, unfilteredTotal = 0): string | undefined {
|
|
320
|
+
// A search or column filter emptying the table is the reader's own doing.
|
|
321
|
+
// Explaining that none is the resting state then answers a question they did
|
|
322
|
+
// not ask, while their own term is still in the box.
|
|
323
|
+
if (unfilteredTotal > 0) return undefined
|
|
324
|
+
const g = group ?? ''
|
|
325
|
+
if (kind.toLowerCase() === 'updaterequest' && g === 'kyverno.io') {
|
|
326
|
+
return 'These are deleted seconds after the work completes, so none is the normal resting state. It also looks like this if a generate or mutate-existing rule never ran — check the policy itself to tell the two apart.'
|
|
327
|
+
}
|
|
328
|
+
if ((kind.toLowerCase() === 'ephemeralreport' || kind.toLowerCase() === 'clusterephemeralreport') && g === 'reports.kyverno.io') {
|
|
329
|
+
return 'These exist only between a background scan and the PolicyReport it becomes, so none means the scan has finished rather than that nothing was checked.'
|
|
330
|
+
}
|
|
331
|
+
return undefined
|
|
332
|
+
}
|
|
333
|
+
|
|
299
334
|
const DEFAULT_COLUMNS: Column[] = [
|
|
300
335
|
{ key: 'name', label: 'Name' },
|
|
301
336
|
{ key: 'namespace', label: 'Namespace', width: 'w-48' },
|
|
@@ -464,6 +499,14 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
464
499
|
{ key: 'images', label: 'Images', width: 'w-48', hideOnMobile: true },
|
|
465
500
|
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
466
501
|
],
|
|
502
|
+
analysisruns: [
|
|
503
|
+
{ key: 'name', label: 'Name' },
|
|
504
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-48' },
|
|
505
|
+
{ key: 'status', label: 'Phase', width: 'w-28' },
|
|
506
|
+
{ key: 'trigger', label: 'Trigger', width: 'w-32', tooltip: 'Which part of the Rollout started this run' },
|
|
507
|
+
{ key: 'metrics', label: 'Metrics', width: 'w-40', hideOnMobile: true, tooltip: 'Per-metric verdicts' },
|
|
508
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
509
|
+
],
|
|
467
510
|
workflows: [
|
|
468
511
|
{ key: 'name', label: 'Name' },
|
|
469
512
|
{ key: 'namespace', label: 'Namespace', width: 'w-48' },
|
|
@@ -707,6 +750,7 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
707
750
|
policyreports: [
|
|
708
751
|
{ key: 'name', label: 'Name' },
|
|
709
752
|
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
753
|
+
{ key: 'scope', label: 'Subject', width: 'w-56' },
|
|
710
754
|
{ key: 'status', label: 'Status', width: 'w-32' },
|
|
711
755
|
{ key: 'pass', label: 'Pass', width: 'w-16' },
|
|
712
756
|
{ key: 'fail', label: 'Fail', width: 'w-16' },
|
|
@@ -717,6 +761,7 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
717
761
|
],
|
|
718
762
|
clusterpolicyreports: [
|
|
719
763
|
{ key: 'name', label: 'Name' },
|
|
764
|
+
{ key: 'scope', label: 'Subject', width: 'w-56' },
|
|
720
765
|
{ key: 'status', label: 'Status', width: 'w-32' },
|
|
721
766
|
{ key: 'pass', label: 'Pass', width: 'w-16' },
|
|
722
767
|
{ key: 'fail', label: 'Fail', width: 'w-16' },
|
|
@@ -911,6 +956,88 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
911
956
|
{ key: 'rules', label: 'Rules', width: 'w-24', tooltip: 'Ingress / Egress rule count' },
|
|
912
957
|
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
913
958
|
],
|
|
959
|
+
caliconetworkpolicies: [
|
|
960
|
+
{ key: 'name', label: 'Name' },
|
|
961
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
962
|
+
{ key: 'selector', label: 'Selector', width: 'w-48' },
|
|
963
|
+
{ key: 'namespaceSelector', label: 'Namespace Selector', width: 'w-48', defaultVisible: false },
|
|
964
|
+
{ key: 'serviceAccountSelector', label: 'Service Account Selector', width: 'w-48', defaultVisible: false },
|
|
965
|
+
{ key: 'tier', label: 'Tier', width: 'w-28' },
|
|
966
|
+
{ key: 'order', label: 'Order', width: 'w-24' },
|
|
967
|
+
{ key: 'types', label: 'Types', width: 'w-28' },
|
|
968
|
+
{ key: 'rules', label: 'Rules', width: 'w-24', tooltip: 'Ingress / Egress rule count' },
|
|
969
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
970
|
+
],
|
|
971
|
+
calicoglobalnetworkpolicies: [
|
|
972
|
+
{ key: 'name', label: 'Name' },
|
|
973
|
+
{ key: 'selector', label: 'Selector', width: 'w-48' },
|
|
974
|
+
{ key: 'namespaceSelector', label: 'Namespace Selector', width: 'w-48', defaultVisible: false },
|
|
975
|
+
{ key: 'serviceAccountSelector', label: 'Service Account Selector', width: 'w-48', defaultVisible: false },
|
|
976
|
+
{ key: 'tier', label: 'Tier', width: 'w-28' },
|
|
977
|
+
{ key: 'order', label: 'Order', width: 'w-24' },
|
|
978
|
+
{ key: 'types', label: 'Types', width: 'w-28' },
|
|
979
|
+
{ key: 'rules', label: 'Rules', width: 'w-24', tooltip: 'Ingress / Egress rule count' },
|
|
980
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
981
|
+
],
|
|
982
|
+
calicostagednetworkpolicies: [
|
|
983
|
+
{ key: 'name', label: 'Name' },
|
|
984
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
985
|
+
{ key: 'selector', label: 'Selector', width: 'w-48' },
|
|
986
|
+
{ key: 'namespaceSelector', label: 'Namespace Selector', width: 'w-48', defaultVisible: false },
|
|
987
|
+
{ key: 'serviceAccountSelector', label: 'Service Account Selector', width: 'w-48', defaultVisible: false },
|
|
988
|
+
{ key: 'tier', label: 'Tier', width: 'w-28' },
|
|
989
|
+
{ key: 'order', label: 'Order', width: 'w-24' },
|
|
990
|
+
{ key: 'stagedAction', label: 'Staged Action', width: 'w-32' },
|
|
991
|
+
{ key: 'types', label: 'Types', width: 'w-28' },
|
|
992
|
+
{ key: 'rules', label: 'Rules', width: 'w-24', tooltip: 'Ingress / Egress rule count' },
|
|
993
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
994
|
+
],
|
|
995
|
+
calicostagedglobalnetworkpolicies: [
|
|
996
|
+
{ key: 'name', label: 'Name' },
|
|
997
|
+
{ key: 'selector', label: 'Selector', width: 'w-48' },
|
|
998
|
+
{ key: 'namespaceSelector', label: 'Namespace Selector', width: 'w-48', defaultVisible: false },
|
|
999
|
+
{ key: 'serviceAccountSelector', label: 'Service Account Selector', width: 'w-48', defaultVisible: false },
|
|
1000
|
+
{ key: 'tier', label: 'Tier', width: 'w-28' },
|
|
1001
|
+
{ key: 'order', label: 'Order', width: 'w-24' },
|
|
1002
|
+
{ key: 'stagedAction', label: 'Staged Action', width: 'w-32' },
|
|
1003
|
+
{ key: 'types', label: 'Types', width: 'w-28' },
|
|
1004
|
+
{ key: 'rules', label: 'Rules', width: 'w-24', tooltip: 'Ingress / Egress rule count' },
|
|
1005
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1006
|
+
],
|
|
1007
|
+
calicoippools: [
|
|
1008
|
+
{ key: 'name', label: 'Name' },
|
|
1009
|
+
{ key: 'cidr', label: 'CIDR', width: 'w-44' },
|
|
1010
|
+
{ key: 'blockSize', label: 'Block Size', width: 'w-28' },
|
|
1011
|
+
{ key: 'encapsulation', label: 'Encapsulation', width: 'w-36' },
|
|
1012
|
+
{ key: 'natOutgoing', label: 'NAT Outgoing', width: 'w-32' },
|
|
1013
|
+
{ key: 'disabled', label: 'Disabled', width: 'w-28' },
|
|
1014
|
+
{ key: 'allowedUses', label: 'Allowed Uses', width: 'w-40', defaultVisible: false },
|
|
1015
|
+
{ key: 'nodeSelector', label: 'Node Selector', width: 'w-48', defaultVisible: false },
|
|
1016
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1017
|
+
],
|
|
1018
|
+
calicohostendpoints: [
|
|
1019
|
+
{ key: 'name', label: 'Name' },
|
|
1020
|
+
{ key: 'node', label: 'Node', width: 'w-48' },
|
|
1021
|
+
{ key: 'interfaceName', label: 'Interface', width: 'w-32' },
|
|
1022
|
+
{ key: 'expectedIPs', label: 'Expected IPs', width: 'w-48' },
|
|
1023
|
+
{ key: 'profiles', label: 'Profiles', width: 'w-48', defaultVisible: false },
|
|
1024
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1025
|
+
],
|
|
1026
|
+
calicotiers: [
|
|
1027
|
+
{ key: 'name', label: 'Name' },
|
|
1028
|
+
{ key: 'order', label: 'Order', width: 'w-24' },
|
|
1029
|
+
{ key: 'defaultAction', label: 'Default Action', width: 'w-36' },
|
|
1030
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1031
|
+
],
|
|
1032
|
+
calicostagedkubernetesnetworkpolicies: [
|
|
1033
|
+
{ key: 'name', label: 'Name' },
|
|
1034
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1035
|
+
{ key: 'selector', label: 'Pod Selector', width: 'w-48' },
|
|
1036
|
+
{ key: 'stagedAction', label: 'Staged Action', width: 'w-32' },
|
|
1037
|
+
{ key: 'types', label: 'Types', width: 'w-28' },
|
|
1038
|
+
{ key: 'rules', label: 'Rules', width: 'w-24', tooltip: 'Ingress / Egress rule count' },
|
|
1039
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1040
|
+
],
|
|
914
1041
|
poddisruptionbudgets: [
|
|
915
1042
|
{ key: 'name', label: 'Name' },
|
|
916
1043
|
{ key: 'namespace', label: 'Namespace', width: 'w-48' },
|
|
@@ -1303,6 +1430,92 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
1303
1430
|
// than an absent one — the reader can't tell which meaning they're getting.
|
|
1304
1431
|
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1305
1432
|
],
|
|
1433
|
+
// `databases`, `publications` and `subscriptions` are crowded plurals — other
|
|
1434
|
+
// database operators ship all three, and Knative owns the unqualified
|
|
1435
|
+
// `subscriptions` set. Keyed under cnpg* and reached only through
|
|
1436
|
+
// GROUP_QUALIFIED_COLUMN_KEYS, so a foreign CRD gets the generic columns
|
|
1437
|
+
// instead of a Cluster column it can never fill.
|
|
1438
|
+
// Kyverno's working records. Both are keyed by things the reader has to see
|
|
1439
|
+
// to know whether anything is wrong: which policy queued the work and what it
|
|
1440
|
+
// was queued against, and which resource a scan is about.
|
|
1441
|
+
updaterequests: [
|
|
1442
|
+
{ key: 'name', label: 'Name' },
|
|
1443
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-32' },
|
|
1444
|
+
{ key: 'status', label: 'State', width: 'w-28' },
|
|
1445
|
+
{ key: 'type', label: 'Type', width: 'w-24' },
|
|
1446
|
+
{ key: 'policy', label: 'Policy', width: 'w-52' },
|
|
1447
|
+
{ key: 'triggers', label: 'Triggered By', width: 'w-56' },
|
|
1448
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1449
|
+
],
|
|
1450
|
+
ephemeralreports: [
|
|
1451
|
+
{ key: 'name', label: 'Name' },
|
|
1452
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-32' },
|
|
1453
|
+
{ key: 'status', label: 'Outcome', width: 'w-28' },
|
|
1454
|
+
{ key: 'subject', label: 'About', width: 'w-56' },
|
|
1455
|
+
{ key: 'source', label: 'Produced By', width: 'w-36' },
|
|
1456
|
+
{ key: 'results', label: 'Results', width: 'w-24' },
|
|
1457
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1458
|
+
],
|
|
1459
|
+
clusterephemeralreports: [
|
|
1460
|
+
{ key: 'name', label: 'Name' },
|
|
1461
|
+
{ key: 'status', label: 'Outcome', width: 'w-28' },
|
|
1462
|
+
{ key: 'subject', label: 'About', width: 'w-56' },
|
|
1463
|
+
{ key: 'source', label: 'Produced By', width: 'w-36' },
|
|
1464
|
+
{ key: 'results', label: 'Results', width: 'w-24' },
|
|
1465
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1466
|
+
],
|
|
1467
|
+
cnpgdatabases: [
|
|
1468
|
+
{ key: 'name', label: 'Name' },
|
|
1469
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1470
|
+
{ key: 'status', label: 'Applied', width: 'w-32' },
|
|
1471
|
+
{ key: 'cluster', label: 'Cluster', width: 'w-36' },
|
|
1472
|
+
{ key: 'target', label: 'Database', width: 'w-40' },
|
|
1473
|
+
{ key: 'message', label: 'Message', width: 'w-64' },
|
|
1474
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1475
|
+
],
|
|
1476
|
+
cnpgpublications: [
|
|
1477
|
+
{ key: 'name', label: 'Name' },
|
|
1478
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1479
|
+
{ key: 'status', label: 'Applied', width: 'w-32' },
|
|
1480
|
+
{ key: 'cluster', label: 'Cluster', width: 'w-36' },
|
|
1481
|
+
{ key: 'dbname', label: 'In Database', width: 'w-40' },
|
|
1482
|
+
{ key: 'message', label: 'Message', width: 'w-64' },
|
|
1483
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1484
|
+
],
|
|
1485
|
+
cnpgsubscriptions: [
|
|
1486
|
+
{ key: 'name', label: 'Name' },
|
|
1487
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1488
|
+
{ key: 'status', label: 'Applied', width: 'w-32' },
|
|
1489
|
+
{ key: 'cluster', label: 'Cluster', width: 'w-36' },
|
|
1490
|
+
{ key: 'dbname', label: 'In Database', width: 'w-40' },
|
|
1491
|
+
{ key: 'message', label: 'Message', width: 'w-64' },
|
|
1492
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1493
|
+
],
|
|
1494
|
+
cnpgimagecatalogs: [
|
|
1495
|
+
{ key: 'name', label: 'Name' },
|
|
1496
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1497
|
+
{ key: 'majors', label: 'Major Versions', width: 'w-40' },
|
|
1498
|
+
{ key: 'images', label: 'Images', width: 'w-24' },
|
|
1499
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1500
|
+
],
|
|
1501
|
+
cnpgclusterimagecatalogs: [
|
|
1502
|
+
{ key: 'name', label: 'Name' },
|
|
1503
|
+
{ key: 'majors', label: 'Major Versions', width: 'w-40' },
|
|
1504
|
+
{ key: 'images', label: 'Images', width: 'w-24' },
|
|
1505
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1506
|
+
],
|
|
1507
|
+
barmanobjectstores: [
|
|
1508
|
+
{ key: 'name', label: 'Name' },
|
|
1509
|
+
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1510
|
+
{ key: 'status', label: 'Status', width: 'w-40' },
|
|
1511
|
+
// Sized rather than flexible: every sibling table gives its long value a
|
|
1512
|
+
// fixed width, and leaving two columns unsized let Name absorb the row at
|
|
1513
|
+
// 1920px — truncating the destination and pushing Retention off-screen.
|
|
1514
|
+
{ key: 'destination', label: 'Destination', width: 'w-64' },
|
|
1515
|
+
{ key: 'servers', label: 'Servers', width: 'w-32' },
|
|
1516
|
+
{ key: 'retention', label: 'Retention', width: 'w-28' },
|
|
1517
|
+
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1518
|
+
],
|
|
1306
1519
|
cnpgbackups: [
|
|
1307
1520
|
{ key: 'name', label: 'Name' },
|
|
1308
1521
|
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
@@ -1497,7 +1710,10 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
1497
1710
|
{ key: 'address', label: 'Address', width: 'w-56' },
|
|
1498
1711
|
{ key: 'age', label: 'Age', width: 'w-24' },
|
|
1499
1712
|
],
|
|
1500
|
-
|
|
1713
|
+
// Keyed under knative*, reached only through GROUP_QUALIFIED_COLUMN_KEYS, so a
|
|
1714
|
+
// third operator's `subscriptions` gets the generic columns instead of Channel
|
|
1715
|
+
// and Subscriber it can never fill.
|
|
1716
|
+
knativesubscriptions: [
|
|
1501
1717
|
{ key: 'name', label: 'Name' },
|
|
1502
1718
|
{ key: 'namespace', label: 'Namespace', width: 'w-36' },
|
|
1503
1719
|
{ key: 'status', label: 'Status', width: 'w-28' },
|
|
@@ -1867,6 +2083,16 @@ const KNOWN_COLUMNS: Record<string, Column[]> = {
|
|
|
1867
2083
|
|
|
1868
2084
|
// Map (plural, group) → KNOWN_COLUMNS key for kinds that collide with core K8s
|
|
1869
2085
|
const GROUP_QUALIFIED_COLUMN_KEYS: Record<string, Record<string, string>> = {
|
|
2086
|
+
networkpolicy: {
|
|
2087
|
+
'networking.k8s.io': 'networkpolicies',
|
|
2088
|
+
'projectcalico.org': 'caliconetworkpolicies',
|
|
2089
|
+
'crd.projectcalico.org': 'caliconetworkpolicies',
|
|
2090
|
+
},
|
|
2091
|
+
networkpolicies: {
|
|
2092
|
+
'networking.k8s.io': 'networkpolicies',
|
|
2093
|
+
'projectcalico.org': 'caliconetworkpolicies',
|
|
2094
|
+
'crd.projectcalico.org': 'caliconetworkpolicies',
|
|
2095
|
+
},
|
|
1870
2096
|
clusters: { 'postgresql.cnpg.io': 'cnpgclusters', 'cluster.x-k8s.io': 'capiclusters' },
|
|
1871
2097
|
// Velero owns the unqualified `backups` column set; CNPG Backups carry a
|
|
1872
2098
|
// completely different shape (cluster + method, no storage location/expiry).
|
|
@@ -1880,8 +2106,81 @@ const GROUP_QUALIFIED_COLUMN_KEYS: Record<string, Record<string, string>> = {
|
|
|
1880
2106
|
certificates: { 'networking.internal.knative.dev': 'knativecertificates' },
|
|
1881
2107
|
restores: { 'velero.io': 'velerorestores' },
|
|
1882
2108
|
schedules: { 'velero.io': 'veleroschedules' },
|
|
2109
|
+
// CNPG's declarative objects. Knative owns the unqualified `subscriptions`
|
|
2110
|
+
// set, and `databases` / `publications` are shipped by several database
|
|
2111
|
+
// operators — none of which have a CNPG Cluster to point at.
|
|
2112
|
+
databases: { 'postgresql.cnpg.io': 'cnpgdatabases' },
|
|
2113
|
+
publications: { 'postgresql.cnpg.io': 'cnpgpublications' },
|
|
2114
|
+
subscriptions: {
|
|
2115
|
+
'postgresql.cnpg.io': 'cnpgsubscriptions',
|
|
2116
|
+
'messaging.knative.dev': 'knativesubscriptions',
|
|
2117
|
+
},
|
|
2118
|
+
imagecatalogs: { 'postgresql.cnpg.io': 'cnpgimagecatalogs' },
|
|
2119
|
+
clusterimagecatalogs: { 'postgresql.cnpg.io': 'cnpgclusterimagecatalogs' },
|
|
2120
|
+
objectstores: { 'barmancloud.cnpg.io': 'barmanobjectstores' },
|
|
2121
|
+
ippools: {
|
|
2122
|
+
'projectcalico.org': 'calicoippools',
|
|
2123
|
+
'crd.projectcalico.org': 'calicoippools',
|
|
2124
|
+
},
|
|
2125
|
+
hostendpoints: {
|
|
2126
|
+
'projectcalico.org': 'calicohostendpoints',
|
|
2127
|
+
'crd.projectcalico.org': 'calicohostendpoints',
|
|
2128
|
+
},
|
|
2129
|
+
tiers: {
|
|
2130
|
+
'projectcalico.org': 'calicotiers',
|
|
2131
|
+
'crd.projectcalico.org': 'calicotiers',
|
|
2132
|
+
},
|
|
2133
|
+
globalnetworkpolicies: {
|
|
2134
|
+
'projectcalico.org': 'calicoglobalnetworkpolicies',
|
|
2135
|
+
'crd.projectcalico.org': 'calicoglobalnetworkpolicies',
|
|
2136
|
+
},
|
|
2137
|
+
globalnetworkpolicy: {
|
|
2138
|
+
'projectcalico.org': 'calicoglobalnetworkpolicies',
|
|
2139
|
+
'crd.projectcalico.org': 'calicoglobalnetworkpolicies',
|
|
2140
|
+
},
|
|
2141
|
+
stagednetworkpolicies: {
|
|
2142
|
+
'projectcalico.org': 'calicostagednetworkpolicies',
|
|
2143
|
+
'crd.projectcalico.org': 'calicostagednetworkpolicies',
|
|
2144
|
+
},
|
|
2145
|
+
stagednetworkpolicy: {
|
|
2146
|
+
'projectcalico.org': 'calicostagednetworkpolicies',
|
|
2147
|
+
'crd.projectcalico.org': 'calicostagednetworkpolicies',
|
|
2148
|
+
},
|
|
2149
|
+
stagedglobalnetworkpolicies: {
|
|
2150
|
+
'projectcalico.org': 'calicostagedglobalnetworkpolicies',
|
|
2151
|
+
'crd.projectcalico.org': 'calicostagedglobalnetworkpolicies',
|
|
2152
|
+
},
|
|
2153
|
+
stagedglobalnetworkpolicy: {
|
|
2154
|
+
'projectcalico.org': 'calicostagedglobalnetworkpolicies',
|
|
2155
|
+
'crd.projectcalico.org': 'calicostagedglobalnetworkpolicies',
|
|
2156
|
+
},
|
|
2157
|
+
stagedkubernetesnetworkpolicies: {
|
|
2158
|
+
'projectcalico.org': 'calicostagedkubernetesnetworkpolicies',
|
|
2159
|
+
'crd.projectcalico.org': 'calicostagedkubernetesnetworkpolicies',
|
|
2160
|
+
},
|
|
2161
|
+
stagedkubernetesnetworkpolicy: {
|
|
2162
|
+
'projectcalico.org': 'calicostagedkubernetesnetworkpolicies',
|
|
2163
|
+
'crd.projectcalico.org': 'calicostagedkubernetesnetworkpolicies',
|
|
2164
|
+
},
|
|
1883
2165
|
}
|
|
1884
2166
|
|
|
2167
|
+
const GROUP_QUALIFIED_ONLY_COLUMN_KEYS = new Set([
|
|
2168
|
+
'networkpolicy', 'networkpolicies',
|
|
2169
|
+
// Other projects serve their own IPPool CRD, so only a Calico group earns the
|
|
2170
|
+
// Calico columns.
|
|
2171
|
+
'ippool', 'ippools',
|
|
2172
|
+
'globalnetworkpolicy', 'globalnetworkpolicies',
|
|
2173
|
+
'stagednetworkpolicy', 'stagednetworkpolicies',
|
|
2174
|
+
'stagedglobalnetworkpolicy', 'stagedglobalnetworkpolicies',
|
|
2175
|
+
'stagedkubernetesnetworkpolicy', 'stagedkubernetesnetworkpolicies',
|
|
2176
|
+
])
|
|
2177
|
+
const CALICO_ONLY_COLUMN_KEYS = new Set([
|
|
2178
|
+
'globalnetworkpolicy', 'globalnetworkpolicies',
|
|
2179
|
+
'stagednetworkpolicy', 'stagednetworkpolicies',
|
|
2180
|
+
'stagedglobalnetworkpolicy', 'stagedglobalnetworkpolicies',
|
|
2181
|
+
'stagedkubernetesnetworkpolicy', 'stagedkubernetesnetworkpolicies',
|
|
2182
|
+
])
|
|
2183
|
+
|
|
1885
2184
|
// Normalize a kind name to its plural API form used in KNOWN_COLUMNS keys.
|
|
1886
2185
|
// Handles CRD singular names from URLs: 'ScaledObject' → 'scaledobjects', 'NodePool' → 'nodepools'
|
|
1887
2186
|
// When group is provided, resolves collisions (e.g., 'services' + 'serving.knative.dev' → 'knativeservices')
|
|
@@ -1891,6 +2190,8 @@ function normalizeKindToPlural(kind: string, group?: string): string {
|
|
|
1891
2190
|
if (group && GROUP_QUALIFIED_COLUMN_KEYS[lower]?.[group]) {
|
|
1892
2191
|
return GROUP_QUALIFIED_COLUMN_KEYS[lower][group]
|
|
1893
2192
|
}
|
|
2193
|
+
if (group && GROUP_QUALIFIED_ONLY_COLUMN_KEYS.has(lower)) return `__generic_${lower}`
|
|
2194
|
+
if (CALICO_ONLY_COLUMN_KEYS.has(lower)) return `__generic_${lower}`
|
|
1894
2195
|
if (KNOWN_COLUMNS[lower]) return lower
|
|
1895
2196
|
// Try adding 's' but avoid double-s (e.g., "ingress" → "ingresss")
|
|
1896
2197
|
if (!lower.endsWith('s') && KNOWN_COLUMNS[lower + 's']) return lower + 's'
|
|
@@ -4926,6 +5227,11 @@ export function ResourcesView({
|
|
|
4926
5227
|
) : filteredResources.length === 0 ? (
|
|
4927
5228
|
<div className="absolute inset-0 flex flex-col items-center justify-center text-theme-text-tertiary">
|
|
4928
5229
|
<p>No {selectedKind.kind} found</p>
|
|
5230
|
+
{emptyKindNote(selectedKind.kind, selectedKind.group, resources?.length ?? 0) && (
|
|
5231
|
+
<p className="text-xs mt-2 max-w-md text-center text-theme-text-disabled">
|
|
5232
|
+
{emptyKindNote(selectedKind.kind, selectedKind.group, resources?.length ?? 0)}
|
|
5233
|
+
</p>
|
|
5234
|
+
)}
|
|
4929
5235
|
{searchTerm && (
|
|
4930
5236
|
<button
|
|
4931
5237
|
onClick={() => {
|
|
@@ -5690,6 +5996,8 @@ function CellContent({ resource, kind, column, group, majorityNodeMinorVersion,
|
|
|
5690
5996
|
return <PVCCell resource={resource} column={column} />
|
|
5691
5997
|
case 'rollouts':
|
|
5692
5998
|
return <RolloutCell resource={resource} column={column} />
|
|
5999
|
+
case 'analysisruns':
|
|
6000
|
+
return <AnalysisRunCell resource={resource} column={column} />
|
|
5693
6001
|
case 'workflows':
|
|
5694
6002
|
return <WorkflowCell resource={resource} column={column} />
|
|
5695
6003
|
case 'cronworkflows':
|
|
@@ -5729,7 +6037,21 @@ function CellContent({ resource, kind, column, group, majorityNodeMinorVersion,
|
|
|
5729
6037
|
case 'clusterworkflowtemplates':
|
|
5730
6038
|
return <WorkflowTemplateCell resource={resource} column={column} />
|
|
5731
6039
|
case 'networkpolicies':
|
|
6040
|
+
if (!isCoreNetworkPolicyKind(resource.kind ?? kind, resource.apiVersion, group)) {
|
|
6041
|
+
return <GenericCell resource={resource} column={column} />
|
|
6042
|
+
}
|
|
5732
6043
|
return <NetworkPolicyCell resource={resource} column={column} />
|
|
6044
|
+
case 'calicoippools':
|
|
6045
|
+
case 'calicohostendpoints':
|
|
6046
|
+
case 'calicotiers':
|
|
6047
|
+
return <CalicoInfraCell resource={resource} column={column} />
|
|
6048
|
+
case 'caliconetworkpolicies':
|
|
6049
|
+
case 'calicoglobalnetworkpolicies':
|
|
6050
|
+
case 'calicostagednetworkpolicies':
|
|
6051
|
+
case 'calicostagedglobalnetworkpolicies':
|
|
6052
|
+
case 'calicostagedkubernetesnetworkpolicies':
|
|
6053
|
+
if (!isCalicoPolicyResource(resource)) return <GenericCell resource={resource} column={column} />
|
|
6054
|
+
return <CalicoPolicyCell resource={resource} column={column} />
|
|
5733
6055
|
case 'poddisruptionbudgets':
|
|
5734
6056
|
return <PDBCell resource={resource} column={column} />
|
|
5735
6057
|
case 'serviceaccounts':
|
|
@@ -5846,6 +6168,42 @@ function CellContent({ resource, kind, column, group, majorityNodeMinorVersion,
|
|
|
5846
6168
|
case 'clustersecretstores':
|
|
5847
6169
|
return <ClusterSecretStoreCell resource={resource} column={column} />
|
|
5848
6170
|
// Velero
|
|
6171
|
+
// The cnpg* keys come from GROUP_QUALIFIED_COLUMN_KEYS; the unqualified
|
|
6172
|
+
// plurals below are reached when the caller had no group to resolve with,
|
|
6173
|
+
// and stay group-guarded so a foreign CRD is not read as CNPG.
|
|
6174
|
+
case 'updaterequests':
|
|
6175
|
+
return <KyvernoUpdateRequestCell resource={resource} column={column} />
|
|
6176
|
+
case 'ephemeralreports':
|
|
6177
|
+
case 'clusterephemeralreports':
|
|
6178
|
+
return <KyvernoEphemeralReportCell resource={resource} column={column} />
|
|
6179
|
+
case 'cnpgdatabases':
|
|
6180
|
+
case 'cnpgpublications':
|
|
6181
|
+
case 'cnpgsubscriptions':
|
|
6182
|
+
return <CNPGDeclarativeCell resource={resource} column={column} />
|
|
6183
|
+
case 'databases':
|
|
6184
|
+
case 'publications':
|
|
6185
|
+
if (isApiGroup(resource.apiVersion, CNPG_GROUP)) {
|
|
6186
|
+
return <CNPGDeclarativeCell resource={resource} column={column} />
|
|
6187
|
+
}
|
|
6188
|
+
return <GenericCell resource={resource} column={column} />
|
|
6189
|
+
case 'cnpgimagecatalogs':
|
|
6190
|
+
case 'cnpgclusterimagecatalogs':
|
|
6191
|
+
return <CNPGImageCatalogCell resource={resource} column={column} />
|
|
6192
|
+
case 'imagecatalogs':
|
|
6193
|
+
case 'clusterimagecatalogs':
|
|
6194
|
+
if (isApiGroup(resource.apiVersion, CNPG_GROUP)) {
|
|
6195
|
+
return <CNPGImageCatalogCell resource={resource} column={column} />
|
|
6196
|
+
}
|
|
6197
|
+
return <GenericCell resource={resource} column={column} />
|
|
6198
|
+
case 'barmanobjectstores':
|
|
6199
|
+
return <CNPGObjectStoreCell resource={resource} column={column} />
|
|
6200
|
+
case 'objectstores':
|
|
6201
|
+
// Group-guarded: another operator could serve an `objectstores` plural,
|
|
6202
|
+
// and it would have no recovery window to report.
|
|
6203
|
+
if (isApiGroup(resource.apiVersion, 'barmancloud.cnpg.io')) {
|
|
6204
|
+
return <CNPGObjectStoreCell resource={resource} column={column} />
|
|
6205
|
+
}
|
|
6206
|
+
return <GenericCell resource={resource} column={column} />
|
|
5849
6207
|
case 'cnpgbackups':
|
|
5850
6208
|
return <CNPGBackupCell resource={resource} column={column} />
|
|
5851
6209
|
case 'backups':
|
|
@@ -5934,8 +6292,19 @@ function CellContent({ resource, kind, column, group, majorityNodeMinorVersion,
|
|
|
5934
6292
|
return <ChannelCell resource={resource} column={column} />
|
|
5935
6293
|
case 'inmemorychannels':
|
|
5936
6294
|
return <InMemoryChannelCell resource={resource} column={column} />
|
|
5937
|
-
case '
|
|
6295
|
+
case 'knativesubscriptions':
|
|
5938
6296
|
return <SubscriptionCell resource={resource} column={column} />
|
|
6297
|
+
case 'subscriptions':
|
|
6298
|
+
// Shared plural, and not only by two: CNPG declares one, Knative declares
|
|
6299
|
+
// one, and a third operator's would be read as Knative's — Channel and
|
|
6300
|
+
// Subscriber blank on every row — unless both are matched positively.
|
|
6301
|
+
if (isApiGroup(resource.apiVersion, CNPG_GROUP)) {
|
|
6302
|
+
return <CNPGDeclarativeCell resource={resource} column={column} />
|
|
6303
|
+
}
|
|
6304
|
+
if (isApiGroup(resource.apiVersion, 'messaging.knative.dev')) {
|
|
6305
|
+
return <SubscriptionCell resource={resource} column={column} />
|
|
6306
|
+
}
|
|
6307
|
+
return <GenericCell resource={resource} column={column} />
|
|
5939
6308
|
// Knative Flows
|
|
5940
6309
|
case 'sequences':
|
|
5941
6310
|
return <SequenceCell resource={resource} column={column} />
|
|
@@ -7238,6 +7607,44 @@ function RolloutCell({ resource, column }: { resource: any; column: string }) {
|
|
|
7238
7607
|
}
|
|
7239
7608
|
}
|
|
7240
7609
|
|
|
7610
|
+
function AnalysisRunCell({ resource, column }: { resource: any; column: string }) {
|
|
7611
|
+
switch (column) {
|
|
7612
|
+
case 'status': {
|
|
7613
|
+
const status = getAnalysisRunStatus(resource)
|
|
7614
|
+
return <span className={clsx('badge', status.color)}>{status.text}</span>
|
|
7615
|
+
}
|
|
7616
|
+
case 'trigger': {
|
|
7617
|
+
const trigger = resource.metadata?.labels?.['rollout-type']
|
|
7618
|
+
const step = resource.metadata?.labels?.['step-index']
|
|
7619
|
+
if (!trigger) return <span className="text-sm text-theme-text-tertiary">-</span>
|
|
7620
|
+
return (
|
|
7621
|
+
<span className="text-sm text-theme-text-secondary">
|
|
7622
|
+
{trigger}
|
|
7623
|
+
{step ? ` (step ${step})` : ''}
|
|
7624
|
+
</span>
|
|
7625
|
+
)
|
|
7626
|
+
}
|
|
7627
|
+
case 'metrics': {
|
|
7628
|
+
const results: any[] = resource.status?.metricResults || []
|
|
7629
|
+
if (results.length === 0) return <span className="text-sm text-theme-text-tertiary">-</span>
|
|
7630
|
+
const { total, passing, notPassing } = summarizeAnalysisMetrics(resource)
|
|
7631
|
+
return (
|
|
7632
|
+
<Tooltip
|
|
7633
|
+
content={results
|
|
7634
|
+
.map((m) => `${m.name}: ${m.phase || 'Unknown'}${m.dryRun ? ' (dry-run)' : ''}`)
|
|
7635
|
+
.join('\n')}
|
|
7636
|
+
>
|
|
7637
|
+
<span className={clsx('text-sm', notPassing > 0 ? 'text-amber-400' : 'text-theme-text-secondary')}>
|
|
7638
|
+
{notPassing > 0 ? `${notPassing}/${total} not passing` : `${passing}/${total} passing`}
|
|
7639
|
+
</span>
|
|
7640
|
+
</Tooltip>
|
|
7641
|
+
)
|
|
7642
|
+
}
|
|
7643
|
+
default:
|
|
7644
|
+
return <span className="text-sm text-theme-text-tertiary">-</span>
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
|
|
7241
7648
|
function WorkflowCell({ resource, column }: { resource: any; column: string }) {
|
|
7242
7649
|
switch (column) {
|
|
7243
7650
|
case 'status': {
|
|
@@ -3,6 +3,33 @@ export * from './resource-utils-hpa'
|
|
|
3
3
|
export * from './resource-utils-argo'
|
|
4
4
|
export * from './resource-utils-certmanager'
|
|
5
5
|
export * from './resource-utils-cnpg'
|
|
6
|
+
export {
|
|
7
|
+
CALICO_GROUPS,
|
|
8
|
+
type CalicoApiGroup,
|
|
9
|
+
isCalicoApiGroup,
|
|
10
|
+
isCalicoApiVersion,
|
|
11
|
+
isCalicoPolicyKind,
|
|
12
|
+
isCalicoNetworkPolicyKind,
|
|
13
|
+
isCalicoStagedKubernetesNetworkPolicyKind,
|
|
14
|
+
formatKubernetesLabelSelector,
|
|
15
|
+
isCalicoPolicyResource,
|
|
16
|
+
isCoreNetworkPolicyApiVersion,
|
|
17
|
+
isCoreNetworkPolicyResource,
|
|
18
|
+
isCoreNetworkPolicyKind,
|
|
19
|
+
getCalicoPolicyKindLabel,
|
|
20
|
+
getCalicoPolicyTypes,
|
|
21
|
+
getCalicoPolicyRuleCount,
|
|
22
|
+
getCalicoPolicySelector,
|
|
23
|
+
getCalicoIPPoolAllowedUses,
|
|
24
|
+
getCalicoIPPoolBlockSize,
|
|
25
|
+
getCalicoIPPoolEncapsulation,
|
|
26
|
+
getCalicoStagedAction,
|
|
27
|
+
isCalicoStagedDeletion,
|
|
28
|
+
isCalicoStagedIgnored,
|
|
29
|
+
CALICO_SELECTOR_NOT_APPLICABLE,
|
|
30
|
+
getCalicoPolicyNamespaceSelector,
|
|
31
|
+
getCalicoPolicyServiceAccountSelector,
|
|
32
|
+
} from './resource-utils-calico'
|
|
6
33
|
export * from './resource-utils-crossplane'
|
|
7
34
|
export * from './resource-utils-eso'
|
|
8
35
|
export * from './resource-utils-flux'
|