@skyhook-io/k8s-ui 1.0.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 +63 -0
- package/src/components/dock/BottomDock.tsx +204 -0
- package/src/components/dock/DockContext.tsx +212 -0
- package/src/components/dock/TerminalTab.tsx +333 -0
- package/src/components/dock/index.ts +3 -0
- package/src/components/gitops/GitOpsActions.tsx +227 -0
- package/src/components/gitops/GitOpsStatusBadge.tsx +221 -0
- package/src/components/gitops/ManagedResourcesList.tsx +210 -0
- package/src/components/gitops/SyncCountdown.tsx +146 -0
- package/src/components/gitops/index.ts +4 -0
- package/src/components/logs/JsonLogLine.tsx +90 -0
- package/src/components/logs/LogCore.tsx +553 -0
- package/src/components/logs/LogToolbarSelects.tsx +74 -0
- package/src/components/logs/LogsViewer.tsx +146 -0
- package/src/components/logs/WorkloadLogsViewer.tsx +263 -0
- package/src/components/logs/index.ts +13 -0
- package/src/components/logs/useLogBuffer.ts +138 -0
- package/src/components/logs/useLogSearch.ts +151 -0
- package/src/components/logs/useLogStream.ts +61 -0
- package/src/components/resources/ResourcesView.tsx +5494 -0
- package/src/components/resources/index.ts +17 -0
- package/src/components/resources/renderers/AlertRenderer.tsx +166 -0
- package/src/components/resources/renderers/ArgoApplicationRenderer.tsx +233 -0
- package/src/components/resources/renderers/CNPGBackupRenderer.tsx +89 -0
- package/src/components/resources/renderers/CNPGClusterRenderer.tsx +194 -0
- package/src/components/resources/renderers/CNPGPoolerRenderer.tsx +79 -0
- package/src/components/resources/renderers/CNPGScheduledBackupRenderer.tsx +68 -0
- package/src/components/resources/renderers/CertificateRenderer.tsx +209 -0
- package/src/components/resources/renderers/CertificateRequestRenderer.tsx +123 -0
- package/src/components/resources/renderers/ChallengeRenderer.tsx +111 -0
- package/src/components/resources/renderers/ClusterComplianceReportRenderer.tsx +164 -0
- package/src/components/resources/renderers/ClusterExternalSecretRenderer.tsx +140 -0
- package/src/components/resources/renderers/ClusterIssuerRenderer.tsx +153 -0
- package/src/components/resources/renderers/ConfigAuditReportRenderer.tsx +221 -0
- package/src/components/resources/renderers/ConfigMapRenderer.tsx +124 -0
- package/src/components/resources/renderers/CronJobRenderer.tsx +86 -0
- package/src/components/resources/renderers/EventRenderer.tsx +175 -0
- package/src/components/resources/renderers/ExposedSecretReportRenderer.tsx +119 -0
- package/src/components/resources/renderers/ExternalSecretRenderer.tsx +172 -0
- package/src/components/resources/renderers/FluxHelmReleaseRenderer.tsx +242 -0
- package/src/components/resources/renderers/GRPCRouteRenderer.tsx +263 -0
- package/src/components/resources/renderers/GatewayClassRenderer.tsx +68 -0
- package/src/components/resources/renderers/GatewayRenderer.tsx +218 -0
- package/src/components/resources/renderers/GenericRenderer.tsx +476 -0
- package/src/components/resources/renderers/GitRepositoryRenderer.tsx +154 -0
- package/src/components/resources/renderers/HPARenderer.tsx +164 -0
- package/src/components/resources/renderers/HTTPRouteRenderer.tsx +303 -0
- package/src/components/resources/renderers/HelmRepositoryRenderer.tsx +167 -0
- package/src/components/resources/renderers/IngressClassRenderer.tsx +49 -0
- package/src/components/resources/renderers/IngressRenderer.tsx +104 -0
- package/src/components/resources/renderers/IstioAuthorizationPolicyRenderer.tsx +175 -0
- package/src/components/resources/renderers/IstioDestinationRuleRenderer.tsx +176 -0
- package/src/components/resources/renderers/IstioGatewayRenderer.tsx +125 -0
- package/src/components/resources/renderers/IstioPeerAuthenticationRenderer.tsx +84 -0
- package/src/components/resources/renderers/IstioServiceEntryRenderer.tsx +112 -0
- package/src/components/resources/renderers/IstioVirtualServiceRenderer.tsx +288 -0
- package/src/components/resources/renderers/JobRenderer.tsx +103 -0
- package/src/components/resources/renderers/KarpenterEC2NodeClassRenderer.tsx +157 -0
- package/src/components/resources/renderers/KarpenterNodeClaimRenderer.tsx +188 -0
- package/src/components/resources/renderers/KarpenterNodePoolRenderer.tsx +148 -0
- package/src/components/resources/renderers/KedaScaledJobRenderer.tsx +90 -0
- package/src/components/resources/renderers/KedaScaledObjectRenderer.tsx +136 -0
- package/src/components/resources/renderers/KedaTriggerAuthRenderer.tsx +151 -0
- package/src/components/resources/renderers/KnativeConfigurationRenderer.tsx +70 -0
- package/src/components/resources/renderers/KnativeEventingRenderer.tsx +309 -0
- package/src/components/resources/renderers/KnativeFlowRenderer.tsx +142 -0
- package/src/components/resources/renderers/KnativeNetworkingRenderer.tsx +232 -0
- package/src/components/resources/renderers/KnativeRevisionRenderer.tsx +97 -0
- package/src/components/resources/renderers/KnativeRouteRenderer.tsx +74 -0
- package/src/components/resources/renderers/KnativeServiceRenderer.tsx +138 -0
- package/src/components/resources/renderers/KnativeSourceRenderer.tsx +220 -0
- package/src/components/resources/renderers/KustomizationRenderer.tsx +151 -0
- package/src/components/resources/renderers/KyvernoPolicyReportRenderer.tsx +352 -0
- package/src/components/resources/renderers/LeaseRenderer.tsx +93 -0
- package/src/components/resources/renderers/NetworkPolicyRenderer.tsx +208 -0
- package/src/components/resources/renderers/NodeRenderer.tsx +282 -0
- package/src/components/resources/renderers/OCIRepositoryRenderer.tsx +153 -0
- package/src/components/resources/renderers/OrderRenderer.tsx +108 -0
- package/src/components/resources/renderers/PVCRenderer.tsx +98 -0
- package/src/components/resources/renderers/PersistentVolumeRenderer.tsx +138 -0
- package/src/components/resources/renderers/PodDisruptionBudgetRenderer.tsx +126 -0
- package/src/components/resources/renderers/PodMonitorRenderer.tsx +63 -0
- package/src/components/resources/renderers/PodRenderer.tsx +677 -0
- package/src/components/resources/renderers/PriorityClassRenderer.tsx +50 -0
- package/src/components/resources/renderers/PrometheusRuleRenderer.tsx +62 -0
- package/src/components/resources/renderers/ReplicaSetRenderer.tsx +71 -0
- package/src/components/resources/renderers/RoleBindingRenderer.tsx +97 -0
- package/src/components/resources/renderers/RoleRenderer.tsx +192 -0
- package/src/components/resources/renderers/RolloutRenderer.tsx +227 -0
- package/src/components/resources/renderers/RuntimeClassRenderer.tsx +75 -0
- package/src/components/resources/renderers/SbomReportRenderer.tsx +98 -0
- package/src/components/resources/renderers/SealedSecretRenderer.tsx +121 -0
- package/src/components/resources/renderers/SecretRenderer.tsx +321 -0
- package/src/components/resources/renderers/SecretStoreRenderer.tsx +111 -0
- package/src/components/resources/renderers/ServiceAccountRenderer.tsx +81 -0
- package/src/components/resources/renderers/ServiceMonitorRenderer.tsx +65 -0
- package/src/components/resources/renderers/ServiceRenderer.tsx +98 -0
- package/src/components/resources/renderers/SimpleRouteRenderer.tsx +195 -0
- package/src/components/resources/renderers/StorageClassRenderer.tsx +82 -0
- package/src/components/resources/renderers/TraefikIngressRouteRenderer.tsx +257 -0
- package/src/components/resources/renderers/VPARenderer.tsx +193 -0
- package/src/components/resources/renderers/VeleroBSLRenderer.tsx +73 -0
- package/src/components/resources/renderers/VeleroBackupRenderer.tsx +193 -0
- package/src/components/resources/renderers/VeleroRestoreRenderer.tsx +161 -0
- package/src/components/resources/renderers/VeleroScheduleRenderer.tsx +134 -0
- package/src/components/resources/renderers/VeleroVSLRenderer.tsx +36 -0
- package/src/components/resources/renderers/VulnerabilityReportRenderer.tsx +347 -0
- package/src/components/resources/renderers/WebhookConfigRenderer.tsx +156 -0
- package/src/components/resources/renderers/WorkflowRenderer.tsx +202 -0
- package/src/components/resources/renderers/WorkflowTemplateRenderer.tsx +91 -0
- package/src/components/resources/renderers/WorkloadRenderer.tsx +311 -0
- package/src/components/resources/renderers/argo-cells.tsx +118 -0
- package/src/components/resources/renderers/certmanager-cells.tsx +164 -0
- package/src/components/resources/renderers/cnpg-cells.tsx +161 -0
- package/src/components/resources/renderers/eso-cells.tsx +115 -0
- package/src/components/resources/renderers/flux-cells.tsx +253 -0
- package/src/components/resources/renderers/index.ts +105 -0
- package/src/components/resources/renderers/istio-cells.tsx +210 -0
- package/src/components/resources/renderers/karpenter-cells.tsx +107 -0
- package/src/components/resources/renderers/keda-cells.tsx +94 -0
- package/src/components/resources/renderers/knative-cells.tsx +396 -0
- package/src/components/resources/renderers/kyverno-cells.tsx +85 -0
- package/src/components/resources/renderers/prometheus-cells.tsx +74 -0
- package/src/components/resources/renderers/traefik-cells.tsx +120 -0
- package/src/components/resources/renderers/trivy-cells.tsx +153 -0
- package/src/components/resources/renderers/trivy-shared.tsx +67 -0
- package/src/components/resources/renderers/velero-cells.tsx +164 -0
- package/src/components/resources/resource-utils-argo.ts +155 -0
- package/src/components/resources/resource-utils-certmanager.ts +198 -0
- package/src/components/resources/resource-utils-cnpg.ts +344 -0
- package/src/components/resources/resource-utils-eso.ts +385 -0
- package/src/components/resources/resource-utils-flux.ts +186 -0
- package/src/components/resources/resource-utils-istio.ts +372 -0
- package/src/components/resources/resource-utils-karpenter.ts +150 -0
- package/src/components/resources/resource-utils-keda.ts +203 -0
- package/src/components/resources/resource-utils-knative.ts +218 -0
- package/src/components/resources/resource-utils-kyverno.ts +224 -0
- package/src/components/resources/resource-utils-prometheus.ts +159 -0
- package/src/components/resources/resource-utils-traefik.ts +180 -0
- package/src/components/resources/resource-utils-trivy.ts +146 -0
- package/src/components/resources/resource-utils-velero.ts +293 -0
- package/src/components/resources/resource-utils.ts +1558 -0
- package/src/components/shared/EditableYamlView.tsx +302 -0
- package/src/components/shared/ResourceActionsBar.tsx +924 -0
- package/src/components/shared/ResourceRendererDispatch.tsx +557 -0
- package/src/components/shared/index.ts +3 -0
- package/src/components/timeline/index.ts +1 -0
- package/src/components/timeline/shared.tsx +614 -0
- package/src/components/topology/GroupNode.tsx +198 -0
- package/src/components/topology/K8sResourceNode.tsx +440 -0
- package/src/components/topology/TopologyControls.tsx +62 -0
- package/src/components/topology/TopologyFilterSidebar.tsx +377 -0
- package/src/components/topology/TopologyGraph.tsx +748 -0
- package/src/components/topology/TopologySearch.tsx +304 -0
- package/src/components/topology/index.ts +7 -0
- package/src/components/topology/layout.ts +734 -0
- package/src/components/topology/layout.worker.ts +272 -0
- package/src/components/topology/topology.css +129 -0
- package/src/components/ui/CodeViewer.tsx +451 -0
- package/src/components/ui/ConfirmDialog.tsx +188 -0
- package/src/components/ui/ForceDeleteConfirmDialog.tsx +57 -0
- package/src/components/ui/HealthRing.tsx +72 -0
- package/src/components/ui/MetricsChart.tsx +259 -0
- package/src/components/ui/ResourceBar.tsx +68 -0
- package/src/components/ui/Toast.tsx +225 -0
- package/src/components/ui/Tooltip.tsx +165 -0
- package/src/components/ui/YamlEditor.tsx +280 -0
- package/src/components/ui/drawer-components.tsx +792 -0
- package/src/components/ui/index.ts +10 -0
- package/src/components/workload/ResourceDetailDrawer.tsx +158 -0
- package/src/components/workload/WorkloadView.tsx +1109 -0
- package/src/components/workload/index.ts +2 -0
- package/src/hooks/index.ts +9 -0
- package/src/hooks/useAnimatedUnmount.ts +30 -0
- package/src/hooks/useKeyboardShortcuts.tsx +336 -0
- package/src/hooks/useRefreshAnimation.ts +58 -0
- package/src/index.ts +35 -0
- package/src/types/core.ts +894 -0
- package/src/types/gitops.ts +458 -0
- package/src/types/index.ts +2 -0
- package/src/utils/animation.ts +40 -0
- package/src/utils/api-resources.ts +185 -0
- package/src/utils/badge-colors.ts +399 -0
- package/src/utils/context-name.ts +72 -0
- package/src/utils/download.ts +19 -0
- package/src/utils/format.ts +233 -0
- package/src/utils/index.ts +10 -0
- package/src/utils/log-format.ts +300 -0
- package/src/utils/navigation.ts +119 -0
- package/src/utils/resource-hierarchy.ts +630 -0
- package/src/utils/resource-icons.ts +206 -0
- package/src/vite-env.d.ts +1 -0
- package/tsconfig.json +24 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { HardDrive, Link, Database, Server } from 'lucide-react'
|
|
2
|
+
import { clsx } from 'clsx'
|
|
3
|
+
import { Section, PropertyList, Property, ConditionsSection, AlertBanner, ResourceLink } from '../../ui/drawer-components'
|
|
4
|
+
|
|
5
|
+
interface PersistentVolumeRendererProps {
|
|
6
|
+
data: any
|
|
7
|
+
onNavigate?: (ref: { kind: string; namespace: string; name: string }) => void
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
const accessModeShorthand: Record<string, string> = {
|
|
11
|
+
ReadWriteOnce: 'RWO',
|
|
12
|
+
ReadOnlyMany: 'ROX',
|
|
13
|
+
ReadWriteMany: 'RWX',
|
|
14
|
+
ReadWriteOncePod: 'RWOP',
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function formatAccessModes(modes: string[] | undefined): string | undefined {
|
|
18
|
+
if (!modes || modes.length === 0) return undefined
|
|
19
|
+
return modes.map(m => accessModeShorthand[m] || m).join(', ')
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export function PersistentVolumeRenderer({ data, onNavigate }: PersistentVolumeRendererProps) {
|
|
23
|
+
const status = data.status || {}
|
|
24
|
+
const spec = data.spec || {}
|
|
25
|
+
const phase = status.phase
|
|
26
|
+
|
|
27
|
+
const claimRef = spec.claimRef
|
|
28
|
+
const csi = spec.csi
|
|
29
|
+
const nodeAffinity = spec.nodeAffinity
|
|
30
|
+
|
|
31
|
+
// Problem detection
|
|
32
|
+
const isFailed = phase === 'Failed'
|
|
33
|
+
const isReleased = phase === 'Released'
|
|
34
|
+
|
|
35
|
+
return (
|
|
36
|
+
<>
|
|
37
|
+
{/* Problem alerts */}
|
|
38
|
+
{isFailed && (
|
|
39
|
+
<AlertBanner
|
|
40
|
+
variant="error"
|
|
41
|
+
title="Issues Detected"
|
|
42
|
+
message="PV has failed"
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
|
|
46
|
+
{isReleased && (
|
|
47
|
+
<AlertBanner
|
|
48
|
+
variant="warning"
|
|
49
|
+
title="Issues Detected"
|
|
50
|
+
message="PV is released but not yet available or reclaimed"
|
|
51
|
+
/>
|
|
52
|
+
)}
|
|
53
|
+
|
|
54
|
+
{/* Status */}
|
|
55
|
+
<Section title="Status" icon={HardDrive}>
|
|
56
|
+
<PropertyList>
|
|
57
|
+
<Property
|
|
58
|
+
label="Phase"
|
|
59
|
+
value={
|
|
60
|
+
<span className={clsx(
|
|
61
|
+
(phase === 'Bound' || phase === 'Available') && 'text-green-400',
|
|
62
|
+
phase === 'Released' && 'text-yellow-400',
|
|
63
|
+
phase === 'Failed' && 'text-red-400',
|
|
64
|
+
)}>
|
|
65
|
+
{phase}
|
|
66
|
+
</span>
|
|
67
|
+
}
|
|
68
|
+
/>
|
|
69
|
+
<Property label="Capacity" value={spec.capacity?.storage} />
|
|
70
|
+
<Property label="Access Modes" value={formatAccessModes(spec.accessModes)} />
|
|
71
|
+
<Property label="Volume Mode" value={spec.volumeMode} />
|
|
72
|
+
<Property
|
|
73
|
+
label="Reclaim Policy"
|
|
74
|
+
value={
|
|
75
|
+
spec.persistentVolumeReclaimPolicy ? (
|
|
76
|
+
<span className={clsx(
|
|
77
|
+
spec.persistentVolumeReclaimPolicy === 'Delete' && 'text-red-400',
|
|
78
|
+
spec.persistentVolumeReclaimPolicy === 'Retain' && 'text-green-400',
|
|
79
|
+
)}>
|
|
80
|
+
{spec.persistentVolumeReclaimPolicy}
|
|
81
|
+
</span>
|
|
82
|
+
) : undefined
|
|
83
|
+
}
|
|
84
|
+
/>
|
|
85
|
+
<Property label="Storage Class" value={
|
|
86
|
+
spec.storageClassName ? <ResourceLink name={spec.storageClassName} kind="storageclasses" namespace="" onNavigate={onNavigate} /> : undefined
|
|
87
|
+
} />
|
|
88
|
+
</PropertyList>
|
|
89
|
+
</Section>
|
|
90
|
+
|
|
91
|
+
{/* Claim Reference */}
|
|
92
|
+
{claimRef && (
|
|
93
|
+
<Section title="Claim" icon={Link}>
|
|
94
|
+
<PropertyList>
|
|
95
|
+
<Property label="Namespace" value={claimRef.namespace} />
|
|
96
|
+
<Property label="Name" value={
|
|
97
|
+
claimRef.name ? <ResourceLink name={claimRef.name} kind="persistentvolumeclaims" namespace={claimRef.namespace || ''} onNavigate={onNavigate} /> : undefined
|
|
98
|
+
} />
|
|
99
|
+
<Property label="UID" value={claimRef.uid} />
|
|
100
|
+
</PropertyList>
|
|
101
|
+
</Section>
|
|
102
|
+
)}
|
|
103
|
+
|
|
104
|
+
{/* CSI */}
|
|
105
|
+
{csi && (
|
|
106
|
+
<Section title="CSI" icon={Database}>
|
|
107
|
+
<PropertyList>
|
|
108
|
+
<Property label="Driver" value={csi.driver} />
|
|
109
|
+
<Property label="Volume Handle" value={csi.volumeHandle} />
|
|
110
|
+
<Property label="FS Type" value={csi.fsType} />
|
|
111
|
+
</PropertyList>
|
|
112
|
+
</Section>
|
|
113
|
+
)}
|
|
114
|
+
|
|
115
|
+
{/* Node Affinity */}
|
|
116
|
+
{nodeAffinity?.required?.nodeSelectorTerms && nodeAffinity.required.nodeSelectorTerms.length > 0 && (
|
|
117
|
+
<Section title="Node Affinity" icon={Server}>
|
|
118
|
+
<div className="space-y-2">
|
|
119
|
+
{nodeAffinity.required.nodeSelectorTerms.map((term: any, termIdx: number) => (
|
|
120
|
+
<div key={termIdx} className="space-y-1">
|
|
121
|
+
{term.matchExpressions?.map((expr: any, exprIdx: number) => (
|
|
122
|
+
<div key={exprIdx} className="flex flex-wrap gap-1">
|
|
123
|
+
<span className="px-2 py-0.5 bg-theme-elevated rounded text-xs text-theme-text-secondary">
|
|
124
|
+
{expr.key} {expr.operator} {expr.values?.join(', ')}
|
|
125
|
+
</span>
|
|
126
|
+
</div>
|
|
127
|
+
))}
|
|
128
|
+
</div>
|
|
129
|
+
))}
|
|
130
|
+
</div>
|
|
131
|
+
</Section>
|
|
132
|
+
)}
|
|
133
|
+
|
|
134
|
+
{/* Conditions */}
|
|
135
|
+
<ConditionsSection conditions={status.conditions} />
|
|
136
|
+
</>
|
|
137
|
+
)
|
|
138
|
+
}
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
import { Shield, Activity } from 'lucide-react'
|
|
2
|
+
import { clsx } from 'clsx'
|
|
3
|
+
import { Section, PropertyList, Property, ConditionsSection, KeyValueBadgeList, AlertBanner } from '../../ui/drawer-components'
|
|
4
|
+
|
|
5
|
+
interface PodDisruptionBudgetRendererProps {
|
|
6
|
+
data: any
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function PodDisruptionBudgetRenderer({ data }: PodDisruptionBudgetRendererProps) {
|
|
10
|
+
const spec = data.spec || {}
|
|
11
|
+
const status = data.status || {}
|
|
12
|
+
const matchLabels = spec.selector?.matchLabels || {}
|
|
13
|
+
const hasSelector = Object.keys(matchLabels).length > 0
|
|
14
|
+
|
|
15
|
+
// Determine budget type
|
|
16
|
+
const hasMaxUnavailable = spec.maxUnavailable !== undefined && spec.maxUnavailable !== null
|
|
17
|
+
const hasMinAvailable = spec.minAvailable !== undefined && spec.minAvailable !== null
|
|
18
|
+
const budgetType = hasMaxUnavailable ? 'Max Unavailable' : hasMinAvailable ? 'Min Available' : undefined
|
|
19
|
+
const budgetValue = hasMaxUnavailable ? spec.maxUnavailable : hasMinAvailable ? spec.minAvailable : undefined
|
|
20
|
+
|
|
21
|
+
// Problem detection
|
|
22
|
+
const disruptionsAllowed = status.disruptionsAllowed
|
|
23
|
+
const expectedPods = status.expectedPods
|
|
24
|
+
const currentHealthy = status.currentHealthy
|
|
25
|
+
const desiredHealthy = status.desiredHealthy
|
|
26
|
+
|
|
27
|
+
const noDisruptionsAllowed = disruptionsAllowed === 0 && expectedPods > 0
|
|
28
|
+
const insufficientHealthy = currentHealthy !== undefined && desiredHealthy !== undefined && currentHealthy < desiredHealthy
|
|
29
|
+
|
|
30
|
+
return (
|
|
31
|
+
<>
|
|
32
|
+
{/* Problem alerts */}
|
|
33
|
+
{insufficientHealthy && (
|
|
34
|
+
<AlertBanner
|
|
35
|
+
variant="error"
|
|
36
|
+
title="Issues Detected"
|
|
37
|
+
message={`Insufficient healthy pods (${currentHealthy} healthy, ${desiredHealthy} desired)`}
|
|
38
|
+
/>
|
|
39
|
+
)}
|
|
40
|
+
|
|
41
|
+
{noDisruptionsAllowed && !insufficientHealthy && (
|
|
42
|
+
<AlertBanner
|
|
43
|
+
variant="warning"
|
|
44
|
+
title="Issues Detected"
|
|
45
|
+
message="No disruptions currently allowed"
|
|
46
|
+
/>
|
|
47
|
+
)}
|
|
48
|
+
|
|
49
|
+
<Section title="Budget" icon={Shield}>
|
|
50
|
+
<PropertyList>
|
|
51
|
+
<Property label="Budget Type" value={budgetType} />
|
|
52
|
+
<Property label="Budget Value" value={budgetValue !== undefined ? String(budgetValue) : undefined} />
|
|
53
|
+
<Property
|
|
54
|
+
label="Disruptions"
|
|
55
|
+
value={
|
|
56
|
+
disruptionsAllowed !== undefined ? (
|
|
57
|
+
<span className={clsx(
|
|
58
|
+
disruptionsAllowed > 0 ? 'text-green-400' : 'text-red-400'
|
|
59
|
+
)}>
|
|
60
|
+
{disruptionsAllowed} allowed
|
|
61
|
+
</span>
|
|
62
|
+
) : undefined
|
|
63
|
+
}
|
|
64
|
+
/>
|
|
65
|
+
<Property label="Eviction Policy" value={spec.unhealthyPodEvictionPolicy} />
|
|
66
|
+
</PropertyList>
|
|
67
|
+
</Section>
|
|
68
|
+
|
|
69
|
+
<Section title="Pod Status" icon={Activity}>
|
|
70
|
+
<PropertyList>
|
|
71
|
+
<Property
|
|
72
|
+
label="Current Healthy"
|
|
73
|
+
value={
|
|
74
|
+
currentHealthy !== undefined ? (
|
|
75
|
+
<span className={clsx(
|
|
76
|
+
desiredHealthy !== undefined && currentHealthy >= desiredHealthy
|
|
77
|
+
? 'text-green-400'
|
|
78
|
+
: 'text-red-400'
|
|
79
|
+
)}>
|
|
80
|
+
{currentHealthy}
|
|
81
|
+
</span>
|
|
82
|
+
) : undefined
|
|
83
|
+
}
|
|
84
|
+
/>
|
|
85
|
+
<Property label="Desired Healthy" value={desiredHealthy} />
|
|
86
|
+
<Property label="Expected Pods" value={expectedPods} />
|
|
87
|
+
</PropertyList>
|
|
88
|
+
{currentHealthy !== undefined && expectedPods !== undefined && expectedPods > 0 && (
|
|
89
|
+
<div className="mt-3 bg-theme-elevated/30 rounded p-2 text-sm">
|
|
90
|
+
<div className="flex items-center justify-between">
|
|
91
|
+
<span className="text-theme-text-secondary">Health</span>
|
|
92
|
+
<span className={clsx(
|
|
93
|
+
desiredHealthy !== undefined && currentHealthy >= desiredHealthy
|
|
94
|
+
? 'text-green-400'
|
|
95
|
+
: 'text-red-400'
|
|
96
|
+
)}>
|
|
97
|
+
{currentHealthy}/{expectedPods} healthy
|
|
98
|
+
</span>
|
|
99
|
+
</div>
|
|
100
|
+
<div className="mt-2 h-2 bg-theme-hover rounded overflow-hidden">
|
|
101
|
+
<div
|
|
102
|
+
className={clsx(
|
|
103
|
+
'h-full transition-all',
|
|
104
|
+
desiredHealthy !== undefined && currentHealthy >= desiredHealthy
|
|
105
|
+
? 'bg-green-500'
|
|
106
|
+
: 'bg-red-500'
|
|
107
|
+
)}
|
|
108
|
+
style={{ width: `${Math.min(100, (currentHealthy / expectedPods) * 100)}%` }}
|
|
109
|
+
/>
|
|
110
|
+
</div>
|
|
111
|
+
</div>
|
|
112
|
+
)}
|
|
113
|
+
</Section>
|
|
114
|
+
|
|
115
|
+
<Section title="Selector">
|
|
116
|
+
{hasSelector ? (
|
|
117
|
+
<KeyValueBadgeList items={matchLabels} />
|
|
118
|
+
) : (
|
|
119
|
+
<div className="text-sm text-theme-text-tertiary">All pods in namespace</div>
|
|
120
|
+
)}
|
|
121
|
+
</Section>
|
|
122
|
+
|
|
123
|
+
<ConditionsSection conditions={status.conditions} />
|
|
124
|
+
</>
|
|
125
|
+
)
|
|
126
|
+
}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
import { Radio } from 'lucide-react'
|
|
2
|
+
import { Section, PropertyList, Property, ConditionsSection, KeyValueBadgeList } from '../../ui/drawer-components'
|
|
3
|
+
import {
|
|
4
|
+
getPodMonitorEndpoints,
|
|
5
|
+
getPodMonitorNamespaceSelector,
|
|
6
|
+
} from '../resource-utils-prometheus'
|
|
7
|
+
|
|
8
|
+
interface PodMonitorRendererProps {
|
|
9
|
+
data: any
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export function PodMonitorRenderer({ data }: PodMonitorRendererProps) {
|
|
13
|
+
const endpoints = getPodMonitorEndpoints(data)
|
|
14
|
+
const selector = data.spec?.selector?.matchLabels
|
|
15
|
+
const conditions = data.status?.conditions
|
|
16
|
+
|
|
17
|
+
return (
|
|
18
|
+
<>
|
|
19
|
+
<Section title="PodMonitor" icon={Radio}>
|
|
20
|
+
<PropertyList>
|
|
21
|
+
<Property label="Endpoints" value={String(endpoints.length)} />
|
|
22
|
+
<Property label="Namespace Scope" value={getPodMonitorNamespaceSelector(data)} />
|
|
23
|
+
<Property label="Sample Limit" value={data.spec?.sampleLimit ? String(data.spec.sampleLimit) : undefined} />
|
|
24
|
+
</PropertyList>
|
|
25
|
+
</Section>
|
|
26
|
+
|
|
27
|
+
{endpoints.length > 0 && (
|
|
28
|
+
<Section title={`Pod Metrics Endpoints (${endpoints.length})`} defaultExpanded>
|
|
29
|
+
<div className="space-y-2">
|
|
30
|
+
{endpoints.map((ep, i) => (
|
|
31
|
+
<div key={i} className="bg-theme-elevated/30 rounded p-2 text-sm">
|
|
32
|
+
<div className="flex items-center gap-2 flex-wrap">
|
|
33
|
+
{ep.port && (
|
|
34
|
+
<span className="text-theme-text-primary font-medium">{ep.port}</span>
|
|
35
|
+
)}
|
|
36
|
+
<span className="text-theme-text-secondary">{ep.path}</span>
|
|
37
|
+
{ep.interval && (
|
|
38
|
+
<span className="px-1.5 py-0.5 bg-theme-hover rounded text-xs text-theme-text-secondary">
|
|
39
|
+
every {ep.interval}
|
|
40
|
+
</span>
|
|
41
|
+
)}
|
|
42
|
+
{ep.scheme && ep.scheme !== 'http' && (
|
|
43
|
+
<span className="px-1.5 py-0.5 bg-theme-hover rounded text-xs text-theme-text-secondary">
|
|
44
|
+
{ep.scheme}
|
|
45
|
+
</span>
|
|
46
|
+
)}
|
|
47
|
+
</div>
|
|
48
|
+
</div>
|
|
49
|
+
))}
|
|
50
|
+
</div>
|
|
51
|
+
</Section>
|
|
52
|
+
)}
|
|
53
|
+
|
|
54
|
+
{selector && Object.keys(selector).length > 0 && (
|
|
55
|
+
<Section title="Selector">
|
|
56
|
+
<KeyValueBadgeList items={selector} />
|
|
57
|
+
</Section>
|
|
58
|
+
)}
|
|
59
|
+
|
|
60
|
+
<ConditionsSection conditions={conditions} />
|
|
61
|
+
</>
|
|
62
|
+
)
|
|
63
|
+
}
|