diff --git a/locales/en/plugin__odf-console.json b/locales/en/plugin__odf-console.json
index 0ce5b7c17..cfbbf23e6 100644
--- a/locales/en/plugin__odf-console.json
+++ b/locales/en/plugin__odf-console.json
@@ -55,6 +55,8 @@
"We could not retrieve any information about the managed cluster {{names}}. Check the documentation for potential causes and follow the steps mentioned and try again.": "We could not retrieve any information about the managed cluster {{names}}. Check the documentation for potential causes and follow the steps mentioned and try again.",
"{{ names }} has either an unsupported Data Foundation version or the Data Foundation operator is missing, install or update to Data Foundation {{ version }} or the latest version to enable DR protection.": "{{ names }} has either an unsupported Data Foundation version or the Data Foundation operator is missing, install or update to Data Foundation {{ version }} or the latest version to enable DR protection.",
"{{ names }} is not connected to RHCS": "{{ names }} is not connected to RHCS",
+ "Cluster not pre-configured for Regional-DR": "Cluster not pre-configured for Regional-DR",
+ "The selected cluster(s)[{{clusters}}] is not configured for Regional-DR setup. Migrate the OSDs to optimise the cluster for disaster recovery services.": "The selected cluster(s)[{{clusters}}] is not configured for Regional-DR setup. Migrate the OSDs to optimise the cluster for disaster recovery services.",
"Sync schedule": "Sync schedule",
"Replication policy": "Replication policy",
"Information unavailable": "Information unavailable",
diff --git a/packages/mco/components/create-dr-policy/create-dr-policy.tsx b/packages/mco/components/create-dr-policy/create-dr-policy.tsx
index 67661b83c..803c3deb1 100644
--- a/packages/mco/components/create-dr-policy/create-dr-policy.tsx
+++ b/packages/mco/components/create-dr-policy/create-dr-policy.tsx
@@ -242,7 +242,7 @@ const CreateDRPolicy: React.FC<{}> = () => {
!!state.policyName &&
!!state.replicationType &&
state.selectedClusters.length === MAX_ALLOWED_CLUSTERS &&
- !checkForErrors(state.selectedClusters);
+ !checkForErrors(state.selectedClusters, state.replicationType);
const loaded = mirrorPeerLoaded && policyLoaded;
const loadedError = mirrorPeerLoadError || policyLoadedError;
@@ -317,7 +317,12 @@ const CreateDRPolicy: React.FC<{}> = () => {
label={t('Selected clusters')}
>
{state.selectedClusters.map((c, i) => (
-
+
))}
)}
diff --git a/packages/mco/components/create-dr-policy/reducer.ts b/packages/mco/components/create-dr-policy/reducer.ts
index b43f1c58f..ab2712097 100644
--- a/packages/mco/components/create-dr-policy/reducer.ts
+++ b/packages/mco/components/create-dr-policy/reducer.ts
@@ -7,6 +7,8 @@ export type StorageClusterInfoType = {
storageSystemNamespacedName: string;
// Ceph FSID to determine RDR/MDR.
cephFSID: string;
+ // OSDs are migrated for the RDR or not.
+ isDROptimized: boolean;
};
export type ODFConfigInfoType = {
diff --git a/packages/mco/components/create-dr-policy/select-cluster-list.tsx b/packages/mco/components/create-dr-policy/select-cluster-list.tsx
index e9e13af49..90399d7b1 100644
--- a/packages/mco/components/create-dr-policy/select-cluster-list.tsx
+++ b/packages/mco/components/create-dr-policy/select-cluster-list.tsx
@@ -93,6 +93,7 @@ const getODFInfo = (
storageClusterNamespace
);
const cephFSID = odfInfo?.storageCluster?.cephClusterFSID;
+ const isDROptimized = odfInfo?.storageCluster?.isDROptimized;
return {
odfVersion,
@@ -105,6 +106,7 @@ const getODFInfo = (
storageClusterNamespacedName,
storageSystemNamespacedName,
cephFSID,
+ isDROptimized,
},
};
} catch (err) {
@@ -119,6 +121,7 @@ const getODFInfo = (
storageClusterNamespacedName: '',
storageSystemNamespacedName: '',
cephFSID: '',
+ isDROptimized: false,
},
};
}
diff --git a/packages/mco/components/create-dr-policy/select-replication-type.tsx b/packages/mco/components/create-dr-policy/select-replication-type.tsx
index f9fcce86d..eab7064d6 100644
--- a/packages/mco/components/create-dr-policy/select-replication-type.tsx
+++ b/packages/mco/components/create-dr-policy/select-replication-type.tsx
@@ -45,7 +45,8 @@ const checkSyncPolicyAlreadyExists = (
});
const getClusterErrorInfo = (
- selectedClusters: ManagedClusterInfoType[]
+ selectedClusters: ManagedClusterInfoType[],
+ replicationType: REPLICATION_TYPE
): ClusterErrorType =>
selectedClusters.reduce(
(acc, cluster) => {
@@ -62,6 +63,12 @@ const getClusterErrorInfo = (
if (!storageClusterInfo?.cephFSID) {
acc.clustersWithUnsuccessfulODF.push(cluster.name);
}
+ if (
+ !storageClusterInfo?.isDROptimized &&
+ replicationType === REPLICATION_TYPE.ASYNC
+ ) {
+ acc.clustersWithoutDROptimizedODF.push(cluster.name);
+ }
return acc;
},
{
@@ -69,6 +76,7 @@ const getClusterErrorInfo = (
clustersWithUnsupportedODF: [],
clustersWithoutODF: [],
clustersWithUnsuccessfulODF: [],
+ clustersWithoutDROptimizedODF: [],
}
);
@@ -76,9 +84,13 @@ const getErrorMessage = (
selectedClusters: ManagedClusterInfoType[],
requiredODFVersion: string,
isSyncPolicyFound: boolean,
+ replicationType: REPLICATION_TYPE,
t: TFunction
): ErrorMessageType => {
- const clusterErrorInfo = getClusterErrorInfo(selectedClusters);
+ const clusterErrorInfo = getClusterErrorInfo(
+ selectedClusters,
+ replicationType
+ );
if (isSyncPolicyFound) {
return {
message: t('Existing DRPolicy detected'),
@@ -117,6 +129,14 @@ const getErrorMessage = (
names: clusterErrorInfo.clustersWithUnsuccessfulODF.join(' & '),
}),
};
+ } else if (!!clusterErrorInfo.clustersWithoutDROptimizedODF.length) {
+ return {
+ message: t('Cluster not pre-configured for Regional-DR'),
+ description: t(
+ 'The selected cluster(s)[{{clusters}}] is not configured for Regional-DR setup. Migrate the OSDs to optimise the cluster for disaster recovery services.',
+ { clusters: clusterErrorInfo.clustersWithoutDROptimizedODF.join(', ') }
+ ),
+ };
}
return null;
};
@@ -171,6 +191,7 @@ export const DRReplicationType: React.FC = ({
selectedClusters,
requiredODFVersion,
isSyncPolicyFound,
+ replicationType,
t
);
@@ -276,6 +297,7 @@ type ClusterErrorType = {
clustersWithUnsupportedODF: string[];
clustersWithoutODF: string[];
clustersWithUnsuccessfulODF: string[];
+ clustersWithoutDROptimizedODF: string[];
};
type ErrorMessageType = {
diff --git a/packages/mco/components/create-dr-policy/selected-cluster-view.tsx b/packages/mco/components/create-dr-policy/selected-cluster-view.tsx
index 1a70fdfa8..594026db6 100644
--- a/packages/mco/components/create-dr-policy/selected-cluster-view.tsx
+++ b/packages/mco/components/create-dr-policy/selected-cluster-view.tsx
@@ -1,4 +1,5 @@
import * as React from 'react';
+import { REPLICATION_TYPE } from '@odf/mco/constants';
import { parseNamespaceName } from '@odf/mco/utils';
import { RedExclamationCircleIcon } from '@odf/shared/status/icons';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
@@ -16,32 +17,38 @@ import './create-dr-policy.scss';
type SelectedClusterProps = {
id: number;
cluster: ManagedClusterInfoType;
+ replicationType: REPLICATION_TYPE;
};
-export const checkForErrors = (clusters: ManagedClusterInfoType[]) =>
+export const checkForErrors = (
+ clusters: ManagedClusterInfoType[],
+ replicationType: REPLICATION_TYPE
+) =>
clusters.some((cluster) => {
const { isManagedClusterAvailable, odfInfo } = cluster;
- const { cephFSID, storageSystemNamespacedName } =
+ const { cephFSID, storageSystemNamespacedName, isDROptimized } =
odfInfo.storageClusterInfo;
const [storageSystemName] = parseNamespaceName(storageSystemNamespacedName);
return (
!isManagedClusterAvailable ||
!odfInfo?.isValidODFVersion ||
!storageSystemName ||
- !cephFSID
+ !cephFSID ||
+ (replicationType === REPLICATION_TYPE.ASYNC && !isDROptimized)
);
});
export const SelectedCluster: React.FC = ({
id,
cluster,
+ replicationType,
}) => {
const { t } = useCustomTranslation();
const { name, region, odfInfo } = cluster;
const [storageSystemName] = parseNamespaceName(
odfInfo.storageClusterInfo.storageSystemNamespacedName
);
- const anyError = checkForErrors([cluster]);
+ const anyError = checkForErrors([cluster], replicationType);
return (