mirror of
https://github.com/grafana/grafana.git
synced 2025-08-01 07:32:12 +08:00
Elasticsearch: Fix URL creation and allowlist for /_mapping
requests (#80970)
* Elasticsearch: Fix URL creation for mapping requests * remove leading slash by default * add comment for es route * hardcode `_mapping` * update doc
This commit is contained in:
@ -188,9 +188,10 @@ func (s *Service) CallResource(ctx context.Context, req *backend.CallResourceReq
|
|||||||
logger := eslog.FromContext(ctx)
|
logger := eslog.FromContext(ctx)
|
||||||
// allowed paths for resource calls:
|
// allowed paths for resource calls:
|
||||||
// - empty string for fetching db version
|
// - empty string for fetching db version
|
||||||
// - ?/_mapping for fetching index mapping
|
// - /_mapping for fetching index mapping, e.g. requests going to `index/_mapping`
|
||||||
// - _msearch for executing getTerms queries
|
// - _msearch for executing getTerms queries
|
||||||
if req.Path != "" && !strings.HasSuffix(req.Path, "/_mapping") && req.Path != "_msearch" {
|
// - _mapping for fetching "root" index mappings
|
||||||
|
if req.Path != "" && !strings.HasSuffix(req.Path, "/_mapping") && req.Path != "_msearch" && req.Path != "_mapping" {
|
||||||
logger.Error("Invalid resource path", "path", req.Path)
|
logger.Error("Invalid resource path", "path", req.Path)
|
||||||
return fmt.Errorf("invalid resource URL: %s", req.Path)
|
return fmt.Errorf("invalid resource URL: %s", req.Path)
|
||||||
}
|
}
|
||||||
|
@ -151,6 +151,15 @@ describe('ElasticDatasource', () => {
|
|||||||
const lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1];
|
const lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1];
|
||||||
expect(lastCall[0].url).toBe(`${ELASTICSEARCH_MOCK_URL}/test-${today}/_mapping`);
|
expect(lastCall[0].url).toBe(`${ELASTICSEARCH_MOCK_URL}/test-${today}/_mapping`);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('should call `/_mapping` with an empty index', async () => {
|
||||||
|
const { ds, fetchMock } = getTestContext({ jsonData: { index: '' } });
|
||||||
|
|
||||||
|
await ds.testDatasource();
|
||||||
|
|
||||||
|
const lastCall = fetchMock.mock.calls[fetchMock.mock.calls.length - 1];
|
||||||
|
expect(lastCall[0].url).toBe(`${ELASTICSEARCH_MOCK_URL}/_mapping`);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('When issuing metric query with interval pattern', () => {
|
describe('When issuing metric query with interval pattern', () => {
|
||||||
|
@ -195,17 +195,24 @@ export class ElasticDatasource
|
|||||||
*
|
*
|
||||||
* When multiple indices span the provided time range, the request is sent starting from the newest index,
|
* When multiple indices span the provided time range, the request is sent starting from the newest index,
|
||||||
* and then going backwards until an index is found.
|
* and then going backwards until an index is found.
|
||||||
*
|
|
||||||
* @param url the url to query the index on, for example `/_mapping`.
|
|
||||||
*/
|
*/
|
||||||
|
private requestAllIndices(range = getDefaultTimeRange()) {
|
||||||
private requestAllIndices(url: string, range = getDefaultTimeRange()) {
|
|
||||||
let indexList = this.indexPattern.getIndexList(range.from, range.to);
|
let indexList = this.indexPattern.getIndexList(range.from, range.to);
|
||||||
if (!Array.isArray(indexList)) {
|
if (!Array.isArray(indexList)) {
|
||||||
indexList = [this.indexPattern.getIndexForToday()];
|
indexList = [this.indexPattern.getIndexForToday()];
|
||||||
}
|
}
|
||||||
|
|
||||||
const indexUrlList = indexList.map((index) => index + url);
|
const url = '_mapping';
|
||||||
|
|
||||||
|
const indexUrlList = indexList.map((index) => {
|
||||||
|
// make sure `index` does not end with a slash
|
||||||
|
index = index.replace(/\/$/, '');
|
||||||
|
if (index === '') {
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return `${index}/${url}`;
|
||||||
|
});
|
||||||
|
|
||||||
const maxTraversals = 7; // do not go beyond one week (for a daily pattern)
|
const maxTraversals = 7; // do not go beyond one week (for a daily pattern)
|
||||||
const listLen = indexUrlList.length;
|
const listLen = indexUrlList.length;
|
||||||
@ -708,7 +715,7 @@ export class ElasticDatasource
|
|||||||
nested: 'nested',
|
nested: 'nested',
|
||||||
histogram: 'number',
|
histogram: 'number',
|
||||||
};
|
};
|
||||||
return this.requestAllIndices('/_mapping', range).pipe(
|
return this.requestAllIndices(range).pipe(
|
||||||
map((result) => {
|
map((result) => {
|
||||||
const shouldAddField = (obj: any, key: string) => {
|
const shouldAddField = (obj: any, key: string) => {
|
||||||
if (this.isMetadataField(key)) {
|
if (this.isMetadataField(key)) {
|
||||||
|
@ -39,9 +39,9 @@ export function createElasticDatasource(settings: Partial<DataSourceInstanceSett
|
|||||||
jsonData: {
|
jsonData: {
|
||||||
timeField: '',
|
timeField: '',
|
||||||
timeInterval: '',
|
timeInterval: '',
|
||||||
|
index: '[test-]YYYY.MM.DD',
|
||||||
...jsonData,
|
...jsonData,
|
||||||
},
|
},
|
||||||
database: '[test-]YYYY.MM.DD',
|
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user