0}>
- {getFailedOperatorsNames(
- failedOperators,
- cluster.openshiftVersion,
- featureSupportLevel,
- t,
- )}{' '}
+ {failedOperators.map(({ name }) => opSpecs[name || '']?.title || name).join(' and ')}{' '}
failed to install. Due to this, the cluster will be degraded, but you can try to install
the operator from the Operator Hub. Please check the installation log for more
information.
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx b/libs/ui-lib/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx
index 5aaace5f11..67ca2c5e0c 100644
--- a/libs/ui-lib/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/ClusterWizardContextProvider.tsx
@@ -114,7 +114,6 @@ const ClusterWizardContextProvider = ({
staticIpInfo,
cluster?.status,
cluster?.hosts,
- isSingleClusterFeatureEnabled,
customManifestsStepNeedsToBeFilled,
);
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx b/libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx
index 7c579a4c65..d618d53fe1 100644
--- a/libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/Operators.tsx
@@ -2,33 +2,13 @@ import React from 'react';
import { useDispatch } from 'react-redux';
import { useLocation, useNavigate } from 'react-router-dom-v5-compat';
import { Formik, FormikConfig, useFormikContext } from 'formik';
+import { Cluster } from '@openshift-assisted/types/assisted-installer-service';
import {
ClusterWizardStep,
getFormikErrorFields,
- OPERATOR_NAME_AMD_GPU,
- OPERATOR_NAME_AUTHORINO,
- OPERATOR_NAME_CNV,
- OPERATOR_NAME_KMM,
- OPERATOR_NAME_LSO,
- OPERATOR_NAME_LVM,
- OPERATOR_NAME_MCE,
- OPERATOR_NAME_MTV,
- OPERATOR_NAME_NMSTATE,
- OPERATOR_NAME_NODE_FEATURE_DISCOVERY,
- OPERATOR_NAME_NVIDIA_GPU,
- OPERATOR_NAME_ODF,
- OPERATOR_NAME_OPENSHIFT_AI,
- OPERATOR_NAME_OSC,
- OPERATOR_NAME_PIPELINES,
- OPERATOR_NAME_SERVERLESS,
- OPERATOR_NAME_SERVICEMESH,
- OPERATOR_NAME_NODE_HEALTHCHECK,
- OPERATOR_NAME_SELF_NODE_REMEDIATION,
- OPERATOR_NAME_FENCE_AGENTS_REMEDIATION,
- OPERATOR_NAME_NODE_MAINTENANCE,
- OPERATOR_NAME_KUBE_DESCHEDULER,
OperatorsValues,
- selectMonitoredOperators,
+ selectOlmOperators,
+ UISettingsValues,
useAlerts,
useFormikAutoSave,
} from '../../../common';
@@ -36,40 +16,18 @@ import { useClusterWizardContext } from './ClusterWizardContext';
import ClusterWizardFooter from '../clusterWizard/ClusterWizardFooter';
import ClusterWizardNavigation from '../clusterWizard/ClusterWizardNavigation';
import { OperatorsStep } from './OperatorsStep';
-import { ClustersService, OperatorsService } from '../../services';
+import { ClustersService } from '../../services';
import { setServerUpdateError, updateCluster } from '../../store/slices/current-cluster/slice';
import { getApiErrorMessage, handleApiError, isUnknownServerError } from '../../../common/api';
import { canNextOperators } from './wizardTransition';
-import { Cluster, MonitoredOperator } from '@openshift-assisted/types/assisted-installer-service';
-export const getOperatorsInitialValues = (
- monitoredOperators: MonitoredOperator[],
+const getOperatorsInitialValues = (
+ uiSettings: UISettingsValues | undefined,
+ cluster: Cluster,
): OperatorsValues => {
- const isOperatorEnabled = (operatorNames: string[]) =>
- !!monitoredOperators.find((operator) => operatorNames.includes(operator.name || ''));
return {
- useOpenShiftDataFoundation: isOperatorEnabled([OPERATOR_NAME_ODF]),
- useOdfLogicalVolumeManager: isOperatorEnabled([OPERATOR_NAME_LVM]),
- useContainerNativeVirtualization: isOperatorEnabled([OPERATOR_NAME_CNV]),
- useMultiClusterEngine: isOperatorEnabled([OPERATOR_NAME_MCE]),
- useMigrationToolkitforVirtualization: isOperatorEnabled([OPERATOR_NAME_MTV]),
- useOpenShiftAI: isOperatorEnabled([OPERATOR_NAME_OPENSHIFT_AI]),
- useOsc: isOperatorEnabled([OPERATOR_NAME_OSC]),
- useNodeFeatureDiscovery: isOperatorEnabled([OPERATOR_NAME_NODE_FEATURE_DISCOVERY]),
- useNmstate: isOperatorEnabled([OPERATOR_NAME_NMSTATE]),
- useLso: isOperatorEnabled([OPERATOR_NAME_LSO]),
- useServerless: isOperatorEnabled([OPERATOR_NAME_SERVERLESS]),
- useAuthorino: isOperatorEnabled([OPERATOR_NAME_AUTHORINO]),
- usePipelines: isOperatorEnabled([OPERATOR_NAME_PIPELINES]),
- useServicemesh: isOperatorEnabled([OPERATOR_NAME_SERVICEMESH]),
- useNvidiaGpu: isOperatorEnabled([OPERATOR_NAME_NVIDIA_GPU]),
- useAmdGpu: isOperatorEnabled([OPERATOR_NAME_AMD_GPU]),
- useKmm: isOperatorEnabled([OPERATOR_NAME_KMM]),
- useNodeHealthcheck: isOperatorEnabled([OPERATOR_NAME_NODE_HEALTHCHECK]),
- useSelfNodeRemediation: isOperatorEnabled([OPERATOR_NAME_SELF_NODE_REMEDIATION]),
- useFenceAgentsRemediation: isOperatorEnabled([OPERATOR_NAME_FENCE_AGENTS_REMEDIATION]),
- useNodeMaintenance: isOperatorEnabled([OPERATOR_NAME_NODE_MAINTENANCE]),
- useKubeDescheduler: isOperatorEnabled([OPERATOR_NAME_KUBE_DESCHEDULER]),
+ selectedBundles: uiSettings?.bundlesSelected || [],
+ selectedOperators: selectOlmOperators(cluster).map((o) => o.name || ''),
};
};
@@ -110,47 +68,29 @@ const OperatorsForm = ({ cluster }: { cluster: Cluster }) => {
/>
}
>
-
+
);
};
const Operators = ({ cluster }: { cluster: Cluster }) => {
const dispatch = useDispatch();
+ const { updateUISettings, uiSettings } = useClusterWizardContext();
const { addAlert, clearAlerts } = useAlerts();
- const olmOperators = selectMonitoredOperators(cluster.monitoredOperators);
-
- const initialValues = React.useMemo(
- () => getOperatorsInitialValues(olmOperators),
- // eslint-disable-next-line react-hooks/exhaustive-deps
- [], // just once, Formik does not reinitialize
- );
-
- const handleSubmit: FormikConfig['onSubmit'] = async (
- values,
- { setFieldValue },
- ) => {
+ const handleSubmit: FormikConfig['onSubmit'] = async (values) => {
clearAlerts();
- const enabledOperators = OperatorsService.getOLMOperators(values, cluster);
+ const enabledOperators = values.selectedOperators.map((so) => ({
+ name: so,
+ }));
try {
const { data: updatedCluster } = await ClustersService.update(cluster.id, cluster.tags, {
olmOperators: enabledOperators,
});
- const needSyncOperators = OperatorsService.syncOperators(
- enabledOperators,
- updatedCluster.monitoredOperators,
- );
- Object.keys(needSyncOperators).forEach((operatorName) => {
- setFieldValue(operatorName, true);
- });
+ await updateUISettings({ bundlesSelected: values.selectedBundles });
dispatch(updateCluster(updatedCluster));
} catch (e) {
@@ -164,7 +104,7 @@ const Operators = ({ cluster }: { cluster: Cluster }) => {
};
return (
-
+
);
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsBundle.css b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsBundle.css
new file mode 100644
index 0000000000..05b08d9674
--- /dev/null
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsBundle.css
@@ -0,0 +1,6 @@
+.ai-bundle-card {
+ --pf-v5-c-card--m-selectable--m-selected--BackgroundColor: var(
+ --pf-v5-global--BackgroundColor--100
+ );
+ --pf-v5-c-card--m-selectable--hover--BackgroundColor: var(--pf-v5-global--BackgroundColor--100);
+}
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsBundle.tsx b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsBundle.tsx
new file mode 100644
index 0000000000..3b4d34939c
--- /dev/null
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsBundle.tsx
@@ -0,0 +1,215 @@
+import * as React from 'react';
+import {
+ Card,
+ CardBody,
+ CardHeader,
+ CardTitle,
+ Gallery,
+ GalleryItem,
+ List,
+ ListItem,
+ Split,
+ SplitItem,
+ Stack,
+ StackItem,
+ Title,
+ Tooltip,
+} from '@patternfly/react-core';
+import {
+ Bundle,
+ PreflightHardwareRequirements,
+} from '@openshift-assisted/types/assisted-installer-service';
+import NewFeatureSupportLevelBadge from '../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
+import { ExternalLink, OperatorsValues, PopoverIcon, singleClusterBundles } from '../../../common';
+import { useFormikContext } from 'formik';
+import { useNewFeatureSupportLevel } from '../../../common/components/newFeatureSupportLevels';
+import { useFeature } from '../../hooks/use-feature';
+import { useSelector } from 'react-redux';
+import { selectIsCurrentClusterSNO } from '../../store/slices/current-cluster/selectors';
+import { getNewBundleOperators } from '../clusterConfiguration/operators/utils';
+import { bundleSpecs } from '../clusterConfiguration/operators/bundleSpecs';
+import { useOperatorSpecs } from '../../../common/components/operators/operatorSpecs';
+
+import './OperatorsBundle.css';
+
+const BundleLabel = ({ bundle }: { bundle: Bundle }) => {
+ const opSpecs = useOperatorSpecs();
+ const bundleSpec = bundleSpecs[bundle.id || ''];
+
+ return (
+ <>
+ {bundle.title}
+ Requirements and dependencies}
+ bodyContent={
+
+ {bundleSpec?.Description && (
+
+
+
+ )}
+ {bundle.operators?.length && (
+ <>
+ Bundle operators:
+
+
+ {bundle.operators.map((op) => (
+ {opSpecs[op]?.title || op}
+ ))}
+
+
+ >
+ )}
+ {bundleSpec?.docsLink && (
+
+ Learn more
+
+ )}
+
+ }
+ />
+ >
+ );
+};
+
+const BundleCard = ({
+ bundle,
+ bundles,
+ preflightRequirements,
+}: {
+ bundle: Bundle;
+ bundles: Bundle[];
+ preflightRequirements: PreflightHardwareRequirements | undefined;
+}) => {
+ const { values, setFieldValue } = useFormikContext();
+ const isSNO = useSelector(selectIsCurrentClusterSNO);
+ const { isFeatureSupported } = useNewFeatureSupportLevel();
+ const opSpecs = useOperatorSpecs();
+
+ const hasUnsupportedOperators = !!bundle.operators?.some((op) => {
+ const operatorSpec = opSpecs[op];
+ if (!operatorSpec) {
+ return false;
+ }
+ return !isFeatureSupported(operatorSpec.featureId);
+ });
+
+ const bundleSpec = bundleSpecs[bundle.id || ''];
+
+ const incompatibleBundle = bundleSpec?.incompatibleBundles?.find((b) =>
+ values.selectedBundles.includes(b),
+ );
+
+ const disabledReason = hasUnsupportedOperators
+ ? 'Some operators in this bundle are not supported with the current configuration.'
+ : isSNO && bundleSpec?.noSNO
+ ? 'This bundle is not available when deploying a Single Node OpenShift.'
+ : incompatibleBundle
+ ? `Bundle cannot be installed together with ${
+ bundles.find(({ id }) => id === incompatibleBundle)?.title || incompatibleBundle
+ }`
+ : undefined;
+
+ const onSelect = (checked: boolean) => {
+ const newBundles = checked
+ ? [...values.selectedBundles, bundle.id || '']
+ : values.selectedBundles.filter((sb) => sb !== bundle.id);
+ setFieldValue('selectedBundles', newBundles);
+ const newOperators = getNewBundleOperators(
+ values.selectedOperators,
+ newBundles,
+ bundles,
+ bundle,
+ preflightRequirements,
+ checked,
+ );
+ setFieldValue('selectedOperators', newOperators);
+ };
+
+ const isSelected = values.selectedBundles.includes(bundle.id || '');
+ const checkboxId = `bundle-${bundle.id || ''}`;
+ return (
+
+
+ onSelect(checked),
+ isChecked: isSelected,
+ }}
+ >
+
+
+
+
+
+
+
+ {bundle.description}
+
+ {bundleSpec.featureId && (
+
+
+
+
+
+
+
+
+ )}
+
+
+
+
+ );
+};
+
+const OperatorsBundle = ({
+ bundles,
+ preflightRequirements,
+}: {
+ bundles: Bundle[];
+ preflightRequirements: PreflightHardwareRequirements | undefined;
+}) => {
+ const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
+
+ return (
+
+
+
+ Bundles
+
+
+
+
+ {(isSingleClusterFeatureEnabled
+ ? bundles.filter((b) => b.id && singleClusterBundles.includes(b.id))
+ : bundles
+ ).map((bundle) => (
+
+
+
+ ))}
+
+
+
+ );
+};
+
+export default OperatorsBundle;
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.tsx b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.tsx
new file mode 100644
index 0000000000..046898ef20
--- /dev/null
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsSelect.tsx
@@ -0,0 +1,108 @@
+import * as React from 'react';
+import { ExpandableSection, Stack, StackItem } from '@patternfly/react-core';
+import {
+ Bundle,
+ Cluster,
+ PreflightHardwareRequirements,
+} from '@openshift-assisted/types/assisted-installer-service';
+import { useFormikContext } from 'formik';
+import {
+ getApiErrorMessage,
+ handleApiError,
+ LoadingState,
+ OperatorsValues,
+ singleClusterOperators,
+ useAlerts,
+ useStateSafely,
+} from '../../../common';
+import { OperatorsService } from '../../services';
+import { useFeature } from '../../hooks/use-feature';
+import OperatorCheckbox from '../clusterConfiguration/operators/OperatorCheckbox';
+import { useOperatorSpecs } from '../../../common/components/operators/operatorSpecs';
+
+const OperatorsSelect = ({
+ cluster,
+ bundles,
+ preflightRequirements,
+}: {
+ cluster: Cluster;
+ bundles: Bundle[];
+ preflightRequirements: PreflightHardwareRequirements | undefined;
+}) => {
+ const [isLoading, setIsLoading] = useStateSafely(true);
+ const { addAlert } = useAlerts();
+ const [isExpanded, setIsExpanded] = React.useState(false);
+ const [supportedOperators, setSupportedOperators] = useStateSafely([]);
+ const isSingleClusterFeatureEnabled = useFeature('ASSISTED_INSTALLER_SINGLE_CLUSTER_FEATURE');
+ const { values } = useFormikContext();
+
+ React.useEffect(() => {
+ const fetchSupportedOperators = async () => {
+ try {
+ const fetchedOperators = await OperatorsService.getSupportedOperators();
+ setSupportedOperators(fetchedOperators);
+ } catch (error) {
+ handleApiError(error, () =>
+ addAlert({ title: 'Failed to fetch operators', message: getApiErrorMessage(error) }),
+ );
+ } finally {
+ setIsLoading(false);
+ }
+ };
+
+ void fetchSupportedOperators();
+ }, [addAlert, setSupportedOperators, setIsLoading]);
+
+ const opSpecs = useOperatorSpecs();
+
+ const operators = React.useMemo(() => {
+ return supportedOperators
+ .sort((a, b) => {
+ const aTitle = opSpecs[a]?.title || a;
+ const bTitle = opSpecs[b]?.title || b;
+ return aTitle.localeCompare(bTitle);
+ })
+ .filter((op) => {
+ if (!isSingleClusterFeatureEnabled) {
+ return true;
+ }
+ return singleClusterOperators.includes(op);
+ });
+ }, [isSingleClusterFeatureEnabled, supportedOperators, opSpecs]);
+
+ if (isLoading) {
+ return ;
+ }
+
+ return (
+ setIsExpanded(!isExpanded)}
+ isExpanded={isExpanded}
+ data-testid="single-operators-section"
+ >
+
+ {operators.map((operatorKey) => {
+ if (!opSpecs[operatorKey]) {
+ return null;
+ }
+
+ return (
+
+
+
+ );
+ })}
+
+
+ );
+};
+
+export default OperatorsSelect;
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsStep.tsx b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsStep.tsx
index 3a78c730de..4c94f947c8 100644
--- a/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsStep.tsx
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/OperatorsStep.tsx
@@ -1,470 +1,63 @@
-import React, { useEffect, useState } from 'react';
-import { useSelector } from 'react-redux';
-import {
- Card,
- CardBody,
- CardTitle,
- Checkbox,
- ExpandableSection,
- Flex,
- FlexItem,
- Gallery,
- GalleryItem,
- Stack,
- StackItem,
- TextInput,
- Title,
- Tooltip,
-} from '@patternfly/react-core';
+import React from 'react';
+import { Stack, StackItem } from '@patternfly/react-core';
+import { Bundle } from '@openshift-assisted/types/assisted-installer-service';
import {
ClusterOperatorProps,
ClusterWizardStepHeader,
- numberOfEnabledOperators,
- OPERATOR_NAME_CNV,
- OPERATOR_NAME_ODF,
- OperatorsValues,
- PopoverIcon,
+ getApiErrorMessage,
+ handleApiError,
+ LoadingState,
+ useAlerts,
} from '../../../common';
-import { selectIsCurrentClusterSNO } from '../../store/slices/current-cluster/selectors';
-import { isOCPVersionEqualsOrMajor } from '../utils';
+import OperatorsBundle from './OperatorsBundle';
+import OperatorsSelect from './OperatorsSelect';
import BundleService from '../../services/BundleService';
-import { Bundle } from '@openshift-assisted/types/./assisted-installer-service';
-import { OperatorsService } from '../../services';
-import {
- mapOperatorIdToFeatureId,
- mapOperatorsToFieldIds,
- operatorComponentMap,
-} from '../clusterConfiguration/operators/SupportedOperators';
-import { useClusterWizardContext } from './ClusterWizardContext';
-import { useFormikContext } from 'formik';
-import NewFeatureSupportLevelBadge from '../../../common/components/newFeatureSupportLevels/NewFeatureSupportLevelBadge';
-import { useNewFeatureSupportLevel } from '../../../common/components/newFeatureSupportLevels';
-import {
- getCnvIncompatibleWithLvmReason,
- getLvmIncompatibleWithCnvReason,
- getLvmsIncompatibleWithOdfReason,
- getLvmsIncompatibleWithOpenShiftAIReason,
- getOdfIncompatibleWithLvmsReason,
- getOpenShiftAIIncompatibleWithLvmsReason,
-} from '../featureSupportLevels/featureStateUtils';
-import OpenshiftAINvidiaRequirements from '../clusterConfiguration/operators/OpenshiftAINvidiaRequirements';
-import VirtualizationRequirements from '../clusterConfiguration/operators/VirtualizationRequirements';
-import OpenshiftAIAmdRequirements from '../clusterConfiguration/operators/OpenshiftAIAmdRequirements';
-
-const operatorsThatCanNotBeInstalledAlone = [
- 'nvdia-gpu',
- 'pipelines',
- 'servicemesh',
- 'serverless',
- 'authorino',
- 'lso',
- 'amd-gpu',
- 'nvidia-gpu',
- 'node-healthcheck',
- 'self-node-remediation',
- 'fence-agents-remediation',
- 'node-maintenance',
- 'kube-descheduler',
-];
-
-export const OperatorsStep = (props: ClusterOperatorProps) => {
- const isSNO = useSelector(selectIsCurrentClusterSNO);
- const isVersionEqualsOrMajorThan4_15 = isOCPVersionEqualsOrMajor(
- props.openshiftVersion || '',
- '4.15',
- );
-
- const [bundles, setBundles] = useState([]);
- const [isExpanded, setIsExpanded] = useState(false);
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- const [supportedOperators, setSupportedOperators] = useState([]);
- const [searchTerm, setSearchTerm] = useState('');
- const [selectedOperators, setSelectedOperators] = useState([]);
- const [selectedBundles, setSelectedBundles] = useState<{ [key: string]: boolean }>({});
- const [bundleOperators, setBundleOperators] = useState([]);
- const { updateUISettings, uiSettings } = useClusterWizardContext();
- const { values, setFieldValue } = useFormikContext();
- const featureSupportLevelData = useNewFeatureSupportLevel();
-
- useEffect(() => {
+import { useClusterPreflightRequirements } from '../../hooks';
+
+export const OperatorsStep = ({ cluster }: ClusterOperatorProps) => {
+ const { addAlert } = useAlerts();
+ const [bundlesLoading, setBundlesLoading] = React.useState(true);
+ const [bundles, setBundles] = React.useState([]);
+ const { preflightRequirements, isLoading } = useClusterPreflightRequirements(cluster.id);
+ React.useEffect(() => {
const fetchBundles = async () => {
try {
const fetchedBundles = await BundleService.listBundles();
-
setBundles(fetchedBundles);
} catch (error) {
- // eslint-disable-next-line no-console
- console.error('Error getting bundles:', error);
+ handleApiError(error, () =>
+ addAlert({
+ title: 'Failed to fetch operator bundles',
+ message: getApiErrorMessage(error),
+ }),
+ );
+ } finally {
+ setBundlesLoading(false);
}
};
void fetchBundles();
- }, []);
-
- useEffect(() => {
- const fetchSupportedOperators = async () => {
- try {
- const fetchedOperators = await OperatorsService.getSupportedOperators();
- const sortedOperators = fetchedOperators.sort((a, b) => a.localeCompare(b));
+ }, [addAlert]);
- setSupportedOperators(sortedOperators);
- } catch (error) {
- // eslint-disable-next-line no-console
- console.error('Error getting operators:', error);
- }
- };
-
- void fetchSupportedOperators();
- }, []);
-
- const filteredBundles = bundles.filter(
- (bundle) =>
- bundle.title?.toLowerCase().includes(searchTerm.toLowerCase()) ||
- bundle.description?.toLowerCase().includes(searchTerm.toLowerCase()),
- );
-
- useEffect(() => {
- if (uiSettings?.bundlesSelected) {
- setSelectedBundles(
- uiSettings.bundlesSelected.reduce((acc, id) => ({ ...acc, [id]: true }), {}),
- );
-
- setBundleOperators(() => {
- const newSelection: string[] = [];
- bundles
- .filter((bundle) => uiSettings?.bundlesSelected?.includes(bundle.id ?? ''))
- .forEach((bundle) => {
- bundle.operators?.forEach((op) => {
- newSelection.push(op);
- });
- });
-
- return newSelection;
- });
- }
- }, [bundles, uiSettings?.bundlesSelected]);
-
- useEffect(() => {
- const newSelection: string[] = [];
-
- props.monitoredOperators?.forEach((operator) => {
- if (operator.operatorType === 'olm') {
- newSelection.push(operator.name ?? '');
- }
- });
-
- setSelectedOperators(newSelection);
- newSelection.forEach((op) => {
- const fieldId = mapOperatorsToFieldIds[op]; // Obtener el ID del campo correspondiente
- setFieldValue(fieldId, true);
- });
- }, [props.monitoredOperators, setFieldValue]);
-
- const handleBundleSelection = async (bundleId: string, operators: string[], checked: boolean) => {
- let bundlesSelected = uiSettings?.bundlesSelected ? [...uiSettings.bundlesSelected] : [];
- let newBundleOperators = [...bundleOperators];
-
- if (checked) {
- // Agregar el bundle si se marca
- bundlesSelected.push(bundleId);
- operators.forEach((op) => {
- if (!newBundleOperators.includes(op)) {
- newBundleOperators.push(op);
- const fieldId = mapOperatorsToFieldIds[op]; // Obtener el ID del campo correspondiente
- setFieldValue(fieldId, checked);
- if (op === OPERATOR_NAME_CNV || op === OPERATOR_NAME_ODF) {
- if (featureSupportLevelData.isFeatureSupported('LSO')) setFieldValue('useLso', checked);
- }
- }
- });
- } else {
- // Eliminar el bundle si se desmarca
- bundlesSelected = bundlesSelected.filter((id) => id !== bundleId);
- newBundleOperators = newBundleOperators.filter((op) => !operators.includes(op));
- operators.forEach((op) => {
- const fieldId = mapOperatorsToFieldIds[op]; // Obtener el ID del campo correspondiente
- setFieldValue(fieldId, checked);
- if (op === OPERATOR_NAME_CNV || op === OPERATOR_NAME_ODF) {
- if (featureSupportLevelData.isFeatureSupported('LSO')) setFieldValue('useLso', checked);
- }
- });
- }
-
- await updateUISettings({ bundlesSelected });
-
- setSelectedBundles((prev) => ({
- ...prev,
- [bundleId]: checked,
- }));
-
- setBundleOperators(newBundleOperators);
- };
-
- const getBundleLabel = (bundle: Bundle) => {
- let requirements: React.ReactElement | null = null;
- switch (bundle.id) {
- case 'virtualization':
- requirements = ;
- break;
- case 'openshift-ai-nvidia':
- requirements = ;
- break;
- case 'openshift-ai-amd':
- requirements = ;
- break;
- }
-
- return (
- <>
- {bundle.title}
- {requirements && (
-
- {'Requirements and dependencies'}
- {requirements}
- >
- }
- />
- )}
- >
- );
- };
-
- const bundleHasOperatorsNotSupported = React.useCallback(
- (operators: string[] | undefined) => {
- return (
- operators?.some(
- (operator) =>
- !featureSupportLevelData.isFeatureSupported(mapOperatorIdToFeatureId[operator]),
- ) ?? false
- );
- },
- [featureSupportLevelData],
- );
-
- const getDisabledReasonForOperator = React.useCallback(
- (operatorKey: string, values: OperatorsValues) => {
- let disabledReason = featureSupportLevelData.getFeatureDisabledReason(
- mapOperatorIdToFeatureId[operatorKey],
- );
- if (operatorKey === 'cnv') {
- if (!disabledReason) {
- const lvmSupport = featureSupportLevelData.getFeatureSupportLevel('LVM');
- disabledReason = getCnvIncompatibleWithLvmReason(values, lvmSupport);
- }
- }
- if (operatorKey === 'lvm') {
- if (!disabledReason) {
- const lvmSupport = featureSupportLevelData.getFeatureSupportLevel('LVM');
- disabledReason = getLvmIncompatibleWithCnvReason(values, lvmSupport);
- }
- if (!disabledReason) {
- disabledReason = getLvmsIncompatibleWithOdfReason(values);
- }
- if (!disabledReason) {
- disabledReason = getLvmsIncompatibleWithOpenShiftAIReason(values);
- }
- }
- if (operatorKey === 'odf') {
- if (!disabledReason) {
- disabledReason = getOdfIncompatibleWithLvmsReason(values);
- }
- }
- if (operatorKey === 'openshift-ai') {
- if (!disabledReason) {
- disabledReason = getOpenShiftAIIncompatibleWithLvmsReason(values);
- }
- }
- return disabledReason;
- },
- [featureSupportLevelData],
- );
-
- const bundleHasOperatorsNotCompatibles = React.useCallback(
- (operators: string[] | undefined, values: OperatorsValues, isSelected: boolean) => {
- if (!isSelected) {
- return (
- operators?.some((operatorKey) => {
- const disabledReason = getDisabledReasonForOperator(operatorKey, values);
- return disabledReason !== undefined;
- }) ?? false
- );
- } else return false;
- },
- [getDisabledReasonForOperator],
- );
+ if (isLoading || bundlesLoading) {
+ return ;
+ }
return (
-
-
- Operators
-
-
- setSearchTerm(value)}
- placeholder="Search"
- style={{ width: '400px' }}
- />
-
-
+ Operators
-
- Bundles
-
+
+
+
+
- {/* Mostrar bundles como tarjetas */}
-
- {filteredBundles.map((bundle) => {
- const isSnoAndBlockedBundle =
- isSNO && (bundle.id === 'openshift-ai-nvidia' || bundle.id === 'openshift-ai-amd');
- const hasUnsupportedOperators = bundleHasOperatorsNotSupported(bundle.operators);
- const hasIncompatibleOperators = bundleHasOperatorsNotCompatibles(
- bundle.operators,
- values,
- bundle.id ? selectedBundles[bundle.id] : false,
- );
- const hasAnotherAIBundleSelected =
- (bundle.id === 'openshift-ai-nvidia' && selectedBundles['openshift-ai-amd']) ||
- (bundle.id === 'openshift-ai-amd' && selectedBundles['openshift-ai-nvidia']);
-
- const tooltipContent = hasUnsupportedOperators
- ? 'Some operators in this bundle are not supported with the current configuration.'
- : isSnoAndBlockedBundle
- ? 'This bundle is not available when deploying a Single Node OpenShift.'
- : hasIncompatibleOperators
- ? 'Some operators in this bundle can not be installed with some single operators selected.'
- : hasAnotherAIBundleSelected
- ? 'This bundle cannot be selected because you already have another OpenShift AI bundle selected.'
- : '';
- return (
-
-
-
-
-
- {getBundleLabel(bundle)}
-
-
- void handleBundleSelection(bundle.id || '', bundle.operators || [], checked)
- }
- isDisabled={
- hasUnsupportedOperators ||
- hasIncompatibleOperators ||
- isSnoAndBlockedBundle ||
- hasAnotherAIBundleSelected
- }
- />
-
-
- {bundle.description}
-
- {/* Badge aligned to the bottom-left */}
-
- {(bundle.id === 'openshift-ai-nvidia' ||
- bundle.id === 'openshift-ai-amd') && (
-
- )}
-
-
-
-
-
- );
- })}
-
- setIsExpanded(!isExpanded)}
- isExpanded={isExpanded}
- data-testid="single-operators-section"
- >
-
- {supportedOperators.map((operatorKey) => {
- const isOperatorSelected = bundleOperators.includes(operatorKey);
- const isOperatorNotAllowedAlone =
- operatorsThatCanNotBeInstalledAlone.includes(operatorKey);
- const disabledReason = getDisabledReasonForOperator(operatorKey, values);
- const featureSupportLevel = featureSupportLevelData.getFeatureSupportLevel(
- mapOperatorIdToFeatureId[operatorKey],
- );
- const OperatorComponent = operatorComponentMap[operatorKey];
- if (!OperatorComponent) {
- return null;
- }
- return (
-
-
-
- );
- })}
-
-
);
};
diff --git a/libs/ui-lib/lib/ocm/components/clusterWizard/wizardTransition.ts b/libs/ui-lib/lib/ocm/components/clusterWizard/wizardTransition.ts
index 050cd58577..721e2ef2ab 100644
--- a/libs/ui-lib/lib/ocm/components/clusterWizard/wizardTransition.ts
+++ b/libs/ui-lib/lib/ocm/components/clusterWizard/wizardTransition.ts
@@ -73,14 +73,10 @@ export const getClusterWizardFirstStep = (
staticIpInfo: StaticIpInfo | undefined,
state?: ClusterWizardFlowStateType,
hosts?: Host[] | undefined,
- isSingleClusterFeatureEnabled?: boolean,
customManifestsStepNeedsToBeFilled?: boolean,
): ClusterWizardStepsType => {
// Just for the first time when the cluster is created
if (locationState === ClusterWizardFlowStateNew && !staticIpInfo) {
- if (isSingleClusterFeatureEnabled) {
- return 'host-discovery';
- }
return 'operators';
}
diff --git a/libs/ui-lib/lib/ocm/components/clusters/utils.ts b/libs/ui-lib/lib/ocm/components/clusters/utils.ts
index c024141059..ab5f85ab12 100644
--- a/libs/ui-lib/lib/ocm/components/clusters/utils.ts
+++ b/libs/ui-lib/lib/ocm/components/clusters/utils.ts
@@ -3,9 +3,7 @@ import {
LogsState,
MonitoredOperator,
MonitoredOperatorsList,
- OperatorCreateParams,
} from '@openshift-assisted/types/assisted-installer-service';
-import { selectOlmOperators } from '../../../common';
// The Day2 cluster
export const isAddHostsCluster = (cluster: Cluster) => cluster.kind === 'AddHostsCluster';
@@ -24,23 +22,6 @@ export const calculateCollectedLogsCount = (cluster: Cluster) => {
export const getBuiltInOperators = (monitoredOperators: MonitoredOperatorsList = []) =>
monitoredOperators.filter((operator: MonitoredOperator) => operator.operatorType === 'builtin');
-export const getOlmOperatorCreateParams = (cluster?: Cluster): OperatorCreateParams[] =>
- selectOlmOperators(cluster).map((operator) => ({
- name: operator.name,
- properties: operator.properties,
- }));
-
-export const getOlmOperatorCreateParamsByName = (cluster?: Cluster) =>
- getOlmOperatorCreateParams(cluster).reduce(
- (result: { [key: string]: OperatorCreateParams }, operator) => {
- if (operator.name) {
- result[operator.name] = operator;
- }
- return result;
- },
- {},
- );
-
export const canAbortInstallation = (cluster: Cluster) => {
const allowedClusterStates: Cluster['status'][] = [
'preparing-for-installation',
diff --git a/libs/ui-lib/lib/ocm/components/featureSupportLevels/FeatureSupportLevelProvider.tsx b/libs/ui-lib/lib/ocm/components/featureSupportLevels/FeatureSupportLevelProvider.tsx
index 0bb5fba276..332dccc04c 100644
--- a/libs/ui-lib/lib/ocm/components/featureSupportLevels/FeatureSupportLevelProvider.tsx
+++ b/libs/ui-lib/lib/ocm/components/featureSupportLevels/FeatureSupportLevelProvider.tsx
@@ -90,7 +90,6 @@ export const NewFeatureSupportLevelProvider: React.FC {
- // eslint-disable-next-line react-hooks/exhaustive-deps
if (supportLevelDataNew) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
diff --git a/libs/ui-lib/lib/ocm/components/featureSupportLevels/featureStateUtils.ts b/libs/ui-lib/lib/ocm/components/featureSupportLevels/featureStateUtils.ts
index 9582bfecdd..411265f74b 100644
--- a/libs/ui-lib/lib/ocm/components/featureSupportLevels/featureStateUtils.ts
+++ b/libs/ui-lib/lib/ocm/components/featureSupportLevels/featureStateUtils.ts
@@ -4,7 +4,11 @@ import {
CpuArchitecture,
FeatureId,
isSNO,
- OperatorsValues,
+ OPERATOR_NAME_CNV,
+ OPERATOR_NAME_LVM,
+ OPERATOR_NAME_ODF,
+ OPERATOR_NAME_OPENSHIFT_AI,
+ OPERATOR_NAME_OSC,
SupportedCpuArchitecture,
} from '../../../common';
import {
@@ -13,43 +17,10 @@ import {
SupportLevel,
} from '@openshift-assisted/types/assisted-installer-service';
import { ExternalPlatformLabels } from '../clusterConfiguration/platformIntegration/constants';
-
-const CNV_OPERATOR_LABEL = 'OpenShift Virtualization';
-const LVMS_OPERATOR_LABEL = 'Logical Volume Manager Storage';
-const LVM_OPERATOR_LABEL = 'Logical Volume Manager';
-const ODF_OPERATOR_LABEL = 'OpenShift Data Foundation';
-const OPENSHIFT_AI_OPERATOR_LABEL = 'OpenShift AI';
-const MTV_OPERATOR_LABEL = 'Migration Toolkit for Virtualization';
-const OSC_OPERATOR_LABEL = 'OpenShift sandboxed containers';
+import { getOperatorSpecs } from '../../../common/components/operators/operatorSpecs';
export const clusterExistsReason = 'This option is not editable after the draft cluster is created';
-export const getCnvIncompatibleWithLvmReason = (
- operatorValues: OperatorsValues,
- lvmSupport: SupportLevel | undefined,
-) => {
- const mustDisableCnv =
- !operatorValues.useContainerNativeVirtualization &&
- operatorValues.useOdfLogicalVolumeManager &&
- lvmSupport !== 'supported';
- // In versions with none or limited support for LVM (< 4.12), it's not possible to select CNV + LVM
- return mustDisableCnv
- ? `Currently, you cannot install ${CNV_OPERATOR_LABEL} operator at the same time as ${LVM_OPERATOR_LABEL} operator.`
- : undefined;
-};
-
-export const getLvmIncompatibleWithCnvReason = (
- operatorValues: OperatorsValues,
- lvmSupport: SupportLevel | undefined,
-) => {
- const hasSelectedCnv = operatorValues.useContainerNativeVirtualization;
- // In versions with none or limited support for LVM (< 4.12), it's not possible to select CNV + LVM
- if (hasSelectedCnv && lvmSupport !== 'supported') {
- return `Currently, you cannot install ${LVM_OPERATOR_LABEL} operator at the same time as ${CNV_OPERATOR_LABEL} operator.`;
- }
- return undefined;
-};
-
const getSNODisabledReason = (cluster: Cluster | undefined, isSupported: boolean) => {
if (cluster) {
return clusterExistsReason;
@@ -75,18 +46,22 @@ const getOdfDisabledReason = (
return undefined;
}
+ const opSpecs = getOperatorSpecs();
+
+ const operatorTitle = opSpecs[OPERATOR_NAME_ODF]?.title || '';
+
const isArm = activeFeatureConfiguration?.underlyingCpuArchitecture === CpuArchitecture.ARM;
if (isArm && isSNO(cluster)) {
- return `${ODF_OPERATOR_LABEL} is not available when using Single Node OpenShift or ARM CPU architecture.`;
+ return `${operatorTitle} is not available when using Single Node OpenShift or ARM CPU architecture.`;
}
if (isArm) {
- return `${ODF_OPERATOR_LABEL} is not available when ARM CPU architecture is selected.`;
+ return `${operatorTitle} is not available when ARM CPU architecture is selected.`;
}
if (isSNO(cluster)) {
- return `${ODF_OPERATOR_LABEL} is not available when deploying a Single Node OpenShift.`;
+ return `${operatorTitle} is not available when deploying a Single Node OpenShift.`;
}
if (!isSupported) {
- return `The installer cannot currently enable ${ODF_OPERATOR_LABEL} with the selected OpenShift version, but it can be enabled later through the OpenShift Console once the installation is complete.`;
+ return `The installer cannot currently enable ${operatorTitle} with the selected OpenShift version, but it can be enabled later through the OpenShift Console once the installation is complete.`;
}
return undefined;
};
@@ -99,8 +74,11 @@ const getCnvDisabledReason = (
if (!activeFeatureConfiguration) {
return undefined;
}
+
+ const opSpecs = getOperatorSpecs();
+ const operatorTitle = opSpecs[OPERATOR_NAME_CNV]?.title || '';
if (platformType === 'nutanix') {
- return `${CNV_OPERATOR_LABEL} is not available when Nutanix platform type is selected.`;
+ return `${operatorTitle} is not available when Nutanix platform type is selected.`;
}
if (!isSupported) {
const cpuArchitectureLabel =
@@ -108,7 +86,7 @@ const getCnvDisabledReason = (
activeFeatureConfiguration.underlyingCpuArchitecture as SupportedCpuArchitecture
].label;
- return `${CNV_OPERATOR_LABEL} is not available when ${
+ return `${operatorTitle} is not available when ${
cpuArchitectureLabel
? cpuArchitectureLabel
: activeFeatureConfiguration.underlyingCpuArchitecture
@@ -126,12 +104,14 @@ const getLvmDisabledReason = (
if (!activeFeatureConfiguration) {
return undefined;
}
- const operatorLabel = isSupported ? LVMS_OPERATOR_LABEL : LVM_OPERATOR_LABEL;
+
+ const opSpecs = getOperatorSpecs();
+ const operatorTitle = opSpecs[OPERATOR_NAME_LVM]?.title;
if (platformType === 'nutanix') {
- return `${operatorLabel} is not supported when Nutanix platform type is selected.`;
+ return `${operatorTitle} is not supported when Nutanix platform type is selected.`;
}
if (!isSupported) {
- return `${operatorLabel} is not supported in this OpenShift version.`;
+ return `${operatorTitle} is not supported in this OpenShift version.`;
}
return undefined;
};
@@ -144,8 +124,11 @@ const getOscDisabledReason = (
if (!cluster) {
return undefined;
}
+
+ const opSpecs = getOperatorSpecs();
+ const operatorTitle = opSpecs[OPERATOR_NAME_OSC]?.title || '';
if (!isSupported) {
- return `${OSC_OPERATOR_LABEL} is not supported in this OpenShift version.`;
+ return `${operatorTitle} is not supported in this OpenShift version.`;
}
return undefined;
};
@@ -307,37 +290,6 @@ export const isFeatureSupportedAndAvailable = (supportLevel: SupportLevel | unde
export const hostsNetworkConfigurationDisabledReason =
"DHCP only is the supported hosts' network configuration when external partner integrations is selected";
-export const getOdfIncompatibleWithLvmsReason = (operatorValues: OperatorsValues) => {
- const mustDisableOdf = operatorValues.useOdfLogicalVolumeManager;
- // In versions >= 4.15, it's not possible to select ODF + LVMS
- return mustDisableOdf
- ? `Currently, you cannot install ${ODF_OPERATOR_LABEL} operator at the same time as ${LVMS_OPERATOR_LABEL} operator.`
- : undefined;
-};
-
-export const getOpenShiftAIIncompatibleWithLvmsReason = (operatorValues: OperatorsValues) => {
- // Currently OpenShift AI requires ODF, and that is incompatible with LVM.
- const mustDisableOpenShiftAI = operatorValues.useOdfLogicalVolumeManager;
- return mustDisableOpenShiftAI
- ? `Currently the ${OPENSHIFT_AI_OPERATOR_LABEL} requires ${ODF_OPERATOR_LABEL}, and you cannot install that at the same time as ${LVMS_OPERATOR_LABEL} operator.`
- : undefined;
-};
-
-export const getLvmsIncompatibleWithOdfReason = (operatorValues: OperatorsValues) => {
- const mustDisableLvms = operatorValues.useOpenShiftDataFoundation;
- // In versions >= 4.15, it's not possible to select ODF + LVMS
- return mustDisableLvms
- ? `Currently, you cannot install ${LVMS_OPERATOR_LABEL} operator at the same time as ${ODF_OPERATOR_LABEL} operator.`
- : undefined;
-};
-
-export const getLvmsIncompatibleWithOpenShiftAIReason = (operatorValues: OperatorsValues) => {
- const mustDisableLvms = operatorValues.useOpenShiftAI;
- return mustDisableLvms
- ? `Currently, you cannot install ${LVMS_OPERATOR_LABEL} operator at the same time as ${OPENSHIFT_AI_OPERATOR_LABEL} operator.`
- : undefined;
-};
-
const getOpenShiftAIDisabledReason = (
cluster: Cluster | undefined,
activeFeatureConfiguration: ActiveFeatureConfiguration | undefined,
@@ -347,24 +299,17 @@ const getOpenShiftAIDisabledReason = (
return undefined;
}
+ const opSpecs = getOperatorSpecs();
+ const operatorTitle = opSpecs[OPERATOR_NAME_OPENSHIFT_AI]?.title || '';
const isArm = activeFeatureConfiguration?.underlyingCpuArchitecture === CpuArchitecture.ARM;
if (isArm) {
- return `${OPENSHIFT_AI_OPERATOR_LABEL} is not available when ARM CPU architecture is selected.`;
+ return `${operatorTitle} is not available when ARM CPU architecture is selected.`;
}
if (isSNO(cluster)) {
- return `${OPENSHIFT_AI_OPERATOR_LABEL} is not available when deploying a Single Node OpenShift.`;
+ return `${operatorTitle} is not available when deploying a Single Node OpenShift.`;
}
if (!isSupported) {
- return `The installer cannot currently enable ${OPENSHIFT_AI_OPERATOR_LABEL} with the selected OpenShift version, but it can be enabled later through the OpenShift Console once the installation is complete.`;
+ return `The installer cannot currently enable ${operatorTitle} with the selected OpenShift version, but it can be enabled later through the OpenShift Console once the installation is complete.`;
}
return undefined;
};
-
-export const getCnvDisabledWithMtvReason = (operatorValues: OperatorsValues) => {
- const mustDisableCnv =
- operatorValues.useContainerNativeVirtualization &&
- !operatorValues.useMigrationToolkitforVirtualization;
- return mustDisableCnv
- ? `Currently, you need to install ${CNV_OPERATOR_LABEL} operator at the same time as ${MTV_OPERATOR_LABEL} operator.`
- : undefined;
-};
diff --git a/libs/ui-lib/lib/ocm/components/utils.ts b/libs/ui-lib/lib/ocm/components/utils.ts
index 764764e575..ef4b670068 100644
--- a/libs/ui-lib/lib/ocm/components/utils.ts
+++ b/libs/ui-lib/lib/ocm/components/utils.ts
@@ -5,15 +5,3 @@ export const isOciPlatformType = (cluster: Cluster): boolean => {
cluster.platform?.type === 'external' && cluster.platform?.external?.platformName === 'oci'
);
};
-
-export const getMajorMinorVersion = (version = '') => {
- const match = /[0-9].[0-9][0-9]?/g.exec(version);
- return match?.[0] || '';
-};
-
-export const isOCPVersionEqualsOrMajor = (
- openshiftVersion: string,
- ocpVersionToCompare: string,
-): boolean => {
- return parseFloat(getMajorMinorVersion(openshiftVersion)) >= parseFloat(ocpVersionToCompare);
-};
diff --git a/libs/ui-lib/lib/ocm/services/OperatorsService.tsx b/libs/ui-lib/lib/ocm/services/OperatorsService.tsx
index d65c013b34..e3b0c758fb 100644
--- a/libs/ui-lib/lib/ocm/services/OperatorsService.tsx
+++ b/libs/ui-lib/lib/ocm/services/OperatorsService.tsx
@@ -1,106 +1,7 @@
-import {
- OperatorsValues,
- OPERATOR_NAME_CNV,
- OPERATOR_NAME_ODF,
- OPERATOR_NAME_LSO,
- OPERATOR_NAME_LVM,
- OperatorName,
- OPERATOR_NAME_MCE,
- OPERATOR_NAME_MTV,
- OPERATOR_NAME_OPENSHIFT_AI,
- OPERATOR_NAME_OSC,
- OPERATOR_NAME_NODE_FEATURE_DISCOVERY,
- OPERATOR_NAME_NMSTATE,
- OPERATOR_NAME_SERVERLESS,
- OPERATOR_NAME_AUTHORINO,
- OPERATOR_NAME_PIPELINES,
- OPERATOR_NAME_SERVICEMESH,
- OPERATOR_NAME_NVIDIA_GPU,
- OPERATOR_NAME_AMD_GPU,
- OPERATOR_NAME_KMM,
- OPERATOR_NAME_NODE_HEALTHCHECK,
- OPERATOR_NAME_SELF_NODE_REMEDIATION,
- OPERATOR_NAME_FENCE_AGENTS_REMEDIATION,
- OPERATOR_NAME_NODE_MAINTENANCE,
- OPERATOR_NAME_KUBE_DESCHEDULER,
-} from '../../common';
-import { getOlmOperatorCreateParamsByName } from '../components/clusters/utils';
-import {
- Cluster,
- OperatorCreateParams,
-} from '@openshift-assisted/types/assisted-installer-service';
import OperatorsAPI from '../../common/api/assisted-service/OperatorsAPI';
const OperatorsService = {
- getOLMOperators(values: OperatorsValues, cluster: Cluster): OperatorCreateParams[] {
- const enabledOlmOperatorsByName = getOlmOperatorCreateParamsByName(cluster);
-
- // TODO: change OperatorName to ExposedOperatorName once the LSO option is exposed to the user
- const setOperator = (name: OperatorName, enabled: boolean) => {
- if (enabled) {
- enabledOlmOperatorsByName[name] = { name };
- } else {
- delete enabledOlmOperatorsByName[name];
- }
- };
-
- setOperator(OPERATOR_NAME_LVM, values.useOdfLogicalVolumeManager);
- setOperator(OPERATOR_NAME_CNV, values.useContainerNativeVirtualization);
- setOperator(OPERATOR_NAME_ODF, values.useOpenShiftDataFoundation);
- setOperator(OPERATOR_NAME_MCE, values.useMultiClusterEngine);
- setOperator(OPERATOR_NAME_MTV, values.useMigrationToolkitforVirtualization);
- setOperator(OPERATOR_NAME_OPENSHIFT_AI, values.useOpenShiftAI);
- setOperator(OPERATOR_NAME_OSC, values.useOsc);
- setOperator(OPERATOR_NAME_NODE_FEATURE_DISCOVERY, values.useNodeFeatureDiscovery);
- setOperator(OPERATOR_NAME_NMSTATE, values.useNmstate);
- setOperator(OPERATOR_NAME_LSO, values.useLso);
- setOperator(OPERATOR_NAME_SERVERLESS, values.useServerless);
- setOperator(OPERATOR_NAME_AUTHORINO, values.useAuthorino);
- setOperator(OPERATOR_NAME_PIPELINES, values.usePipelines);
- setOperator(OPERATOR_NAME_SERVICEMESH, values.useServicemesh);
- setOperator(OPERATOR_NAME_NVIDIA_GPU, values.useNvidiaGpu);
- setOperator(OPERATOR_NAME_AMD_GPU, values.useAmdGpu);
- setOperator(OPERATOR_NAME_KMM, values.useKmm);
- setOperator(OPERATOR_NAME_NODE_HEALTHCHECK, values.useNodeHealthcheck);
- setOperator(OPERATOR_NAME_SELF_NODE_REMEDIATION, values.useNodeMaintenance);
- setOperator(OPERATOR_NAME_FENCE_AGENTS_REMEDIATION, values.useFenceAgentsRemediation);
- setOperator(OPERATOR_NAME_NODE_MAINTENANCE, values.useNodeMaintenance);
- setOperator(OPERATOR_NAME_KUBE_DESCHEDULER, values.useKubeDescheduler);
-
- return Object.values(enabledOlmOperatorsByName);
- },
-
- /**
- * Depending on the OpenShift version and certain selected operators, the
- * Backend can activate some other operators.
- * We need to synchronise them back to the form
- */
- syncOperators(
- uiOperators: OperatorCreateParams[],
- updatedOperators: Cluster['monitoredOperators'],
- ): Partial {
- const updates: Partial = {};
-
- // LVM operator can be automatically selected depending on OpenShift version + other operators
- const lvmPrevInactive = uiOperators?.find((op) => op.name === OPERATOR_NAME_LVM) === undefined;
- const lvmNowActive =
- updatedOperators?.find((op) => op.name === OPERATOR_NAME_LVM) !== undefined;
- if (lvmPrevInactive && lvmNowActive) {
- updates.useOdfLogicalVolumeManager = true;
- }
-
- // ODF operator will be automatically selected when the OpenShift AI operator is selected:
- const odfPrevInactive = uiOperators?.find((op) => op.name === OPERATOR_NAME_ODF) === undefined;
- const odfNowActive =
- updatedOperators?.find((op) => op.name === OPERATOR_NAME_ODF) !== undefined;
- if (odfPrevInactive && odfNowActive) {
- updates.useOpenShiftDataFoundation = true;
- }
-
- return updates;
- },
-
- async getSupportedOperators(): Promise {
+ getSupportedOperators: async (): Promise => {
const { data: operators } = await OperatorsAPI.list();
return operators;
},