-
Notifications
You must be signed in to change notification settings - Fork 667
Bug 1796551: Create Snapshot for PVC for OCS #3976
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -17,7 +17,9 @@ describe(CopyToClipboard.displayName, () => { | |
| .find<any>(CTC) | ||
| .props() | ||
| .onCopy(); | ||
| wrapper.update(); | ||
|
|
||
| // re-render component created via React.memo | ||
| wrapper.setProps({ value: 'FuzzBizz' }); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Details: enzymejs/enzyme#2196 (comment) |
||
|
|
||
| expect(wrapper.find(Tooltip).props().content[0].props.children).toEqual('Copied'); | ||
| }); | ||
|
|
@@ -28,7 +30,6 @@ describe(CopyToClipboard.displayName, () => { | |
| .find<any>(CTC) | ||
| .props() | ||
| .onCopy(); | ||
| wrapper.update(); | ||
|
|
||
| wrapper.find('.co-copy-to-clipboard__btn').simulate('mouseenter'); | ||
|
|
||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| .ceph-restore-pvc-modal__details { | ||
|
||
| display: flex; | ||
| flex-direction: row; | ||
| justify-content: space-between; | ||
| } | ||
|
|
||
| .ceph-restore-pvc-modal__details-section { | ||
| margin-top: var(--pf-global--spacer--xl); | ||
| } | ||
|
|
||
| .ceph-restore-pvc-modal__pvc-details { | ||
| font-weight: 600; | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,142 @@ | ||
| import './_restore-pvc-modal.scss'; | ||
|
|
||
| import * as React from 'react'; | ||
|
|
||
| import { Form, FormGroup, Grid, GridItem, TextInput } from '@patternfly/react-core'; | ||
| import { | ||
| HandlePromiseProps, | ||
| ResourceIcon, | ||
| withHandlePromise, | ||
| } from '@console/internal/components/utils/index'; | ||
| import { K8sResourceKind, k8sCreate, k8sGet } from '@console/internal/module/k8s'; | ||
| import { | ||
| ModalBody, | ||
| ModalComponentProps, | ||
| ModalSubmitFooter, | ||
| ModalTitle, | ||
| createModalLauncher, | ||
| } from '@console/internal/components/factory'; | ||
| import { NamespaceModel, PersistentVolumeClaimModel } from '@console/internal/models'; | ||
| import { getName, getNamespace } from '@console/shared'; | ||
|
|
||
| import { VolumeSnapshotModel } from '../../../models'; | ||
|
|
||
| export const RestorePVCModal = withHandlePromise((props: RestorePVCModalProps) => { | ||
| const { close, cancel, resource, errorMessage, inProgress, handlePromise } = props; | ||
| const [pvcResource, setResource] = React.useState(null); | ||
| const [restorePVCName, setPVCName] = React.useState(`${getName(resource) || 'pvc'}-restore`); | ||
|
|
||
| React.useEffect(() => { | ||
| k8sGet(PersistentVolumeClaimModel, resource?.spec?.source?.name, getNamespace(resource)) | ||
| .then(setResource) | ||
| .catch((error) => { | ||
| setResource(null); | ||
| throw error; | ||
| }); | ||
| }, [resource]); | ||
|
|
||
| const submit = (event: React.FormEvent<EventTarget>) => { | ||
| event.preventDefault(); | ||
| const snapshotName = getName(resource); | ||
| const pvcSize = resource?.status?.restoreSize; | ||
| const accessModes = pvcResource?.spec?.accessModes; | ||
| const pvcStorageClass = pvcResource?.spec?.storageClassName; | ||
| const namespace = getNamespace(resource); | ||
| const restorePVCTemplate: K8sResourceKind = { | ||
| apiVersion: PersistentVolumeClaimModel.apiVersion, | ||
| kind: PersistentVolumeClaimModel.kind, | ||
| metadata: { | ||
| name: restorePVCName, | ||
| }, | ||
| spec: { | ||
| storageClassName: pvcStorageClass, | ||
| dataSource: { | ||
| name: snapshotName, | ||
| kind: VolumeSnapshotModel.kind, | ||
| apiGroup: 'snapshot.storage.k8s.io', | ||
| }, | ||
| accessModes: [...accessModes], | ||
| resources: { | ||
| requests: { | ||
| storage: pvcSize, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
| handlePromise(k8sCreate(PersistentVolumeClaimModel, restorePVCTemplate, { ns: namespace })) | ||
| .then(close) | ||
| .catch((error) => { | ||
| throw error; | ||
|
||
| }); | ||
| }; | ||
|
|
||
| return ( | ||
| <div className="modal-content modal-content--no-inner-scroll"> | ||
| <ModalTitle>Restore</ModalTitle> | ||
| <ModalBody> | ||
| <p>After restore action is finished, a new PVC will be created.</p> | ||
| <Form onSubmit={submit}> | ||
| <FormGroup label="Name" isRequired fieldId="restore-pvc-modal__name"> | ||
| <TextInput | ||
| isRequired | ||
| type="text" | ||
| id="restore-pvc-modal__name" | ||
| name="restore-pvc-modal__name" | ||
| value={restorePVCName} | ||
| onChange={setPVCName} | ||
| /> | ||
| </FormGroup> | ||
| <div className="ceph-restore-pvc-modal__details-section"> | ||
| <Grid gutter="md"> | ||
| <GridItem span={6}> | ||
| <div> | ||
| <p className="ceph-restore-pvc-modal__pvc-details">Date</p> | ||
| <p>{resource?.metadata?.creationTimestamp}</p> | ||
| </div> | ||
| <div> | ||
| <p className="ceph-restore-pvc-modal__pvc-details">Status</p> | ||
| <p>{resource?.status?.readyToUse ? 'Ready' : 'Not Ready'}</p> | ||
| </div> | ||
| <div> | ||
| <p className="ceph-restore-pvc-modal__pvc-details">Size</p> | ||
| <p>{resource?.status?.restoreSize || 'No Data'}</p> | ||
| </div> | ||
| </GridItem> | ||
| <GridItem span={6}> | ||
| <div> | ||
| <p className="ceph-restore-pvc-modal__pvc-details">Namespace</p> | ||
| <p> | ||
| <ResourceIcon kind={NamespaceModel.kind} /> | ||
| {getNamespace(resource)} | ||
| </p> | ||
| </div> | ||
| <div> | ||
| <p className="ceph-restore-pvc-modal__pvc-details">API Version</p> | ||
| <p>{resource?.apiVersion}</p> | ||
| </div> | ||
| <div> | ||
| <p className="ceph-restore-pvc-modal__pvc-details">Persistent Volume</p> | ||
| <ResourceIcon kind={PersistentVolumeClaimModel.kind} /> | ||
| {resource?.spec?.source?.name} | ||
| </div> | ||
| </GridItem> | ||
| </Grid> | ||
| </div> | ||
| </Form> | ||
| </ModalBody> | ||
| <ModalSubmitFooter | ||
| inProgress={inProgress} | ||
| errorMessage={errorMessage} | ||
| submitText="Restore" | ||
| cancel={cancel} | ||
| /> | ||
| </div> | ||
| ); | ||
| }); | ||
|
|
||
| export type RestorePVCModalProps = { | ||
| resource: K8sResourceKind; | ||
| } & HandlePromiseProps & | ||
| ModalComponentProps; | ||
|
|
||
| export default createModalLauncher(RestorePVCModal); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,123 @@ | ||
| import * as React from 'react'; | ||
|
|
||
| import { | ||
| Dropdown, | ||
| Firehose, | ||
| FirehoseResourcesResult, | ||
| HandlePromiseProps, | ||
| withHandlePromise, | ||
| } from '@console/internal/components/utils'; | ||
| import { Form, FormGroup, TextInput } from '@patternfly/react-core'; | ||
| import { K8sResourceKind, K8sResourceKindReference, k8sCreate } from '@console/internal/module/k8s'; | ||
| import { | ||
| ModalBody, | ||
| ModalComponentProps, | ||
| ModalSubmitFooter, | ||
| ModalTitle, | ||
| createModalLauncher, | ||
| } from '@console/internal/components/factory'; | ||
| import { getName, getNamespace } from '@console/shared'; | ||
|
|
||
| import { PersistentVolumeClaimModel } from '@console/internal/models'; | ||
| import { VolumeSnapshotModel } from '../../../models'; | ||
|
|
||
| export type VolumeSnapshotModalProps = { | ||
| pvcData?: FirehoseResourcesResult; | ||
| } & HandlePromiseProps & | ||
| ModalComponentProps; | ||
|
|
||
| export const VolumeSnapshotModal = withHandlePromise((props: VolumeSnapshotModalProps) => { | ||
| const { close, cancel, pvcData, errorMessage, inProgress, handlePromise } = props; | ||
| const resource = pvcData.data as K8sResourceKind; | ||
| const [snapshotName, setSnapshotName] = React.useState( | ||
| `${getName(resource) || 'pvc'}-snapshot-1`, | ||
| ); | ||
| const snapshotTypes = { | ||
| single: 'Single Snapshot', | ||
| }; | ||
|
|
||
| const submit = (event: React.FormEvent<EventTarget>) => { | ||
| event.preventDefault(); | ||
| const ns = getNamespace(resource); | ||
| const pvcName = getName(resource); | ||
| const snapshotTemplate: K8sResourceKind = { | ||
| apiVersion: VolumeSnapshotModel.apiVersion, | ||
| kind: VolumeSnapshotModel.kind, | ||
| metadata: { | ||
| name: snapshotName, | ||
| namespace: ns, | ||
| }, | ||
| spec: { | ||
| source: { | ||
| name: pvcName, | ||
| kind: PersistentVolumeClaimModel.kind, | ||
| }, | ||
| }, | ||
| }; | ||
| handlePromise(k8sCreate(VolumeSnapshotModel, snapshotTemplate)) | ||
| .then(close) | ||
| .catch((error) => { | ||
| throw error; | ||
|
||
| }); | ||
| }; | ||
|
|
||
| return ( | ||
| <Form onSubmit={submit}> | ||
| <div className="modal-content modal-content--no-inner-scroll"> | ||
| <ModalTitle>Create Snapshot</ModalTitle> | ||
| <ModalBody> | ||
| <p>Creating snapshot for {getName(resource)}</p> | ||
| <FormGroup label="Name" isRequired fieldId="snapshot-name"> | ||
| <TextInput | ||
| isRequired | ||
| type="text" | ||
| name="snapshot-name" | ||
| aria-label="snapshot-name" | ||
| value={snapshotName} | ||
| onChange={setSnapshotName} | ||
| /> | ||
| </FormGroup> | ||
| <FormGroup label="Schedule" fieldId="snapshot-modal__schedule"> | ||
| <Dropdown | ||
| dropDownClassName="dropdown--full-width" | ||
| items={snapshotTypes} | ||
| selectedKey={snapshotTypes.single} | ||
| /> | ||
| </FormGroup> | ||
| </ModalBody> | ||
| <ModalSubmitFooter | ||
| inProgress={inProgress} | ||
| errorMessage={errorMessage} | ||
| submitText="Create" | ||
| cancel={cancel} | ||
| /> | ||
| </div> | ||
| </Form> | ||
| ); | ||
| }); | ||
|
|
||
| type VolumeSnapshotModalWithFireHoseProps = { | ||
| name: string; | ||
| namespace: string; | ||
| kind: K8sResourceKindReference; | ||
| pvcData?: FirehoseResourcesResult; | ||
| resource?: K8sResourceKind; | ||
| } & ModalComponentProps; | ||
|
|
||
| const VolumeSnapshotModalWithFireHose: React.FC<VolumeSnapshotModalWithFireHoseProps> = (props) => ( | ||
| <Firehose | ||
| resources={[ | ||
| { | ||
| kind: props.kind || PersistentVolumeClaimModel.kind, | ||
| prop: 'pvcData', | ||
| namespace: props?.resource?.metadata?.namespace || props.namespace, | ||
| isList: false, | ||
| name: props?.resource?.metadata?.name || props.name, | ||
| }, | ||
| ]} | ||
| > | ||
| <VolumeSnapshotModal {...props} /> | ||
| </Firehose> | ||
| ); | ||
|
|
||
| export const volumeSnapshotModal = createModalLauncher(VolumeSnapshotModalWithFireHose); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| .ceph-volume-snapshot__header { | ||
| border-bottom: 1px solid #ddd; | ||
| padding: 10px 30px; | ||
| } | ||
|
|
||
| .ceph-volume-snapshot__header-buttons { | ||
| align-items: baseline; | ||
| display: flex; | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@spadgett @christianvogt FYI this seems to be the recommended way to test Redux-connected components.
https://airbnb.io/enzyme/docs/api/ShallowWrapper/getWrappingComponent.html