From ed4d16dd870019afc355158f551e5ac8637d9e99 Mon Sep 17 00:00:00 2001 From: cyril-ui-developer Date: Fri, 5 Dec 2025 12:24:19 -0500 Subject: [PATCH] There should be no role ARN field as token-auth-aws/azure/gcp=false in csv annotations --- .../src/components/operator-hub/index.ts | 2 + .../operator-hub/operator-hub-items.tsx | 25 ++++++---- .../src/hooks/useOperatorCatalogItems.tsx | 47 ++++++++++++------- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/index.ts b/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/index.ts index d72b718390e..753f5dba7c0 100644 --- a/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/index.ts +++ b/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/index.ts @@ -40,6 +40,8 @@ export enum ValidSubscriptionValue { RequiresSeparateSubscription = 'Requires separate subscription', } +export type TokenizedAuthProvider = 'AWS' | 'Azure' | 'GCP'; + export type OperatorHubItem = { authentication: AuthenticationKind; catalogSource: string; diff --git a/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/operator-hub-items.tsx b/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/operator-hub-items.tsx index 1757d268fe9..342ed2686cf 100644 --- a/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/operator-hub-items.tsx +++ b/frontend/packages/operator-lifecycle-manager/src/components/operator-hub/operator-hub-items.tsx @@ -41,7 +41,7 @@ import { sourceSort, validSubscriptionSort, } from './operator-hub-utils'; -import { InfrastructureFeature, OperatorHubItem } from './index'; +import { InfrastructureFeature, OperatorHubItem, TokenizedAuthProvider } from './index'; // Scoring and priority code no longer used and will be removed with Operator Hub catalog files cleanup effort const SCORE = { @@ -578,7 +578,9 @@ export const OperatorHubTileView: React.FC = (props) = >(userSettingsKey, storeKey, false); const [updateChannel, setUpdateChannel] = React.useState(''); const [updateVersion, setUpdateVersion] = React.useState(''); - const [tokenizedAuth, setTokenizedAuth] = React.useState(null); + const [tokenizedAuth, setTokenizedAuth] = React.useState( + undefined, + ); const installVersion = getQueryArgument('version'); const filteredItems = filterByArchAndOS(props.items); @@ -769,7 +771,7 @@ export const OperatorHubTileView: React.FC = (props) = // reset version and channel state so that switching between operator cards does not carry over previous selections setUpdateChannel(''); setUpdateVersion(''); - setTokenizedAuth(''); + setTokenizedAuth(undefined); }; const openOverlay = (item: OperatorHubItem) => { @@ -790,21 +792,24 @@ export const OperatorHubTileView: React.FC = (props) = ); - const installParamsURL = - detailsItem && - detailsItem.obj && - new URLSearchParams({ + let installParamsURL = ''; + if (detailsItem && detailsItem.obj) { + const installParams: Record = { pkg: detailsItem.obj.metadata.name, catalog: detailsItem.catalogSource, catalogNamespace: detailsItem.catalogSourceNamespace, targetNamespace: props.namespace, channel: updateChannel, version: updateVersion, - tokenizedAuth, - }).toString(); + }; + if (tokenizedAuth) { + installParams.tokenizedAuth = tokenizedAuth; + } + installParamsURL = new URLSearchParams(installParams).toString(); + } const installLink = - detailsItem && detailsItem.obj && `/operatorhub/subscribe?${installParamsURL.toString()}`; + detailsItem && detailsItem.obj && `/operatorhub/subscribe?${installParamsURL}`; const uninstallLink = () => detailsItem && diff --git a/frontend/packages/operator-lifecycle-manager/src/hooks/useOperatorCatalogItems.tsx b/frontend/packages/operator-lifecycle-manager/src/hooks/useOperatorCatalogItems.tsx index 8f103e40512..668168f88a8 100644 --- a/frontend/packages/operator-lifecycle-manager/src/hooks/useOperatorCatalogItems.tsx +++ b/frontend/packages/operator-lifecycle-manager/src/hooks/useOperatorCatalogItems.tsx @@ -13,7 +13,13 @@ import { Timestamp } from '@console/shared/src/components/datetime/Timestamp'; import { ExternalLink } from '@console/shared/src/components/links/ExternalLink'; import { iconFor } from '../components'; import { subscriptionFor } from '../components/operator-group'; -import { InstalledState, OLMAnnotation, CSVAnnotations } from '../components/operator-hub/index'; +import { + InstalledState, + OLMAnnotation, + CSVAnnotations, + InfrastructureFeature, + TokenizedAuthProvider, +} from '../components/operator-hub/index'; import { OperatorVersionSelect, OperatorChannelSelect, @@ -90,7 +96,6 @@ export const useOperatorCatalogItems = () => { const [updateChannel, setUpdateChannel] = React.useState(''); const [updateVersion, setUpdateVersion] = React.useState(''); - const [tokenizedAuth, setTokenizedAuth] = React.useState(null); const loaded = React.useMemo( () => @@ -138,16 +143,6 @@ export const useOperatorCatalogItems = () => { const clusterIsAzureWIF = isAzureWIFCluster(cloudCredentials, infrastructure, authentication); const clusterIsGCPWIF = isGCPWIFCluster(cloudCredentials, infrastructure, authentication); - React.useEffect(() => { - if (clusterIsAWSSTS) { - setTokenizedAuth('AWS'); - } else if (clusterIsAzureWIF) { - setTokenizedAuth('Azure'); - } else if (clusterIsGCPWIF) { - setTokenizedAuth('GCP'); - } - }, [clusterIsAWSSTS, clusterIsAzureWIF, clusterIsGCPWIF]); - const items = React.useMemo(() => { if (!loaded || loadError) { return []; @@ -219,14 +214,35 @@ export const useOperatorCatalogItems = () => { const imgUrl = iconFor(pkg); const type = 'operator'; + // Compute tokenizedAuth per operator based on its infrastructureFeatures + // Only set tokenizedAuth if both the cluster supports it AND the operator supports it + // (i.e., the operator's CSV annotations don't have token-auth-aws/azure/gcp=false) + let operatorTokenizedAuth: TokenizedAuthProvider | undefined; + if (clusterIsAWSSTS && infrastructureFeatures.includes(InfrastructureFeature.TokenAuth)) { + operatorTokenizedAuth = 'AWS'; + } else if ( + clusterIsAzureWIF && + infrastructureFeatures.includes(InfrastructureFeature.TokenAuth) + ) { + operatorTokenizedAuth = 'Azure'; + } else if ( + clusterIsGCPWIF && + infrastructureFeatures.includes(InfrastructureFeature.TokenAuthGCP) + ) { + operatorTokenizedAuth = 'GCP'; + } + // Build install parameters URL - const installParamsURL = new URLSearchParams({ + const installParams: Record = { pkg: pkg.metadata.name, catalog: catalogSource, catalogNamespace: catalogSourceNamespace, targetNamespace: namespace, - tokenizedAuth, - }).toString(); + }; + if (operatorTokenizedAuth) { + installParams.tokenizedAuth = operatorTokenizedAuth; + } + const installParamsURL = new URLSearchParams(installParams).toString(); const installLink = `/operatorhub/subscribe?${installParamsURL}`; const uninstallLink = subscription @@ -453,7 +469,6 @@ export const useOperatorCatalogItems = () => { t, updateChannel, updateVersion, - tokenizedAuth, ]); return [items, loaded];