Skip to content

Commit

Permalink
Bug 1870331: Not allow to change size for OCS based resource
Browse files Browse the repository at this point in the history
Signed-off-by: Kanika Murarka <kmurarka@redhat.com>
  • Loading branch information
Kanika Murarka committed Sep 24, 2020
1 parent 23d8c16 commit 3bb14f2
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 25 deletions.
@@ -1,5 +1,5 @@
.co-clone-pvc-modal__details {
margin-top: var(--pf-global--spacer--xl);
margin-top: var(--pf-global--spacer--md);
}

.co-clone-pvc-modal__details-section {
Expand All @@ -14,3 +14,7 @@
.co-clone-pvc-modal__name--margin {
margin-bottom: var(--pf-global--spacer--sm);
}

.co-clone-pvc-modal__ocs-size .form-group{
margin-bottom: var(--pf-global--spacer--sm);
}
Expand Up @@ -3,7 +3,12 @@ import './_clone-pvc-modal.scss';
import * as React from 'react';

import { Form, FormGroup, TextInput } from '@patternfly/react-core';
import { k8sCreate, referenceFor, PersistentVolumeClaimKind } from '@console/internal/module/k8s';
import {
k8sCreate,
referenceFor,
PersistentVolumeClaimKind,
StorageClassResourceKind,
} from '@console/internal/module/k8s';
import {
LoadingInline,
ResourceIcon,
Expand All @@ -13,6 +18,7 @@ import {
RequestSizeInput,
validate,
resourceObjPath,
convertToBaseValue,
} from '@console/internal/components/utils';
import {
ModalBody,
Expand All @@ -33,6 +39,8 @@ import { getInstantVectorStats } from '@console/internal/components/graphs/utils
import { usePrometheusPoll } from '@console/internal/components/graphs/prometheus-poll-hook';
import { getRequestedPVCSize } from '@console/shared/src/selectors';
import { dropdownUnits, accessModeRadios } from '@console/internal/components/storage/shared';
import { useK8sGet } from '@console/internal/components/utils/k8s-get-hook';
import { isCephProvisioner } from '@console/shared';

const ClonePVCModal = withHandlePromise((props: ClonePVCModalProps) => {
const { close, cancel, resource, handlePromise, errorMessage, inProgress } = props;
Expand All @@ -42,11 +50,18 @@ const ClonePVCModal = withHandlePromise((props: ClonePVCModalProps) => {

const [clonePVCName, setClonePVCName] = React.useState(`${pvcName}-clone`);
const [requestedSize, setRequestedSize] = React.useState(defaultSize[0] || '');
const [requestedUnit, setRequestedUnit] = React.useState(defaultSize[1] || 'Gi');
const accessMode = accessModeRadios.find(
(mode) => mode.value === resource?.spec?.accessModes?.[0],
);

const [requestedUnit, setRequestedUnit] = React.useState(defaultSize[1] || 'Ti');
const [validSize, setValidSize] = React.useState(true);

const [scResource, scResourceLoaded, scResourceLoadError] = useK8sGet<StorageClassResourceKind>(
StorageClassModel,
resource?.spec?.storageClassName,
);

const pvcUsedCapacityQuery: string = `kubelet_volume_stats_used_bytes{persistentvolumeclaim='${pvcName}'}`;
const [response, error, loading] = usePrometheusPoll({
endpoint: PrometheusEndpoint.QUERY,
Expand All @@ -62,6 +77,10 @@ const ClonePVCModal = withHandlePromise((props: ClonePVCModalProps) => {
const requestedSizeInputChange = ({ value, unit }) => {
setRequestedSize(value);
setRequestedUnit(unit);
const cloneSizeInBytes = convertToBaseValue(value + unit);
const pvcSizeInBytes = convertToBaseValue(getRequestedPVCSize(resource));
const isValid = cloneSizeInBytes >= pvcSizeInBytes;
setValidSize(isValid);
};

const submit = (event: React.FormEvent<EventTarget>) => {
Expand Down Expand Up @@ -111,16 +130,28 @@ const ClonePVCModal = withHandlePromise((props: ClonePVCModalProps) => {
aria-label="Clone Pvc"
/>
</FormGroup>
<FormGroup label="Size" isRequired fieldId="clone-pvc-modal__size">
<RequestSizeInput
name="requestSize"
testID="input-request-size"
onChange={requestedSizeInputChange}
defaultRequestSizeUnit={requestedUnit}
defaultRequestSizeValue={requestedSize}
dropdownUnits={dropdownUnits}
required
/>
<FormGroup
label="Size"
isRequired
fieldId="clone-pvc-modal__size"
className="co-clone-pvc-modal__ocs-size"
helperTextInvalid="Size should be equal or higher than the requested size of PVC"
validated={validSize ? 'default' : 'error'}
>
{scResourceLoaded && !scResourceLoadError ? (
<RequestSizeInput
name="requestSize"
testID="input-request-size"
onChange={requestedSizeInputChange}
defaultRequestSizeUnit={requestedUnit}
defaultRequestSizeValue={requestedSize}
dropdownUnits={dropdownUnits}
isInputDisabled={isCephProvisioner(scResource?.provisioner)}
required
/>
) : (
<div className="skeleton-text" />
)}
</FormGroup>
<div className="co-clone-pvc-modal__details">
<p className="text-muted">PVC Details</p>
Expand Down Expand Up @@ -170,6 +201,7 @@ const ClonePVCModal = withHandlePromise((props: ClonePVCModalProps) => {
</ModalBody>
<ModalSubmitFooter
inProgress={inProgress}
submitDisabled={!validSize}
errorMessage={errorMessage}
submitText="Clone"
cancel={cancel}
Expand Down
Expand Up @@ -15,3 +15,7 @@
.co-restore-pvc-modal__input {
margin: var(--pf-global--spacer--md) 0;
}

.co-restore-pvc-modal__ocs-size .form-group{
margin-bottom: var(--pf-global--spacer--sm);
}
Expand Up @@ -10,6 +10,7 @@ import {
RequestSizeInput,
Timestamp,
resourcePathFromModel,
convertToBaseValue,
} from '@console/internal/components/utils';
import {
k8sCreate,
Expand All @@ -31,7 +32,7 @@ import {
VolumeSnapshotModel,
VolumeSnapshotClassModel,
} from '@console/internal/models';
import { getName, getNamespace, Status } from '@console/shared';
import { getName, getNamespace, Status, isCephProvisioner } from '@console/shared';
import { StorageClassDropdown } from '@console/internal/components/utils/storage-class-dropdown';
import { dropdownUnits } from '@console/internal/components/storage/shared';
import { useK8sGet } from '@console/internal/components/utils/k8s-get-hook';
Expand All @@ -48,8 +49,9 @@ const RestorePVCModal = withHandlePromise<RestorePVCModalProps>(
? `${defaultSize[0]} ${dropdownUnits[defaultSize[1]]}`
: '';
const [requestedSize, setRequestedSize] = React.useState(defaultSize?.[0] ?? '');
const [requestedUnit, setRequestedUnit] = React.useState(defaultSize?.[1] ?? 'Gi');
const [requestedUnit, setRequestedUnit] = React.useState(defaultSize?.[1] ?? 'Ti');
const [pvcSC, setPVCStorageClass] = React.useState('');
const [validSize, setValidSize] = React.useState(true);
const namespace = getNamespace(resource);
const snapshotName = getName(resource);

Expand All @@ -74,6 +76,10 @@ const RestorePVCModal = withHandlePromise<RestorePVCModalProps>(
const requestedSizeInputChange = ({ value, unit }) => {
setRequestedSize(value);
setRequestedUnit(unit);
const restoreSizeInBytes = convertToBaseValue(value + unit);
const snapshotSizeInBytes = convertToBaseValue(resource?.status?.restoreSize);
const isValid = restoreSizeInBytes >= snapshotSizeInBytes;
setValidSize(isValid);
};

const handleStorageClass = (updatedStorageClass) =>
Expand Down Expand Up @@ -119,7 +125,6 @@ const RestorePVCModal = withHandlePromise<RestorePVCModalProps>(
},
);
};

return (
<div className="modal-content modal-content--no-inner-scroll">
<ModalTitle>Restore as new PVC</ModalTitle>
Expand Down Expand Up @@ -165,16 +170,23 @@ const RestorePVCModal = withHandlePromise<RestorePVCModalProps>(
label="Size"
isRequired
fieldId="pvc-size"
className="co-restore-pvc-modal__input"
className="co-restore-pvc-modal__input co-restore-pvc-modal__ocs-size"
helperTextInvalid="Size should be equal or higher than the restore size of snapshot"
validated={validSize ? 'default' : 'error'}
>
<RequestSizeInput
name="requestSize"
onChange={requestedSizeInputChange}
defaultRequestSizeUnit={requestedUnit}
defaultRequestSizeValue={requestedSize}
dropdownUnits={dropdownUnits}
required
/>
{snapshotClassResourceLoaded && !snapshotClassResourceLoadError ? (
<RequestSizeInput
name="requestSize"
onChange={requestedSizeInputChange}
defaultRequestSizeUnit={requestedUnit}
defaultRequestSizeValue={requestedSize}
dropdownUnits={dropdownUnits}
isInputDisabled={isCephProvisioner(snapshotClassResource?.driver)}
required
/>
) : (
<div className="skeleton-text" />
)}
</FormGroup>
<div className="co-restore-pvc-modal__details-section">
<p className="text-muted">{VolumeSnapshotModel.label} details</p>
Expand Down Expand Up @@ -213,6 +225,7 @@ const RestorePVCModal = withHandlePromise<RestorePVCModalProps>(
</ModalBody>
<ModalSubmitFooter
inProgress={inProgress}
submitDisabled={!validSize}
errorMessage={errorMessage}
submitText="Restore"
cancel={cancel}
Expand Down
3 changes: 3 additions & 0 deletions frontend/public/components/utils/request-size-input.tsx
Expand Up @@ -38,6 +38,7 @@ export class RequestSizeInput extends React.Component<RequestSizeInputProps> {
required={this.props.required}
value={this.props.defaultRequestSizeValue}
min={this.props.minValue}
disabled={this.props.isInputDisabled}
/>
<Dropdown
title={this.props.dropdownUnits[this.props.defaultRequestSizeUnit]}
Expand All @@ -46,6 +47,7 @@ export class RequestSizeInput extends React.Component<RequestSizeInputProps> {
className="btn-group"
items={this.props.dropdownUnits}
onChange={this.onUnitChange}
disabled={this.props.isInputDisabled}
required={this.props.required}
ariaLabel={`Number of ${this.props.dropdownUnits[this.props.defaultRequestSizeUnit]}`}
/>
Expand All @@ -69,4 +71,5 @@ export type RequestSizeInputProps = {
inputClassName?: string;
inputID?: string;
testID?: string;
isInputDisabled?: boolean;
};

0 comments on commit 3bb14f2

Please sign in to comment.