mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
CloudWatch: filter alert queries (#47222)
This commit is contained in:
parent
1c34cc8b91
commit
b1c68b5a12
@ -10,8 +10,13 @@ import {
|
|||||||
namespaceVariable,
|
namespaceVariable,
|
||||||
setupMockedDataSource,
|
setupMockedDataSource,
|
||||||
} from './__mocks__/CloudWatchDataSource';
|
} from './__mocks__/CloudWatchDataSource';
|
||||||
import { CloudWatchDatasource } from './datasource';
|
import {
|
||||||
import { CloudWatchLogsQueryStatus, CloudWatchMetricsQuery, MetricEditorMode, MetricQueryType } from './types';
|
CloudWatchLogsQuery,
|
||||||
|
CloudWatchLogsQueryStatus,
|
||||||
|
CloudWatchMetricsQuery,
|
||||||
|
MetricEditorMode,
|
||||||
|
MetricQueryType,
|
||||||
|
} from './types';
|
||||||
|
|
||||||
describe('datasource', () => {
|
describe('datasource', () => {
|
||||||
describe('query', () => {
|
describe('query', () => {
|
||||||
@ -144,12 +149,26 @@ describe('datasource', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('filterMetricQuery', () => {
|
describe('filterQuery', () => {
|
||||||
|
const datasource = setupMockedDataSource().datasource;
|
||||||
|
describe('CloudWatchLogsQuery', () => {
|
||||||
|
const baseQuery: CloudWatchLogsQuery = {
|
||||||
|
queryMode: 'Logs',
|
||||||
|
id: '',
|
||||||
|
region: '',
|
||||||
|
refId: '',
|
||||||
|
logGroupNames: ['foo', 'bar'],
|
||||||
|
};
|
||||||
|
it('should return false if empty logGroupNames', () => {
|
||||||
|
expect(datasource.filterQuery({ ...baseQuery, logGroupNames: undefined })).toBeFalsy();
|
||||||
|
});
|
||||||
|
it('should return true if has logGroupNames', () => {
|
||||||
|
expect(datasource.filterQuery(baseQuery)).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
describe('CloudWatchMetricsQuery', () => {
|
||||||
let baseQuery: CloudWatchMetricsQuery;
|
let baseQuery: CloudWatchMetricsQuery;
|
||||||
let datasource: CloudWatchDatasource;
|
|
||||||
|
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
datasource = setupMockedDataSource().datasource;
|
|
||||||
baseQuery = {
|
baseQuery = {
|
||||||
id: '',
|
id: '',
|
||||||
region: 'us-east-2',
|
region: 'us-east-2',
|
||||||
@ -166,12 +185,11 @@ describe('datasource', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should error if invalid mode', async () => {
|
it('should error if invalid mode', async () => {
|
||||||
expect(() => datasource.filterMetricQuery(baseQuery)).toThrowError('invalid metric editor mode');
|
expect(() => datasource.filterQuery(baseQuery)).toThrowError('invalid metric editor mode');
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('metric search queries', () => {
|
describe('metric search queries', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
datasource = setupMockedDataSource().datasource;
|
|
||||||
baseQuery = {
|
baseQuery = {
|
||||||
...baseQuery,
|
...baseQuery,
|
||||||
namespace: 'AWS/EC2',
|
namespace: 'AWS/EC2',
|
||||||
@ -183,31 +201,30 @@ describe('datasource', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow builder queries that dont have namespace, metric or statistic', async () => {
|
it('should not allow builder queries that dont have namespace, metric or statistic', async () => {
|
||||||
expect(datasource.filterMetricQuery({ ...baseQuery, statistic: undefined })).toBeFalsy();
|
expect(datasource.filterQuery({ ...baseQuery, statistic: undefined })).toBeFalsy();
|
||||||
expect(datasource.filterMetricQuery({ ...baseQuery, metricName: undefined })).toBeFalsy();
|
expect(datasource.filterQuery({ ...baseQuery, metricName: undefined })).toBeFalsy();
|
||||||
expect(datasource.filterMetricQuery({ ...baseQuery, namespace: '' })).toBeFalsy();
|
expect(datasource.filterQuery({ ...baseQuery, namespace: '' })).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow builder queries that have namespace, metric or statistic', async () => {
|
it('should allow builder queries that have namespace, metric or statistic', async () => {
|
||||||
expect(datasource.filterMetricQuery(baseQuery)).toBeTruthy();
|
expect(datasource.filterQuery(baseQuery)).toBeTruthy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow code queries that dont have an expression', async () => {
|
it('should not allow code queries that dont have an expression', async () => {
|
||||||
expect(
|
expect(
|
||||||
datasource.filterMetricQuery({ ...baseQuery, expression: undefined, metricEditorMode: MetricEditorMode.Code })
|
datasource.filterQuery({ ...baseQuery, expression: undefined, metricEditorMode: MetricEditorMode.Code })
|
||||||
).toBeFalsy();
|
).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow code queries that have an expression', async () => {
|
it('should allow code queries that have an expression', async () => {
|
||||||
expect(
|
expect(
|
||||||
datasource.filterMetricQuery({ ...baseQuery, expression: 'x * 2', metricEditorMode: MetricEditorMode.Code })
|
datasource.filterQuery({ ...baseQuery, expression: 'x * 2', metricEditorMode: MetricEditorMode.Code })
|
||||||
).toBeTruthy();
|
).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('metric search expression queries', () => {
|
describe('metric search expression queries', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
datasource = setupMockedDataSource().datasource;
|
|
||||||
baseQuery = {
|
baseQuery = {
|
||||||
...baseQuery,
|
...baseQuery,
|
||||||
metricQueryType: MetricQueryType.Search,
|
metricQueryType: MetricQueryType.Search,
|
||||||
@ -215,21 +232,20 @@ describe('datasource', () => {
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow queries that dont have an expresssion', async () => {
|
it('should not allow queries that dont have an expression', async () => {
|
||||||
const valid = datasource.filterMetricQuery(baseQuery);
|
const valid = datasource.filterQuery(baseQuery);
|
||||||
expect(valid).toBeFalsy();
|
expect(valid).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow queries that have an expresssion', async () => {
|
it('should allow queries that have an expression', async () => {
|
||||||
baseQuery.expression = 'SUM([a,x])';
|
baseQuery.expression = 'SUM([a,x])';
|
||||||
const valid = datasource.filterMetricQuery(baseQuery);
|
const valid = datasource.filterQuery(baseQuery);
|
||||||
expect(valid).toBeTruthy();
|
expect(valid).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('metric query queries', () => {
|
describe('metric query queries', () => {
|
||||||
beforeEach(() => {
|
beforeEach(() => {
|
||||||
datasource = setupMockedDataSource().datasource;
|
|
||||||
baseQuery = {
|
baseQuery = {
|
||||||
...baseQuery,
|
...baseQuery,
|
||||||
metricQueryType: MetricQueryType.Query,
|
metricQueryType: MetricQueryType.Query,
|
||||||
@ -238,17 +254,19 @@ describe('datasource', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
it('should not allow queries that dont have a sql expresssion', async () => {
|
it('should not allow queries that dont have a sql expresssion', async () => {
|
||||||
const valid = datasource.filterMetricQuery(baseQuery);
|
const valid = datasource.filterQuery(baseQuery);
|
||||||
expect(valid).toBeFalsy();
|
expect(valid).toBeFalsy();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should allow queries that have a sql expresssion', async () => {
|
it('should allow queries that have a sql expresssion', async () => {
|
||||||
baseQuery.sqlExpression = 'select SUM(CPUUtilization) from "AWS/EC2"';
|
baseQuery.sqlExpression = 'select SUM(CPUUtilization) from "AWS/EC2"';
|
||||||
const valid = datasource.filterMetricQuery(baseQuery);
|
const valid = datasource.filterQuery(baseQuery);
|
||||||
expect(valid).toBeTruthy();
|
expect(valid).toBeTruthy();
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('resource requests', () => {
|
describe('resource requests', () => {
|
||||||
it('should map resource response to metric response', async () => {
|
it('should map resource response to metric response', async () => {
|
||||||
const datasource = setupMockedDataSource().datasource;
|
const datasource = setupMockedDataSource().datasource;
|
||||||
|
@ -234,22 +234,15 @@ export class CloudWatchDatasource
|
|||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
filterMetricQuery({
|
filterQuery(query: CloudWatchQuery): boolean {
|
||||||
region,
|
if (query.queryMode === 'Logs') {
|
||||||
metricQueryType,
|
return !!query.logGroupNames?.length;
|
||||||
metricEditorMode,
|
}
|
||||||
expression,
|
const { region, metricQueryType, metricEditorMode, expression, metricName, namespace, sqlExpression, statistic } =
|
||||||
metricName,
|
query;
|
||||||
namespace,
|
|
||||||
sqlExpression,
|
|
||||||
statistic,
|
|
||||||
dimensions,
|
|
||||||
...rest
|
|
||||||
}: CloudWatchMetricsQuery): boolean {
|
|
||||||
if (!region) {
|
if (!region) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (metricQueryType === MetricQueryType.Search && metricEditorMode === MetricEditorMode.Builder) {
|
if (metricQueryType === MetricQueryType.Search && metricEditorMode === MetricEditorMode.Builder) {
|
||||||
return !!namespace && !!metricName && !!statistic;
|
return !!namespace && !!metricName && !!statistic;
|
||||||
} else if (metricQueryType === MetricQueryType.Search && metricEditorMode === MetricEditorMode.Code) {
|
} else if (metricQueryType === MetricQueryType.Search && metricEditorMode === MetricEditorMode.Code) {
|
||||||
@ -266,9 +259,7 @@ export class CloudWatchDatasource
|
|||||||
metricQueries: CloudWatchMetricsQuery[],
|
metricQueries: CloudWatchMetricsQuery[],
|
||||||
options: DataQueryRequest<CloudWatchQuery>
|
options: DataQueryRequest<CloudWatchQuery>
|
||||||
): Observable<DataQueryResponse> => {
|
): Observable<DataQueryResponse> => {
|
||||||
const validMetricsQueries = metricQueries
|
const validMetricsQueries = metricQueries.map((item: CloudWatchMetricsQuery): MetricQuery => {
|
||||||
.filter(this.filterMetricQuery)
|
|
||||||
.map((item: CloudWatchMetricsQuery): MetricQuery => {
|
|
||||||
item.region = this.templateSrv.replace(this.getActualRegion(item.region), options.scopedVars);
|
item.region = this.templateSrv.replace(this.getActualRegion(item.region), options.scopedVars);
|
||||||
item.namespace = this.replace(item.namespace, options.scopedVars, true, 'namespace');
|
item.namespace = this.replace(item.namespace, options.scopedVars, true, 'namespace');
|
||||||
item.metricName = this.replace(item.metricName, options.scopedVars, true, 'metric name');
|
item.metricName = this.replace(item.metricName, options.scopedVars, true, 'metric name');
|
||||||
|
Loading…
Reference in New Issue
Block a user