Skip to content

Commit

Permalink
Selects the default snapshot class or the first item from the list if…
Browse files Browse the repository at this point in the history
… no default is available

Signed-off-by: Vineet Badrinath <vbadrina@redhat.com>
  • Loading branch information
vbnrh committed Dec 14, 2020
1 parent 70e7888 commit 65e7871
Showing 1 changed file with 56 additions and 36 deletions.
Expand Up @@ -25,9 +25,9 @@ import {
VolumeSnapshotClassKind,
StorageClassResourceKind,
PersistentVolumeClaimKind,
k8sGet,
VolumeSnapshotKind,
apiVersionForModel,
ListKind,
} from '@console/internal/module/k8s';
import { connectToPlural } from '@console/internal/kinds';
import {
Expand All @@ -38,12 +38,13 @@ import {
NamespaceModel,
} from '@console/internal/models';
import { accessModeRadios } from '@console/internal/components/storage/shared';
import { useK8sGet } from '@console/internal/components/utils/k8s-get-hook';
import { PVCDropdown } from '@console/internal/components/utils/pvc-dropdown';
import { getName, getNamespace } from '@console/shared';
import { getName, getNamespace, getAnnotations } from '@console/shared';
import { PVCStatus } from '@console/internal/components/persistent-volume-claim';
import { useK8sWatchResource } from '@console/internal/components/utils/k8s-watch-hook';

import './_create-volume-snapshot.scss';
import { useCallback } from 'react';

const LoadingComponent: React.FC = () => (
<Grid className="skeleton-box">
Expand All @@ -59,32 +60,9 @@ const LoadingComponent: React.FC = () => (
);

const SnapshotClassDropdown: React.FC<SnapshotClassDropdownProps> = (props) => {
const { selectedKey, pvcSC } = props;
const { selectedKey, filter } = props;
const kind = referenceForModel(VolumeSnapshotClassModel);
const resources = [{ kind }];
const [scObj, setSCObj] = React.useState<StorageClassResourceKind>(null);
const [scError, setError] = React.useState('');

React.useEffect(() => {
k8sGet(StorageClassModel, pvcSC)
.then(setSCObj)
.catch((error) => setError(error));
}, [pvcSC]);

const filter = (snapshotClass: VolumeSnapshotClassKind) =>
!scObj || !scObj.provisioner ? false : scObj?.provisioner.includes(snapshotClass?.driver);

if (scError) {
return (
<Alert
className="co-alert co-volume-snapshot__alert-body"
variant="danger"
title="Error fetching info on claim's provisioner"
isInline
/>
);
}

return (
<ListDropdown
{...props}
Expand Down Expand Up @@ -141,6 +119,12 @@ const PVCSummary: React.FC<PVCSummaryProps> = ({ persistentVolumeClaim }) => {
);
};

const defaultSnapshotClassAnnotation: string = 'snapshot.storage.kubernetes.io/is-default-class';
const isDefaultSnapshotClass = (volumeSnapshotClass: VolumeSnapshotClassKind) =>
getAnnotations(volumeSnapshotClass, { defaultSnapshotClassAnnotation: 'false' })[
defaultSnapshotClassAnnotation
] === 'true';

const CreateSnapshotForm = withHandlePromise<SnapshotResourceProps>((props) => {
const {
resourceName,
Expand All @@ -156,8 +140,15 @@ const CreateSnapshotForm = withHandlePromise<SnapshotResourceProps>((props) => {
const [pvcObj, setPVCObj] = React.useState<PersistentVolumeClaimKind>(null);
const [snapshotName, setSnapshotName] = React.useState(`${pvcName || 'pvc'}-snapshot`);
const [snapshotClassName, setSnapshotClassName] = React.useState('');
const [scObj, setSCObj] = React.useState<StorageClassResourceKind>(null);
const [scName, setSCName] = React.useState('');
const [vscObj, vscLoaded, vscErr] = useK8sGet<ListKind<VolumeSnapshotClassKind>>(
VolumeSnapshotClassModel,
);
const [scObjList, scObjListLoaded, scObjListErr] = useK8sGet<ListKind<StorageClassResourceKind>>(
StorageClassModel,
);
const title = 'Create VolumeSnapshot';

const resourceWatch = React.useMemo(() => {
return Object.assign(
{
Expand All @@ -170,11 +161,30 @@ const CreateSnapshotForm = withHandlePromise<SnapshotResourceProps>((props) => {
}, [namespace, pvcName]);

const [data, loaded, loadError] = useK8sWatchResource<PersistentVolumeClaimKind[]>(resourceWatch);
const scList = scObjListLoaded ? (scObjList.items as StorageClassResourceKind[]) : [];
const snapshotClassFilter = useCallback(
(snapshotClass: VolumeSnapshotClassKind) => scObj?.provisioner.includes(snapshotClass?.driver),
[scObj],
);
const vscList = vscLoaded ? (vscObj.items as VolumeSnapshotClassKind[]) : [];
const getDefaultItem = useCallback(() => {
const filteredVSC: VolumeSnapshotClassKind[] = vscList.filter(snapshotClassFilter);
const defaultFilteredVSC: VolumeSnapshotClassKind[] = filteredVSC.filter(
isDefaultSnapshotClass,
);
const defaultItem: string = getName(defaultFilteredVSC?.[0]) || getName(filteredVSC?.[0]);

return defaultItem;
}, [vscList, snapshotClassFilter]);

React.useEffect(() => {
const currentPVC = data.find((pvc) => pvc.metadata.name === pvcName);
setPVCObj(currentPVC);
}, [data, pvcName, namespace, loadError]);
setSCName(currentPVC?.spec?.storageClassName);
const currentSC = scList.find((sc) => sc.metadata.name === scName);
setSCObj(currentSC);
setSnapshotClassName(getDefaultItem());
}, [data, pvcName, namespace, loadError, getDefaultItem, scObjList, scObj, scName, scList]);

const handleSnapshotName: React.ReactEventHandler<HTMLInputElement> = (event) =>
setSnapshotName(event.currentTarget.value);
Expand All @@ -184,6 +194,7 @@ const CreateSnapshotForm = withHandlePromise<SnapshotResourceProps>((props) => {
setPVCObj(currentPVC);
setSnapshotName(`${name}-snapshot`);
setPVCName(name);
setSnapshotClassName(getDefaultItem());
};

const create = (event: React.FormEvent<EventTarget>) => {
Expand Down Expand Up @@ -270,12 +281,21 @@ const CreateSnapshotForm = withHandlePromise<SnapshotResourceProps>((props) => {
<label className="control-label co-required" htmlFor="snapshot-class">
Snapshot Class
</label>
<SnapshotClassDropdown
onChange={setSnapshotClassName}
dataTest="snapshot-dropdown"
selectedKey={snapshotClassName}
pvcSC={pvcObj?.spec?.storageClassName}
/>
{vscErr || scObjListErr ? (
<Alert
className="co-alert co-volume-snapshot__alert-body"
variant="danger"
title="Error fetching info on claim's provisioner"
isInline
/>
) : (
<SnapshotClassDropdown
filter={snapshotClassFilter}
onChange={setSnapshotClassName}
dataTest="snapshot-dropdown"
selectedKey={snapshotClassName}
/>
)}
</div>
)}
<ButtonBar errorMessage={errorMessage || loadError} inProgress={inProgress}>
Expand Down Expand Up @@ -332,9 +352,9 @@ export const VolumeSnapshot = connectToPlural(VolumeSnapshotComponent);

type SnapshotClassDropdownProps = {
selectedKey: string;
filter: (obj) => boolean;
onChange: (string) => void;
id?: string;
pvcSC: string;
dataTest?: string;
};

Expand Down

0 comments on commit 65e7871

Please sign in to comment.