Skip to content

Commit

Permalink
feat: added the options to select via pvc and namespace for the break…
Browse files Browse the repository at this point in the history
…down card
  • Loading branch information
dpandit committed Jul 3, 2023
1 parent 5510f5e commit fd552bc
Show file tree
Hide file tree
Showing 7 changed files with 192 additions and 14 deletions.
8 changes: 6 additions & 2 deletions locales/en/plugin__odf-console.json
Original file line number Diff line number Diff line change
Expand Up @@ -409,8 +409,12 @@
"Utilization": "Utilization",
"Expanding StorageCluster": "Expanding StorageCluster",
"Upgrading Data Foundation's Operator": "Upgrading Data Foundation's Operator",
"Used capacity breakdown": "Used capacity breakdown",
"PersistentVolumeClaims": "PersistentVolumeClaims",
"This card shows the used capacity for different Kubernetes resources. The figures shown represent the Usable storage, meaning that data replication is not taken into consideration.": "This card shows the used capacity for different Kubernetes resources. The figures shown represent the Usable storage, meaning that data replication is not taken into consideration.",
"Select a namespace:": "Select a namespace:",
"{{pvcNamespace}}": "{{pvcNamespace}}",
"PVCs Namespace Dropdown": "PVCs Namespace Dropdown",
"Only showing PVCs that are being mounted on an active pod": "Only showing PVCs that are being mounted on an active pod",
"Internal": "Internal",
"Raw capacity is the absolute total disk space available to the array subsystem.": "Raw capacity is the absolute total disk space available to the array subsystem.",
"Troubleshoot": "Troubleshoot",
Expand Down Expand Up @@ -957,6 +961,7 @@
"Only lowercase letters, numbers, non-consecutive periods, or hyphens": "Only lowercase letters, numbers, non-consecutive periods, or hyphens",
"Cannot be used before": "Cannot be used before",
"Not enough usage data": "Not enough usage data",
"Total requests: ": "Total requests: ",
"used": "used",
"available": "available",
"Other": "Other",
Expand Down Expand Up @@ -1041,7 +1046,6 @@
"PersistentVolume": "PersistentVolume",
"PersistentVolumes": "PersistentVolumes",
"PersistentVolumeClaim": "PersistentVolumeClaim",
"PersistentVolumeClaims": "PersistentVolumeClaims",
"Namespaces": "Namespaces",
"ConfigMap": "ConfigMap",
"ConfigMaps": "ConfigMaps",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,39 @@
}

.ceph-capacity-breakdown-card__header {
border-bottom: var(--pf-global--BorderWidth--sm) solid var(--pf-global--BorderColor--100);
display: flex;
align-items: center;
justify-content: space-between;
}

.ceph-capacity-breakdown-card-header__dropdown {
max-width: 12em;
max-width: 30em;
@media screen and (min-width: $pf-global--breakpoint--lg) {
min-width: 12em;
}
}

.odf-capacity-breakdown-card-pvc-namespace {
&__header {
display: flex;
align-items: center;
justify-content: end;
padding: var(--pf-global--spacer--md) var(--pf-global--spacer--lg) 0;
}
&__dropdown > ul {
max-height: 300px;
@media screen and (min-width: $pf-global--breakpoint--lg) {
min-width: 12em;
}
max-width: 30em;
overflow: auto;
}
&__title {
padding-right: var(--pf-global--spacer--lg);
}
}

.odf-capacity-breakdown-card-pvc-description {
font-size: var(--pf-global--FontSize--xs);
}
Original file line number Diff line number Diff line change
@@ -1,12 +1,18 @@
import * as React from 'react';
import { BreakdownCardBody } from '@odf/shared/dashboards/breakdown-card/breakdown-body';
import { getSelectOptions } from '@odf/shared/dashboards/breakdown-card/breakdown-dropdown';
import {
getPVCSelectOptions,
getSelectOptions,
} from '@odf/shared/dashboards/breakdown-card/breakdown-dropdown';
import { FieldLevelHelp } from '@odf/shared/generic/FieldLevelHelp';
import { Loading } from '@odf/shared/generic/status-box';
import {
useCustomPrometheusPoll,
usePrometheusBasePath,
} from '@odf/shared/hooks/custom-prometheus-poll';
import { BreakdownCardFields } from '@odf/shared/queries';
import { useK8sList } from '@odf/shared/hooks/useK8sList';
import { NamespaceModel } from '@odf/shared/models';
import { useCustomTranslation } from '@odf/shared/useCustomTranslationHook';
import {
getInstantVectorStats,
Expand All @@ -22,7 +28,7 @@ import {
CardTitle,
} from '@patternfly/react-core';
import {
breakdownQueryMapCEPH,
getBreakdownMetricsQuery,
CEPH_CAPACITY_BREAKDOWN_QUERIES,
StorageDashboardQuery,
} from '../../../queries/ceph-storage';
Expand All @@ -49,8 +55,20 @@ const BreakdownCard: React.FC = () => {
BreakdownCardFields.PROJECTS
);
const [isOpenBreakdownSelect, setBreakdownSelect] = React.useState(false);
const [isNamespaceSelectOpen, setNamespaceSelect] = React.useState(false);
const [pvcNamespace, setPVCNamespace] = React.useState('');

const { queries, model, metric } = breakdownQueryMapCEPH[metricType];
const [allNamespace, allNamespaceLoaded, allNamespaceError] =
useK8sList(NamespaceModel);
React.useEffect(
() => setPVCNamespace(allNamespace?.sort()[0]?.metadata?.name || ''),
[allNamespace]
);

const { queries, model, metric } = React.useMemo(
() => getBreakdownMetricsQuery(metricType, pvcNamespace),
[metricType, pvcNamespace]
);

const [modelByUsed, modelUsedError, modelUsedLoading] =
useCustomPrometheusPoll({
Expand Down Expand Up @@ -86,6 +104,11 @@ const BreakdownCard: React.FC = () => {
setBreakdownSelect(!isOpenBreakdownSelect);
};

const handleNamespaceChange: SelectProps['onSelect'] = (_e, namespace) => {
setPVCNamespace(namespace as any);
setNamespaceSelect(!isNamespaceSelectOpen);
};

const dropdownOptions = [
{
name: t('Projects'),
Expand All @@ -99,15 +122,19 @@ const BreakdownCard: React.FC = () => {
name: t('Pods'),
id: BreakdownCardFields.PODS,
},
{
name: t('PersistentVolumeClaims'),
id: PVCs,
},
];
const breakdownSelectItems = getSelectOptions(dropdownOptions);

return (
<Card>
<CardHeader className="ceph-capacity-breakdown-card__header">
<CardTitle>
{t('Used capacity breakdown')}
<FieldLevelHelp>
<CardTitle id="breakdown-card-title">
{t('Requested capacity')}
<FieldLevelHelp testId="breakdown-card-helper-text">
{t(
'This card shows the used capacity for different Kubernetes resources. The figures shown represent the Usable storage, meaning that data replication is not taken into consideration.'
)}
Expand All @@ -125,10 +152,42 @@ const BreakdownCard: React.FC = () => {
})}
aria-label={t('Break By Dropdown')}
isCheckboxSelectionBadgeHidden
id="breakdown-card-metrics-dropdown"
>
{breakdownSelectItems}
</Select>
</CardHeader>
{metricType === PVCs && (
<div className="odf-capacity-breakdown-card-pvc-namespace__header">
{allNamespaceLoaded && !allNamespaceError ? (
<>
<div
id="odf-capacity-breakdown-card-pvc-namespace-title"
className="odf-capacity-breakdown-card-pvc-namespace__title"
>
{t('Select a namespace:')}
</div>

<Select
className="ceph-capacity-breakdown-card-header__dropdown odf-capacity-breakdown-card-pvc-namespace__dropdown"
autoFocus={false}
onSelect={handleNamespaceChange}
onToggle={() => setNamespaceSelect(!isNamespaceSelectOpen)}
isOpen={isNamespaceSelectOpen}
placeholderText={t('{{pvcNamespace}}', {
pvcNamespace,
})}
aria-label={t('PVCs Namespace Dropdown')}
id="odf-capacity-breakdown-card-pvc-namespace-dropdown"
>
{getPVCSelectOptions(allNamespace)}
</Select>
</>
) : (
<Loading />
)}
</div>
)}
<CardBody className="ceph-capacity-breakdown-card__body">
<BreakdownCardBody
isLoading={!dataLoaded}
Expand All @@ -138,8 +197,17 @@ const BreakdownCard: React.FC = () => {
capacityUsed={cephUsed}
metricModel={model}
humanize={humanize}
isOfBlockAndFileType={true}
/>
</CardBody>
{metricType === PVCs &&
!queriesLoadError &&
top5MetricsStats.length > 0 &&
cephUsed && (
<CardBody className="odf-capacity-breakdown-card-pvc-description">
{t('Only showing PVCs that are being mounted on an active pod')}
</CardBody>
)}
</Card>
);
};
Expand Down
59 changes: 59 additions & 0 deletions packages/ocs/queries/ceph-storage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,24 @@ export const breakdownQueryMapCEPH: BreakdownCardQueryMap = {
},
};

export const getBreakdownMetricsQuery = (
metricType: string,
namespace?: string
): MetricsQueryProps => {
if (metricType === PVCs && namespace) {
const queries = {
[StorageDashboardQuery.PVC_NAMESPACES_BY_USED]: `sum by (namespace, persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace='${namespace}'} * on (namespace, persistentvolumeclaim) group_left(storageclass, provisioner) (kube_persistentvolumeclaim_info * on (storageclass) group_left(provisioner) kube_storageclass_info {provisioner=~"(.*rbd.csi.ceph.com)|(.*cephfs.csi.ceph.com)|(ceph.rook.io/block)"}))`,
[StorageDashboardQuery.PVC_NAMESPACES_TOTAL_USED]: `sum(sum by (namespace, persistentvolumeclaim) (kubelet_volume_stats_used_bytes{namespace='${namespace}'} * on (namespace, persistentvolumeclaim) group_left(storageclass, provisioner) (kube_persistentvolumeclaim_info * on (storageclass) group_left(provisioner) kube_storageclass_info {provisioner=~"(.*rbd.csi.ceph.com)|(.*cephfs.csi.ceph.com)|(ceph.rook.io/block)"})))`,
};
return {
model: PersistentVolumeClaimModel,
metric: 'persistentvolumeclaim',
queries,
};
}
return breakdownQueryMapCEPH[metricType];
};

export const CAPACITY_INFO_QUERIES = {
[StorageDashboardQuery.RAW_CAPACITY_TOTAL]: 'ceph_cluster_total_bytes',
[StorageDashboardQuery.RAW_CAPACITY_USED]:
Expand Down Expand Up @@ -265,3 +283,44 @@ export const breakdownIndependentQueryMap: BreakdownCardQueryMap = {
},
},
};

type projectQueryProps = {
metric: 'namespace';
queries: {
[StorageDashboardQuery.PROJECTS_BY_USED]: string;
[StorageDashboardQuery.PROJECTS_TOTAL_USED]: string;
[StorageDashboardQuery.CEPH_CAPACITY_USED]: string;
};
};
type storageClassQueryProps = {
metric: 'storageclass';
queries: {
[StorageDashboardQuery.STORAGE_CLASSES_BY_USED]: string;
[StorageDashboardQuery.STORAGE_CLASSES_TOTAL_USED]: string;
[StorageDashboardQuery.CEPH_CAPACITY_USED]: string;
};
};
type podsQueryProps = {
metric: 'pod';
queries: {
[StorageDashboardQuery.PODS_BY_USED]: string;
[StorageDashboardQuery.PODS_TOTAL_USED]: string;
[StorageDashboardQuery.CEPH_CAPACITY_USED]: string;
};
};
type pvcQueryProps = {
metric: 'persistentvolumeclaim';
queries: {
[StorageDashboardQuery.PVC_NAMESPACES_BY_USED]: string;
[StorageDashboardQuery.PVC_NAMESPACES_TOTAL_USED]: string;
};
};

type MetricsQueryProps = {
model: K8sModel;
} & (
| projectQueryProps
| podsQueryProps
| storageClassQueryProps
| pvcQueryProps
);
10 changes: 7 additions & 3 deletions packages/shared/dashboards/breakdown-card/breakdown-body.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const BreakdownCardBody: React.FC<BreakdownBodyProps> = ({
hasLoadError,
ocsVersion = '',
labelPadding,
isOfBlockAndFileType,
}) => {
const { t } = useCustomTranslation();

Expand Down Expand Up @@ -59,16 +60,18 @@ export const BreakdownCardBody: React.FC<BreakdownBodyProps> = ({
<Grid>
<GridItem span={4}>
<TotalCapacityBody
capacity={humanize(capacityUsed).string}
suffix={t('used')}
prefix={isOfBlockAndFileType && t('Total requests: ')}
capacity={humanize(metricTotal).string}
suffix={isOfBlockAndFileType ? undefined : t('used')}
makeCapacityInBold={isOfBlockAndFileType}
/>
</GridItem>
<GridItem span={4} />
<GridItem span={4}>
{capacityAvailable && (
<TotalCapacityBody
capacity={humanize(capacityAvailable).string}
suffix={t('available')}
suffix={isOfBlockAndFileType ? undefined : t('available')}
className="capacity-breakdown-card__available-body text-secondary"
/>
)}
Expand Down Expand Up @@ -97,4 +100,5 @@ export type BreakdownBodyProps = {
humanize: Humanize;
ocsVersion?: string;
labelPadding?: LabelPadding;
isOfBlockAndFileType?: boolean;
};
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ import './breakdown-card.scss';

export const TotalCapacityBody: React.FC<TotalCapacityBodyProps> = ({
capacity,
prefix,
suffix,
className,
makeCapacityInBold,
}) => {
return (
<p
Expand All @@ -14,13 +16,16 @@ export const TotalCapacityBody: React.FC<TotalCapacityBodyProps> = ({
className
)}
>
{capacity} {suffix}
{prefix} {makeCapacityInBold ? <strong>{capacity}</strong> : capacity}{' '}
{suffix}
</p>
);
};

type TotalCapacityBodyProps = {
capacity: string;
suffix: string;
prefix?: string;
suffix?: string;
className?: string;
makeCapacityInBold?: boolean;
};
13 changes: 13 additions & 0 deletions packages/shared/dashboards/breakdown-card/breakdown-dropdown.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as React from 'react';
import { K8sResourceCommon } from '@openshift-console/dynamic-plugin-sdk';
import {
SelectOption,
SelectGroup,
Expand All @@ -20,6 +21,18 @@ export const getSelectOptions = (
</SelectOption>
));

export const getPVCSelectOptions = (
selectItems: K8sResourceCommon[]
): React.ReactElement[] =>
selectItems.map((namespace) => {
const { name } = namespace.metadata;
return (
<SelectOption key={name} value={name}>
{name}
</SelectOption>
);
});

export const getGroupedSelectOptions = (
groupedSelectItems: GroupedSelectItems
): React.ReactElement[] =>
Expand Down

0 comments on commit fd552bc

Please sign in to comment.