From b36f606ca8cdaf243420e09d6a1aefa94bd20cd5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Wed, 18 Jun 2025 10:05:40 +0200 Subject: [PATCH 01/16] prometheus metrics configuration ui --- .../PrivateConfigPrometheusMetricsDetails.tsx | 25 ++ .../Details/SystemConfigDetails.tsx | 16 + .../components/PrometheusMetricsCard.tsx | 311 ++++++++++++++++++ .../SystemConfig/Form/SystemConfigForm.tsx | 11 + ui/apps/platform/src/types/config.proto.ts | 17 + 5 files changed, 380 insertions(+) create mode 100644 ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx create mode 100644 ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx new file mode 100644 index 0000000000000..d947e209b6fdf --- /dev/null +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx @@ -0,0 +1,25 @@ +import { ReactElement } from 'react'; + +import { PrivateConfig } from 'types/config.proto'; +import { PrometheusMetricsCard } from './components/PrometheusMetricsCard'; + +export type PrivateConfigPrometheusMetricsDetailsProps = { + privateConfig: PrivateConfig; +}; + +const PrivateConfigPrometheusMetricsDetails = ({ + privateConfig, +}: PrivateConfigPrometheusMetricsDetailsProps): ReactElement[] => { + const imageVulnerabilitiesCfg = privateConfig?.metrics?.imageVulnerabilities; + + return [ + PrometheusMetricsCard( + 'imageVulnerabilities', + imageVulnerabilitiesCfg?.gatheringPeriodMinutes || 0, + imageVulnerabilitiesCfg?.descriptors, + 'Image vulnerabilities' + ), + ]; +}; + +export default PrivateConfigPrometheusMetricsDetails; diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx index 75e09774d959f..8bb826f4e6dea 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx @@ -20,6 +20,7 @@ import PublicConfigBannerDetails from './PublicConfigBannerDetails'; import PublicConfigLoginDetails from './PublicConfigLoginDetails'; import PublicConfigTelemetryDetails from './PublicConfigTelemetryDetails'; import PlatformComponentsConfigDetails from './PlatformComponentsConfigDetails'; +import PrivateConfigPrometheusMetricsDetails from './PrivateConfigPrometheusMetricsDetails'; export type SystemConfigDetailsProps = { systemConfig: SystemConfig; @@ -81,6 +82,21 @@ function SystemConfigDetails({ privateConfig={systemConfig?.privateConfig} /> + + + Prometheus metrics configuration + + + The Prometheus metrics are exposed on the API endpoint, at the{' '} + /metrics path and require permissions to view Administration + resources. + + + + + Public configuration diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx new file mode 100644 index 0000000000000..574fa7fdc3ca7 --- /dev/null +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -0,0 +1,311 @@ +import React, { ReactElement } from 'react'; +import { Category, PrivateConfig, Labels } from 'types/config.proto'; +import { + Card, + CardBody, + CardHeader, + CardTitle, + DataList, + DataListCell, + DataListCheck, + DataListItem, + DataListItemCells, + DataListItemRow, + DescriptionList, + DescriptionListDescription, + DescriptionListGroup, + DescriptionListTerm, + Divider, + EmptyState, + EmptyStateBody, + EmptyStateHeader, + FormGroup, + FormSection, + Grid, + GridItem, + Label, + LabelGroup, + TextInput, +} from '@patternfly/react-core'; +import pluralize from 'pluralize'; +import { FormikErrors, FormikValues } from 'formik'; + +const predefinedMetrics: Record<Category, Record<string, Labels>> = { + imageVulnerabilities: { + image_vuln_namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, + image_vuln_deployment_severity: { + labels: ['Cluster', 'Namespace', 'Deployment', 'Severity'], + }, + image_vuln_user_workload_severity: { + labels: ['Cluster', 'Namespace', 'Deployment', 'IsPlatformWorkload', 'Severity'], + }, + }, +}; + +function labelGroup(labels: Labels): ReactElement { + return ( + <LabelGroup isCompact numLabels={Infinity}> + {labels.labels.map((label) => { + return ( + <Label isCompact key={label}> + {label} + </Label> + ); + })} + </LabelGroup> + ); +} + +function predefinedMetricListItem( + enabled: boolean, + category: Category, + metric: string, + onCustomChange: + | ((value: unknown, id: string) => Promise<void> | Promise<FormikErrors<FormikValues>>) + | undefined +): ReactElement { + return ( + <DataListItem key={`${category}-${metric}`}> + <DataListItemRow> + <DataListItemCells + dataListCells={[ + onCustomChange ? ( + <DataListCheck + key={`${category}-${metric}-checkbox`} + id={`${category}-${metric}-checkbox`} + aria-labelledby={`${category}-${metric}-label`} + name={`${category}-${metric}`} + isChecked={enabled} + onChange={(_, checked) => + onCustomChange( + checked ? predefinedMetrics[category][metric] : undefined, + `privateConfig.metrics.${category}.descriptors.${metric}` + ) + } + /> + ) : null, + <DataListCell + key={`${category}-${metric}-label`} + id={`${category}-${metric}-label`} + > + {metric} + </DataListCell>, + <DataListCell key={`${category}-${metric}-predefined`}> + Predefined + </DataListCell>, + <DataListCell key={`${category}-${metric}-descriptors`}> + {labelGroup(predefinedMetrics[category][metric])} + </DataListCell>, + ]} + /> + </DataListItemRow> + </DataListItem> + ); +} + +// hasMetric checks if the descriptors contain the given metric by looking at +// the metric name and the labels (ignoring the order). +function hasMetric( + descriptors: Record<string, Labels> | undefined, + metric: string, + labels: Labels +): boolean { + const cfgLabels = descriptors?.[metric]?.labels || []; + const ll = labels.labels; + return cfgLabels.length === ll.length && cfgLabels.every((label) => ll.includes(label)); +} + +function prometheusMetricsDataList( + descriptors: Record<string, Labels> | undefined, + category: Category, + onCustomChange: + | ((value: unknown, id: string) => Promise<void> | Promise<FormikErrors<FormikValues>>) + | undefined +): ReactElement { + return ( + <DataList aria-label={`${category}-metrics-descriptors`} isCompact> + {Object.entries(predefinedMetrics[category]).map( + ([predefinedMetric, originalLabels]) => { + // In view mode show only enabled predefined metrics. + // In edit mode show all predefined metrics unless they're + // overridden. + + const isEnabledOriginal = hasMetric( + descriptors, + predefinedMetric, + originalLabels + ); + const enabled = descriptors !== undefined && predefinedMetric in descriptors; + if (isEnabledOriginal || (onCustomChange && !enabled)) { + return predefinedMetricListItem( + isEnabledOriginal, + category, + predefinedMetric, + onCustomChange + ); + } + return null; + } + )} + {Object.entries(descriptors || {}).map(([metric, labels]) => { + // Predefined are rendered above. + if (hasMetric(predefinedMetrics[category], metric, labels)) { + return null; + } + return ( + <DataListItem key={`${category}-${metric}`} id={`${category}-${metric}`}> + <DataListItemRow> + <DataListItemCells + dataListCells={[ + onCustomChange ? ( + <DataListCheck + id={metric} + aria-labelledby={metric} + name={metric} + isChecked + isDisabled + /> + ) : null, + <DataListCell>{metric}</DataListCell>, + <DataListCell>Custom</DataListCell>, + <DataListCell>{labelGroup(labels)}</DataListCell>, + ]} + /> + </DataListItemRow> + </DataListItem> + ); + })} + </DataList> + ); +} + +export function PrometheusMetricsCard( + category: Category, + period: number, + descriptors: Record<string, Labels> | undefined, + title: string +) { + const hasMetrics = descriptors && Object.keys(descriptors).length > 0; + return ( + <GridItem key={category} md={hasMetrics ? 12 : 6} lg={hasMetrics ? 12 : 6}> + <Card isFlat data-testid={`${category}-view-metrics-config`}> + <CardHeader + actions={{ + actions: ( + <> + {period && hasMetrics ? ( + <Label color="green">Enabled</Label> + ) : ( + <Label>Disabled</Label> + )} + </> + ), + hasNoOffset: false, + className: undefined, + }} + > + <CardTitle component="h3">{title}</CardTitle> + </CardHeader> + <Divider component="div" /> + <CardBody> + {hasMetrics ? ( + <DescriptionList + isCompact + isHorizontal + columnModifier={{ + default: '1Col', + }} + > + {period ? ( + <DescriptionListGroup key={`${category}-period`}> + <DescriptionListTerm>Gathering period</DescriptionListTerm> + <DescriptionListDescription> + {period}  + {pluralize('minute', period)} + </DescriptionListDescription> + </DescriptionListGroup> + ) : null} + <DescriptionListGroup key={`${category}-metrics`}> + <DescriptionListTerm>Metrics</DescriptionListTerm> + <DescriptionListDescription> + {prometheusMetricsDataList(descriptors, category, undefined)} + </DescriptionListDescription> + </DescriptionListGroup> + </DescriptionList> + ) : ( + <EmptyState variant="xs"> + <EmptyStateHeader>No metrics has been configured</EmptyStateHeader> + <EmptyStateBody> + Edit the configuration, or call <code>/v1/config</code> API to add + custom metrics. + </EmptyStateBody> + </EmptyState> + )} + </CardBody> + </Card> + </GridItem> + ); +} + +function prometheusMetricsPeriodForm( + pcfg: PrivateConfig, + category: Category, + onChange: (value, event) => Promise<void> | Promise<FormikErrors<FormikValues>> +): ReactElement { + return ( + <FormGroup + label="Gathering period in minutes (set to 0 to disable)" + isRequired + fieldId={`privateConfig.metrics.${category}.gatheringPeriodMinutes`} + > + <TextInput + isRequired + type="number" + id={`privateConfig.metrics.${category}.gatheringPeriodMinutes`} + name={`privateConfig.metrics.${category}.gatheringPeriodMinutes`} + value={pcfg?.metrics?.[category]?.gatheringPeriodMinutes || 0} + onChange={(event, value) => onChange(value, event)} + min={0} + /> + </FormGroup> + ); +} + +export function PrometheusMetricsForm( + pcfg: PrivateConfig, + category: Category, + title: string, + onChange: (value, event) => Promise<void> | Promise<FormikErrors<FormikValues>>, + onCustomChange: + | ((value: unknown, id: string) => Promise<void> | Promise<FormikErrors<FormikValues>>) + | undefined +) { + return ( + <GridItem> + <Card isFlat data-testid={`${category}-metrics-config`}> + <CardHeader> + <CardTitle component="h3">{title}</CardTitle> + </CardHeader> + <Divider component="div" /> + <CardBody> + <FormSection> + <Grid hasGutter> + <GridItem md={12}> + {prometheusMetricsPeriodForm(pcfg, category, onChange)} + </GridItem> + <GridItem md={12}> + <FormGroup label="Metrics configuration" role="group"> + {prometheusMetricsDataList( + pcfg?.metrics?.[category]?.descriptors, + category, + onCustomChange + )} + </FormGroup> + </GridItem> + </Grid> + </FormSection> + </CardBody> + </Card> + </GridItem> + ); +} diff --git a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx index 5324c162f8e91..a79dbcf3430fb 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx @@ -43,6 +43,7 @@ import { convertBetweenBytesAndMB } from '../SystemConfig.utils'; import { getPlatformComponentsConfigRules, PlatformComponentsConfigRules } from '../configUtils'; import { Values } from './formTypes'; import PlatformComponentsConfigForm from './PlatformComponentsConfigForm'; +import { PrometheusMetricsForm } from '../Details/components/PrometheusMetricsCard'; function getCompletePublicConfig(systemConfig: SystemConfig): PublicConfig { return { @@ -531,6 +532,16 @@ const SystemConfigForm = ({ </FormGroup> </GridItem> </Grid> + <Title headingLevel="h2">Prometheus metrics configuration + + {PrometheusMetricsForm( + values?.privateConfig, + 'imageVulnerabilities', + 'Image vulnerabilities', + onChange, + onCustomChange + )} + Public configuration diff --git a/ui/apps/platform/src/types/config.proto.ts b/ui/apps/platform/src/types/config.proto.ts index fed1385e61b9a..781a0b7f86a64 100644 --- a/ui/apps/platform/src/types/config.proto.ts +++ b/ui/apps/platform/src/types/config.proto.ts @@ -52,6 +52,22 @@ export type AdministrationEventsConfig = { retentionDurationDays: number; // uint32 }; +export type Labels = { + labels: string[]; +}; + +export type MetricsGroup = { + gatheringPeriodMinutes?: number; // uint32 + descriptors?: Record; +}; + +// The type list of known metrics categories. +export type Category = 'imageVulnerabilities'; + +export type PrometheusMetrics = { + imageVulnerabilities?: MetricsGroup; +}; + export type PrivateConfig = { alertConfig: AlertRetentionConfig; imageRetentionDurationDays: number; // int32 @@ -59,6 +75,7 @@ export type PrivateConfig = { decommissionedClusterRetention: DecommissionedClusterRetentionConfig; reportRetentionConfig: ReportRetentionConfig; administrationEventsConfig: AdministrationEventsConfig; + metrics: PrometheusMetrics; }; export type PlatformComponentRule = { From d0c30e66aba3da041d762891e6e8269319381741 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Tue, 9 Sep 2025 10:44:09 +0200 Subject: [PATCH 02/16] proto types renaming, refactoring --- .../components/PrometheusMetricsCard.tsx | 54 ++++++++++++------- .../SystemConfig/Form/SystemConfigForm.tsx | 14 ++--- ui/apps/platform/src/types/config.proto.ts | 12 ++--- 3 files changed, 47 insertions(+), 33 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 574fa7fdc3ca7..a05191a7d0efd 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -1,5 +1,9 @@ import React, { ReactElement } from 'react'; -import { Category, PrivateConfig, Labels } from 'types/config.proto'; +import { + PrometheusMetricsCategory, + PrivateConfig, + PrometheusMetricsLabels, +} from 'types/config.proto'; import { Card, CardBody, @@ -30,7 +34,10 @@ import { import pluralize from 'pluralize'; import { FormikErrors, FormikValues } from 'formik'; -const predefinedMetrics: Record> = { +const predefinedMetrics: Record< + PrometheusMetricsCategory, + Record +> = { imageVulnerabilities: { image_vuln_namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, image_vuln_deployment_severity: { @@ -42,7 +49,7 @@ const predefinedMetrics: Record> = { }, }; -function labelGroup(labels: Labels): ReactElement { +function labelGroup(labels: PrometheusMetricsLabels): ReactElement { return ( {labels.labels.map((label) => { @@ -58,7 +65,7 @@ function labelGroup(labels: Labels): ReactElement { function predefinedMetricListItem( enabled: boolean, - category: Category, + category: PrometheusMetricsCategory, metric: string, onCustomChange: | ((value: unknown, id: string) => Promise | Promise>) @@ -88,7 +95,7 @@ function predefinedMetricListItem( key={`${category}-${metric}-label`} id={`${category}-${metric}-label`} > - {metric} + , Predefined @@ -106,9 +113,9 @@ function predefinedMetricListItem( // hasMetric checks if the descriptors contain the given metric by looking at // the metric name and the labels (ignoring the order). function hasMetric( - descriptors: Record | undefined, + descriptors: Record | undefined, metric: string, - labels: Labels + labels: PrometheusMetricsLabels ): boolean { const cfgLabels = descriptors?.[metric]?.labels || []; const ll = labels.labels; @@ -116,8 +123,8 @@ function hasMetric( } function prometheusMetricsDataList( - descriptors: Record | undefined, - category: Category, + descriptors: Record | undefined, + category: PrometheusMetricsCategory, onCustomChange: | ((value: unknown, id: string) => Promise | Promise>) | undefined @@ -180,9 +187,9 @@ function prometheusMetricsDataList( } export function PrometheusMetricsCard( - category: Category, + category: PrometheusMetricsCategory, period: number, - descriptors: Record | undefined, + descriptors: Record | undefined, title: string ) { const hasMetrics = descriptors && Object.keys(descriptors).length > 0; @@ -249,7 +256,7 @@ export function PrometheusMetricsCard( function prometheusMetricsPeriodForm( pcfg: PrivateConfig, - category: Category, + category: PrometheusMetricsCategory, onChange: (value, event) => Promise | Promise> ): ReactElement { return ( @@ -270,16 +277,23 @@ function prometheusMetricsPeriodForm( ); } - -export function PrometheusMetricsForm( - pcfg: PrivateConfig, - category: Category, - title: string, - onChange: (value, event) => Promise | Promise>, +export type PrometheusMetricsFormProps = { + pcfg: PrivateConfig; + category: PrometheusMetricsCategory; + title: string; + onChange: (value, event) => Promise | Promise>; onCustomChange: | ((value: unknown, id: string) => Promise | Promise>) - | undefined -) { + | undefined; +}; + +export function PrometheusMetricsForm({ + pcfg, + category, + title, + onChange, + onCustomChange, +}: PrometheusMetricsFormProps) { return ( diff --git a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx index a79dbcf3430fb..9a1ecc2575638 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx @@ -534,13 +534,13 @@ const SystemConfigForm = ({ Prometheus metrics configuration - {PrometheusMetricsForm( - values?.privateConfig, - 'imageVulnerabilities', - 'Image vulnerabilities', - onChange, - onCustomChange - )} + Public configuration diff --git a/ui/apps/platform/src/types/config.proto.ts b/ui/apps/platform/src/types/config.proto.ts index 781a0b7f86a64..3585c1df04ff1 100644 --- a/ui/apps/platform/src/types/config.proto.ts +++ b/ui/apps/platform/src/types/config.proto.ts @@ -52,20 +52,20 @@ export type AdministrationEventsConfig = { retentionDurationDays: number; // uint32 }; -export type Labels = { +export type PrometheusMetricsLabels = { labels: string[]; }; -export type MetricsGroup = { +export type PrometheusMetricsGroup = { gatheringPeriodMinutes?: number; // uint32 - descriptors?: Record; + descriptors?: Record; }; // The type list of known metrics categories. -export type Category = 'imageVulnerabilities'; +export type PrometheusMetricsCategory = keyof PrometheusMetrics; export type PrometheusMetrics = { - imageVulnerabilities?: MetricsGroup; + imageVulnerabilities?: PrometheusMetricsGroup | null; }; export type PrivateConfig = { @@ -75,7 +75,7 @@ export type PrivateConfig = { decommissionedClusterRetention: DecommissionedClusterRetentionConfig; reportRetentionConfig: ReportRetentionConfig; administrationEventsConfig: AdministrationEventsConfig; - metrics: PrometheusMetrics; + metrics?: PrometheusMetrics | null; }; export type PlatformComponentRule = { From cee46366f7bcad50bfac2908b8acb06204907edc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Tue, 9 Sep 2025 10:53:09 +0200 Subject: [PATCH 03/16] PrometheusMetricsCardProps --- .../PrivateConfigPrometheusMetricsDetails.tsx | 14 ++++++------- .../components/PrometheusMetricsCard.tsx | 20 +++++++++++++------ 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx index d947e209b6fdf..2592d71236657 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx @@ -1,4 +1,4 @@ -import { ReactElement } from 'react'; +import React, { ReactElement } from 'react'; import { PrivateConfig } from 'types/config.proto'; import { PrometheusMetricsCard } from './components/PrometheusMetricsCard'; @@ -13,12 +13,12 @@ const PrivateConfigPrometheusMetricsDetails = ({ const imageVulnerabilitiesCfg = privateConfig?.metrics?.imageVulnerabilities; return [ - PrometheusMetricsCard( - 'imageVulnerabilities', - imageVulnerabilitiesCfg?.gatheringPeriodMinutes || 0, - imageVulnerabilitiesCfg?.descriptors, - 'Image vulnerabilities' - ), + , ]; }; diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index a05191a7d0efd..519ed189cf18e 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -186,12 +186,19 @@ function prometheusMetricsDataList( ); } -export function PrometheusMetricsCard( - category: PrometheusMetricsCategory, - period: number, - descriptors: Record | undefined, - title: string -) { +export type PrometheusMetricsCardProps = { + category: PrometheusMetricsCategory; + period: number; + descriptors?: Record; + title: string; +}; + +export function PrometheusMetricsCard({ + category, + period, + descriptors, + title, +}: PrometheusMetricsCardProps) { const hasMetrics = descriptors && Object.keys(descriptors).length > 0; return ( @@ -277,6 +284,7 @@ function prometheusMetricsPeriodForm( ); } + export type PrometheusMetricsFormProps = { pcfg: PrivateConfig; category: PrometheusMetricsCategory; From a44284fe8bfc924725dd945d4bd7410900a231f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Tue, 9 Sep 2025 10:53:45 +0200 Subject: [PATCH 04/16] nit --- .../Details/components/PrometheusMetricsCard.tsx | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 519ed189cf18e..977b17a79e32d 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -290,9 +290,10 @@ export type PrometheusMetricsFormProps = { category: PrometheusMetricsCategory; title: string; onChange: (value, event) => Promise | Promise>; - onCustomChange: - | ((value: unknown, id: string) => Promise | Promise>) - | undefined; + onCustomChange?: ( + value: unknown, + id: string + ) => Promise | Promise>; }; export function PrometheusMetricsForm({ From 9d184f38d790698c01ac1a3209f79cbbdc750cf3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Tue, 9 Sep 2025 11:02:06 +0200 Subject: [PATCH 05/16] refactor DataListItemRow --- .../components/PrometheusMetricsCard.tsx | 48 +++++++++---------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 977b17a79e32d..7b1672a328e4e 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -74,23 +74,23 @@ function predefinedMetricListItem( return ( + {onCustomChange ? ( + + onCustomChange( + checked ? predefinedMetrics[category][metric] : undefined, + `privateConfig.metrics.${category}.descriptors.${metric}` + ) + } + /> + ) : null} - onCustomChange( - checked ? predefinedMetrics[category][metric] : undefined, - `privateConfig.metrics.${category}.descriptors.${metric}` - ) - } - /> - ) : null, + {onCustomChange ? ( + + ) : null} - ) : null, {metric}, Custom, {labelGroup(labels)}, From 9f0dc3693100fc38bf0e9f87a83eaba428729270 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Tue, 9 Sep 2025 19:46:24 +0200 Subject: [PATCH 06/16] policy violations card and form --- .../Details/PrivateConfigPrometheusMetricsDetails.tsx | 7 +++++++ .../Details/components/PrometheusMetricsCard.tsx | 3 +++ .../src/Containers/SystemConfig/Form/SystemConfigForm.tsx | 7 +++++++ ui/apps/platform/src/types/config.proto.ts | 1 + 4 files changed, 18 insertions(+) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx index 2592d71236657..c2ea320ca607d 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx @@ -11,6 +11,7 @@ const PrivateConfigPrometheusMetricsDetails = ({ privateConfig, }: PrivateConfigPrometheusMetricsDetailsProps): ReactElement[] => { const imageVulnerabilitiesCfg = privateConfig?.metrics?.imageVulnerabilities; + const policyViolationsCfg = privateConfig?.metrics?.policyViolations; return [ , + , ]; }; diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 7b1672a328e4e..60eedd6d13760 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -47,6 +47,9 @@ const predefinedMetrics: Record< labels: ['Cluster', 'Namespace', 'Deployment', 'IsPlatformWorkload', 'Severity'], }, }, + policyViolations: { + policy_vuln_namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, + }, }; function labelGroup(labels: PrometheusMetricsLabels): ReactElement { diff --git a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx index 9a1ecc2575638..ea10b95b1b3d5 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx @@ -541,6 +541,13 @@ const SystemConfigForm = ({ onChange={onChange} onCustomChange={onCustomChange} /> + Public configuration diff --git a/ui/apps/platform/src/types/config.proto.ts b/ui/apps/platform/src/types/config.proto.ts index 3585c1df04ff1..c5539e5fb33c3 100644 --- a/ui/apps/platform/src/types/config.proto.ts +++ b/ui/apps/platform/src/types/config.proto.ts @@ -66,6 +66,7 @@ export type PrometheusMetricsCategory = keyof PrometheusMetrics; export type PrometheusMetrics = { imageVulnerabilities?: PrometheusMetricsGroup | null; + policyViolations?: PrometheusMetricsGroup | null; }; export type PrivateConfig = { From eb53baf50e57f58e661c8dbe89a76de6f0c8987c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Mon, 15 Sep 2025 22:33:33 +0200 Subject: [PATCH 07/16] keys in PrivateConfigPrometheusMetricsDetails --- .../Details/PrivateConfigPrometheusMetricsDetails.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx index c2ea320ca607d..09857e3d9f7be 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx @@ -16,12 +16,14 @@ const PrivateConfigPrometheusMetricsDetails = ({ return [ , Date: Tue, 16 Sep 2025 17:53:24 +0200 Subject: [PATCH 08/16] highlight metric prefixes --- .../components/PrometheusMetricsCard.tsx | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 60eedd6d13760..2a8c3ac4b4319 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -34,21 +34,26 @@ import { import pluralize from 'pluralize'; import { FormikErrors, FormikValues } from 'formik'; +const metricPrefixes = { + imageVulnerabilities: 'rox_central_image_vuln_', + policyViolations: 'rox_central_policy_violation_', +}; + const predefinedMetrics: Record< PrometheusMetricsCategory, Record > = { imageVulnerabilities: { - image_vuln_namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, - image_vuln_deployment_severity: { + namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, + deployment_severity: { labels: ['Cluster', 'Namespace', 'Deployment', 'Severity'], }, - image_vuln_user_workload_severity: { + user_workload_severity: { labels: ['Cluster', 'Namespace', 'Deployment', 'IsPlatformWorkload', 'Severity'], }, }, policyViolations: { - policy_vuln_namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, + namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, }, }; @@ -98,7 +103,10 @@ function predefinedMetricListItem( key={`${category}-${metric}-label`} id={`${category}-${metric}-label`} > - + , Predefined From 58d49d1b749dda2273bd310faadef6da3e3a4f35 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Mon, 29 Sep 2025 09:47:13 +0200 Subject: [PATCH 09/16] updated predefined metrics --- .../components/PrometheusMetricsCard.tsx | 37 +++++++++++++++++-- ui/apps/platform/src/types/config.proto.ts | 1 + 2 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 2a8c3ac4b4319..c12ca2c3d59c2 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -45,15 +45,44 @@ const predefinedMetrics: Record< > = { imageVulnerabilities: { namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, - deployment_severity: { - labels: ['Cluster', 'Namespace', 'Deployment', 'Severity'], + registry_severity: { + labels: ['Cluster', 'Namespace', 'ImageRegistry', 'Severity'], }, - user_workload_severity: { - labels: ['Cluster', 'Namespace', 'Deployment', 'IsPlatformWorkload', 'Severity'], + deployment_severity: { + labels: [ + 'Cluster', + 'Namespace', + 'Deployment', + 'IsPlatformWorkload', + 'IsFixable', + 'Severity', + ], }, }, policyViolations: { namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, + action: { + labels: ['Cluster', 'Namespace', 'IsPlatformComponent', 'State', 'Severity', 'Action'], + }, + stage_severity: { + labels: [ + 'Cluster', + 'Namespace', + 'IsPlatformComponent', + 'Categories', + 'Stage', + 'State', + 'Severity', + ], + }, + }, + nodeVulnerabilities: { + node_severity: { + labels: ['Cluster', 'Node', 'Severity'], + }, + component_severity: { + labels: ['Cluster', 'Node', 'Component', 'IsFixable', 'IsSnoozed', 'Severity'], + }, }, }; diff --git a/ui/apps/platform/src/types/config.proto.ts b/ui/apps/platform/src/types/config.proto.ts index c5539e5fb33c3..3532c3924a2a4 100644 --- a/ui/apps/platform/src/types/config.proto.ts +++ b/ui/apps/platform/src/types/config.proto.ts @@ -67,6 +67,7 @@ export type PrometheusMetricsCategory = keyof PrometheusMetrics; export type PrometheusMetrics = { imageVulnerabilities?: PrometheusMetricsGroup | null; policyViolations?: PrometheusMetricsGroup | null; + nodeVulnerabilities?: PrometheusMetricsGroup | null; }; export type PrivateConfig = { From fe2667b74db271b651e2e7c50c2357d1ebd7516e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Mon, 29 Sep 2025 10:09:31 +0200 Subject: [PATCH 10/16] node vulnerabilities card --- .../Details/PrivateConfigPrometheusMetricsDetails.tsx | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx index 09857e3d9f7be..5f0671c9cfbb4 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx @@ -11,6 +11,7 @@ const PrivateConfigPrometheusMetricsDetails = ({ privateConfig, }: PrivateConfigPrometheusMetricsDetailsProps): ReactElement[] => { const imageVulnerabilitiesCfg = privateConfig?.metrics?.imageVulnerabilities; + const nodeVulnerabilitiesCfg = privateConfig?.metrics?.nodeVulnerabilities; const policyViolationsCfg = privateConfig?.metrics?.policyViolations; return [ @@ -21,6 +22,13 @@ const PrivateConfigPrometheusMetricsDetails = ({ descriptors={imageVulnerabilitiesCfg?.descriptors} title="Image vulnerabilities" />, + , Date: Mon, 29 Sep 2025 10:09:41 +0200 Subject: [PATCH 11/16] table --- .../components/PrometheusMetricsCard.tsx | 239 +++++++++--------- .../SystemConfig/Form/SystemConfigForm.tsx | 7 + 2 files changed, 129 insertions(+), 117 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index c12ca2c3d59c2..c9cafc769ccd6 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -9,12 +9,6 @@ import { CardBody, CardHeader, CardTitle, - DataList, - DataListCell, - DataListCheck, - DataListItem, - DataListItemCells, - DataListItemRow, DescriptionList, DescriptionListDescription, DescriptionListGroup, @@ -31,11 +25,13 @@ import { LabelGroup, TextInput, } from '@patternfly/react-core'; +import { Table, Tr, Td, Thead, Tbody, Th } from '@patternfly/react-table'; import pluralize from 'pluralize'; import { FormikErrors, FormikValues } from 'formik'; const metricPrefixes = { imageVulnerabilities: 'rox_central_image_vuln_', + nodeVulnerabilities: 'rox_central_node_vuln_', policyViolations: 'rox_central_policy_violation_', }; @@ -100,7 +96,8 @@ function labelGroup(labels: PrometheusMetricsLabels): ReactElement { ); } -function predefinedMetricListItem( +function predefinedMetricTableRow( + rowIndex: number, enabled: boolean, category: PrometheusMetricsCategory, metric: string, @@ -109,44 +106,36 @@ function predefinedMetricListItem( | undefined ): ReactElement { return ( - - - {onCustomChange ? ( - + + {onCustomChange ? ( + onCustomChange( checked ? predefinedMetrics[category][metric] : undefined, `privateConfig.metrics.${category}.descriptors.${metric}` - ) - } - /> - ) : null} - - - , - - Predefined - , - - {labelGroup(predefinedMetrics[category][metric])} - , - ]} + ), + isSelected: enabled, + isDisabled: false, + }} /> - - + ) : null} + + + + Predefined + + {labelGroup(predefinedMetrics[category][metric])} + + ); } @@ -162,67 +151,82 @@ function hasMetric( return cfgLabels.length === ll.length && cfgLabels.every((label) => ll.includes(label)); } -function prometheusMetricsDataList( - descriptors: Record | undefined, - category: PrometheusMetricsCategory, +type PrometheusMetricsTableProps = { + descriptors: Record | undefined; + category: PrometheusMetricsCategory; onCustomChange: | ((value: unknown, id: string) => Promise | Promise>) - | undefined -): ReactElement { + | undefined; +}; + +function PrometheusMetricsTable({ + descriptors, + category, + onCustomChange, +}: PrometheusMetricsTableProps): ReactElement { return ( - - {Object.entries(predefinedMetrics[category]).map( - ([predefinedMetric, originalLabels]) => { - // In view mode show only enabled predefined metrics. - // In edit mode show all predefined metrics unless they're - // overridden. + + + + {onCustomChange ? + + + + + + {Object.entries(predefinedMetrics[category]).map( + ([predefinedMetric, originalLabels], rowIndex) => { + // In view mode show only enabled predefined metrics. + // In edit mode show all predefined metrics unless they're + // overridden. - const isEnabledOriginal = hasMetric( - descriptors, - predefinedMetric, - originalLabels - ); - const enabled = descriptors !== undefined && predefinedMetric in descriptors; - if (isEnabledOriginal || (onCustomChange && !enabled)) { - return predefinedMetricListItem( - isEnabledOriginal, - category, + const isEnabledOriginal = hasMetric( + descriptors, predefinedMetric, - onCustomChange + originalLabels ); + const enabled = + descriptors !== undefined && predefinedMetric in descriptors; + if (isEnabledOriginal || (onCustomChange && !enabled)) { + return predefinedMetricTableRow( + rowIndex, + isEnabledOriginal, + category, + predefinedMetric, + onCustomChange + ); + } + return null; } - return null; - } - )} - {Object.entries(descriptors || {}).map(([metric, labels]) => { - // Predefined are rendered above. - if (hasMetric(predefinedMetrics[category], metric, labels)) { - return null; - } - return ( - - + )} + {Object.entries(descriptors || {}).map(([metric, labels]) => { + // Predefined are rendered above. + if (hasMetric(predefinedMetrics[category], metric, labels)) { + return null; + } + return ( + {onCustomChange ? ( - ) : null} - {metric}, - Custom, - {labelGroup(labels)}, - ]} - /> - - - ); - })} - + + + + + ); + })} + +
: null} + Metric nameOriginLabels
+ {metricPrefixes[category]} + {metric} + Custom{labelGroup(labels)}
); } @@ -263,29 +267,30 @@ export function PrometheusMetricsCard({ {hasMetrics ? ( - - {period ? ( - - Gathering period - - {period}  - {pluralize('minute', period)} - - - ) : null} - - Metrics - - {prometheusMetricsDataList(descriptors, category, undefined)} - - - + <> + + {period ? ( + + Gathering period + + {period}  + {pluralize('minute', period)} + + + ) : null} + + + ) : ( No metrics has been configured @@ -358,11 +363,11 @@ export function PrometheusMetricsForm({ - {prometheusMetricsDataList( - pcfg?.metrics?.[category]?.descriptors, - category, - onCustomChange - )} +
diff --git a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx index ea10b95b1b3d5..621e645085e82 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Form/SystemConfigForm.tsx @@ -541,6 +541,13 @@ const SystemConfigForm = ({ onChange={onChange} onCustomChange={onCustomChange} /> + Date: Wed, 8 Oct 2025 10:11:18 +0200 Subject: [PATCH 12/16] reactify PrometheusMetricsPeriodForm --- .../components/PrometheusMetricsCard.tsx | 22 ++++++++++++++----- 1 file changed, 16 insertions(+), 6 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index c9cafc769ccd6..98f0c8bdfe06a 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -306,11 +306,17 @@ export function PrometheusMetricsCard({ ); } -function prometheusMetricsPeriodForm( - pcfg: PrivateConfig, - category: PrometheusMetricsCategory, - onChange: (value, event) => Promise | Promise> -): ReactElement { +type PrometheusMetricsPeriodFormProps = { + pcfg: PrivateConfig; + category: PrometheusMetricsCategory; + onChange: (value, event) => Promise | Promise>; +}; + +function PrometheusMetricsPeriodForm({ + pcfg, + category, + onChange, +}: PrometheusMetricsPeriodFormProps): ReactElement { return ( - {prometheusMetricsPeriodForm(pcfg, category, onChange)} + From 83e1daba87a4e3f999a9799cce9895b269d244ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Wed, 8 Oct 2025 11:01:48 +0200 Subject: [PATCH 13/16] refactor card generation --- .../PrivateConfigPrometheusMetricsDetails.tsx | 45 ++++++++----------- 1 file changed, 18 insertions(+), 27 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx index 5f0671c9cfbb4..55c82219faa8f 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/PrivateConfigPrometheusMetricsDetails.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react'; -import { PrivateConfig } from 'types/config.proto'; +import { PrivateConfig, PrometheusMetricsCategory } from 'types/config.proto'; import { PrometheusMetricsCard } from './components/PrometheusMetricsCard'; export type PrivateConfigPrometheusMetricsDetailsProps = { @@ -10,33 +10,24 @@ export type PrivateConfigPrometheusMetricsDetailsProps = { const PrivateConfigPrometheusMetricsDetails = ({ privateConfig, }: PrivateConfigPrometheusMetricsDetailsProps): ReactElement[] => { - const imageVulnerabilitiesCfg = privateConfig?.metrics?.imageVulnerabilities; - const nodeVulnerabilitiesCfg = privateConfig?.metrics?.nodeVulnerabilities; - const policyViolationsCfg = privateConfig?.metrics?.policyViolations; + const categoryTitles: Record = { + imageVulnerabilities: 'Image vulnerabilities', + nodeVulnerabilities: 'Node vulnerabilities', + policyViolations: 'Policy violations', + }; - return [ - , - , - , - ]; + return Object.entries(categoryTitles).map(([category, title]) => { + const config = privateConfig?.metrics?.[category]; + return ( + + ); + }); }; export default PrivateConfigPrometheusMetricsDetails; From 640330c0accea07ef9775401c9f355abdd07ace4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Wed, 8 Oct 2025 11:34:51 +0200 Subject: [PATCH 14/16] remove "|| 0" to allow deleting 0 --- .../SystemConfig/Details/components/PrometheusMetricsCard.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index 98f0c8bdfe06a..a44e90fef84a5 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -328,7 +328,7 @@ function PrometheusMetricsPeriodForm({ type="number" id={`privateConfig.metrics.${category}.gatheringPeriodMinutes`} name={`privateConfig.metrics.${category}.gatheringPeriodMinutes`} - value={pcfg?.metrics?.[category]?.gatheringPeriodMinutes || 0} + value={pcfg?.metrics?.[category]?.gatheringPeriodMinutes} onChange={(event, value) => onChange(value, event)} min={0} /> From f4a8ba6d4670ce8ece4fb89be9c9490e5209ef94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Wed, 8 Oct 2025 12:02:23 +0200 Subject: [PATCH 15/16] wording --- .../Containers/SystemConfig/Details/SystemConfigDetails.tsx | 6 +++--- .../Details/components/PrometheusMetricsCard.tsx | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx index 8bb826f4e6dea..3f477f1305a57 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/SystemConfigDetails.tsx @@ -87,9 +87,9 @@ function SystemConfigDetails({ Prometheus metrics configuration - The Prometheus metrics are exposed on the API endpoint, at the{' '} - /metrics path and require permissions to view Administration - resources. + The following Prometheus metrics are exposed on the API endpoint at the{' '} + /metrics path. Scrape requests require permissions to view + Administration resources and are subject for the scoped access control. ) : ( - No metrics has been configured + No metrics configured Edit the configuration, or call /v1/config API to add custom metrics. From 16ce17406e68d8a2798842a2a1233715886aa37c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C3=ABl=20Petrov?= Date: Wed, 8 Oct 2025 15:27:21 +0200 Subject: [PATCH 16/16] fixed the predefined metrics --- .../components/PrometheusMetricsCard.tsx | 39 ++++++++++--------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx index d771f392166b7..8d83c52b7a728 100644 --- a/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx +++ b/ui/apps/platform/src/Containers/SystemConfig/Details/components/PrometheusMetricsCard.tsx @@ -40,9 +40,8 @@ const predefinedMetrics: Record< Record > = { imageVulnerabilities: { - namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, - registry_severity: { - labels: ['Cluster', 'Namespace', 'ImageRegistry', 'Severity'], + namespace_severity: { + labels: ['Cluster', 'Namespace', 'IsPlatformWorkload', 'IsFixable', 'Severity'], }, deployment_severity: { labels: [ @@ -54,32 +53,36 @@ const predefinedMetrics: Record< 'Severity', ], }, + cve_severity: { + labels: ['Cluster', 'CVE', 'IsPlatformWorkload', 'IsFixable', 'Severity'], + }, + }, + nodeVulnerabilities: { + node_severity: { + labels: ['Cluster', 'Node', 'IsFixable', 'Severity'], + }, + component_severity: { + labels: ['Cluster', 'Node', 'Component', 'IsFixable', 'Severity'], + }, + cve_severity: { + labels: ['Cluster', 'CVE', 'IsFixable', 'Severity'], + }, }, policyViolations: { - namespace_severity: { labels: ['Cluster', 'Namespace', 'Severity'] }, - action: { - labels: ['Cluster', 'Namespace', 'IsPlatformComponent', 'State', 'Severity', 'Action'], + namespace_severity: { + labels: ['Cluster', 'Namespace', 'IsPlatformComponent', 'Action', 'Severity'], }, - stage_severity: { + deployment_severity: { labels: [ 'Cluster', 'Namespace', + 'Deployment', 'IsPlatformComponent', - 'Categories', - 'Stage', - 'State', + 'Action', 'Severity', ], }, }, - nodeVulnerabilities: { - node_severity: { - labels: ['Cluster', 'Node', 'Severity'], - }, - component_severity: { - labels: ['Cluster', 'Node', 'Component', 'IsFixable', 'IsSnoozed', 'Severity'], - }, - }, }; function labelGroup(labels: PrometheusMetricsLabels): ReactElement {