From 1ac83af6ac9a66d066e40d2f86db51f7d568c1f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Mart=C3=ADnez?= Date: Mon, 18 Nov 2024 15:16:39 +0100 Subject: [PATCH 1/5] Hide NFS builtin pool --- cypress/constants/storage-pool-const.ts | 2 + cypress/support.ts | 4 ++ .../storage-pool-in-storageclass-form.spec.ts | 20 +++++-- cypress/views/storage-pool.ts | 24 +++++--- packages/ocs/storage-class/sc-form.scss | 1 - packages/ocs/storage-class/sc-form.tsx | 31 +++++------ .../ocs/storage-pool/StoragePoolListPage.tsx | 55 ++++++++++--------- packages/odf/resources.ts | 13 +++-- 8 files changed, 90 insertions(+), 60 deletions(-) diff --git a/cypress/constants/storage-pool-const.ts b/cypress/constants/storage-pool-const.ts index c453774d7..e0d685f40 100644 --- a/cypress/constants/storage-pool-const.ts +++ b/cypress/constants/storage-pool-const.ts @@ -22,6 +22,8 @@ export enum POOL_TYPE { export const COMPRESSION_ON = 'aggressive'; export const ROOK_MODEL = 'cephblockpools.ceph.rook.io'; +export const CEPH_BUILTIN_MGR_POOL = 'builtin-mgr'; +export const CEPH_BUILTIN_NFS_POOL = 'ocs-storagecluster-cephnfs-builtin-pool'; export const CEPH_DEFAULT_BLOCK_POOL_NAME = 'ocs-storagecluster-cephblockpool'; export const CEPH_DEFAULT_FS_POOL_PREFIX = 'ocs-storagecluster-cephfilesystem'; export const CEPH_DEFAULT_FS_POOL_NAME = `${CEPH_DEFAULT_FS_POOL_PREFIX}-data0`; diff --git a/cypress/support.ts b/cypress/support.ts index 2d45a6bc9..9f1f85e0b 100644 --- a/cypress/support.ts +++ b/cypress/support.ts @@ -60,6 +60,10 @@ Cypress.Commands.add('install', () => { cy.contains('Create StorageSystem', { timeout: 15 * SECOND }).should( 'be.visible' ); + + // Uncomment next line only if the cluster has enough resources. + // cy.get('label[for="enable-nfs"]').click(); + cy.get('button').contains('Next').click(); // @TODO: Do we still want to uncheck the already unchecked 'Taint nodes' checkbox? // If yes, we should scroll down (needed after adding the performance profile selection) diff --git a/cypress/tests/storage-pool-in-storageclass-form.spec.ts b/cypress/tests/storage-pool-in-storageclass-form.spec.ts index 6abe7e204..46b6f5901 100644 --- a/cypress/tests/storage-pool-in-storageclass-form.spec.ts +++ b/cypress/tests/storage-pool-in-storageclass-form.spec.ts @@ -1,4 +1,6 @@ import { + CEPH_BUILTIN_MGR_POOL, + CEPH_BUILTIN_NFS_POOL, CEPH_DEFAULT_FS_POOL_PREFIX, POOL_TYPE, } from '../constants/storage-pool-const'; @@ -9,14 +11,23 @@ import { createStoragePoolInSCForm, fillPoolModalForm, checkStoragePoolIsSelectableInSCForm, + showAvailablePoolsInSCForm, } from '../views/storage-pool'; describe('Test storage pool creation when creating a new StorageClass', () => { - it(`Creates a new ${POOL_TYPE.BLOCK} pool`, () => { - const poolName = 'sc-block-name'; - + beforeEach(() => { cy.clickNavLink(['Storage', 'StorageClasses']); cy.byTestID('item-create').click(); + }); + + it(`does not show hidden pools`, () => { + showAvailablePoolsInSCForm(POOL_TYPE.BLOCK); + cy.byTestID(CEPH_BUILTIN_MGR_POOL).should('not.exist'); + cy.byTestID(CEPH_BUILTIN_NFS_POOL).should('not.exist'); + }); + + it(`Creates a new ${POOL_TYPE.BLOCK} pool`, () => { + const poolName = 'sc-block-name'; cy.log(`Create a new ${POOL_TYPE.BLOCK} pool`); createStoragePoolInSCForm(POOL_TYPE.BLOCK, poolName); @@ -37,9 +48,6 @@ describe('Test storage pool creation when creating a new StorageClass', () => { const poolName = 'sc-fs-name'; const poolFullName = `${CEPH_DEFAULT_FS_POOL_PREFIX}-${poolName}`; - cy.clickNavLink(['Storage', 'StorageClasses']); - cy.byTestID('item-create').click(); - cy.log(`Create a new ${POOL_TYPE.FILESYSTEM} pool`); createStoragePoolInSCForm(POOL_TYPE.FILESYSTEM, poolName); checkStoragePoolIsSelectableInSCForm(poolFullName); diff --git a/cypress/views/storage-pool.ts b/cypress/views/storage-pool.ts index 8d78c43ff..8bc024ef1 100644 --- a/cypress/views/storage-pool.ts +++ b/cypress/views/storage-pool.ts @@ -1,9 +1,10 @@ import { CEPH_DEFAULT_BLOCK_POOL_NAME, + CEPH_DEFAULT_FS_POOL_NAME, POOL_PROGRESS, POOL_TYPE, } from '../constants/storage-pool-const'; -import { STORAGE_SYSTEM_NAME } from '../consts'; +import { SECOND, STORAGE_SYSTEM_NAME } from '../consts'; import { NS } from '../utils/consts'; import { ODFCommon } from '../views/odf-common'; import { modal } from './modals'; @@ -38,8 +39,13 @@ export const navigateToStoragePoolList = () => { cy.byTestID('horizontal-link-Storage pools').click(); }; -const prepareStorageClassForm = (poolType: POOL_TYPE) => { +export const showAvailablePoolsInSCForm = (poolType: POOL_TYPE) => { const provisioner = poolType === POOL_TYPE.BLOCK ? 'rbd' : 'cephfs'; + const defaultPool = + poolType === POOL_TYPE.BLOCK + ? CEPH_DEFAULT_BLOCK_POOL_NAME + : CEPH_DEFAULT_FS_POOL_NAME; + cy.log('Selecting provisioner'); cy.byTestID('storage-class-provisioner-dropdown').click(); cy.byLegacyTestID('dropdown-text-filter').type( @@ -48,17 +54,19 @@ const prepareStorageClassForm = (poolType: POOL_TYPE) => { cy.byTestID('dropdown-menu-item-link') .contains(`openshift-storage.${provisioner}.csi.ceph.com`) .click(); - - cy.log('Click on: Create new storage pool'); - cy.byTestID('pool-dropdown-toggle', { timeout: 1000 }) + cy.log('Show Storage pool list.'); + cy.byTestID('pool-dropdown-toggle', { timeout: 5 * SECOND }) .should('be.visible') .click(); - cy.byTestID('create-new-pool-button').should('be.visible').click(); + cy.byTestID('create-new-pool-button').should('be.visible'); + cy.byTestID(defaultPool).should('be.visible'); }; export const fillPoolModalForm = (poolType: POOL_TYPE, poolName: string) => { - prepareStorageClassForm(poolType); - cy.log('Make sure the storage pool creation form is open'); + showAvailablePoolsInSCForm(poolType); + cy.log('Click on: Create new storage pool'); + cy.byTestID('create-new-pool-button').click(); + cy.log('Make sure the storage pool creation form modal is opened.'); modal.shouldBeOpened(); modal.modalTitleShouldContain('Create Storage Pool'); fillStoragePoolForm(poolType, poolName); diff --git a/packages/ocs/storage-class/sc-form.scss b/packages/ocs/storage-class/sc-form.scss index 4d6c76a58..dacf53ba6 100644 --- a/packages/ocs/storage-class/sc-form.scss +++ b/packages/ocs/storage-class/sc-form.scss @@ -59,5 +59,4 @@ .ocs-storage-class__pool--create { color: var(--pf-v5-global--primary-color--100); - display: block; } diff --git a/packages/ocs/storage-class/sc-form.tsx b/packages/ocs/storage-class/sc-form.tsx index b3d33ebcb..0b1563e25 100644 --- a/packages/ocs/storage-class/sc-form.tsx +++ b/packages/ocs/storage-class/sc-form.tsx @@ -20,7 +20,7 @@ import { useODFSystemFlagsSelector, } from '@odf/core/redux'; import { - cephBlockPoolResource, + getCephBlockPoolResource, cephClusterResource, } from '@odf/core/resources'; import { @@ -77,7 +77,6 @@ import { Form, Radio, ActionGroup, - Icon, } from '@patternfly/react-core'; import { AddCircleOIcon, CaretDownIcon } from '@patternfly/react-icons'; import { @@ -172,10 +171,10 @@ const getPoolDropdownItems = ( }) } > - + {t('Create new storage pool')} - + , , ] @@ -439,10 +438,6 @@ export const BlockPoolResourceComponent: React.FC = ({ const launchModal = useModal(); - const [poolsData, poolDataLoaded, poolDataLoadError] = useK8sWatchResource< - StoragePoolKind[] - >(cephBlockPoolResource); - const [cephClusters, cephClustersLoaded, cephClustersLoadError] = useK8sWatchResource(cephClusterResource); @@ -450,6 +445,18 @@ export const BlockPoolResourceComponent: React.FC = ({ const [poolName, setPoolName] = React.useState(''); const [systemNamespace, setSystemNamespace] = React.useState(); + const cephCluster = getResourceInNs(cephClusters, systemNamespace); + + const { systemFlags, areFlagsLoaded, flagsLoadError, areFlagsSafe } = + useODFSystemFlagsSelector(); + const isExternal = systemFlags[systemNamespace]?.isExternalMode; + + const poolNs = getNamespace(cephCluster); + const clusterName = systemFlags[poolNs]?.ocsClusterName; + const defaultPoolName = `${clusterName}-cephblockpool`; + const [poolsData, poolDataLoaded, poolDataLoadError] = useK8sWatchResource< + StoragePoolKind[] + >(getCephBlockPoolResource(clusterName)); const filteredPools = poolsData?.filter( (pool) => getNamespace(pool) === systemNamespace ); @@ -458,15 +465,7 @@ export const BlockPoolResourceComponent: React.FC = ({ const poolData = getStoragePoolsFromBlockPools(filteredPools) || []; const existingNames = getExistingBlockPoolNames(poolData); - const cephCluster = getResourceInNs(cephClusters, systemNamespace); - - const { systemFlags, areFlagsLoaded, flagsLoadError, areFlagsSafe } = - useODFSystemFlagsSelector(); - const isExternal = systemFlags[systemNamespace]?.isExternalMode; - // Get the default deviceClass required by the 'create' modal. - const poolNs = getNamespace(cephCluster); - const defaultPoolName = `${systemFlags[poolNs]?.ocsClusterName}-cephblockpool`; const defaultPool = filteredPools.find( (pool: StoragePoolKind) => pool.metadata.name === defaultPoolName ); diff --git a/packages/ocs/storage-pool/StoragePoolListPage.tsx b/packages/ocs/storage-pool/StoragePoolListPage.tsx index 0b3d20b00..dc43d3d0e 100644 --- a/packages/ocs/storage-pool/StoragePoolListPage.tsx +++ b/packages/ocs/storage-pool/StoragePoolListPage.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { useODFSystemFlagsSelector } from '@odf/core/redux'; -import { cephBlockPoolResource } from '@odf/core/resources'; +import { getCephBlockPoolResource } from '@odf/core/resources'; import { healthStateMapping } from '@odf/shared/dashboards/status-card/states'; import { useCustomPrometheusPoll, @@ -33,6 +33,7 @@ import { useListPageFilter, VirtualizedTable, useK8sWatchResources, + WatchK8sResources, } from '@openshift-console/dynamic-plugin-sdk'; import Status from '@openshift-console/dynamic-plugin-sdk/lib/app/components/status/Status'; import classNames from 'classnames'; @@ -420,20 +421,7 @@ type StoragePoolListPageProps = { storageClasses: StorageClassResourceKind[]; loaded: boolean; loadError: any; - managedByOCS: string; -}; - -const resources = { - sc: { - kind: StorageClassModel.kind, - namespaced: false, - isList: true, - }, - blockPools: cephBlockPoolResource, - filesystem: { - kind: referenceForModel(CephFileSystemModel), - isList: false, - }, + clusterName: string; }; type WatchType = { @@ -442,18 +430,35 @@ type WatchType = { filesystem: CephFilesystemKind; }; +const getResources = ( + clusterName: string, + clusterNamespace: string +): WatchK8sResources => { + return { + sc: { + kind: StorageClassModel.kind, + namespaced: false, + isList: true, + }, + blockPools: getCephBlockPoolResource(clusterName), + filesystem: { + kind: referenceForModel(CephFileSystemModel), + isList: false, + name: `${clusterName}-cephfilesystem`, + namespace: clusterNamespace, + }, + }; +}; + // To divide the number of hooks, add _StoragePoolListPage on top of StoragePoolListPage. const _StoragePoolListPage: React.FC = () => { const { namespace: clusterNs } = useParams(); const { systemFlags, areFlagsLoaded, flagsLoadError } = useODFSystemFlagsSelector(); - const managedByOCS = systemFlags[clusterNs]?.ocsClusterName; - - resources.filesystem['name'] = `${managedByOCS}-cephfilesystem`; - resources.filesystem['namespace'] = clusterNs; + const clusterName = systemFlags[clusterNs]?.ocsClusterName; const response = useK8sWatchResources( - resources + getResources(clusterName, clusterNs) ) as WatchK8sResults; const storageClasses = response.sc.data; @@ -489,7 +494,7 @@ const _StoragePoolListPage: React.FC = () => { storageClasses={memoizedSC} loaded={loaded} loadError={error} - managedByOCS={managedByOCS} + clusterName={clusterName} /> ); }; @@ -499,7 +504,7 @@ const StoragePoolListPage: React.FC = ({ storageClasses, loaded, loadError, - managedByOCS, + clusterName, }) => { const { t } = useCustomTranslation(); @@ -516,7 +521,7 @@ const StoragePoolListPage: React.FC = ({ query: getPoolQuery( poolNames, StorageDashboardQuery.POOL_RAW_CAPACITY_USED, - managedByOCS + clusterName ), basePath: usePrometheusBasePath(), }, @@ -532,7 +537,7 @@ const StoragePoolListPage: React.FC = ({ query: getPoolQuery( poolNames, StorageDashboardQuery.POOL_COMPRESSION_SAVINGS, - managedByOCS + clusterName ), basePath: usePrometheusBasePath(), }, @@ -551,7 +556,7 @@ const StoragePoolListPage: React.FC = ({ query: getPoolQuery( poolNames, StorageDashboardQuery.POOL_MIRRORING_IMAGE_HEALTH, - managedByOCS + clusterName ), basePath: usePrometheusBasePath(), }, diff --git a/packages/odf/resources.ts b/packages/odf/resources.ts index 6619667f9..e1cb797fc 100644 --- a/packages/odf/resources.ts +++ b/packages/odf/resources.ts @@ -61,11 +61,16 @@ export const subscriptionResource: WatchK8sResource = { * Retrieve all the CRs except those not meant to be * exposed to the users. See: * https://bugzilla.redhat.com/show_bug.cgi?id=2297295 + * https://issues.redhat.com/browse/DFBUGS-871 */ -export const cephBlockPoolResource: WatchK8sResource = { - kind: referenceForModel(CephBlockPoolModel), - isList: true, - fieldSelector: 'metadata.name!=builtin-mgr', +export const getCephBlockPoolResource = ( + clusterName: string +): WatchK8sResource => { + return { + kind: referenceForModel(CephBlockPoolModel), + isList: true, + fieldSelector: `metadata.name!=builtin-mgr,metadata.name!=${clusterName}-cephnfs-builtin-pool`, + }; }; export const nodeResource: WatchK8sResource = { From 9e4d7e04c019722d9331204908e0b04674e13220 Mon Sep 17 00:00:00 2001 From: SanjalKatiyar Date: Wed, 20 Nov 2024 13:32:43 +0530 Subject: [PATCH 2/5] Fix 'cross-spawn' CVE --- package.json | 3 ++- yarn.lock | 49 +++++-------------------------------------------- 2 files changed, 7 insertions(+), 45 deletions(-) diff --git a/package.json b/package.json index 605d5854d..7d52b477e 100644 --- a/package.json +++ b/package.json @@ -184,7 +184,8 @@ "webpack": "^5.96.1", "webpack-bundle-analyzer/ws": "^7.5.10", "webpack-dev-server/express": "^4.21.0", - "tough-cookie": "^4.1.3" + "tough-cookie": "^4.1.3", + "cross-spawn": "^7.0.6" }, "engines": { "node": ">=20.x" diff --git a/yarn.lock b/yarn.lock index cd2eac92b..3686ca304 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5585,19 +5585,10 @@ create-jest@^29.7.0: jest-util "^29.7.0" prompts "^2.0.1" -cross-spawn@^5.0.1: - version "5.1.0" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-5.1.0.tgz#e8bd0efee58fcff6f8f94510a0a554bbfa235449" - integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== - dependencies: - lru-cache "^4.0.1" - shebang-command "^1.2.0" - which "^1.2.9" - -cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: - version "7.0.3" - resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6" - integrity sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w== +cross-spawn@^5.0.1, cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3, cross-spawn@^7.0.6: + version "7.0.6" + resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.6.tgz#8a58fe78f00dcd70c370451759dfbfaf03e8ee9f" + integrity sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA== dependencies: path-key "^3.1.0" shebang-command "^2.0.0" @@ -9941,14 +9932,6 @@ loose-envify@^1.1.0, loose-envify@^1.2.0, loose-envify@^1.3.1, loose-envify@^1.4 dependencies: js-tokens "^3.0.0 || ^4.0.0" -lru-cache@^4.0.1: - version "4.1.5" - resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-4.1.5.tgz#8bbe50ea85bed59bc9e33dcab8235ee9bcf443cd" - integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== - dependencies: - pseudomap "^1.0.2" - yallist "^2.1.2" - lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920" @@ -11240,11 +11223,6 @@ proxy-from-env@1.0.0: resolved "https://registry.yarnpkg.com/proxy-from-env/-/proxy-from-env-1.0.0.tgz#33c50398f70ea7eb96d21f7b817630a55791c7ee" integrity sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A== -pseudomap@^1.0.2: - version "1.0.2" - resolved "https://registry.yarnpkg.com/pseudomap/-/pseudomap-1.0.2.tgz#f052a28da70e618917ef0a8ac34c1ae5a68286b3" - integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== - psl@^1.1.33: version "1.8.0" resolved "https://registry.yarnpkg.com/psl/-/psl-1.8.0.tgz#9326f8bcfb013adcc005fdff056acce020e51c24" @@ -12224,13 +12202,6 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" -shebang-command@^1.2.0: - version "1.2.0" - resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-1.2.0.tgz#44aac65b695b03398968c39f363fee5deafdf1ea" - integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== - dependencies: - shebang-regex "^1.0.0" - shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/shebang-command/-/shebang-command-2.0.0.tgz#ccd0af4f8835fbdc265b82461aaf0c36663f34ea" @@ -12238,11 +12209,6 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" -shebang-regex@^1.0.0: - version "1.0.0" - resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-1.0.0.tgz#da42f49740c0b42db2ca9728571cb190c98efea3" - integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== - shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/shebang-regex/-/shebang-regex-3.0.0.tgz#ae16f1644d873ecad843b0307b143362d4c42172" @@ -14165,7 +14131,7 @@ which-typed-array@^1.1.8: has-tostringtag "^1.0.0" is-typed-array "^1.1.10" -which@^1.2.9, which@^1.3.1: +which@^1.3.1: version "1.3.1" resolved "https://registry.yarnpkg.com/which/-/which-1.3.1.tgz#a45043d54f5805316da8d62f9f50918d3da70b0a" integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== @@ -14307,11 +14273,6 @@ y18n@^5.0.5: resolved "https://registry.yarnpkg.com/y18n/-/y18n-5.0.8.tgz#7f4934d0f7ca8c56f95314939ddcd2dd91ce1d55" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== -yallist@^2.1.2: - version "2.1.2" - resolved "https://registry.yarnpkg.com/yallist/-/yallist-2.1.2.tgz#1c11f9218f076089a47dd512f93c6699a6a81d52" - integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== - yallist@^3.0.2: version "3.1.1" resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" From a7195d335ff37409cb9971257add1028804ba0c8 Mon Sep 17 00:00:00 2001 From: Gowtham Shanmugasundaram Date: Wed, 20 Nov 2024 14:39:35 +0530 Subject: [PATCH 3/5] Fix - [RDR] UI blocks a DR operation on an appset based workload Signed-off-by: Gowtham Shanmugasundaram --- .../app-failover-relocate/helper/error-messages.tsx | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/mco/components/modals/app-failover-relocate/helper/error-messages.tsx b/packages/mco/components/modals/app-failover-relocate/helper/error-messages.tsx index a97575729..ae08c7017 100644 --- a/packages/mco/components/modals/app-failover-relocate/helper/error-messages.tsx +++ b/packages/mco/components/modals/app-failover-relocate/helper/error-messages.tsx @@ -7,7 +7,7 @@ import { AlertVariant } from '@patternfly/react-core'; export enum ErrorMessageType { // Priority wise error messages - DR_IS_NOT_ENABLED_FAILOVER, + DR_IS_NOT_ENABLED_FAILOVER = 1, DR_IS_NOT_ENABLED_RELOCATE, FAILOVER_READINESS_CHECK_FAILED, RELOCATE_READINESS_CHECK_FAILED, @@ -287,8 +287,8 @@ export const evaluateErrorMessage = ( errorMessage: ErrorMessageType, includeWarning: boolean = false ) => { - if (!includeWarning ? errorMessage < 20 : true) { - return errorMessage; + if (!errorMessage || (!includeWarning && errorMessage >= 20)) { + return -1; } - return -1; + return errorMessage; }; From 3da81f1ca6427239c094dbb3d7138433a5984138 Mon Sep 17 00:00:00 2001 From: Malay Kumar Parida Date: Thu, 14 Nov 2024 08:36:37 +0000 Subject: [PATCH 4/5] Add info alert for In-transit Encryption in external mode The configurations for In-Transit Encryption in external mode are all required to be done on the RHCS cluster by the ceph admin. Ticking the checkbox on ODF side only sets the kernel mount option for cephFS. So it might be misleading the user to think, the checkbox is enough to enable Eit in external mode. So added an info alert under the checkbox to clarify that settings need to be applied on the RHCS cluster. Also reworded the description of the checkbox to make it more clear to the user. Signed-off-by: Malay Kumar Parida --- locales/en/plugin__odf-console.json | 4 ++- .../security-and-network-step/encryption.tsx | 33 +++++++++++++++++-- packages/shared/src/constants/doc.ts | 12 +++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/locales/en/plugin__odf-console.json b/locales/en/plugin__odf-console.json index c4b0aeb3e..305e67331 100644 --- a/locales/en/plugin__odf-console.json +++ b/locales/en/plugin__odf-console.json @@ -981,7 +981,9 @@ "MultiCloud Object Gateway supports encryption for objects by default.": "MultiCloud Object Gateway supports encryption for objects by default.", "Enable data encryption for block and file storage": "Enable data encryption for block and file storage", "Enable encryption": "Enable encryption", - "A secure mode that encrypts all data passing over the network": "A secure mode that encrypts all data passing over the network", + "Encrypts all Ceph traffic including data, using Ceph msgrv2": "Encrypts all Ceph traffic including data, using Ceph msgrv2", + "Verify your RHCS cluster has the necessary in-transit encryption settings configured to enable in-transit encryption on your external cluster. Refer to the documentation for detailed configuration steps.": "Verify your RHCS cluster has the necessary in-transit encryption settings configured to enable in-transit encryption on your external cluster. Refer to the documentation for detailed configuration steps.", + "Documentation link": "Documentation link", "An error has occurred: {{error}}": "An error has occurred: {{error}}", "The uploaded file is not a valid JSON file": "The uploaded file is not a valid JSON file", "External storage system metadata": "External storage system metadata", diff --git a/packages/odf/components/create-storage-system/create-storage-system-steps/security-and-network-step/encryption.tsx b/packages/odf/components/create-storage-system/create-storage-system-steps/security-and-network-step/encryption.tsx index 9c756dfea..4ae8ea0f6 100644 --- a/packages/odf/components/create-storage-system/create-storage-system-steps/security-and-network-step/encryption.tsx +++ b/packages/odf/components/create-storage-system/create-storage-system-steps/security-and-network-step/encryption.tsx @@ -1,9 +1,17 @@ import * as React from 'react'; import { ValidationType } from '@odf/core/types'; import { AdvancedSubscription } from '@odf/shared/badges/advanced-subscription'; +import { inTransitEncryptionSettingsForRHCS } from '@odf/shared/constants/doc'; import { FieldLevelHelp } from '@odf/shared/generic/FieldLevelHelp'; +import { DOC_VERSION as odfDocVersion } from '@odf/shared/hooks'; import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook'; -import { Checkbox, FormGroup, Form } from '@patternfly/react-core'; +import { + Alert, + AlertVariant, + Checkbox, + FormGroup, + Form, +} from '@patternfly/react-core'; import { KMSEmptyState } from '../../../../constants'; import { KMSConfigure } from '../../../kms-config/kms-config'; import { ValidationMessage } from '../../../utils/common-odf-install-el'; @@ -291,13 +299,34 @@ export const Encryption: React.FC = ({ data-checked-state={encryption.inTransit} label={t('In-transit encryption')} description={t( - 'A secure mode that encrypts all data passing over the network' + 'Encrypts all Ceph traffic including data, using Ceph msgrv2' )} onChange={(_event, checked: boolean) => handleInTransitEncryptionOnChange(checked) } /> )} + {isExternal && encryption.inTransit && ( + + {t( + 'Verify your RHCS cluster has the necessary in-transit encryption settings configured to enable in-transit encryption on your external cluster. Refer to the documentation for detailed configuration steps.' + )}{' '} + + {t('Documentation link')} + + + } + /> + )} {!encryption.hasHandled && ( diff --git a/packages/shared/src/constants/doc.ts b/packages/shared/src/constants/doc.ts index 4088b19f3..a5bade02a 100644 --- a/packages/shared/src/constants/doc.ts +++ b/packages/shared/src/constants/doc.ts @@ -14,3 +14,15 @@ export const odfDRDocApplyPolicy = (odfDocVersion) => `${odfDRDocHome( odfDocVersion )}#apply-drpolicy-to-sample-application_manage-dr`; + +export const odfDeployExternalMode = (odfDocVersion) => + `${odfDocBasePath( + odfDocVersion + )}/deploying_openshift_data_foundation_in_external_mode`; + +export const inTransitEncryptionSettingsForRHCS = ( + odfDocVersion: string +): string => + `${odfDeployExternalMode( + odfDocVersion + )}/deploy-openshift-data-foundation-using-red-hat-ceph-storage#creating-an-openshift-data-foundation-cluster-service-for-external-storage_ceph-external`; From f9e4f2a831173cc567cd6937b5db4acedd794b0b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alfonso=20Mart=C3=ADnez?= Date: Tue, 19 Nov 2024 18:12:42 +0100 Subject: [PATCH 5/5] Enable lint rules for naming conventions --- .eslintrc.js | 39 ++++++++++++ cypress/constants/storage-pool-const.ts | 6 +- cypress/consts.ts | 2 +- cypress/tests/add-capacity.spec.ts | 6 +- .../storage-pool-in-storageclass-form.spec.ts | 26 ++++---- cypress/tests/storage-pool.spec.ts | 24 ++++---- cypress/views/block-pool.ts | 49 +++------------ cypress/views/storage-pool.ts | 52 ++++++++-------- packages/ibm/system-connection-details.tsx | 4 +- .../create-dr-policy/create-dr-policy.tsx | 6 +- .../create-dr-policy/select-cluster-list.tsx | 22 ++++--- .../select-replication-type.tsx | 12 ++-- .../selected-cluster-validator.tsx | 4 +- .../utils/cluster-list-utils.ts | 17 +++--- .../create-dr-policy/utils/k8s-utils.ts | 8 +-- .../create-dr-policy/utils/reducer.ts | 6 +- .../drpolicy-list-page/drpolicy-list-page.tsx | 8 +-- .../cluster-app-card/application.tsx | 25 ++++---- .../cluster-app-card/cluster-app-card.tsx | 12 ++-- .../cluster-app-card/cluster.tsx | 18 +++--- .../cluster-app-card/common.tsx | 16 ++--- .../parsers/applicationset-parser.tsx | 8 +-- .../parsers/discovered-parser.tsx | 8 +-- .../parsers/subscription-parser.tsx | 6 +- .../argo-application-set.tsx | 8 +-- .../app-data-policies-status/dr-status.tsx | 16 ++--- .../subscriptions/dr-status-card.tsx | 11 ++-- .../subscriptions/dr-status-table.tsx | 12 ++-- .../failover-relocate-modal-body.tsx | 16 ++--- .../subscriptions/failover-relocate-modal.tsx | 6 +- .../subscriptions/peer-cluster-status.tsx | 18 +++--- .../subscriptions/target-cluster-selector.tsx | 8 +-- .../app-manage-policies-modal.tsx | 4 +- .../assign-policy-view.tsx | 8 +-- .../helper/assign-policy-view-footer.tsx | 4 +- .../helper/pvc-details-wizard-content.tsx | 4 +- .../helper/select-policy-wizard-content.tsx | 4 +- .../manage-policy-view.tsx | 4 +- .../parsers/application-set-parser.tsx | 4 +- .../parsers/subscription-parser.tsx | 4 +- .../app-manage-policies/utils/parser-utils.ts | 4 +- .../modals/app-manage-policies/utils/types.ts | 6 +- .../protected-applications/components.tsx | 42 ++++++------- .../protected-applications/list-page.tsx | 26 ++++---- .../protected-apps-list-page.spec.tsx | 14 ++--- .../protected-applications/utils.tsx | 30 ++++----- packages/mco/constants/acm.ts | 10 +-- packages/mco/constants/dashboard.ts | 2 +- packages/mco/constants/disaster-recovery.ts | 18 +++--- packages/mco/types/dashboard.ts | 10 +-- packages/mco/types/ramen.ts | 4 +- packages/mco/utils/disaster-recovery.tsx | 61 +++++++++---------- packages/ocs/constants/common.ts | 8 +-- .../dashboards/block-pool/details-card.tsx | 4 +- .../buckets-card/buckets-card.tsx | 4 +- .../capacity-breakdown-card.tsx | 10 +-- .../resource-providers-card.tsx | 4 +- .../storage-efficiency-card.tsx | 8 ++- .../create-storage-pool-modal.tsx | 30 ++++----- .../delete-storage-pool-modal.tsx | 24 +++----- .../ocs/modals/storage-pool/modal-footer.tsx | 28 ++++----- .../update-storage-pool-modal.tsx | 14 ++--- packages/ocs/storage-class/sc-form.tsx | 16 ++--- .../ocs/storage-pool/CreateStoragePool.tsx | 18 +++--- .../ocs/storage-pool/StoragePoolListPage.tsx | 39 ++++++------ packages/ocs/storage-pool/body.tsx | 30 ++++----- packages/ocs/types.ts | 8 +-- packages/ocs/utils/common.ts | 4 +- packages/ocs/utils/storage-pool.tsx | 26 ++++---- .../external-storage/external-storage.ts | 4 +- .../attach-storage-storagesystem/state.ts | 12 ++-- .../storage-pool-form.tsx | 6 +- .../odf/components/create-bs/create-bs.tsx | 28 ++++----- .../system-connection-details.tsx | 6 +- .../create-storage-system/payloads.ts | 4 +- .../mcg-endpoints/s3-endpoint-type.tsx | 12 ++-- .../mcg/CreateObjectBucketClaim.tsx | 4 +- .../namespace-store/namespace-store-form.tsx | 48 +++++++-------- .../components/resource-pages/Providers.tsx | 30 ++++----- .../buckets-list-page/bucketsListPage.tsx | 2 +- packages/odf/components/utils/common.ts | 8 +-- packages/odf/constants/common.ts | 2 +- packages/odf/constants/mcg.ts | 58 +++++++++--------- packages/odf/constants/network.ts | 2 +- packages/odf/constants/providerSchema.ts | 36 +++++------ .../add-capacity/add-capacity-modal.tsx | 4 +- .../DeleteBucketModal.tsx | 2 +- packages/odf/redux/actions/odf-namespace.ts | 14 ++--- .../odf/redux/actions/odf-system-flags.ts | 4 +- .../odf/redux/dispatchers/odf-namespace.ts | 6 +- packages/odf/redux/reducers/odf-namespace.ts | 10 +-- .../odf/redux/reducers/odf-system-flags.ts | 4 +- packages/odf/redux/selectors/odf-namespace.ts | 6 +- packages/odf/types/mcg.ts | 8 +-- packages/odf/utils/mcg.ts | 47 ++++++++------ packages/shared/src/charts/tooltip.tsx | 36 +++++------ packages/shared/src/constants/k8s.ts | 2 +- .../prometheus-utilization-item.tsx | 7 +-- .../utilization-card/utilization-item.tsx | 7 +-- .../shared/src/file-handling/upload-file.tsx | 4 +- .../GettingStartedExpandableGrid.tsx | 14 +++-- .../shared/src/table/selectable-table.tsx | 6 +- 102 files changed, 732 insertions(+), 728 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index 4110238e9..a68be04bf 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -66,6 +66,7 @@ module.exports = { 'react/jsx-curly-newline': 'off', 'react/jsx-indent': 'off', 'react/jsx-no-useless-fragment': ['error', { allowExpressions: true }], + 'react/jsx-pascal-case': 'error', 'react/no-unused-prop-types': 'off', 'consistent-return': 'off', 'default-case': 'off', @@ -102,6 +103,44 @@ module.exports = { 'jsx-a11y/no-static-element-interactions': 'off', 'max-classes-per-file': 'off', 'max-len': 'off', + '@typescript-eslint/naming-convention': [ + 'error', + { + selector: 'enumMember', + format: ['PascalCase', 'UPPER_CASE'], + }, + { + selector: 'import', + format: ['camelCase', 'PascalCase'], + leadingUnderscore: 'allow', + }, + { + selector: 'objectLiteralMethod', + format: ['camelCase', 'PascalCase'], + }, + { + selector: 'parameter', + format: ['camelCase', 'PascalCase'], + leadingUnderscore: 'allow', + }, + { + selector: 'property', + format: null, + }, + { + selector: 'variable', + // React Components, regular variables, constants. + format: ['PascalCase', 'camelCase', 'UPPER_CASE'], + }, + { + selector: 'typeLike', + format: ['PascalCase'], + }, + { + selector: 'default', + format: ['camelCase'], + }, + ], 'no-empty-function': 'off', '@typescript-eslint/no-empty-function': 'error', 'no-empty-pattern': 'off', diff --git a/cypress/constants/storage-pool-const.ts b/cypress/constants/storage-pool-const.ts index e0d685f40..00673123f 100644 --- a/cypress/constants/storage-pool-const.ts +++ b/cypress/constants/storage-pool-const.ts @@ -1,10 +1,10 @@ -export enum POOL_STATE { +export enum PoolState { READY = 'Ready', RECONCILE_FAILED = 'ReconcileFailed', FAILURE = 'Failure', } -export enum POOL_PROGRESS { +export enum PoolProgress { CREATED = 'created', FAILED = 'failed', PROGRESS = 'progress', @@ -15,7 +15,7 @@ export enum POOL_PROGRESS { BOUNDED = 'bounded', } -export enum POOL_TYPE { +export enum PoolType { BLOCK = 'Block', FILESYSTEM = 'Filesystem', } diff --git a/cypress/consts.ts b/cypress/consts.ts index 617af4096..9548a0536 100644 --- a/cypress/consts.ts +++ b/cypress/consts.ts @@ -19,7 +19,7 @@ const STORAGECLUSTER_PHASE = `"$(oc get storageclusters -n openshift-storage -o= )}')"`; export const OCS_SC_STATE = `until [ ${STORAGECLUSTER_PHASE} = "Ready" ]; do sleep 1; done;`; -export enum CLUSTER_STATUS { +export enum ClusterStatus { READY = 'Ready', PROGRESSING = 'Progressing', HEALTH_ERROR = 'HEALTH_ERR', diff --git a/cypress/tests/add-capacity.spec.ts b/cypress/tests/add-capacity.spec.ts index fdea50fa7..6f1ec6900 100644 --- a/cypress/tests/add-capacity.spec.ts +++ b/cypress/tests/add-capacity.spec.ts @@ -1,6 +1,6 @@ import * as _ from 'lodash-es'; import { - CLUSTER_STATUS, + ClusterStatus, STORAGE_SYSTEM_NAME, STORAGE_CLUSTER_NAME, CLUSTER_NAMESPACE, @@ -51,7 +51,7 @@ describe('OCS Operator Expansion of Storage Class Test', () => { cy.log('Check if ceph cluster is healthy before expansion'); expect(cephCluster.status.ceph.health).not.to.equal( - CLUSTER_STATUS.HEALTH_ERROR + ClusterStatus.HEALTH_ERROR ); }); cy.exec( @@ -128,7 +128,7 @@ describe('OCS Operator Expansion of Storage Class Test', () => { cy.log('Check if ceph cluster is healthy after expansion'); expect(cephCluster.status.ceph.health).to.not.equal( - CLUSTER_STATUS.HEALTH_ERROR + ClusterStatus.HEALTH_ERROR ); }); cy.exec(`oc get po -n ${CLUSTER_NAMESPACE} -o json`).then((res) => { diff --git a/cypress/tests/storage-pool-in-storageclass-form.spec.ts b/cypress/tests/storage-pool-in-storageclass-form.spec.ts index 46b6f5901..6a2a8e1f8 100644 --- a/cypress/tests/storage-pool-in-storageclass-form.spec.ts +++ b/cypress/tests/storage-pool-in-storageclass-form.spec.ts @@ -2,7 +2,7 @@ import { CEPH_BUILTIN_MGR_POOL, CEPH_BUILTIN_NFS_POOL, CEPH_DEFAULT_FS_POOL_PREFIX, - POOL_TYPE, + PoolType, } from '../constants/storage-pool-const'; import { deleteBlockPoolFromCLI, @@ -21,41 +21,39 @@ describe('Test storage pool creation when creating a new StorageClass', () => { }); it(`does not show hidden pools`, () => { - showAvailablePoolsInSCForm(POOL_TYPE.BLOCK); + showAvailablePoolsInSCForm(PoolType.BLOCK); cy.byTestID(CEPH_BUILTIN_MGR_POOL).should('not.exist'); cy.byTestID(CEPH_BUILTIN_NFS_POOL).should('not.exist'); }); - it(`Creates a new ${POOL_TYPE.BLOCK} pool`, () => { + it(`Creates a new ${PoolType.BLOCK} pool`, () => { const poolName = 'sc-block-name'; - cy.log(`Create a new ${POOL_TYPE.BLOCK} pool`); - createStoragePoolInSCForm(POOL_TYPE.BLOCK, poolName); + cy.log(`Create a new ${PoolType.BLOCK} pool`); + createStoragePoolInSCForm(PoolType.BLOCK, poolName); checkStoragePoolIsSelectableInSCForm(poolName); verifyBlockPoolJSON(poolName); - cy.log( - `Try to create a new ${POOL_TYPE.BLOCK} pool using an existing name` - ); - fillPoolModalForm(POOL_TYPE.BLOCK, poolName); + cy.log(`Try to create a new ${PoolType.BLOCK} pool using an existing name`); + fillPoolModalForm(PoolType.BLOCK, poolName); cy.byLegacyTestID('confirm-action').should('be.disabled'); cy.byLegacyTestID('modal-cancel-action').click(); deleteBlockPoolFromCLI(poolName); }); - it(`Creates a new ${POOL_TYPE.FILESYSTEM} pool`, () => { + it(`Creates a new ${PoolType.FILESYSTEM} pool`, () => { const poolName = 'sc-fs-name'; const poolFullName = `${CEPH_DEFAULT_FS_POOL_PREFIX}-${poolName}`; - cy.log(`Create a new ${POOL_TYPE.FILESYSTEM} pool`); - createStoragePoolInSCForm(POOL_TYPE.FILESYSTEM, poolName); + cy.log(`Create a new ${PoolType.FILESYSTEM} pool`); + createStoragePoolInSCForm(PoolType.FILESYSTEM, poolName); checkStoragePoolIsSelectableInSCForm(poolFullName); cy.log( - `Try to create a new ${POOL_TYPE.FILESYSTEM} pool using an existing name` + `Try to create a new ${PoolType.FILESYSTEM} pool using an existing name` ); - fillPoolModalForm(POOL_TYPE.FILESYSTEM, poolName); + fillPoolModalForm(PoolType.FILESYSTEM, poolName); cy.byLegacyTestID('confirm-action').should('be.disabled'); cy.byLegacyTestID('modal-cancel-action').click(); diff --git a/cypress/tests/storage-pool.spec.ts b/cypress/tests/storage-pool.spec.ts index 8d1527bfa..6224be7a9 100644 --- a/cypress/tests/storage-pool.spec.ts +++ b/cypress/tests/storage-pool.spec.ts @@ -1,7 +1,7 @@ import { - POOL_PROGRESS, + PoolProgress, CEPH_DEFAULT_BLOCK_POOL_NAME, - POOL_TYPE, + PoolType, CEPH_DEFAULT_FS_POOL_NAME, CEPH_DEFAULT_FS_POOL_PREFIX, } from '../constants/storage-pool-const'; @@ -30,9 +30,9 @@ describe('Block pool on ODF UI', () => { }); it('Check for a new pool creation', () => { - createStoragePool(POOL_TYPE.BLOCK, poolName); + createStoragePool(PoolType.BLOCK, poolName); app.waitForLoad(); - cy.log(`Verify ${POOL_TYPE.BLOCK} pool creation`); + cy.log(`Verify ${PoolType.BLOCK} pool creation`); cy.byTestID('status-text').should('contain', 'Ready', { timeout: 2 * 60000, }); @@ -61,7 +61,7 @@ describe('Block pool on ODF UI', () => { it('Test updating/deleting a default block pool is not allowed', () => { cy.log('Kebab action should be disabled'); openStoragePoolKebab(CEPH_DEFAULT_BLOCK_POOL_NAME, true); - cy.log(poolMessage(poolName, POOL_PROGRESS.NOTALLOWED)); + cy.log(poolMessage(poolName, PoolProgress.NOTALLOWED)); }); it('deletion of a non-default pool deletion pool is successful', () => { @@ -80,10 +80,10 @@ describe('Block pool on ODF UI', () => { cy.contains('Delete Storage Pool'); cy.byTestID('pool-bound-message').contains( - poolMessage(poolName, POOL_PROGRESS.BOUNDED) + poolMessage(poolName, PoolProgress.BOUNDED) ); cy.byTestID('pool-storage-classes').contains(scName); - triggerPoolFormFooterAction(POOL_PROGRESS.BOUNDED); + triggerPoolFormFooterAction(PoolProgress.BOUNDED); cy.log('Delete pvc and storage class, then try pool deletion'); cy.exec(`oc delete pvc ${pvcName} -n default`, { @@ -106,7 +106,7 @@ describe('Tests form validations on block pool', () => { }); fieldValidationOnWizardFormsTests(nameFieldTestId, 'Create', () => - fillStoragePoolForm(POOL_TYPE.BLOCK, 'test-name') + fillStoragePoolForm(PoolType.BLOCK, 'test-name') ); }); @@ -119,15 +119,15 @@ describe('Filesystem pool on ODF UI', () => { }); it('creates a new pool', () => { - createStoragePool(POOL_TYPE.FILESYSTEM, poolName); + createStoragePool(PoolType.FILESYSTEM, poolName); - cy.log(`Verify ${POOL_TYPE.FILESYSTEM} pool creation`); + cy.log(`Verify ${PoolType.FILESYSTEM} pool creation`); cy.byTestID(`${poolFullName}-replicas`).contains('2'); cy.byTestID(`${poolFullName}-compression`).contains('Enabled'); }); it(`updates a non-default pool`, () => { - cy.log(`Updating a newly created ${POOL_TYPE.FILESYSTEM} pool`); + cy.log(`Updating a newly created ${PoolType.FILESYSTEM} pool`); openStoragePoolKebab(poolFullName); cy.byTestActionID('Edit Pool').click(); cy.contains('Edit Storage Pool'); @@ -152,6 +152,6 @@ describe('Filesystem pool on ODF UI', () => { it('actions on the default pool are not allowed', () => { cy.log('Kebab action should be disabled'); openStoragePoolKebab(CEPH_DEFAULT_FS_POOL_NAME, true); - cy.log(poolMessage[POOL_PROGRESS.NOTALLOWED]); + cy.log(poolMessage[PoolProgress.NOTALLOWED]); }); }); diff --git a/cypress/views/block-pool.ts b/cypress/views/block-pool.ts index 519a38283..94ff221fe 100644 --- a/cypress/views/block-pool.ts +++ b/cypress/views/block-pool.ts @@ -1,11 +1,12 @@ import { CEPH_DEFAULT_BLOCK_POOL_NAME, - POOL_PROGRESS, + PoolProgress, } from '../constants/storage-pool-const'; import { STORAGE_SYSTEM_NAME } from '../consts'; import { app } from '../support/pages/app'; import { NS } from '../utils/consts'; import { ODFCommon } from '../views/odf-common'; +import { triggerPoolFormFooterAction } from './storage-pool'; // Pool var export const poolName: string = 'example.pool'; @@ -13,13 +14,13 @@ export const replicaCount: string = '2'; export const scName: string = 'testing-sc'; export const poolMessage: { - [key in POOL_PROGRESS]?: string; + [key in PoolProgress]?: string; } = { - [POOL_PROGRESS.FAILED]: `Pool "${poolName}" already exists`, - [POOL_PROGRESS.CREATED]: `Pool ${poolName} was successfully created`, - [POOL_PROGRESS.NOTALLOWED]: + [PoolProgress.FAILED]: `Pool "${poolName}" already exists`, + [PoolProgress.CREATED]: `Pool ${poolName} was successfully created`, + [PoolProgress.NOTALLOWED]: "Pool management tasks are not supported for default pool and ODF's external mode.", - [POOL_PROGRESS.BOUNDED]: `${poolName} cannot be deleted. When a pool is bounded to PVC it cannot be deleted. Please detach all the resources from StorageClass(es):`, + [PoolProgress.BOUNDED]: `${poolName} cannot be deleted. When a pool is bounded to PVC it cannot be deleted. Please detach all the resources from StorageClass(es):`, }; export const navigateToBlockPool = () => { @@ -40,40 +41,6 @@ export const populateBlockPoolForm = () => { cy.byTestID('compression-checkbox').check(); }; -export enum Actions { - created = 'created', - failed = 'failed', - notAllowed = 'notAllowed', - bound = 'bounded', -} - -export const verifyFooterActions = (action: string) => { - switch (action) { - case Actions.failed: - cy.log('Check try-again-action and finish-action are enabled'); - cy.byLegacyTestID('modal-try-again-action').should('be.visible'); - cy.byLegacyTestID('modal-finish-action').click(); - break; - case Actions.created: - cy.log('Check finish-action is enabled'); - cy.byLegacyTestID('modal-finish-action').click(); - break; - case Actions.notAllowed: - cy.log('Check close-action is enabled'); - cy.byLegacyTestID('modal-close-action').click(); - break; - case Actions.bound: - cy.log('Check go-to-pvc-list-action and close-action are enabled'); - cy.byLegacyTestID('modal-go-to-pvc-list-action').should('be.visible'); - cy.byLegacyTestID('modal-close-action').click(); - break; - default: - cy.log(`Invoke ${action} action`); - cy.byLegacyTestID('confirm-action').scrollIntoView(); - cy.byLegacyTestID('confirm-action').click(); - } -}; - export const verifyBlockPoolJSON = ( compressionEnabled: boolean = true, replica: string = replicaCount @@ -100,7 +67,7 @@ export const verifyBlockPoolJSON = ( export const createBlockPool = () => { cy.byTestID('item-create').click(); populateBlockPoolForm(); - verifyFooterActions('create'); + triggerPoolFormFooterAction('create'); app.waitForLoad(); cy.log('Verify a new block pool creation'); cy.byTestID('status-text').should('contain', 'Ready', { timeout: 2 * 60000 }); diff --git a/cypress/views/storage-pool.ts b/cypress/views/storage-pool.ts index 8bc024ef1..24418fc9d 100644 --- a/cypress/views/storage-pool.ts +++ b/cypress/views/storage-pool.ts @@ -1,8 +1,8 @@ import { CEPH_DEFAULT_BLOCK_POOL_NAME, CEPH_DEFAULT_FS_POOL_NAME, - POOL_PROGRESS, - POOL_TYPE, + PoolProgress, + PoolType, } from '../constants/storage-pool-const'; import { SECOND, STORAGE_SYSTEM_NAME } from '../consts'; import { NS } from '../utils/consts'; @@ -15,16 +15,16 @@ export const scName: string = 'testing-sc'; export const poolMessage = ( poolName: string, - poolProgress: POOL_PROGRESS + poolProgress: PoolProgress ): string => { switch (poolProgress) { - case POOL_PROGRESS.FAILED: + case PoolProgress.FAILED: return `Pool "${poolName}" already exists`; - case POOL_PROGRESS.CREATED: + case PoolProgress.CREATED: return `Pool ${poolName} was successfully created`; - case POOL_PROGRESS.NOTALLOWED: + case PoolProgress.NOTALLOWED: return "Pool management tasks are not supported for default pool and ODF's external mode."; - case POOL_PROGRESS.BOUNDED: + case PoolProgress.BOUNDED: return `${poolName} cannot be deleted. When a pool is bounded to PVC it cannot be deleted. Please detach all the resources from StorageClass(es):`; default: return ''; @@ -39,10 +39,10 @@ export const navigateToStoragePoolList = () => { cy.byTestID('horizontal-link-Storage pools').click(); }; -export const showAvailablePoolsInSCForm = (poolType: POOL_TYPE) => { - const provisioner = poolType === POOL_TYPE.BLOCK ? 'rbd' : 'cephfs'; +export const showAvailablePoolsInSCForm = (poolType: PoolType) => { + const provisioner = poolType === PoolType.BLOCK ? 'rbd' : 'cephfs'; const defaultPool = - poolType === POOL_TYPE.BLOCK + poolType === PoolType.BLOCK ? CEPH_DEFAULT_BLOCK_POOL_NAME : CEPH_DEFAULT_FS_POOL_NAME; @@ -62,7 +62,7 @@ export const showAvailablePoolsInSCForm = (poolType: POOL_TYPE) => { cy.byTestID(defaultPool).should('be.visible'); }; -export const fillPoolModalForm = (poolType: POOL_TYPE, poolName: string) => { +export const fillPoolModalForm = (poolType: PoolType, poolName: string) => { showAvailablePoolsInSCForm(poolType); cy.log('Click on: Create new storage pool'); cy.byTestID('create-new-pool-button').click(); @@ -73,7 +73,7 @@ export const fillPoolModalForm = (poolType: POOL_TYPE, poolName: string) => { }; export const createStoragePoolInSCForm = ( - poolType: POOL_TYPE, + poolType: PoolType, poolName: string ) => { fillPoolModalForm(poolType, poolName); @@ -81,9 +81,9 @@ export const createStoragePoolInSCForm = ( cy.log(`Verify the ${poolType} pool creation`); cy.byTestID('empty-state-body').contains( - poolMessage(poolName, POOL_PROGRESS.CREATED) + poolMessage(poolName, PoolProgress.CREATED) ); - triggerPoolFormFooterAction(POOL_PROGRESS.CREATED); + triggerPoolFormFooterAction(PoolProgress.CREATED); cy.byTestID('pool-dropdown-toggle').contains(poolName); }; @@ -92,7 +92,7 @@ export const checkStoragePoolIsSelectableInSCForm = (poolName: string) => { cy.byTestID(poolName).should('be.visible'); }; -export const fillStoragePoolForm = (poolType: POOL_TYPE, poolName: string) => { +export const fillStoragePoolForm = (poolType: PoolType, poolName: string) => { cy.byTestID(`type-${poolType.toLowerCase()}`).click(); cy.byTestID('new-pool-name-textbox').clear(); cy.byTestID('new-pool-name-textbox').type(poolName); @@ -103,36 +103,34 @@ export const fillStoragePoolForm = (poolType: POOL_TYPE, poolName: string) => { cy.byTestID('compression-checkbox').check(); }; -export enum Actions { - created = 'created', - failed = 'failed', - notAllowed = 'notAllowed', - bound = 'bounded', -} - export const triggerPoolFormFooterAction = (action: string) => { switch (action) { - case Actions.failed: + case PoolProgress.FAILED: cy.log('Check try-again-action and finish-action are enabled'); cy.byLegacyTestID('modal-try-again-action').should('be.visible'); + cy.byLegacyTestID('modal-finish-action').should('be.visible'); cy.byLegacyTestID('modal-finish-action').click(); break; - case Actions.created: + case PoolProgress.CREATED: cy.log('Check finish-action is enabled'); + cy.byLegacyTestID('modal-finish-action').should('be.visible'); cy.byLegacyTestID('modal-finish-action').click(); break; - case Actions.notAllowed: + case PoolProgress.NOTALLOWED: cy.log('Check close-action is enabled'); + cy.byLegacyTestID('modal-close-action').should('be.visible'); cy.byLegacyTestID('modal-close-action').click(); break; - case Actions.bound: + case PoolProgress.BOUNDED: cy.log('Check go-to-pvc-list-action and close-action are enabled'); cy.byLegacyTestID('modal-go-to-pvc-list-action').should('be.visible'); + cy.byLegacyTestID('modal-close-action').should('be.visible'); cy.byLegacyTestID('modal-close-action').click(); break; default: cy.log(`Invoke ${action} action`); cy.byLegacyTestID('confirm-action').scrollIntoView(); + cy.byLegacyTestID('confirm-action').should('be.visible'); cy.byLegacyTestID('confirm-action').click(); } }; @@ -161,7 +159,7 @@ export const verifyBlockPoolJSON = ( }); }; -export const createStoragePool = (poolType: POOL_TYPE, poolName: string) => { +export const createStoragePool = (poolType: PoolType, poolName: string) => { cy.byTestID('item-create').click(); fillStoragePoolForm(poolType, poolName); triggerPoolFormFooterAction('create'); diff --git a/packages/ibm/system-connection-details.tsx b/packages/ibm/system-connection-details.tsx index f62f79777..95bccb8c4 100644 --- a/packages/ibm/system-connection-details.tsx +++ b/packages/ibm/system-connection-details.tsx @@ -5,7 +5,7 @@ import { CreatePayload, StorageClassComponentProps as ExternalComponentProps, CanGoToNextStep, - waitToCreate, + WaitToCreate, } from '@odf/odf-plugin-sdk/extensions'; import { FormGroupController } from '@odf/shared/form-group-controller'; import { useK8sList } from '@odf/shared/hooks/useK8sList'; @@ -329,7 +329,7 @@ export const flashSystemCanGoToNextStep: CanGoToNextStep = ( const isCRDAvailable = (crd: K8sResourceKind, plural: string) => crd?.status?.acceptedNames?.plural === plural; -export const waitforCRD: waitToCreate = async (model) => { +export const waitforCRD: WaitToCreate = async (model) => { const crdName = [model.plural, model.apiGroup].join('.'); const POLLING_INTERVAL = 5000; const maxAttempts = 30; 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 4874ef8d2..d0f7401a7 100644 --- a/packages/mco/components/create-dr-policy/create-dr-policy.tsx +++ b/packages/mco/components/create-dr-policy/create-dr-policy.tsx @@ -29,7 +29,7 @@ import { } from '@patternfly/react-core'; import { MAX_ALLOWED_CLUSTERS, - REPLICATION_TYPE, + ReplicationType, ODFMCO_OPERATOR, } from '../../constants'; import { DRPolicyModel, MirrorPeerModel } from '../../models'; @@ -53,7 +53,7 @@ const getDRPolicyListPageLink = (url: string) => const validateDRPolicyInputs = ( policyName: string, - replicationType: REPLICATION_TYPE, + replicationType: ReplicationType, clusterCount: number, isClusterSelectionValid: boolean ) => @@ -235,7 +235,7 @@ const CreateDRPolicy: React.FC<{}> = () => { syncIntervalTime={state.syncIntervalTime} dispatch={dispatch} /> - {state.replicationType === REPLICATION_TYPE.ASYNC && ( + {state.replicationType === ReplicationType.ASYNC && ( > = ({ return ( <> {getName(cluster)} {isManagedClusterAvailable ? ( @@ -78,20 +80,24 @@ const ClusterRow: React.FC> = ({ )} {odfVersion || t('Not Installed')} {!!clientName ? clientName : t('Unavailable')} - + {region || t('Unavailable')} @@ -154,7 +160,7 @@ const PaginatedClusterTable: React.FC = ({ setSelectedRows={onChange} loaded={isLoaded} loadError={error} - variant={TABLE_VARIANT.DEFAULT} + variant={TableVariant.DEFAULT} isColumnSelectableHidden isRowSelectable={(cluster) => isRowSelectable(cluster, selectedClusters) 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 01bf97b18..17af53844 100644 --- a/packages/mco/components/create-dr-policy/select-replication-type.tsx +++ b/packages/mco/components/create-dr-policy/select-replication-type.tsx @@ -5,7 +5,7 @@ import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook'; import { RequestSizeInput } from '@odf/shared/utils/RequestSizeInput'; import { FormGroup, SelectOption } from '@patternfly/react-core'; import { - REPLICATION_TYPE, + ReplicationType, REPLICATION_DISPLAY_TEXT, SYNC_SCHEDULE_DISPLAY_TEXT, } from '../../constants'; @@ -69,9 +69,7 @@ export const SelectReplicationType: React.FC = ({ dispatch({ type: DRPolicyActionType.SET_REPLICATION_TYPE, payload: - cephFSID1 === cephFSID2 - ? REPLICATION_TYPE.SYNC - : REPLICATION_TYPE.ASYNC, + cephFSID1 === cephFSID2 ? ReplicationType.SYNC : ReplicationType.ASYNC, }); }, [selectedClusters, dispatch]); @@ -86,7 +84,7 @@ export const SelectReplicationType: React.FC = ({ /> )); - const onChange = (replType: REPLICATION_TYPE) => + const onChange = (replType: ReplicationType) => dispatch({ type: DRPolicyActionType.SET_REPLICATION_TYPE, payload: replType, @@ -107,7 +105,7 @@ export const SelectReplicationType: React.FC = ({ onChange={onChange} /> - {replicationType === REPLICATION_TYPE.ASYNC && ( + {replicationType === ReplicationType.ASYNC && ( ; }; diff --git a/packages/mco/components/create-dr-policy/selected-cluster-validator.tsx b/packages/mco/components/create-dr-policy/selected-cluster-validator.tsx index d819023e9..bc3edfdb2 100644 --- a/packages/mco/components/create-dr-policy/selected-cluster-validator.tsx +++ b/packages/mco/components/create-dr-policy/selected-cluster-validator.tsx @@ -1,6 +1,6 @@ import * as React from 'react'; import { pluralize } from '@odf/core/components/utils'; -import { REPLICATION_TYPE } from '@odf/mco/constants'; +import { ReplicationType } from '@odf/mco/constants'; import { getDRPolicyResourceObj } from '@odf/mco/hooks'; import { DRPolicyKind, MirrorPeerKind } from '@odf/mco/types'; import { getReplicationType } from '@odf/mco/utils'; @@ -34,7 +34,7 @@ const checkSyncPolicyExists = ( drPolicies.some((drPolicy) => { const { drClusters, schedulingInterval } = drPolicy.spec; const isSyncPolicy = - getReplicationType(schedulingInterval) === REPLICATION_TYPE.SYNC; + getReplicationType(schedulingInterval) === ReplicationType.SYNC; return ( isSyncPolicy && drClusters.every((cluster) => clusters.includes(cluster)) ); diff --git a/packages/mco/components/create-dr-policy/utils/cluster-list-utils.ts b/packages/mco/components/create-dr-policy/utils/cluster-list-utils.ts index 590527e90..d243cdadd 100644 --- a/packages/mco/components/create-dr-policy/utils/cluster-list-utils.ts +++ b/packages/mco/components/create-dr-policy/utils/cluster-list-utils.ts @@ -29,7 +29,7 @@ import { ManagedClusterInfoType, ODFConfigInfoType } from '../utils/reducer'; export const INITIAL_PAGE_NUMBER = 1; export const COUNT_PER_PAGE_NUMBER = 10; -export enum COLUMN_NAMES { +export enum ClusterListColumns { ManagedCluster, AvailabilityStatus, DataFoundation, @@ -60,18 +60,21 @@ export const getColumns = (t: TFunction) => [ }, ]; -export const getColumnHelper = (name: COLUMN_NAMES, t: TFunction) => { +export const getColumnHelper = ( + name: ClusterListColumns, + t: TFunction +) => { const columns = getColumns(t); switch (name) { - case COLUMN_NAMES.ManagedCluster: + case ClusterListColumns.ManagedCluster: return columns[0]; - case COLUMN_NAMES.AvailabilityStatus: + case ClusterListColumns.AvailabilityStatus: return columns[1]; - case COLUMN_NAMES.DataFoundation: + case ClusterListColumns.DataFoundation: return columns[2]; - case COLUMN_NAMES.StorageClients: + case ClusterListColumns.StorageClients: return columns[3]; - case COLUMN_NAMES.Region: + case ClusterListColumns.Region: return columns[4]; } }; diff --git a/packages/mco/components/create-dr-policy/utils/k8s-utils.ts b/packages/mco/components/create-dr-policy/utils/k8s-utils.ts index c26e90f63..a830d72ce 100644 --- a/packages/mco/components/create-dr-policy/utils/k8s-utils.ts +++ b/packages/mco/components/create-dr-policy/utils/k8s-utils.ts @@ -1,4 +1,4 @@ -import { RBD_IMAGE_FLATTEN_LABEL, REPLICATION_TYPE } from '@odf/mco/constants'; +import { RBD_IMAGE_FLATTEN_LABEL, ReplicationType } from '@odf/mco/constants'; import { DRPolicyModel, MirrorPeerModel } from '@odf/mco/models'; import { DRPolicyKind, MirrorPeerKind } from '@odf/mco/types'; import { parseNamespaceName } from '@odf/mco/utils'; @@ -53,7 +53,7 @@ const fetchMirrorPeer = ( const createMirrorPeer = ( selectedClusters: ManagedClusterInfoType[], - replicationType: REPLICATION_TYPE + replicationType: ReplicationType ): Promise => { const mirrorPeerPayload: MirrorPeerKind = { apiVersion: getAPIVersionForModel(MirrorPeerModel), @@ -73,7 +73,7 @@ const createMirrorPeer = ( const createDRPolicy = ( policyName: string, - replicationType: REPLICATION_TYPE, + replicationType: ReplicationType, syncIntervalTime: string, enableRBDImageFlatten: boolean, peerNames: string[] @@ -87,7 +87,7 @@ const createDRPolicy = ( ? { matchLabels: RBD_IMAGE_FLATTEN_LABEL } : {}, schedulingInterval: - replicationType === REPLICATION_TYPE.ASYNC ? syncIntervalTime : '0m', + replicationType === ReplicationType.ASYNC ? syncIntervalTime : '0m', drClusters: peerNames, }, }; diff --git a/packages/mco/components/create-dr-policy/utils/reducer.ts b/packages/mco/components/create-dr-policy/utils/reducer.ts index 2e02c74b8..e41264e6a 100644 --- a/packages/mco/components/create-dr-policy/utils/reducer.ts +++ b/packages/mco/components/create-dr-policy/utils/reducer.ts @@ -1,4 +1,4 @@ -import { REPLICATION_TYPE } from '@odf/mco/constants'; +import { ReplicationType } from '@odf/mco/constants'; import { ConnectedClient } from '@odf/mco/types'; import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk'; @@ -43,7 +43,7 @@ export type DRPolicyState = { // DRPolicy CR name. policyName: string; // DRPolicy type Async / Sync. - replicationType: REPLICATION_TYPE; + replicationType: ReplicationType; // Sync interval schedule for Async policy. syncIntervalTime: string; // Selected managed cluster for DRPolicy paring. @@ -75,7 +75,7 @@ export const drPolicyInitialState: DRPolicyState = { export type DRPolicyAction = | { type: DRPolicyActionType.SET_POLICY_NAME; payload: string } - | { type: DRPolicyActionType.SET_REPLICATION_TYPE; payload: REPLICATION_TYPE } + | { type: DRPolicyActionType.SET_REPLICATION_TYPE; payload: ReplicationType } | { type: DRPolicyActionType.SET_SYNC_INTERVAL_TIME; payload: string } | { type: DRPolicyActionType.SET_SELECTED_CLUSTERS; diff --git a/packages/mco/components/drpolicy-list-page/drpolicy-list-page.tsx b/packages/mco/components/drpolicy-list-page/drpolicy-list-page.tsx index 4b8b4fa84..8ed96034e 100644 --- a/packages/mco/components/drpolicy-list-page/drpolicy-list-page.tsx +++ b/packages/mco/components/drpolicy-list-page/drpolicy-list-page.tsx @@ -20,7 +20,7 @@ import { } from '@openshift-console/dynamic-plugin-sdk'; import { Trans } from 'react-i18next'; import { useLocation, useNavigate } from 'react-router-dom-v5-compat'; -import { HUB_CLUSTER_NAME, REPLICATION_TYPE } from '../../constants'; +import { HUB_CLUSTER_NAME, ReplicationType } from '../../constants'; import { DRPolicyToAppCount, getDRPolicyResourceObj, @@ -60,12 +60,12 @@ const DRPolicyRow: React.FC> = ({ {clusterNames} - {replicationType === REPLICATION_TYPE.ASYNC + {replicationType === ReplicationType.ASYNC ? t('{{async}}, interval: {{syncInterval}}', { - async: REPLICATION_TYPE.ASYNC, + async: ReplicationType.ASYNC, syncInterval, }) - : REPLICATION_TYPE.SYNC} + : ReplicationType.SYNC} {appCount > 0 diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/application.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/application.tsx index 498827caf..ff9b0dcd8 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/application.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/application.tsx @@ -3,8 +3,8 @@ */ import * as React from 'react'; -import { DRPC_STATUS } from '@odf/mco/constants'; -import { REPLICATION_TYPE } from '@odf/mco/constants'; +import { DRPCStatus } from '@odf/mco/constants'; +import { ReplicationType } from '@odf/mco/constants'; import { PlacementControlInfo, ProtectedAppsMap } from '@odf/mco/types'; import { getDRStatus } from '@odf/mco/utils'; import { formatTime } from '@odf/shared/details-page/datetime'; @@ -59,12 +59,12 @@ export const getCurrentActivity = ( preferredCluster: string, t: TFunction, isCleanupPending?: boolean, - replicationType?: REPLICATION_TYPE + replicationType?: ReplicationType ): { description: string; status: string; icon: JSX.Element } => { - const status = currentStatus as DRPC_STATUS; + const status = currentStatus as DRPCStatus; switch (status) { - case DRPC_STATUS.Relocating: + case DRPCStatus.Relocating: return isCleanupPending ? { description: t( @@ -82,7 +82,7 @@ export const getCurrentActivity = ( icon: , }; - case DRPC_STATUS.Relocated: + case DRPCStatus.Relocated: return { description: t('Relocated to cluster {{ preferredCluster }}', { preferredCluster, @@ -91,7 +91,7 @@ export const getCurrentActivity = ( icon: , }; - case DRPC_STATUS.FailingOver: + case DRPCStatus.FailingOver: return { description: t('FailingOver to cluster {{ failoverCluster }}', { failoverCluster, @@ -100,9 +100,9 @@ export const getCurrentActivity = ( icon: , }; - case DRPC_STATUS.FailedOver: + case DRPCStatus.FailedOver: if (isCleanupPending) { - return replicationType === REPLICATION_TYPE.ASYNC + return replicationType === ReplicationType.ASYNC ? { description: t( 'Clean up application resources on failed cluster {{ preferredCluster }} to start the replication.', @@ -141,7 +141,7 @@ export const getCurrentActivity = ( const getSubscriptionRow = ( placementControlInfoList: PlacementControlInfo[] = [] ): SubscriptionRowProps[] => { - const _getRowProps = ( + const getRowProps = ( subscriptions: string[], { status, @@ -160,10 +160,7 @@ const getSubscriptionRow = ( return placementControlInfoList.reduce( (acc, placementControlInfo) => [ ...acc, - ..._getRowProps( - placementControlInfo?.subscriptions, - placementControlInfo - ), + ...getRowProps(placementControlInfo?.subscriptions, placementControlInfo), ], [] ); diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster-app-card.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster-app-card.tsx index 81ddc27f0..83ee4ec8a 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster-app-card.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster-app-card.tsx @@ -2,7 +2,7 @@ import * as React from 'react'; import { ALL_APPS, applicationDetails, - APPLICATION_TYPE, + DRApplication, APPLICATION_TYPE_DISPLAY_TEXT, } from '@odf/mco/constants'; import { @@ -218,11 +218,11 @@ const ClusterWiseCard: React.FC = ({ const AppWiseCard: React.FC = (props) => { switch (props?.selectedApplication?.appType) { - case APPLICATION_TYPE.APPSET: + case DRApplication.APPSET: return ; - case APPLICATION_TYPE.SUBSCRIPTION: + case DRApplication.SUBSCRIPTION: return ; - case APPLICATION_TYPE.DISCOVERED: + case DRApplication.DISCOVERED: return ; default: return null; @@ -250,7 +250,7 @@ const ClusterAppCardTitle: React.FC = ({
{t('Application: ')} - {appType === APPLICATION_TYPE.DISCOVERED ? ( + {appType === DRApplication.DISCOVERED ? ( app.name ) : ( @@ -400,5 +400,5 @@ type ClusterAppCardTitleProps = { cluster: string; appKind: string; appAPIVersion: string; - appType: APPLICATION_TYPE; + appType: DRApplication; }; diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster.tsx index 18e462f24..197a4b745 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/cluster.tsx @@ -11,13 +11,13 @@ import { ODR_CLUSTER_OPERATOR, VOL_SYNC, ACM_ENDPOINT, - VOLUME_REPLICATION_HEALTH, + VolumeReplicationHealth, OBJECT_NAMESPACE, OBJECT_NAME, MANAGED_CLUSTER_CONDITION_AVAILABLE, - APPLICATION_TYPE, + DRApplication, LEAST_SECONDS_IN_PROMETHEUS, - REPLICATION_TYPE, + ReplicationType, } from '@odf/mco/constants'; import { DRClusterAppsMap, ProtectedAppsMap } from '@odf/mco/types'; import { @@ -70,7 +70,7 @@ const checkVolumeReplicationHealth = ( getVolumeReplicationHealth( Number(item.value[1]) || 0, placementInfo.volumeSyncInterval - )[0] !== VOLUME_REPLICATION_HEALTH.HEALTHY + )[0] !== VolumeReplicationHealth.HEALTHY ) ); @@ -81,14 +81,14 @@ const checkKubeObjBackupHealth = ( protectedAppMap.placementControlInfo[0]; const objCaptureInterval = protectedAppMap.placementControlInfo[0].kubeObjSyncInterval; - return protectedAppMap.appType === APPLICATION_TYPE.DISCOVERED && - replicationType === REPLICATION_TYPE.ASYNC + return protectedAppMap.appType === DRApplication.DISCOVERED && + replicationType === ReplicationType.ASYNC ? getVolumeReplicationHealth( !!kubeObjectLastProtectionTime ? getTimeDifferenceInSeconds(kubeObjectLastProtectionTime) : LEAST_SECONDS_IN_PROMETHEUS, objCaptureInterval - )[0] !== VOLUME_REPLICATION_HEALTH.HEALTHY + )[0] !== VolumeReplicationHealth.HEALTHY : false; }; @@ -266,9 +266,7 @@ export const ApplicationsSection: React.FC = ({ checkKubeObjBackupHealth(protectedAppMap); const hasIssue = hasVolumeReplicationIssue || hasKubeObjBackupIssue; hasIssue && - ++acc[ - protectedAppMap.appType === APPLICATION_TYPE.DISCOVERED ? 0 : 1 - ]; + ++acc[protectedAppMap.appType === DRApplication.DISCOVERED ? 0 : 1]; return acc; }, [0, 0] diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/common.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/common.tsx index da70739fc..ca3249d71 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/common.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/cluster-app-card/common.tsx @@ -9,8 +9,8 @@ import { GITOPS_OPERATOR_NAMESPACE, LEAST_SECONDS_IN_PROMETHEUS, DISCOVERED_APP_NS, - REPLICATION_TYPE, - VOLUME_REPLICATION_HEALTH, + ReplicationType, + VolumeReplicationHealth, } from '@odf/mco/constants'; import { ACMSubscriptionModel, @@ -105,14 +105,14 @@ export const VolumeSummarySection: React.FC = ({ const pvcLastSyncTime = pvcData?.lastSyncTime; // Only RDR(async) has volume replication const health = - pvcData.replicationType === REPLICATION_TYPE.ASYNC + pvcData.replicationType === ReplicationType.ASYNC ? getVolumeReplicationHealth( !!pvcLastSyncTime ? getTimeDifferenceInSeconds(pvcLastSyncTime) : LEAST_SECONDS_IN_PROMETHEUS, pvcData?.schedulingInterval )[0] - : VOLUME_REPLICATION_HEALTH.HEALTHY; + : VolumeReplicationHealth.HEALTHY; !!selectedApplication ? filterPVCDataUsingApp(pvcData, selectedApplication) && volumeHealth[health]++ @@ -429,18 +429,18 @@ export const ProtectedPVCsSection: React.FC = ({ const pvcLastSyncTime = protectedPVCItem?.lastSyncTime; // Only RDR(async) has volume replication const replicationHealth = - protectedPVCItem.replicationType === REPLICATION_TYPE.ASYNC + protectedPVCItem.replicationType === ReplicationType.ASYNC ? getVolumeReplicationHealth( !!pvcLastSyncTime ? getTimeDifferenceInSeconds(pvcLastSyncTime) : LEAST_SECONDS_IN_PROMETHEUS, protectedPVCItem?.schedulingInterval )[0] - : VOLUME_REPLICATION_HEALTH.HEALTHY; + : VolumeReplicationHealth.HEALTHY; (!!selectedApplication ? !!filterPVCDataUsingApp(protectedPVCItem, selectedApplication) && - replicationHealth !== VOLUME_REPLICATION_HEALTH.HEALTHY - : replicationHealth !== VOLUME_REPLICATION_HEALTH.HEALTHY) && acc++; + replicationHealth !== VolumeReplicationHealth.HEALTHY + : replicationHealth !== VolumeReplicationHealth.HEALTHY) && acc++; return acc; }, 0) || 0; diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/parsers/applicationset-parser.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/parsers/applicationset-parser.tsx index 6b2ea9f8f..6ff717f4e 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/parsers/applicationset-parser.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/parsers/applicationset-parser.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { - APPLICATION_TYPE, - DRPC_STATUS, + DRApplication, + DRPCStatus, GITOPS_OPERATOR_NAMESPACE, } from '@odf/mco/constants'; import { @@ -132,7 +132,7 @@ export const useApplicationSetParser: UseApplicationSetParser = ( appNamespace: getNamespace(application), appKind: application?.kind, appAPIVersion: application?.apiVersion, - appType: APPLICATION_TYPE.APPSET, + appType: DRApplication.APPSET, placementControlInfo: [ { deploymentClusterName: decisionCluster, @@ -149,7 +149,7 @@ export const useApplicationSetParser: UseApplicationSetParser = ( drPlacementControl?.spec?.preferredCluster, lastVolumeGroupSyncTime: drPlacementControl?.status?.lastGroupSyncTime, - status: drPlacementControl?.status?.phase as DRPC_STATUS, + status: drPlacementControl?.status?.phase as DRPCStatus, }, ], }); diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/parsers/discovered-parser.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/parsers/discovered-parser.tsx index ea9206c7e..516109425 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/parsers/discovered-parser.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/parsers/discovered-parser.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { - APPLICATION_TYPE, - DRPC_STATUS, + DRApplication, + DRPCStatus, DISCOVERED_APP_NS, } from '@odf/mco/constants'; import { @@ -102,7 +102,7 @@ export const useDiscoveredParser: UseDiscoveredParser = ( appNamespace: getNamespace(drPlacementControl), appKind: drPlacementControl.kind, appAPIVersion: drPlacementControl.apiVersion, - appType: APPLICATION_TYPE.DISCOVERED, + appType: DRApplication.DISCOVERED, placementControlInfo: [ { deploymentClusterName: decisionCluster, @@ -117,7 +117,7 @@ export const useDiscoveredParser: UseDiscoveredParser = ( preferredCluster: drPlacementControl.spec?.preferredCluster, lastVolumeGroupSyncTime: drPlacementControl.status?.lastGroupSyncTime, - status: drPlacementControl.status?.phase as DRPC_STATUS, + status: drPlacementControl.status?.phase as DRPCStatus, kubeObjSyncInterval: drPlacementControl.spec?.kubeObjectProtection ?.captureInterval, diff --git a/packages/mco/components/mco-dashboard/disaster-recovery/parsers/subscription-parser.tsx b/packages/mco/components/mco-dashboard/disaster-recovery/parsers/subscription-parser.tsx index 91e114a13..86c6cbc81 100644 --- a/packages/mco/components/mco-dashboard/disaster-recovery/parsers/subscription-parser.tsx +++ b/packages/mco/components/mco-dashboard/disaster-recovery/parsers/subscription-parser.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { APPLICATION_TYPE, DRPC_STATUS } from '@odf/mco/constants'; +import { DRApplication, DRPCStatus } from '@odf/mco/constants'; import { SubscriptionGroupType, useDisasterRecoveryResourceWatch, @@ -50,7 +50,7 @@ const createPlacementControlInfoList = ( failoverCluster: drPlacementControl?.spec?.failoverCluster, preferredCluster: drPlacementControl?.spec?.preferredCluster, lastVolumeGroupSyncTime: drPlacementControl?.status?.lastGroupSyncTime, - status: drPlacementControl?.status?.phase as DRPC_STATUS, + status: drPlacementControl?.status?.phase as DRPCStatus, subscriptions: subscriptionGroup?.subscriptions?.map((subs) => getName(subs) ), @@ -74,7 +74,7 @@ const createProtectedAppMap = ( appNamespace: applicationNamespace, appKind: application?.kind, appAPIVersion: application?.apiVersion, - appType: APPLICATION_TYPE.SUBSCRIPTION, + appType: DRApplication.SUBSCRIPTION, placementControlInfo: createPlacementControlInfoList( subscriptionGroupsList, clusterName, diff --git a/packages/mco/components/modals/app-data-policies-status/argo-application-set.tsx b/packages/mco/components/modals/app-data-policies-status/argo-application-set.tsx index 7a2b0e666..73cad9223 100644 --- a/packages/mco/components/modals/app-data-policies-status/argo-application-set.tsx +++ b/packages/mco/components/modals/app-data-policies-status/argo-application-set.tsx @@ -1,7 +1,7 @@ import * as React from 'react'; import { getNamespace, getName } from '@odf/shared/selectors'; import * as _ from 'lodash-es'; -import { DRPC_STATUS } from '../../../constants'; +import { DRPCStatus } from '../../../constants'; import { getDRClusterResourceObj, getDRPlacementControlResourceObj, @@ -42,10 +42,10 @@ export const ArogoApplicationSetStatus: React.FC if (!_.isEmpty(drResource)) { const drpc = drResource?.drPlacementControls?.[0]; const drPolicy = drResource?.drPolicy; - const status = drpc?.status?.phase as DRPC_STATUS; + const status = drpc?.status?.phase as DRPCStatus; const targetCluster = [ - DRPC_STATUS.FailedOver, - DRPC_STATUS.FailingOver, + DRPCStatus.FailedOver, + DRPCStatus.FailingOver, ].includes(status) ? drpc?.spec?.failoverCluster : drpc?.spec?.preferredCluster; diff --git a/packages/mco/components/modals/app-data-policies-status/dr-status.tsx b/packages/mco/components/modals/app-data-policies-status/dr-status.tsx index b379ca957..88519ec5f 100644 --- a/packages/mco/components/modals/app-data-policies-status/dr-status.tsx +++ b/packages/mco/components/modals/app-data-policies-status/dr-status.tsx @@ -1,5 +1,5 @@ import * as React from 'react'; -import { REPLICATION_TYPE, DRPC_STATUS } from '@odf/mco/constants'; +import { ReplicationType, DRPCStatus } from '@odf/mco/constants'; import { fromNow } from '@odf/shared/details-page/datetime'; import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook'; import { StatusIconAndText } from '@openshift-console/dynamic-plugin-sdk'; @@ -14,8 +14,8 @@ import { } from '@patternfly/react-core'; import { getDRStatus } from '../../../utils'; -const failOverStatus = [DRPC_STATUS.FailedOver, DRPC_STATUS.FailingOver]; -const relocateStatus = [DRPC_STATUS.Relocating, DRPC_STATUS.Relocated]; +const failOverStatus = [DRPCStatus.FailedOver, DRPCStatus.FailingOver]; +const relocateStatus = [DRPCStatus.Relocating, DRPCStatus.Relocated]; export const DRStatus: React.FC = (disasterRecoveryStatus) => { const { t } = useCustomTranslation(); @@ -29,8 +29,8 @@ export const DRStatus: React.FC = (disasterRecoveryStatus) => { targetCluster, } = drStatus || {}; const customText: string = [ - DRPC_STATUS.FailedOver, - DRPC_STATUS.Relocated, + DRPCStatus.FailedOver, + DRPCStatus.Relocated, ].includes(status) ? t('Completed') : t('In Progress'); @@ -54,7 +54,7 @@ export const DRStatus: React.FC = (disasterRecoveryStatus) => { {t('Disaster recovery')} - {replicationType === REPLICATION_TYPE.ASYNC ? ( + {replicationType === ReplicationType.ASYNC ? ( <> {t('{{drPolicy}}, sync every {{syncInterval}}', { @@ -140,9 +140,9 @@ export const DRStatus: React.FC = (disasterRecoveryStatus) => { export type DRStatusProps = { policyName: string; - status: DRPC_STATUS; + status: DRPCStatus; targetCluster: string; - replicationType: REPLICATION_TYPE; + replicationType: ReplicationType; dataLastSyncedOn: string; schedulingInterval: string; }; diff --git a/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-card.tsx b/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-card.tsx index 4e09acdcd..9747b5078 100644 --- a/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-card.tsx +++ b/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-card.tsx @@ -10,7 +10,7 @@ import { HelperTextItem, } from '@patternfly/react-core'; import { InProgressIcon } from '@patternfly/react-icons'; -import { DRPC_STATUS } from '../../../../constants'; +import { DRPCStatus } from '../../../../constants'; import { DRPlacementControlKind } from '../../../../types'; import { getDRPoliciesCount, DRPolicyMap } from '../../../../utils'; @@ -18,13 +18,12 @@ const updateStatusSummary = ( currentStatus: string, prevStatus?: DRStatusSummaryType ) => { - (currentStatus === DRPC_STATUS.FailedOver && - prevStatus.failover.finished++) || - (currentStatus === DRPC_STATUS.FailingOver && + (currentStatus === DRPCStatus.FailedOver && prevStatus.failover.finished++) || + (currentStatus === DRPCStatus.FailingOver && prevStatus.failover.inProgress++) || - (currentStatus === DRPC_STATUS.Relocated && + (currentStatus === DRPCStatus.Relocated && prevStatus.relocate.finished++) || - (currentStatus === DRPC_STATUS.Relocating && + (currentStatus === DRPCStatus.Relocating && prevStatus.relocate.inProgress++); return prevStatus; }; diff --git a/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-table.tsx b/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-table.tsx index 2c62c2417..41e18b8a4 100644 --- a/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-table.tsx +++ b/packages/mco/components/modals/app-data-policies-status/subscriptions/dr-status-table.tsx @@ -26,7 +26,7 @@ import { ThProps, SortByDirection, } from '@patternfly/react-table'; -import { DRPC_STATUS } from '../../../../constants'; +import { DRPCStatus } from '../../../../constants'; import { DRPlacementControlKind } from '../../../../types'; import { DRPolicyMap, @@ -39,18 +39,18 @@ import './dr-status-table.scss'; const getLastDataSyncTime = (drpcList: DRPlacementControlKind[]): string => getLatestDate(drpcList?.map((drpc) => drpc?.status?.lastGroupSyncTime)); -const isRelocating = (status: DRPC_STATUS) => - [DRPC_STATUS.Relocating, DRPC_STATUS.Relocated].includes(status); +const isRelocating = (status: DRPCStatus) => + [DRPCStatus.Relocating, DRPCStatus.Relocated].includes(status); -const isFailingOver = (status: DRPC_STATUS) => - [DRPC_STATUS.FailingOver, DRPC_STATUS.FailedOver].includes(status); +const isFailingOver = (status: DRPCStatus) => + [DRPCStatus.FailingOver, DRPCStatus.FailedOver].includes(status); const getTargetClusters = ( currentStatus: string, drpcList: DRPlacementControlKind[] ) => { const targetClusters = drpcList.reduce((acc, drpc) => { - const status = DRPC_STATUS[drpc?.status?.phase] || ''; + const status = DRPCStatus[drpc?.status?.phase] || ''; if (status === currentStatus) { (isRelocating(status) && acc.add(drpc?.spec?.preferredCluster)) || (isFailingOver(status) && acc.add(drpc?.spec?.failoverCluster)); diff --git a/packages/mco/components/modals/app-failover-relocate/failover-relocate-modal-body.tsx b/packages/mco/components/modals/app-failover-relocate/failover-relocate-modal-body.tsx index ab01207cf..ff0750333 100644 --- a/packages/mco/components/modals/app-failover-relocate/failover-relocate-modal-body.tsx +++ b/packages/mco/components/modals/app-failover-relocate/failover-relocate-modal-body.tsx @@ -24,9 +24,9 @@ import { import { UnknownIcon } from '@patternfly/react-icons'; import { DRActionType, - REPLICATION_TYPE, + ReplicationType, ACM_OPERATOR_SPEC_NAME, - VOLUME_REPLICATION_HEALTH, + VolumeReplicationHealth, } from '../../../constants'; import { ErrorMessageType, @@ -39,7 +39,7 @@ import './failover-relocate-modal-body.scss'; const failoverPreCheck = (placementControl: PlacementControlProps) => { // Failover pre-check if (placementControl?.isTargetClusterAvailable) { - if (placementControl?.replicationType === REPLICATION_TYPE.SYNC) { + if (placementControl?.replicationType === ReplicationType.SYNC) { if (!placementControl?.isPrimaryClusterFenced) { // Primary cluster is unfenced return ErrorMessageType.PRIMARY_CLUSTER_IS_NOT_FENCED; @@ -61,7 +61,7 @@ const relocatePreCheck = (placementControl: PlacementControlProps) => { placementControl?.isTargetClusterAvailable && placementControl?.isPrimaryClusterAvailable ) { - if (placementControl?.replicationType === REPLICATION_TYPE.SYNC) { + if (placementControl?.replicationType === ReplicationType.SYNC) { if ( placementControl?.isPrimaryClusterFenced || placementControl?.isTargetClusterFenced @@ -110,8 +110,8 @@ const validatePlacement = ( // Check volume replication health if ( [ - VOLUME_REPLICATION_HEALTH.CRITICAL, - VOLUME_REPLICATION_HEALTH.WARNING, + VolumeReplicationHealth.CRITICAL, + VolumeReplicationHealth.WARNING, ].includes( getReplicationHealth( placementControl?.snapshotTakenTime, @@ -300,7 +300,7 @@ export const FailoverRelocateModalBody: React.FC - {placement?.replicationType === REPLICATION_TYPE.ASYNC && ( + {placement?.replicationType === ReplicationType.ASYNC && ( {t('Volume last synced on:')} @@ -346,7 +346,7 @@ export type PlacementControlProps = Partial<{ isTargetClusterAvailable: boolean; isPrimaryClusterAvailable: boolean; isDRActionReady: boolean; - replicationType: REPLICATION_TYPE; + replicationType: ReplicationType; isTargetClusterFenced: boolean; isPrimaryClusterFenced: boolean; areSiblingApplicationsFound: boolean; diff --git a/packages/mco/components/modals/app-failover-relocate/subscriptions/failover-relocate-modal.tsx b/packages/mco/components/modals/app-failover-relocate/subscriptions/failover-relocate-modal.tsx index 8ef4a0899..9411323f9 100644 --- a/packages/mco/components/modals/app-failover-relocate/subscriptions/failover-relocate-modal.tsx +++ b/packages/mco/components/modals/app-failover-relocate/subscriptions/failover-relocate-modal.tsx @@ -45,7 +45,7 @@ const generatefooterButtons = (props: ModalFooterProps): FooterButtonProps => ({ type: ButtonType.button, variant: ButtonVariant.primary, isDisabled: props?.isDisable, - onClick: props?.Onclick, + onClick: props?.onClick, }, ], [ModalFooterStatus.INPROGRESS]: [ @@ -195,7 +195,7 @@ export const SubscriptionFailoverRelocateModal: React.FC (