-
Notifications
You must be signed in to change notification settings - Fork 31
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: Timothy Asir Jeyasingh <[email protected]>
- Loading branch information
1 parent
d768d0b
commit 4be4ca7
Showing
7 changed files
with
247 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
71 changes: 71 additions & 0 deletions
71
packages/ocs/dashboards/persistent-internal/OptimizeModal.spec.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
import React from 'react'; | ||
import { screen, render, fireEvent, waitFor } from '@testing-library/react'; | ||
import '@testing-library/jest-dom/extend-expect'; | ||
import * as migrationStatus from './constants/osd-migration'; | ||
import OptimizeModal from './OptimizeModal'; | ||
|
||
jest.mock('@odf/shared/selectors', () => ({ | ||
getName: jest.fn().mockReturnValue('test'), | ||
})); | ||
|
||
// Mocking getMigrationStatus | ||
jest.mock('./constants/osd-migration'); | ||
|
||
jest.mock('@odf/shared/hooks/useK8sList', () => ({ | ||
__esModule: true, | ||
useK8sList: () => [ | ||
[ | ||
{ | ||
metadata: { | ||
name: 'test', | ||
}, | ||
}, | ||
], | ||
true, | ||
undefined, | ||
], | ||
})); | ||
|
||
describe('OptimizeModal Component', () => { | ||
test('renders without errors', async () => { | ||
// Mock getMigrationStatus to return 'Completed' for this test | ||
migrationStatus.getMigrationStatus.mockReturnValue('Completed'); | ||
|
||
render(<OptimizeModal />); | ||
|
||
// Wait for the component to finish rendering (use async/await) | ||
await waitFor(() => { | ||
expect(screen.queryByText('Optimize')).not.toBeInTheDocument(); | ||
}); | ||
}); | ||
|
||
test('renders with migration pending', async () => { | ||
// Mock getMigrationStatus to return 'Completed' for this test | ||
migrationStatus.getMigrationStatus.mockReturnValue('Pending'); | ||
|
||
render(<OptimizeModal />); | ||
|
||
// Wait for the component to finish rendering (use async/await) | ||
await waitFor(() => { | ||
expect(screen.queryByText('Optimize')).toBeInTheDocument(); | ||
}); | ||
|
||
fireEvent.click(screen.getByText(/Optimize/i)); | ||
|
||
// Wait for modal to be visible | ||
await waitFor(() => { | ||
expect( | ||
screen.queryByText('Configure cluster for Regional-DR?') | ||
).toBeInTheDocument(); | ||
}); | ||
|
||
fireEvent.click(screen.getByText('Close')); | ||
|
||
// Wait for modal to be closed | ||
await waitFor(() => { | ||
expect( | ||
screen.queryByText('Configure cluster for Regional-DR?') | ||
).not.toBeInTheDocument(); | ||
}); | ||
}); | ||
}); |
109 changes: 109 additions & 0 deletions
109
packages/ocs/dashboards/persistent-internal/OptimizeModal.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
import * as React from 'react'; | ||
import { DISASTER_RECOVERY_TARGET_ANNOTATION } from '@odf/core/constants'; | ||
import { CephClusterModel } from '@odf/shared/models'; | ||
import { getName, getNamespace } from '@odf/shared/selectors'; | ||
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook'; | ||
import { | ||
K8sResourceKind, | ||
k8sPatch, | ||
} from '@openshift-console/dynamic-plugin-sdk'; | ||
import { | ||
Modal, | ||
ModalVariant, | ||
Button, | ||
ModalBoxHeader, | ||
ModalBoxBody, | ||
Title, | ||
} from '@patternfly/react-core'; | ||
import { MigrationStatus, getMigrationStatus } from './constants/osd-migration'; | ||
|
||
const OptimizeModal: React.FC<OptimizeModalProps> = ({ cephData }) => { | ||
const { t } = useCustomTranslation(); | ||
const dRSetupStatus = getMigrationStatus(cephData); | ||
const [isOpen, setOpen] = React.useState(false); | ||
const [errorMessage, setErrorMessage] = React.useState<string | null>(null); | ||
|
||
const openModal = () => setOpen(true); | ||
|
||
const closeModal = () => { | ||
setOpen(false); | ||
setErrorMessage(null); | ||
}; | ||
|
||
const handleOptimize = () => { | ||
if (cephData && cephData.length > 0) { | ||
const ceph = cephData[0]; | ||
const patch = [ | ||
{ | ||
op: 'add', | ||
path: `/metadata/annotations/${DISASTER_RECOVERY_TARGET_ANNOTATION}`, | ||
value: 'true', | ||
}, | ||
]; | ||
|
||
k8sPatch({ | ||
model: CephClusterModel, | ||
resource: { | ||
metadata: { | ||
name: getName(ceph), | ||
namespace: getNamespace(ceph), | ||
}, | ||
}, | ||
data: patch, | ||
}) | ||
.then(() => { | ||
closeModal(); | ||
}) | ||
.catch((err) => { | ||
setErrorMessage(err.message); | ||
}); | ||
} | ||
}; | ||
|
||
return ( | ||
<div> | ||
<div style={{ display: 'flex', justifyContent: 'space-between' }}> | ||
<p>{t(dRSetupStatus)}</p> | ||
{dRSetupStatus === MigrationStatus.Pending && ( | ||
<a onClick={openModal}>{t('Optimize')}</a> | ||
)} | ||
</div> | ||
<div> | ||
<Modal | ||
variant={ModalVariant.medium} | ||
title={t('Configure cluster for Regional-DR?')} | ||
isOpen={isOpen} | ||
onClose={closeModal} | ||
actions={[ | ||
<Button key="close" variant="secondary" onClick={closeModal}> | ||
Close | ||
</Button>, | ||
<Button key="optimize" variant="primary" onClick={handleOptimize}> | ||
Optimize | ||
</Button>, | ||
]} | ||
> | ||
<p> | ||
{t( | ||
'Optimize the cluster for a Regional-DR setup by migrating OSDs. Migration may take some time depending on several factors. To learn more about OSD migration best practices and its consequences, refer to the documentation.' | ||
)} | ||
</p> | ||
{errorMessage && ( | ||
<ModalBoxHeader> | ||
<Title headingLevel="h2" size="lg"> | ||
Error | ||
</Title> | ||
</ModalBoxHeader> | ||
)} | ||
<ModalBoxBody>{errorMessage}</ModalBoxBody> | ||
</Modal> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default OptimizeModal; | ||
|
||
type OptimizeModalProps = { | ||
cephData?: K8sResourceKind[]; | ||
}; |
35 changes: 35 additions & 0 deletions
35
packages/ocs/dashboards/persistent-internal/constants/osd-migration.tsx
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
import { DISASTER_RECOVERY_TARGET_ANNOTATION } from '@odf/core/constants'; | ||
import { getAnnotations } from '@odf/shared/selectors'; | ||
|
||
export enum MigrationStatus { | ||
InProgress = 'In Progress', | ||
Pending = 'Pending', | ||
Completed = 'Completed', | ||
Unknown = '', | ||
} | ||
|
||
export const getMigrationStatus = (cephData) => { | ||
if (cephData && cephData.length > 0) { | ||
const ceph = cephData[0]; | ||
const bluestoreCount = ceph?.status?.storage?.osd?.storeType?.['bluestore']; | ||
const bluestoreRdrCount = | ||
ceph?.status?.storage?.osd?.storeType?.['bluestore-rdr']; | ||
|
||
const isDisasterRecoveryTarget = | ||
getAnnotations(cephData[0])?.[DISASTER_RECOVERY_TARGET_ANNOTATION] === | ||
'true'; | ||
|
||
if (bluestoreCount > 0) { | ||
if (bluestoreRdrCount > 0 || isDisasterRecoveryTarget) { | ||
return MigrationStatus.InProgress; | ||
} else { | ||
return MigrationStatus.Pending; | ||
} | ||
} else if (bluestoreRdrCount > 0) { | ||
return MigrationStatus.Completed; | ||
} | ||
|
||
return MigrationStatus.Unknown; | ||
} | ||
return MigrationStatus.Unknown; | ||
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters