From 44a6ff2fccb68fe5bfcce7cb006f409e1ff99a59 Mon Sep 17 00:00:00 2001 From: rcourtman Date: Thu, 19 Mar 2026 20:13:29 +0000 Subject: [PATCH] Move Kubernetes cluster name helper into agent resources --- .../subsystems/performance-and-scalability.md | 6 ++-- .../internal/subsystems/unified-resources.md | 4 +++ .../utils/__tests__/agentResources.test.ts | 26 +++++++++++++++ frontend-modern/src/utils/agentResources.ts | 5 +++ frontend-modern/src/utils/resourceIdentity.ts | 33 ++----------------- 5 files changed, 40 insertions(+), 34 deletions(-) diff --git a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md index c6446f683..d172cb9b5 100644 --- a/docs/release-control/v6/internal/subsystems/performance-and-scalability.md +++ b/docs/release-control/v6/internal/subsystems/performance-and-scalability.md @@ -140,9 +140,9 @@ also routes its Kubernetes-cluster fallback through the same preferred resource display contract, so navigation context does not leak raw `displayName` values for governed clusters. That same workloads-link path and the dashboard workload projection now also -share the canonical Kubernetes context prefix helper in the shared -agent-resource layer, so route labels and pod grouping keep using the same -cluster-context source of truth instead of rebuilding the +share the canonical Kubernetes cluster helpers in the shared agent-resource +layer, so route labels, pod grouping, and cluster-name fetch keys keep using +the same cluster-context source of truth instead of rebuilding the `clusterName`/`context`/`clusterId` prefix locally. The drawer's Kubernetes namespace/deployment tabs use the canonical cluster-name helper for fetch keys, so the visible navigation label stays diff --git a/docs/release-control/v6/internal/subsystems/unified-resources.md b/docs/release-control/v6/internal/subsystems/unified-resources.md index 9cc5c6fce..f6dff45bc 100644 --- a/docs/release-control/v6/internal/subsystems/unified-resources.md +++ b/docs/release-control/v6/internal/subsystems/unified-resources.md @@ -172,6 +172,10 @@ The same surfaces now also render recent changes through the shared `frontend-modern/src/components/Infrastructure/ResourceChangeSummary.tsx` card, so canonical timeline wording and ordering stay governed by one frontend feed instead of separate page-local loops. +The same shared agent-resource module now also owns the canonical Kubernetes +cluster helpers, so cluster-name labels and Kubernetes context prefixes stay +aligned instead of each surface rebuilding its own pod and namespace routing +fallbacks. The canonical unified-resource change and relationship presenters now also share the same elapsed-time and "ago" wording utilities, so `observed`, `last seen`, and `ago` fragments stay consistent without each formatter diff --git a/frontend-modern/src/utils/__tests__/agentResources.test.ts b/frontend-modern/src/utils/__tests__/agentResources.test.ts index 319e9afec..a8b98cef6 100644 --- a/frontend-modern/src/utils/__tests__/agentResources.test.ts +++ b/frontend-modern/src/utils/__tests__/agentResources.test.ts @@ -6,6 +6,7 @@ import { getActionableKubernetesClusterIdFromResource, getExplicitAgentIdFromResource, getMetricsChartKeyCandidatesFromResource, + getPreferredResourceClusterName, hasDockerWorkloadsScope, hasAgentFacet, isAgentFacetInfrastructureResource, @@ -146,6 +147,31 @@ describe('agentResources', () => { ).toBe('cluster-a'); }); + it('resolves preferred kubernetes cluster names from the shared helper', () => { + expect( + getPreferredResourceClusterName( + makeResource({ + type: 'k8s-cluster', + kubernetes: { + clusterName: 'cluster-a', + context: 'cluster-context', + clusterId: 'cluster-a-id', + }, + name: 'fallback-name', + }), + ), + ).toBe('cluster-a'); + + expect( + getPreferredResourceClusterName( + makeResource({ + type: 'k8s-cluster', + name: 'cluster-by-name', + }), + ), + ).toBe('cluster-by-name'); + }); + it('detects docker workloads scope from explicit docker facets instead of source lists', () => { expect( hasDockerWorkloadsScope( diff --git a/frontend-modern/src/utils/agentResources.ts b/frontend-modern/src/utils/agentResources.ts index 90384d6ce..f312f74bf 100644 --- a/frontend-modern/src/utils/agentResources.ts +++ b/frontend-modern/src/utils/agentResources.ts @@ -121,6 +121,11 @@ export const getPreferredResourceKubernetesContext = ( ); }; +export const getPreferredResourceClusterName = ( + resource: KubernetesContextLike, +): string | undefined => + getPreferredResourceKubernetesContext(resource) || asTrimmedString(resource.name); + export const getMetricsChartKeyCandidatesFromResource = (resource: Resource): string[] => { const candidates = [ asTrimmedString(resource.metricsTarget?.resourceId), diff --git a/frontend-modern/src/utils/resourceIdentity.ts b/frontend-modern/src/utils/resourceIdentity.ts index 4846d629b..c7ec8336b 100644 --- a/frontend-modern/src/utils/resourceIdentity.ts +++ b/frontend-modern/src/utils/resourceIdentity.ts @@ -10,6 +10,7 @@ import { getActionableAgentIdFromResource, getActionableDockerRuntimeIdFromResource, getActionableKubernetesClusterIdFromResource, + getPreferredResourceClusterName, getPreferredResourceKubernetesContext, getPlatformAgentRecord, getPlatformDataRecord, @@ -21,23 +22,6 @@ export type ResourceIdentityRow = { value: string; }; -type ResourceClusterNameLike = { - name?: string | null; - clusterId?: string | null; - platformData?: { - kubernetes?: { - clusterName?: string | null; - context?: string | null; - clusterId?: string | null; - } | null; - } | null; - kubernetes?: { - clusterName?: string | null; - context?: string | null; - clusterId?: string | null; - } | null; -}; - type APINormalizedIdentityResource = { id: string; name?: string; @@ -320,20 +304,7 @@ export const getPreferredResourceHostname = (resource: Resource): string | undef }; export { getPreferredResourceKubernetesContext }; - -export const getPreferredResourceClusterName = ( - resource: ResourceClusterNameLike, -): string | undefined => - (() => { - const kubernetes = resource.kubernetes || resource.platformData?.kubernetes; - return ( - asTrimmedString(kubernetes?.clusterName) || - asTrimmedString(kubernetes?.context) || - asTrimmedString(kubernetes?.clusterId) || - asTrimmedString(resource.clusterId) || - asTrimmedString(resource.name) - ); - })(); +export { getPreferredResourceClusterName }; export const getPreferredResourceDisplayName = (resource: Resource): string => requiresGovernedResourceDisplay(resource.policy)