/** * SnapshotsPage — lists VolumeSnapshots backed by tns-csi. * Gracefully degrades when the snapshot CRD is not installed. */ import { Loader, NameValueTable, SectionBox, SectionHeader, SimpleTable, StatusLabel, } from '@kinvolk/headlamp-plugin/lib/CommonComponents'; import React from 'react'; import type { VolumeSnapshot } from '../api/k8s'; import { formatAge } from '../api/k8s'; import { useTnsCsiContext } from '../api/TnsCsiDataContext'; export default function SnapshotsPage() { const { volumeSnapshots, volumeSnapshotClasses, snapshotCrdAvailable, loading, error } = useTnsCsiContext(); if (loading) return ; if (error) { return ( <> {error} }]} /> ); } if (!snapshotCrdAvailable) { return ( <> VolumeSnapshot CRDs (snapshot.storage.k8s.io/v1) not found on this cluster ), }, { name: 'Documentation', value: ( See tns-csi documentation for snapshot setup instructions ), }, ]} /> ); } return ( <> {volumeSnapshotClasses.length > 0 && ( vsc.metadata.name }, { label: 'Driver', getter: vsc => vsc.driver ?? '—' }, { label: 'Deletion Policy', getter: vsc => vsc.deletionPolicy ?? '—' }, { label: 'Age', getter: vsc => formatAge(vsc.metadata.creationTimestamp) }, ]} data={volumeSnapshotClasses} /> )} s.metadata.name }, { label: 'Namespace', getter: (s: VolumeSnapshot) => s.metadata.namespace ?? '—' }, { label: 'Source PVC', getter: (s: VolumeSnapshot) => s.spec?.source?.persistentVolumeClaimName ?? '—', }, { label: 'Snapshot Class', getter: (s: VolumeSnapshot) => s.spec?.volumeSnapshotClassName ?? '—', }, { label: 'Ready', getter: (s: VolumeSnapshot) => { const ready = s.status?.readyToUse; if (ready === undefined) return Unknown; return ( {ready ? 'Yes' : 'No'} ); }, }, { label: 'Size', getter: (s: VolumeSnapshot) => s.status?.restoreSize ?? '—', }, { label: 'Age', getter: (s: VolumeSnapshot) => formatAge(s.metadata.creationTimestamp), }, ]} data={volumeSnapshots} emptyMessage="No tns-csi VolumeSnapshots found." /> ); }