Skip to content

Commit

Permalink
Merge pull request #8489 from karthikjeeyar/fix-pipeline-metrics-quri…
Browse files Browse the repository at this point in the history
…es-4.7

[release-4.7] Bug 1943643: fix pipeline metrics endpoint for 1.4 osp
  • Loading branch information
openshift-merge-robot committed Apr 1, 2021
2 parents 93dfee2 + 2fa51db commit d1c1498
Show file tree
Hide file tree
Showing 21 changed files with 145 additions and 46 deletions.
Expand Up @@ -19,7 +19,10 @@ import {
} from './detail-page-tabs';
import PipelineMetrics from './pipeline-metrics/PipelineMetrics';
import { usePipelineTriggerTemplateNames } from './utils/triggers';
import { isGAVersionInstalled, usePipelineOperatorVersion } from './utils/pipeline-operator';
import { MetricsQueryPrefix } from './pipeline-metrics/pipeline-metrics-utils';
import { usePipelinesBreadcrumbsFor, useLatestPipelineRun } from './hooks';
import { PipelineDetailsTabProps } from './detail-page-tabs/types';

const PipelineDetailsPage: React.FC<DetailsPageProps> = (props) => {
const { t } = useTranslation();
Expand All @@ -28,6 +31,11 @@ const PipelineDetailsPage: React.FC<DetailsPageProps> = (props) => {
const breadcrumbsFor = usePipelinesBreadcrumbsFor(kindObj, match);
const [, pipelineLoaded, pipelineError] = useK8sGet<Pipeline>(PipelineModel, name, namespace);
const latestPipelineRun = useLatestPipelineRun(name, namespace);
const pipelineOperator = usePipelineOperatorVersion(namespace);
const queryPrefix =
pipelineOperator && !isGAVersionInstalled(pipelineOperator)
? MetricsQueryPrefix.TEKTON
: MetricsQueryPrefix.TEKTON_PIPELINES_CONTROLLER;

const augmentedMenuActions: KebabAction[] = useMenuActionsWithUserAnnotation(
getPipelineKebabActions(latestPipelineRun, templateNames.length > 0),
Expand All @@ -39,7 +47,7 @@ const PipelineDetailsPage: React.FC<DetailsPageProps> = (props) => {
<DetailsPage
{...props}
menuActions={augmentedMenuActions}
customData={templateNames}
customData={{ templateNames, queryPrefix }}
breadcrumbsFor={() => breadcrumbsFor}
pages={[
navFactory.details(PipelineDetails),
Expand All @@ -57,7 +65,7 @@ const PipelineDetailsPage: React.FC<DetailsPageProps> = (props) => {
{
href: 'parameters',
name: t('pipelines-plugin~Parameters'),
component: (pageProps) => (
component: (pageProps: PipelineDetailsTabProps) => (
<PipelineForm
PipelineFormComponent={PipelineParametersForm}
formName="parameters"
Expand All @@ -70,7 +78,7 @@ const PipelineDetailsPage: React.FC<DetailsPageProps> = (props) => {
{
href: 'resources',
name: t('pipelines-plugin~Resources'),
component: (pageProps) => (
component: (pageProps: PipelineDetailsTabProps) => (
<PipelineForm
PipelineFormComponent={PipelineResourcesForm}
formName="resources"
Expand Down
@@ -1,5 +1,6 @@
import * as React from 'react';
import { shallow } from 'enzyme';
import { SemVer } from 'semver';
import { referenceForModel } from '@console/internal/module/k8s';
import { useK8sGet } from '@console/internal/components/utils/k8s-get-hook';
import { DetailsPage } from '@console/internal/components/factory/';
Expand All @@ -11,13 +12,16 @@ import { PipelineRun } from '../../../utils/pipeline-augment';
import { PipelineModel } from '../../../models';
import * as utils from '../../pipelineruns/triggered-by';
import * as hookUtils from '../hooks';
import * as operatorUtils from '../utils/pipeline-operator';
import PipelineDetailsPage from '../PipelineDetailsPage';
import * as triggerUtils from '../utils/triggers';
import { MetricsQueryPrefix } from '../pipeline-metrics/pipeline-metrics-utils';

const menuActions = jest.spyOn(utils, 'useMenuActionsWithUserAnnotation');
const breadCrumbs = jest.spyOn(hookUtils, 'usePipelinesBreadcrumbsFor');
const templateNames = jest.spyOn(triggerUtils, 'usePipelineTriggerTemplateNames');
const latestPipelineRun = jest.spyOn(hookUtils, 'useLatestPipelineRun');
const operatorVersion = jest.spyOn(operatorUtils, 'usePipelineOperatorVersion');

jest.mock('@console/internal/components/utils/k8s-get-hook', () => ({
useK8sGet: jest.fn(),
Expand Down Expand Up @@ -78,6 +82,32 @@ describe('PipelineDetailsPage:', () => {
expect(wrapper.find(ErrorPage404).exists()).toBe(true);
});

it('should have the latest metrics endpoint as default queryPrefix', () => {
(useK8sGet as jest.Mock).mockReturnValue([mockData.pipeline, true, null]);
const wrapper = shallow(<PipelineDetailsPage {...PipelineDetailsPageProps} />);
expect(wrapper.find(DetailsPage).props().customData.queryPrefix).toBe(
MetricsQueryPrefix.TEKTON_PIPELINES_CONTROLLER,
);
});

it('should use the new metrics endpoint if the pipeline operator is greater than 1.4.0', () => {
(useK8sGet as jest.Mock).mockReturnValue([mockData.pipeline, true, null]);
((operatorVersion as unknown) as jest.Mock).mockReturnValue(new SemVer('1.8.0'));
const wrapper = shallow(<PipelineDetailsPage {...PipelineDetailsPageProps} />);
expect(wrapper.find(DetailsPage).props().customData.queryPrefix).toBe(
MetricsQueryPrefix.TEKTON_PIPELINES_CONTROLLER,
);
});

it('should use the old metrics endpoint if the pipeline operator is less than 1.4.0', () => {
(useK8sGet as jest.Mock).mockReturnValue([mockData.pipeline, true, null]);
((operatorVersion as unknown) as jest.Mock).mockReturnValue(new SemVer('1.2.1'));
const wrapper = shallow(<PipelineDetailsPage {...PipelineDetailsPageProps} />);
expect(wrapper.find(DetailsPage).props().customData.queryPrefix).toBe(
MetricsQueryPrefix.TEKTON,
);
});

it('should not contain Start last run menu item if the pipeline run is not present', () => {
menuActions.mockReturnValue(getPipelineKebabActions(null, false));
const wrapper = shallow(<PipelineDetailsPage {...PipelineDetailsPageProps} />);
Expand Down
Expand Up @@ -44,6 +44,7 @@ export const SecretAnnotationType = {
[SecretAnnotationId.Image]: 'Image Registry',
};

export const PIPELINE_GA_VERSION = '1.4.0';
export const PIPELINE_SERVICE_ACCOUNT = 'pipeline';
export const PIPELINE_RUN_AUTO_START_FAILED = `bridge/pipeline-run-auto-start-failed`;

Expand Down
Expand Up @@ -8,6 +8,7 @@ import {
} from '../../../utils/pipeline-filter-reducer';
import { ListFilterId, ListFilterLabels } from '../../../utils/pipeline-utils';
import { PipelineRunModel } from '../../../models';
import { PipelineDetailsTabProps } from './types';

export const runFilters = [
{
Expand All @@ -30,11 +31,7 @@ export const runFilters = [
},
];

interface PipelineRunsProps {
obj: any;
}

const PipelineRuns: React.FC<PipelineRunsProps> = ({ obj }) => (
const PipelineRuns: React.FC<PipelineDetailsTabProps> = ({ obj }) => (
<ListPage
showTitle={false}
canCreate={false}
Expand Down
Expand Up @@ -8,6 +8,13 @@ const pipelineRunProps: React.ComponentProps<typeof PipelineRuns> = {
metadata: {
name: 'pipeline-a',
},
spec: {
tasks: [{ name: 'task1' }],
},
},
customData: {
templateNames: [],
queryPrefix: '',
},
};

Expand Down
@@ -1,26 +1,14 @@
import * as React from 'react';
import { useTranslation } from 'react-i18next';
import { SectionHeading, ResourceSummary } from '@console/internal/components/utils';
import {
getResourceModelFromTaskKind,
Pipeline,
PipelineTask,
} from '../../../../utils/pipeline-augment';
import { getResourceModelFromTaskKind, PipelineTask } from '../../../../utils/pipeline-augment';
import { TriggerTemplateModel } from '../../../../models';
import { RouteTemplate } from '../../utils/triggers';
import DynamicResourceLinkList from '../../resource-overview/DynamicResourceLinkList';
import TriggerTemplateResourceLink from '../../resource-overview/TriggerTemplateResourceLink';
import PipelineVisualization from './PipelineVisualization';
import { PipelineDetailsTabProps } from '../types';

interface PipelineDetailsProps {
obj: Pipeline;
customData: RouteTemplate[];
}

const PipelineDetails: React.FC<PipelineDetailsProps> = ({
obj: pipeline,
customData: routeTemplates,
}) => {
const PipelineDetails: React.FC<PipelineDetailsTabProps> = ({ obj: pipeline, customData }) => {
const { t } = useTranslation();
const taskLinks = pipeline.spec.tasks
.filter((pipelineTask: PipelineTask) => !!pipelineTask.taskRef)
Expand All @@ -41,7 +29,7 @@ const PipelineDetails: React.FC<PipelineDetailsProps> = ({
<TriggerTemplateResourceLink
namespace={pipeline.metadata.namespace}
model={TriggerTemplateModel}
links={routeTemplates}
links={customData.templateNames}
/>
<DynamicResourceLinkList
namespace={pipeline.metadata.namespace}
Expand Down
@@ -0,0 +1,10 @@
import { Pipeline } from '../../../utils/pipeline-augment';
import { RouteTemplate } from '../utils/triggers';

export type PipelineDetailsTabProps = {
obj: Pipeline;
customData: {
templateNames: RouteTemplate[];
queryPrefix: string;
};
};
Expand Up @@ -64,11 +64,11 @@ export const usePipelinePVC = (
return [!PVCError && PVC.length > 0 ? PVC[0] : null, PVCLoaded];
};

export const usePipelineSuccessRatioPoll = ({ delay, namespace, name, timespan }) => {
export const usePipelineSuccessRatioPoll = ({ delay, namespace, name, timespan, queryPrefix }) => {
return useURLPoll<PrometheusResponse>(
getPrometheusURL({
endpoint: PrometheusEndpoint.QUERY_RANGE,
query: metricQueries[PipelineQuery.PIPELINE_SUCCESS_RATIO]({ name, namespace }),
query: metricQueries(queryPrefix)[PipelineQuery.PIPELINE_SUCCESS_RATIO]({ name, namespace }),
samples: 1,
endTime: Date.now(),
timespan,
Expand All @@ -79,11 +79,14 @@ export const usePipelineSuccessRatioPoll = ({ delay, namespace, name, timespan }
);
};

export const usePipelineRunTaskRunPoll = ({ delay, namespace, name, timespan }) => {
export const usePipelineRunTaskRunPoll = ({ delay, namespace, name, timespan, queryPrefix }) => {
return useURLPoll<PrometheusResponse>(
getPrometheusURL({
endpoint: PrometheusEndpoint.QUERY_RANGE,
query: metricQueries[PipelineQuery.PIPELINE_RUN_TASK_RUN_DURATION]({ name, namespace }),
query: metricQueries(queryPrefix)[PipelineQuery.PIPELINE_RUN_TASK_RUN_DURATION]({
name,
namespace,
}),
samples: DEFAULT_SAMPLES,
endTime: Date.now(),
timespan,
Expand All @@ -94,11 +97,17 @@ export const usePipelineRunTaskRunPoll = ({ delay, namespace, name, timespan })
);
};

export const usePipelineRunDurationPoll = ({ delay, namespace, name, timespan }): any => {
export const usePipelineRunDurationPoll = ({
delay,
namespace,
name,
timespan,
queryPrefix,
}): any => {
return useURLPoll<PrometheusResponse>(
getPrometheusURL({
endpoint: PrometheusEndpoint.QUERY_RANGE,
query: metricQueries[PipelineQuery.PIPELINE_RUN_DURATION]({ name, namespace }),
query: metricQueries(queryPrefix)[PipelineQuery.PIPELINE_RUN_DURATION]({ name, namespace }),
samples: DEFAULT_SAMPLES,
endTime: Date.now(),
timespan,
Expand All @@ -109,11 +118,11 @@ export const usePipelineRunDurationPoll = ({ delay, namespace, name, timespan })
);
};

export const usePipelineRunPoll = ({ delay, namespace, name, timespan }) => {
export const usePipelineRunPoll = ({ delay, namespace, name, timespan, queryPrefix }) => {
return useURLPoll<PrometheusResponse>(
getPrometheusURL({
endpoint: PrometheusEndpoint.QUERY_RANGE,
query: metricQueries[PipelineQuery.NUMBER_OF_PIPELINE_RUNS]({ name, namespace }),
query: metricQueries(queryPrefix)[PipelineQuery.NUMBER_OF_PIPELINE_RUNS]({ name, namespace }),
samples: DEFAULT_SAMPLES,
endTime: Date.now(),
timespan,
Expand Down
Expand Up @@ -6,7 +6,6 @@ import DashboardCardBody from '@console/shared/src/components/dashboard/dashboar
import DashboardCardHeader from '@console/shared/src/components/dashboard/dashboard-card/DashboardCardHeader';
import DashboardCardTitle from '@console/shared/src/components/dashboard/dashboard-card/DashboardCardTitle';
import { parsePrometheusDuration } from '@console/internal/components/utils/datetime';
import { Pipeline } from '../../../utils/pipeline-augment';
import PipelineMetricsTimeRangeDropdown from './PipelineMetricsTimeRangeDropdown';
import PipelineMetricsRefreshDropdown from './PipelineMetricsRefreshDropdown';
import PipelineMetricsEmptyState from './PipelineMetricsEmptyState';
Expand All @@ -15,18 +14,16 @@ import PipelineRunDurationGraph from './PipelineRunDurationGraph';
import PipelineRunTaskRunGraph from './PipelineRunTaskRunGraph';
import { GraphData } from './pipeline-metrics-utils';
import PipelineRunCount from './PipelineRunCount';
import { PipelineDetailsTabProps } from '../detail-page-tabs/types';
import { useLatestPipelineRun } from '../hooks';

import './PipelineMetrics.scss';

interface PipelineMeticsProps {
obj: Pipeline;
}

const PipelineMetrics: React.FC<PipelineMeticsProps> = ({ obj }) => {
const PipelineMetrics: React.FC<PipelineDetailsTabProps> = ({ obj, customData }) => {
const {
metadata: { name, namespace },
} = obj;
const { queryPrefix } = customData;
const { t } = useTranslation();
const latestPipelineRun = useLatestPipelineRun(name, namespace);
const [timespan, setTimespan] = React.useState(parsePrometheusDuration('1w'));
Expand Down Expand Up @@ -85,6 +82,7 @@ const PipelineMetrics: React.FC<PipelineMeticsProps> = ({ obj }) => {
pipeline={obj}
loaded={loaded}
onLoad={graphOnLoad}
queryPrefix={queryPrefix}
/>
</DashboardCardBody>
</DashboardCard>
Expand All @@ -103,6 +101,7 @@ const PipelineMetrics: React.FC<PipelineMeticsProps> = ({ obj }) => {
pipeline={obj}
loaded={loaded}
onLoad={graphOnLoad}
queryPrefix={queryPrefix}
/>
</DashboardCardBody>
</DashboardCard>
Expand All @@ -122,6 +121,7 @@ const PipelineMetrics: React.FC<PipelineMeticsProps> = ({ obj }) => {
timespan={timespan}
loaded={loaded}
onLoad={graphOnLoad}
queryPrefix={queryPrefix}
/>
</DashboardCardBody>
</DashboardCard>
Expand All @@ -138,6 +138,7 @@ const PipelineMetrics: React.FC<PipelineMeticsProps> = ({ obj }) => {
pipeline={obj}
loaded={loaded}
onLoad={graphOnLoad}
queryPrefix={queryPrefix}
/>
</DashboardCardBody>
</DashboardCard>
Expand Down
Expand Up @@ -22,6 +22,7 @@ const PipelineRunCount: React.FC<PipelineMetricsGraphProps> = ({
interval,
loaded = true,
onLoad: onInitialLoad,
queryPrefix,
}) => {
const {
metadata: { name, namespace },
Expand All @@ -32,6 +33,7 @@ const PipelineRunCount: React.FC<PipelineMetricsGraphProps> = ({
namespace,
timespan,
delay: interval,
queryPrefix,
});
const pipelineRunResultData = pipelineRunResult?.data?.result ?? [];

Expand Down
Expand Up @@ -19,6 +19,7 @@ const PipelineRunDurationGraph: React.FC<PipelineMetricsGraphProps> = ({
interval,
loaded = true,
onLoad: onInitialLoad,
queryPrefix,
}) => {
const {
metadata: { name, namespace },
Expand All @@ -29,6 +30,7 @@ const PipelineRunDurationGraph: React.FC<PipelineMetricsGraphProps> = ({
namespace,
timespan,
delay: interval,
queryPrefix,
});
const pipelineRunDurationData = runData?.data?.result ?? [];

Expand Down
Expand Up @@ -29,6 +29,7 @@ const PipelineRunTaskRunGraph: React.FC<PipelineMetricsGraphProps> = ({
interval,
loaded = true,
onLoad: onInitialLoad,
queryPrefix,
}) => {
const {
metadata: { name, namespace },
Expand All @@ -41,6 +42,7 @@ const PipelineRunTaskRunGraph: React.FC<PipelineMetricsGraphProps> = ({
namespace,
timespan,
delay: interval,
queryPrefix,
});

const taskNameMap = pipeline.spec.tasks
Expand Down
Expand Up @@ -24,6 +24,7 @@ const PipelineSuccessRatioDonut: React.FC<PipelineMetricsGraphProps> = ({
interval,
loaded = true,
onLoad: onInitialLoad,
queryPrefix,
}) => {
const {
metadata: { name, namespace },
Expand All @@ -34,6 +35,7 @@ const PipelineSuccessRatioDonut: React.FC<PipelineMetricsGraphProps> = ({
namespace,
timespan,
delay: interval,
queryPrefix,
});
const pipelineSuccessData = runData?.data?.result ?? [];

Expand Down

0 comments on commit d1c1498

Please sign in to comment.