Skip to content

Commit

Permalink
Changed CRD fetching to Prometheus
Browse files Browse the repository at this point in the history
  • Loading branch information
bond95 committed Oct 7, 2020
1 parent 20e34e7 commit 79a226b
Show file tree
Hide file tree
Showing 8 changed files with 155 additions and 156 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,7 @@ export type URLHealthHandler<R> = (

export type PrometheusHealthPopupProps = {
responses: { response: PrometheusResponse; error: any }[];
additionalResource?: FirehoseResult<K8sResourceKind | K8sResourceKind[]>;
k8sResult?: FirehoseResult<K8sResourceKind | K8sResourceKind[]>;
};

export type PrometheusHealthHandler = (
Expand Down
14 changes: 2 additions & 12 deletions frontend/packages/insights-plugin/package.json
Original file line number Diff line number Diff line change
@@ -1,24 +1,14 @@
{
"name": "@console/insights-plugin",
"version": "0.0.0-fixed",
"description": "Plugin for Insights operator",
"description": "Insights - provide cluster health data and integrate with OpenShift Cluster Manager",
"private": true,
"main": "src/index.ts",
"scripts": {
"test": "yarn --cwd ../.. run test packages/insights-plugin"
"test": "yarn --cwd ../.. test packages/insights-plugin"
},
"dependencies": {
"@console/ceph-storage-plugin": "0.0.0-fixed",
"@console/container-security": "0.0.0-fixed",
"@console/dev-console": "0.0.0-fixed",
"@console/internal": "0.0.0-fixed",
"@console/knative-plugin": "0.0.0-fixed",
"@console/kubevirt-plugin": "0.0.0-fixed",
"@console/local-storage-operator-plugin": "0.0.0-fixed",
"@console/metal3-plugin": "0.0.0-fixed",
"@console/network-attachment-definition-plugin": "0.0.0-fixed",
"@console/noobaa-storage-plugin": "0.0.0-fixed",
"@console/operator-lifecycle-manager": "0.0.0-fixed",
"@console/patternfly": "0.0.0-fixed",
"@console/plugin-sdk": "0.0.0-fixed",
"@console/shared": "0.0.0-fixed"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,96 @@
import * as React from 'react';
import * as _ from 'lodash';
import { ChartDonut, ChartLegend, ChartLabel } from '@patternfly/react-charts';
import { WatchK8sResults } from '@console/internal/components/utils/k8s-watch-hook';
import { ClusterVersionKind } from '@console/internal/module/k8s';
import { InsightsOperator } from './status';
import { riskIcons, colorScale, legendColorScale, riskSorting } from './mappers';
import { riskIcons, colorScale, legendColorScale, riskSorting, mapMetrics } from './mappers';
import { PrometheusHealthPopupProps } from '@console/plugin-sdk';
import { K8sResourceKind } from '@console/internal/module/k8s';
import { ExternalLink } from '@console/internal/components/utils';
import './style.scss';

const DataComponent: React.FC<DataComponentProps> = ({ x, y, datum }) => {
const Icon = riskIcons[datum.id];
return <Icon x={x} y={y - 5} fill={legendColorScale[datum.id]} />;
};

export const InsightsPopup: React.FC<InsightsPopupProps> = ({ insightsReport, clusterVersion }) => {
const resource = insightsReport.data;
const clusterId = _.get(clusterVersion, 'data.spec.clusterID', '');
const riskEntries = Object.entries(resource.spec).sort(
export const InsightsPopup: React.FC<PrometheusHealthPopupProps> = ({ responses, k8sResult }) => {
const resource = mapMetrics(responses[0].response);
const clusterID = (k8sResult as K8sResourceKind)?.data?.spec?.clusterID || '';
const riskEntries = Object.entries(resource).sort(
([k1], [k2]) => riskSorting[k1] - riskSorting[k2],
);
const numberOfIssues = Object.values(resource).reduce((acc, cur) => acc + cur, 0);
const hasIssues = riskEntries.length > 0 && numberOfIssues > 0;

return (
<div className="co-status-popup__row">
<div className="co-insights__box">
<div className="co-status-popup__section">
Insights identifies and prioritizes risks to security, performance, availability, and
stability of your clusters.
</div>
<div className="co-status-popup__section">
<div>
<ChartDonut
data={riskEntries.map(([k, v]) => ({
label: `${v} ${k}`,
x: k,
y: v,
}))}
title={`${Object.values(resource.spec).reduce((acc, cur) => acc + cur, 0)}`}
subTitle="Total issues"
legendData={Object.entries(resource.spec).map(([k, v]) => ({ name: `${k}: ${v}` }))}
legendOrientation="vertical"
width={300}
height={150}
colorScale={colorScale}
constrainToVisibleArea
legendPosition="left"
legendComponent={
<ChartLegend
title="Total Risk"
titleComponent={<ChartLabel style={{ fontWeight: 'bold' }} />}
data={riskEntries.map(([k, v]) => ({
name: `${v} ${k}`,
id: k,
}))}
dataComponent={<DataComponent />}
{hasIssues && (
<div>
<ChartDonut
data={riskEntries.map(([k, v]) => ({
label: `${v} ${k}`,
x: k,
y: v,
}))}
title={`${numberOfIssues}`}
subTitle="Total issues"
legendData={Object.entries(resource).map(([k, v]) => ({ name: `${k}: ${v}` }))}
legendOrientation="vertical"
width={304}
height={152}
colorScale={colorScale}
constrainToVisibleArea
legendComponent={
<ChartLegend
title="Total Risk"
titleComponent={
<ChartLabel dx={13} style={{ fontWeight: 'bold', fontSize: '14px' }} />
}
data={riskEntries.map(([k, v]) => ({
name: `${v} ${k}`,
id: k,
}))}
dataComponent={<DataComponent />}
x={-13}
/>
}
padding={{
bottom: 20,
left: 145,
right: 20, // Adjusted to accommodate legend
top: 0,
}}
/>
</div>
)}
{!hasIssues && <div className="co-insights__no-rules">No Insights data to display.</div>}
</div>
<div className="co-status-popup__section">
{hasIssues && (
<>
<h6 className="pf-c-title pf-m-md">Fixable issues</h6>
<div>
<ExternalLink
href={`https://cloud.redhat.com/openshift/details/${clusterID}`}
text="View all in OpenShift Cluster Manager"
/>
}
padding={{
bottom: 20,
left: 145,
right: 20, // Adjusted to accommodate legend
top: 0,
}}
</div>
</>
)}
{!hasIssues && (
<ExternalLink
href="https://docs.openshift.com/container-platform/latest/support/getting-support.html"
text="More about Insights"
/>
</div>
</div>
<div className="co-status-popup__section co-status-popup__row">
<div style={{ fontWeight: 'bold' }}>Fixable issues</div>
<div>
<a href={`https://cloud.redhat.com/openshift/details/${clusterId}`}>
View all in OpenShift Cluster Manager
</a>
</div>
)}
</div>
</div>
);
};

export type InsightsPopupProps = WatchK8sResults<{
insightsReport: InsightsOperator;
clusterVersion: ClusterVersionKind;
}>;
export type DataComponentProps = {
x?: number;
y?: number;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
/* eslint-disable @typescript-eslint/camelcase */
import {
global_palette_blue_50,
global_palette_blue_300,
global_palette_gold_400,
global_palette_orange_300,
global_palette_red_200,
} from '@patternfly/react-tokens';
import * as _ from 'lodash';

import { global_palette_blue_50 as blue50 } from '@patternfly/react-tokens/dist/js/global_palette_blue_50';
import { global_palette_blue_300 as blue300 } from '@patternfly/react-tokens/dist/js/global_palette_blue_300';
import { global_palette_gold_400 as gold400 } from '@patternfly/react-tokens/dist/js/global_palette_gold_400';
import { global_palette_orange_300 as orange300 } from '@patternfly/react-tokens/dist/js/global_palette_orange_300';
import { global_palette_red_200 as red200 } from '@patternfly/react-tokens/dist/js/global_palette_red_200';

import { AngleDoubleDownIcon, AngleDoubleUpIcon, EqualsIcon } from '@patternfly/react-icons';
import CriticalIcon from './CriticalIcon';
import { PrometheusResponse } from '@console/internal/components/graphs';

export const riskIcons = {
low: AngleDoubleDownIcon,
Expand All @@ -16,18 +17,13 @@ export const riskIcons = {
critical: CriticalIcon,
};

export const colorScale = [
global_palette_blue_50.value,
global_palette_gold_400.value,
global_palette_orange_300.value,
global_palette_red_200.value,
];
export const colorScale = [blue50.value, gold400.value, orange300.value, red200.value];

export const legendColorScale = {
low: global_palette_blue_300.value,
moderate: global_palette_gold_400.value,
important: global_palette_orange_300.value,
critical: global_palette_red_200.value,
low: blue300.value,
moderate: gold400.value,
important: orange300.value,
critical: red200.value,
};

export const riskSorting = {
Expand All @@ -36,3 +32,24 @@ export const riskSorting = {
important: 2,
critical: 3,
};

type Metrics = {
critical?: number;
important?: number;
low?: number;
moderate?: number;
};

export const mapMetrics = (response: PrometheusResponse): Metrics => {
const values: Metrics = {};
for (let i = 0; i < response.data.result.length; i++) {
const value = response.data?.result?.[i]?.value?.[1];
if (_.isNil(value)) {
return null;
}
const metricName = response.data?.result?.[i]?.metric?.metric;
values[metricName] = parseInt(value, 10);
}

return values;
};
Original file line number Diff line number Diff line change
@@ -1,34 +1,45 @@
import { ResourceHealthHandler } from '@console/plugin-sdk';
import * as _ from 'lodash';
import { PrometheusHealthHandler, SubsystemHealth } from '@console/plugin-sdk';
import { HealthState } from '@console/shared/src/components/dashboard/status-card/states';
import { K8sResourceCommon } from '@console/internal/module/k8s';
import { PrometheusResponse } from '@console/internal/components/graphs';
import { mapMetrics } from './mappers';

export type InsightsOperator = {
spec: {
critical: number;
important: number;
low: number;
moderate: number;
};
} & K8sResourceCommon;

export const getClusterInsightsStatus: ResourceHealthHandler<{
insightsReport: InsightsOperator;
}> = ({ insightsReport }) => {
const { data, loaded, loadError } = insightsReport;

if (loadError) {
return { state: HealthState.UNKNOWN, message: 'Not available' };
export const getClusterInsightsComponentStatus = (
response: PrometheusResponse,
error,
): SubsystemHealth => {
if (error) {
return {
state: HealthState.NOT_AVAILABLE,
message: 'Not available',
};
}
if (!loaded) {
return { state: HealthState.LOADING, message: 'Scanning in progress' };
if (!response) {
return { state: HealthState.LOADING };
}
const values = mapMetrics(response);
if (_.isNil(values)) {
return { state: HealthState.UNKNOWN, message: 'Not available' };
}
const issuesNumber = Object.values(data.spec).reduce((acc, cur) => acc + cur, 0);
const issuesNumber = Object.values(values).reduce((acc, cur) => acc + cur, 0);
const issueStr = `${issuesNumber} issues found`;
if (data.spec.critical > 0) {
if (values.critical > 0) {
return { state: HealthState.ERROR, message: issueStr };
}
if (issuesNumber > 0) {
return { state: HealthState.WARNING, message: issueStr };
}
return { state: HealthState.OK, message: issueStr };
};

export const getClusterInsightsStatus: PrometheusHealthHandler = (responses, cluster) => {
const componentHealth = getClusterInsightsComponentStatus(
responses[0].response,
responses[0].error,
);
if (componentHealth.state === HealthState.LOADING || !_.get(cluster, 'loaded')) {
return { state: HealthState.LOADING };
}

return componentHealth;
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.co-insights__no-rules {
color: var(--pf-global--Color--200);
}
13 changes: 0 additions & 13 deletions frontend/packages/insights-plugin/src/models.ts

This file was deleted.

0 comments on commit 79a226b

Please sign in to comment.