mirror of
https://github.com/grafana/grafana.git
synced 2025-09-26 02:44:12 +08:00
CloudWatch logs: Fix default region interpolation and reset log groups on region change (#24346)
This commit is contained in:
@ -0,0 +1,61 @@
|
|||||||
|
import React from 'react';
|
||||||
|
import { shallow } from 'enzyme';
|
||||||
|
import { CloudWatchLogsQueryField } from './LogsQueryField';
|
||||||
|
import { ExploreId } from '../../../../types';
|
||||||
|
|
||||||
|
describe('CloudWatchLogsQueryField', () => {
|
||||||
|
it('updates upstream query log groups on region change', async () => {
|
||||||
|
const onChange = jest.fn();
|
||||||
|
const wrapper = shallow(
|
||||||
|
<CloudWatchLogsQueryField
|
||||||
|
history={[]}
|
||||||
|
absoluteRange={{ from: 1, to: 10 }}
|
||||||
|
syntaxLoaded={false}
|
||||||
|
syntax={{} as any}
|
||||||
|
exploreId={ExploreId.left}
|
||||||
|
datasource={
|
||||||
|
{
|
||||||
|
getRegions() {
|
||||||
|
return Promise.resolve([
|
||||||
|
{
|
||||||
|
label: 'region1',
|
||||||
|
value: 'region1',
|
||||||
|
text: 'region1',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: 'region2',
|
||||||
|
value: 'region2',
|
||||||
|
text: 'region2',
|
||||||
|
},
|
||||||
|
]);
|
||||||
|
},
|
||||||
|
describeLogGroups(params: any) {
|
||||||
|
if (params.region === 'region1') {
|
||||||
|
return Promise.resolve(['log_group_1']);
|
||||||
|
} else {
|
||||||
|
return Promise.resolve(['log_group_2']);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
} as any
|
||||||
|
}
|
||||||
|
query={{} as any}
|
||||||
|
onRunQuery={() => {}}
|
||||||
|
onChange={onChange}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
const getRegionSelect = () => wrapper.find({ label: 'Region' }).props().inputEl;
|
||||||
|
const getLogGroupSelect = () => wrapper.find({ label: 'Log Groups' }).props().inputEl;
|
||||||
|
|
||||||
|
getLogGroupSelect().props.onChange([{ value: 'log_group_1' }]);
|
||||||
|
expect(getLogGroupSelect().props.value.length).toBe(1);
|
||||||
|
expect(getLogGroupSelect().props.value[0].value).toBe('log_group_1');
|
||||||
|
|
||||||
|
// We select new region where the selected log group does not exist
|
||||||
|
await getRegionSelect().props.onChange({ value: 'region2' });
|
||||||
|
|
||||||
|
// We clear the select
|
||||||
|
expect(getLogGroupSelect().props.value.length).toBe(0);
|
||||||
|
// Make sure we correctly updated the upstream state
|
||||||
|
expect(onChange.mock.calls[1][0]).toEqual({ region: 'region2', logGroupNames: [] });
|
||||||
|
});
|
||||||
|
});
|
@ -186,22 +186,25 @@ export class CloudWatchLogsQueryField extends React.PureComponent<CloudWatchLogs
|
|||||||
|
|
||||||
const logGroups = await this.fetchLogGroupOptions(v.value!);
|
const logGroups = await this.fetchLogGroupOptions(v.value!);
|
||||||
|
|
||||||
this.setState(state => ({
|
this.setState(state => {
|
||||||
availableLogGroups: logGroups,
|
const selectedLogGroups = intersection(state.selectedLogGroups, logGroups);
|
||||||
selectedLogGroups: intersection(state.selectedLogGroups, logGroups),
|
|
||||||
loadingLogGroups: false,
|
|
||||||
}));
|
|
||||||
|
|
||||||
const { onChange, query } = this.props;
|
const { onChange, query } = this.props;
|
||||||
|
if (onChange) {
|
||||||
|
const nextQuery = {
|
||||||
|
...query,
|
||||||
|
region: v.value,
|
||||||
|
logGroupNames: selectedLogGroups.map(group => group.value),
|
||||||
|
};
|
||||||
|
|
||||||
if (onChange) {
|
onChange(nextQuery);
|
||||||
const nextQuery = {
|
}
|
||||||
...query,
|
return {
|
||||||
region: v.value,
|
availableLogGroups: logGroups,
|
||||||
|
selectedLogGroups: selectedLogGroups,
|
||||||
|
loadingLogGroups: false,
|
||||||
};
|
};
|
||||||
|
});
|
||||||
onChange(nextQuery);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
onTypeahead = async (typeahead: TypeaheadInput): Promise<TypeaheadOutput> => {
|
onTypeahead = async (typeahead: TypeaheadInput): Promise<TypeaheadOutput> => {
|
||||||
|
29
public/app/plugins/datasource/cloudwatch/datasource.test.ts
Normal file
29
public/app/plugins/datasource/cloudwatch/datasource.test.ts
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
import { CloudWatchDatasource } from './datasource';
|
||||||
|
import { TemplateSrv } from '../../../features/templating/template_srv';
|
||||||
|
import { setBackendSrv } from '@grafana/runtime';
|
||||||
|
import { DefaultTimeRange } from '@grafana/data';
|
||||||
|
|
||||||
|
describe('datasource', () => {
|
||||||
|
describe('describeLogGroup', () => {
|
||||||
|
it('replaces region correctly in the query', async () => {
|
||||||
|
const datasource = new CloudWatchDatasource(
|
||||||
|
{ jsonData: { defaultRegion: 'us-west-1' } } as any,
|
||||||
|
new TemplateSrv(),
|
||||||
|
{
|
||||||
|
timeRange() {
|
||||||
|
return DefaultTimeRange;
|
||||||
|
},
|
||||||
|
} as any
|
||||||
|
);
|
||||||
|
const datasourceRequestMock = jest.fn();
|
||||||
|
datasourceRequestMock.mockResolvedValue({ data: [] });
|
||||||
|
setBackendSrv({ datasourceRequest: datasourceRequestMock } as any);
|
||||||
|
|
||||||
|
await datasource.describeLogGroups({ region: 'default' });
|
||||||
|
expect(datasourceRequestMock.mock.calls[0][0].data.queries[0].region).toBe('us-west-1');
|
||||||
|
|
||||||
|
await datasource.describeLogGroups({ region: 'eu-east' });
|
||||||
|
expect(datasourceRequestMock.mock.calls[1][0].data.queries[0].region).toBe('eu-east');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
@ -470,7 +470,7 @@ export class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery, CloudWa
|
|||||||
makeLogActionRequest(
|
makeLogActionRequest(
|
||||||
subtype: LogAction,
|
subtype: LogAction,
|
||||||
queryParams: any[],
|
queryParams: any[],
|
||||||
scopedVars?: any,
|
scopedVars?: ScopedVars,
|
||||||
makeReplacements = true
|
makeReplacements = true
|
||||||
): Observable<DataFrame[]> {
|
): Observable<DataFrame[]> {
|
||||||
const range = this.timeSrv.timeRange();
|
const range = this.timeSrv.timeRange();
|
||||||
@ -490,9 +490,10 @@ export class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery, CloudWa
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (makeReplacements) {
|
if (makeReplacements) {
|
||||||
requestParams.queries.forEach(
|
requestParams.queries.forEach(query => {
|
||||||
query => (query.region = this.replace(this.getActualRegion(this.defaultRegion), scopedVars, true, 'region'))
|
query.region = this.replace(query.region, scopedVars, true, 'region');
|
||||||
);
|
query.region = this.getActualRegion(query.region);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const resultsToDataFrames = (val: any): DataFrame[] => toDataQueryResponse(val).data || [];
|
const resultsToDataFrames = (val: any): DataFrame[] => toDataQueryResponse(val).data || [];
|
||||||
@ -785,7 +786,12 @@ export class CloudWatchDatasource extends DataSourceApi<CloudWatchQuery, CloudWa
|
|||||||
}, {});
|
}, {});
|
||||||
}
|
}
|
||||||
|
|
||||||
replace(target: string, scopedVars: ScopedVars, displayErrorIfIsMultiTemplateVariable?: boolean, fieldName?: string) {
|
replace(
|
||||||
|
target: string,
|
||||||
|
scopedVars: ScopedVars | undefined,
|
||||||
|
displayErrorIfIsMultiTemplateVariable?: boolean,
|
||||||
|
fieldName?: string
|
||||||
|
) {
|
||||||
if (displayErrorIfIsMultiTemplateVariable) {
|
if (displayErrorIfIsMultiTemplateVariable) {
|
||||||
const variable = this.templateSrv
|
const variable = this.templateSrv
|
||||||
.getVariables()
|
.getVariables()
|
||||||
|
Reference in New Issue
Block a user