Alerting: Fix cloud rules editing (#72927)

This commit is contained in:
Konrad Lalik 2023-08-04 16:46:58 +02:00 committed by GitHub
parent 01721d910e
commit 4b73e96d93
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 37 additions and 8 deletions

View File

@ -32,6 +32,7 @@ import {
import { mockAlertmanagerConfigResponse } from './mocks/alertmanagerApi';
import { mockSearchApiResponse } from './mocks/grafanaApi';
import { mockRulerRulesApiResponse, mockRulerRulesGroupApiResponse } from './mocks/rulerApi';
import { AlertingQueryRunner } from './state/AlertingQueryRunner';
import { RuleFormValues } from './types/rule-form';
import { Annotation } from './utils/constants';
import { GRAFANA_RULES_SOURCE_NAME } from './utils/datasource';
@ -51,6 +52,8 @@ jest.mock('./components/rule-editor/notificaton-preview/NotificationPreview', ()
NotificationPreview: () => <div />,
}));
jest.spyOn(AlertingQueryRunner.prototype, 'run').mockImplementation(() => Promise.resolve());
const server = setupServer();
beforeAll(() => {

View File

@ -3,13 +3,13 @@ import userEvent from '@testing-library/user-event';
import lodash from 'lodash'; // eslint-disable-line lodash/import-scope
import React from 'react';
import { logInfo } from '@grafana/runtime';
import * as runtime from '@grafana/runtime';
import { LogMessages } from '../../Analytics';
import { MatcherFilter } from './MatcherFilter';
jest.mock('@grafana/runtime');
const logInfoSpy = jest.spyOn(runtime, 'logInfo');
describe('Analytics', () => {
beforeEach(() => {
@ -25,7 +25,7 @@ describe('Analytics', () => {
const searchInput = screen.getByTestId('search-query-input');
await userEvent.type(searchInput, 'job=');
expect(logInfo).toHaveBeenCalledWith(LogMessages.filterByLabel);
expect(logInfoSpy).toHaveBeenCalledWith(LogMessages.filterByLabel);
});
it('should call onChange handler', async () => {

View File

@ -9,13 +9,14 @@ import { useRulesSourcesWithRuler } from '../../hooks/useRuleSourcesWithRuler';
import { fetchAllPromBuildInfoAction } from '../../state/actions';
interface Props {
disabled?: boolean;
onChange: (ds: DataSourceInstanceSettings) => void;
value: string | null;
onBlur?: () => void;
name?: string;
}
export function CloudRulesSourcePicker({ value, ...props }: Props): JSX.Element {
export function CloudRulesSourcePicker({ value, disabled, ...props }: Props): JSX.Element {
const rulesSourcesWithRuler = useRulesSourcesWithRuler();
const { loading = true } = useAsync(() => dispatch(fetchAllPromBuildInfoAction()), [dispatch]);
@ -28,6 +29,13 @@ export function CloudRulesSourcePicker({ value, ...props }: Props): JSX.Element
);
return (
<DataSourcePicker disabled={loading} noDefault alerting filter={dataSourceFilter} current={value} {...props} />
<DataSourcePicker
disabled={loading || disabled}
noDefault
alerting
filter={dataSourceFilter}
current={value}
{...props}
/>
);
}

View File

@ -9,9 +9,10 @@ import { RuleFormType, RuleFormValues } from '../../../types/rule-form';
import { CloudRulesSourcePicker } from '../CloudRulesSourcePicker';
export interface CloudDataSourceSelectorProps {
disabled?: boolean;
onChangeCloudDatasource: (datasourceUid: string) => void;
}
export const CloudDataSourceSelector = ({ onChangeCloudDatasource }: CloudDataSourceSelectorProps) => {
export const CloudDataSourceSelector = ({ disabled, onChangeCloudDatasource }: CloudDataSourceSelectorProps) => {
const {
control,
formState: { errors },
@ -28,7 +29,7 @@ export const CloudDataSourceSelector = ({ onChangeCloudDatasource }: CloudDataSo
{(ruleFormType === RuleFormType.cloudAlerting || ruleFormType === RuleFormType.cloudRecording) && (
<Field
className={styles.formInput}
label="Select data source"
label={disabled ? 'Data source' : 'Select data source'}
error={errors.dataSourceName?.message}
invalid={!!errors.dataSourceName?.message}
data-testid="datasource-picker"
@ -37,6 +38,7 @@ export const CloudDataSourceSelector = ({ onChangeCloudDatasource }: CloudDataSo
render={({ field: { onChange, ref, ...field } }) => (
<CloudRulesSourcePicker
{...field}
disabled={disabled}
onChange={(ds: DataSourceInstanceSettings) => {
// reset location if switching data sources, as different rules source will have different groups and namespaces
setValue('location', undefined);

View File

@ -340,7 +340,7 @@ export const QueryAndExpressionsStep = ({ editingExistingRule, onDataChange }: P
>
{/* This is the cloud data source selector */}
{(type === RuleFormType.cloudRecording || type === RuleFormType.cloudAlerting) && (
<CloudDataSourceSelector onChangeCloudDatasource={onChangeCloudDatasource} />
<CloudDataSourceSelector onChangeCloudDatasource={onChangeCloudDatasource} disabled={editingExistingRule} />
)}
{/* This is the PromQL Editor for recording rules */}

View File

@ -174,11 +174,27 @@ export function rulerRuleToFormValues(ruleWithLocation: RuleWithLocation): RuleF
}
} else {
if (isAlertingRulerRule(rule)) {
const datasourceUid = getDataSourceSrv().getInstanceSettings(ruleSourceName)?.uid ?? '';
const defaultQuery = {
refId: 'A',
datasourceUid,
queryType: '',
relativeTimeRange: getDefaultRelativeTimeRange(),
expr: rule.expr,
model: {
refId: 'A',
hide: false,
expr: rule.expr,
},
};
const alertingRuleValues = alertingRulerRuleToRuleForm(rule);
return {
...defaultFormValues,
...alertingRuleValues,
queries: [defaultQuery],
annotations: normalizeDefaultAnnotations(listifyLabelsOrAnnotations(rule.annotations, false)),
type: RuleFormType.cloudAlerting,
dataSourceName: ruleSourceName,