From 15e4f28bbe2686c2fa402359c8e32520f42fc06e Mon Sep 17 00:00:00 2001 From: Afreen Rahman Date: Thu, 19 Dec 2019 04:46:30 +0530 Subject: [PATCH] Bug 1776855: Fixes negative values in capacity breakdown Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1776855 Co-authored-by: Kanika Signed-off-by: Afreen Rahman --- .../breakdown-card/breakdown-body.tsx | 1 + .../breakdown-card/breakdown-chart.tsx | 8 +++--- .../breakdown-card/consts.ts | 8 ++++++ .../breakdown-card/utils.tsx | 26 +++++++++++++------ .../capacity-breakdown-card.tsx | 7 ++--- .../src/constants/queries.ts | 20 +++++++------- 6 files changed, 44 insertions(+), 26 deletions(-) diff --git a/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-body.tsx b/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-body.tsx index d75359531bc..20cb20a9f52 100644 --- a/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-body.tsx +++ b/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-body.tsx @@ -57,6 +57,7 @@ export const BreakdownCardBody: React.FC = ({ const legends = chartData.map((d: StackDataPoint) => ({ name: [d.name, d.label], labels: { fill: d.color }, + symbol: { fill: d.fill }, link: d.link, })); diff --git a/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-chart.tsx b/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-chart.tsx index fab290382b6..7b84255e937 100644 --- a/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-chart.tsx +++ b/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/breakdown-card/breakdown-chart.tsx @@ -15,14 +15,13 @@ import { DataPoint } from '@console/internal/components/graphs'; import { K8sKind, referenceForModel } from '@console/internal/module/k8s'; import { resourcePathFromModel } from '@console/internal/components/utils'; import { CEPH_STORAGE_NAMESPACE } from '@console/ceph-storage-plugin/src/constants'; -import { isAvailableBar, getBarRadius, StackDataPoint } from './utils'; +import { getBarRadius, StackDataPoint } from './utils'; import { OTHER, CLUSTERWIDE, BUCKETCLASSKIND } from './consts'; import './breakdown-card.scss'; const LinkableLegend: React.FC = React.memo((props: LinkableLegendProps) => { const { metricModel, datum, ocsVersion } = props; let href: string = resourcePathFromModel(metricModel, datum.link, CEPH_STORAGE_NAMESPACE); - const style = {}; const customLegend = ( = React.memo((props: Linkabl } } return ( - + {customLegend} ); @@ -60,7 +59,7 @@ export const BreakdownChart: React.FC = ({ const chartData = data.map((d: StackDataPoint, index) => ( = ({ right: 0, left: 0, }} - themeColor={ChartThemeColor.multiOrdered} > stats.reduce((total, dataPoint) => total + dataPoint.y, 0); @@ -19,6 +19,7 @@ const addOthers = ( name: 'Other', color: Colors.OTHER, label: humanize(others).string, + fill: 'rgb(96, 98, 103)', link: OTHER_TOOLTIP, id: 6, }; @@ -48,6 +49,7 @@ export const addAvailable = ( link: '', color: '', label: humanize(availableInBytes).string, + fill: '#b8bbbe', id: 7, }; newChartData = [...newChartData, availableData] as StackDataPoint[]; @@ -66,24 +68,31 @@ export const getBarRadius = (index: number, length: number) => { return barRadius; }; -export const isAvailableBar = (name: string) => { - let barColor = {}; - if (name === 'Available') { - barColor = { fill: Colors.AVAILABLE }; - } - return barColor; +export const sortInstantVectorStats = (stats: DataPoint[]): DataPoint[] => { + stats.sort((a, b) => { + const y1 = a.y; + const y2 = b.y; + if (y1 === y2) { + const x1 = a.x; + const x2 = b.x; + return x1 < x2 ? -1 : x1 > x2 ? 1 : 0; + } + return y2 - y1; + }); + return stats.length === 6 ? stats.splice(0, 5) : stats; }; export const getStackChartStats: GetStackStats = (response, humanize) => response.map((r, i) => { const capacity = humanize(r.y).string; return { - // INFO: x value needs to be same for single bar stack chart + // x value needs to be same for single bar stack chart x: '0', y: r.y, name: _.truncate(`${r.x}`, { length: 12 }), link: `${r.x}`, color: Colors.LINK, + fill: COLORMAP[i], label: capacity, id: i, }; @@ -98,6 +107,7 @@ export type StackDataPoint = { label: string; link: string; color: string; + fill: string; id: number; }; diff --git a/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/capacity-breakdown/capacity-breakdown-card.tsx b/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/capacity-breakdown/capacity-breakdown-card.tsx index 535bbb9e2e4..fc689682b97 100644 --- a/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/capacity-breakdown/capacity-breakdown-card.tsx +++ b/frontend/packages/ceph-storage-plugin/src/components/dashboard-page/storage-dashboard/capacity-breakdown/capacity-breakdown-card.tsx @@ -14,7 +14,7 @@ import { breakdownQueryMap, CAPACITY_BREAKDOWN_QUERIES } from '../../../../const import { PROJECTS } from '../../../../constants/index'; import { BreakdownCardBody } from '../breakdown-card/breakdown-body'; import { HeaderPrometheusViewLink } from '../breakdown-card/breakdown-header'; -import { getStackChartStats } from '../breakdown-card/utils'; +import { getStackChartStats, sortInstantVectorStats } from '../breakdown-card/utils'; import './capacity-breakdown-card.scss'; const keys = Object.keys(breakdownQueryMap); @@ -42,8 +42,9 @@ const BreakdownCard: React.FC = ({ const queriesDataLoaded = queryKeys.some((q) => !prometheusResults.getIn([queries[q], 'data'])); const humanize = humanizeBinaryBytes; - const top5MetricsData = getInstantVectorStats(results[0], metric); - const top5MetricsStats = getStackChartStats(top5MetricsData, humanize); + const top6MetricsData = getInstantVectorStats(results[0], metric); + const top5SortedMetricsData = sortInstantVectorStats(top6MetricsData); + const top5MetricsStats = getStackChartStats(top5SortedMetricsData, humanize); const metricTotal = _.get(results[1], 'data.result[0].value[1]'); const cephTotal = _.get(results[2], 'data.result[0].value[1]'); const cephUsed = _.get(results[3], 'data.result[0].value[1]'); diff --git a/frontend/packages/ceph-storage-plugin/src/constants/queries.ts b/frontend/packages/ceph-storage-plugin/src/constants/queries.ts index 7ec1b414a26..17169fd8c50 100644 --- a/frontend/packages/ceph-storage-plugin/src/constants/queries.ts +++ b/frontend/packages/ceph-storage-plugin/src/constants/queries.ts @@ -58,16 +58,16 @@ export const CAPACITY_USAGE_QUERIES = { export const CAPACITY_BREAKDOWN_QUERIES = { [StorageDashboardQuery.PROJECTS_TOTAL_USED]: - 'sum(kubelet_volume_stats_used_bytes * 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)"})) by (namespace)', + 'sum(sum(kubelet_volume_stats_used_bytes * 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)"})) by (namespace))', [StorageDashboardQuery.PROJECTS_BY_USED]: 'sum(kubelet_volume_stats_used_bytes * 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)"})) by (namespace)', [StorageDashboardQuery.STORAGE_CLASSES_TOTAL_USED]: - 'sum(kubelet_volume_stats_used_bytes * 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)"})) by (storageclass, provisioner)', + 'sum(sum(kubelet_volume_stats_used_bytes * 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)"})) by (storageclass, provisioner))', [StorageDashboardQuery.STORAGE_CLASSES_BY_USED]: 'sum(kubelet_volume_stats_used_bytes * 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)"})) by (storageclass, provisioner)', - [StorageDashboardQuery.PODS_BY_USED]: - 'sum((kubelet_volume_stats_used_bytes * on (namespace,persistentvolumeclaim) group_right() kube_pod_spec_volumes_persistentvolumeclaims_info) * 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)"})) by (pod,namespace)', [StorageDashboardQuery.PODS_TOTAL_USED]: + 'sum(sum((kubelet_volume_stats_used_bytes * on (namespace,persistentvolumeclaim) group_right() kube_pod_spec_volumes_persistentvolumeclaims_info) * 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)"})) by (pod,namespace))', + [StorageDashboardQuery.PODS_BY_USED]: 'sum((kubelet_volume_stats_used_bytes * on (namespace,persistentvolumeclaim) group_right() kube_pod_spec_volumes_persistentvolumeclaims_info) * 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)"})) by (pod,namespace)', [StorageDashboardQuery.CEPH_CAPACITY_TOTAL]: 'ceph_cluster_total_bytes', [StorageDashboardQuery.CEPH_CAPACITY_USED]: 'ceph_cluster_total_used_bytes', @@ -78,9 +78,9 @@ export const breakdownQueryMap = { model: ProjectModel, metric: 'namespace', queries: { - [StorageDashboardQuery.PROJECTS_BY_USED]: `(sort_desc(topk(5,(${ + [StorageDashboardQuery.PROJECTS_BY_USED]: `(topk(6,(${ CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.PROJECTS_BY_USED] - }))))`, + })))`, [StorageDashboardQuery.PROJECTS_TOTAL_USED]: CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.PROJECTS_TOTAL_USED], [StorageDashboardQuery.CEPH_CAPACITY_TOTAL]: @@ -93,9 +93,9 @@ export const breakdownQueryMap = { model: StorageClassModel, metric: 'storageclass', queries: { - [StorageDashboardQuery.STORAGE_CLASSES_BY_USED]: `(sort_desc(topk(5,(${ + [StorageDashboardQuery.STORAGE_CLASSES_BY_USED]: `(topk(6,(${ CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.STORAGE_CLASSES_BY_USED] - }))))`, + })))`, [StorageDashboardQuery.STORAGE_CLASSES_TOTAL_USED]: CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.STORAGE_CLASSES_TOTAL_USED], [StorageDashboardQuery.CEPH_CAPACITY_TOTAL]: @@ -108,9 +108,9 @@ export const breakdownQueryMap = { model: PodModel, metric: 'pod', queries: { - [StorageDashboardQuery.PODS_BY_USED]: `(sort_desc(topk(5, (${ + [StorageDashboardQuery.PODS_BY_USED]: `(topk(6,(${ CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.PODS_BY_USED] - }))))`, + })))`, [StorageDashboardQuery.PODS_TOTAL_USED]: CAPACITY_BREAKDOWN_QUERIES[StorageDashboardQuery.PODS_TOTAL_USED], [StorageDashboardQuery.CEPH_CAPACITY_TOTAL]: