Index Patterns API - Remove legacy es client usage for field caps (#80116) (#81784)

* remove legacy es client usage
This commit is contained in:
Matthew Kime 2020-10-27 11:41:40 -05:00 committed by GitHub
parent 1424fdfffd
commit 41206e10e4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
26 changed files with 212 additions and 134 deletions

View file

@ -9,12 +9,13 @@ Constructs a new instance of the `IndexPatternsFetcher` class
<b>Signature:</b>
```typescript
constructor(callDataCluster: LegacyAPICaller);
constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices?: boolean);
```
## Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| callDataCluster | <code>LegacyAPICaller</code> | |
| elasticsearchClient | <code>ElasticsearchClient</code> | |
| allowNoIndices | <code>boolean</code> | |

View file

@ -13,7 +13,7 @@ getFieldsForWildcard(options: {
pattern: string | string[];
metaFields?: string[];
fieldCapsOptions?: {
allowNoIndices: boolean;
allow_no_indices: boolean;
};
}): Promise<FieldDescriptor[]>;
```
@ -22,7 +22,7 @@ getFieldsForWildcard(options: {
| Parameter | Type | Description |
| --- | --- | --- |
| options | <code>{</code><br/><code> pattern: string &#124; string[];</code><br/><code> metaFields?: string[];</code><br/><code> fieldCapsOptions?: {</code><br/><code> allowNoIndices: boolean;</code><br/><code> };</code><br/><code> }</code> | |
| options | <code>{</code><br/><code> pattern: string &#124; string[];</code><br/><code> metaFields?: string[];</code><br/><code> fieldCapsOptions?: {</code><br/><code> allow_no_indices: boolean;</code><br/><code> };</code><br/><code> }</code> | |
<b>Returns:</b>

View file

@ -14,7 +14,7 @@ export declare class IndexPatternsFetcher
| Constructor | Modifiers | Description |
| --- | --- | --- |
| [(constructor)(callDataCluster)](./kibana-plugin-plugins-data-server.indexpatternsfetcher._constructor_.md) | | Constructs a new instance of the <code>IndexPatternsFetcher</code> class |
| [(constructor)(elasticsearchClient, allowNoIndices)](./kibana-plugin-plugins-data-server.indexpatternsfetcher._constructor_.md) | | Constructs a new instance of the <code>IndexPatternsFetcher</code> class |
## Methods

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { LegacyAPICaller } from 'kibana/server';
import { ElasticsearchClient } from 'kibana/server';
import { getFieldCapabilities, resolveTimePattern, createNoMatchingIndicesError } from './lib';
@ -37,10 +37,12 @@ interface FieldSubType {
}
export class IndexPatternsFetcher {
private _callDataCluster: LegacyAPICaller;
private elasticsearchClient: ElasticsearchClient;
private allowNoIndices: boolean;
constructor(callDataCluster: LegacyAPICaller) {
this._callDataCluster = callDataCluster;
constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices: boolean = false) {
this.elasticsearchClient = elasticsearchClient;
this.allowNoIndices = allowNoIndices;
}
/**
@ -55,10 +57,12 @@ export class IndexPatternsFetcher {
async getFieldsForWildcard(options: {
pattern: string | string[];
metaFields?: string[];
fieldCapsOptions?: { allowNoIndices: boolean };
fieldCapsOptions?: { allow_no_indices: boolean };
}): Promise<FieldDescriptor[]> {
const { pattern, metaFields, fieldCapsOptions } = options;
return await getFieldCapabilities(this._callDataCluster, pattern, metaFields, fieldCapsOptions);
return await getFieldCapabilities(this.elasticsearchClient, pattern, metaFields, {
allow_no_indices: fieldCapsOptions ? fieldCapsOptions.allow_no_indices : this.allowNoIndices,
});
}
/**
@ -78,11 +82,11 @@ export class IndexPatternsFetcher {
interval: string;
}) {
const { pattern, lookBack, metaFields } = options;
const { matches } = await resolveTimePattern(this._callDataCluster, pattern);
const { matches } = await resolveTimePattern(this.elasticsearchClient, pattern);
const indices = matches.slice(0, lookBack);
if (indices.length === 0) {
throw createNoMatchingIndicesError(pattern);
}
return await getFieldCapabilities(this._callDataCluster, indices, metaFields);
return await getFieldCapabilities(this.elasticsearchClient, indices, metaFields);
}
}

View file

@ -32,36 +32,60 @@ describe('server/index_patterns/service/lib/es_api', () => {
afterEach(() => sandbox.restore());
it('calls indices.getAlias() via callCluster', async () => {
const callCluster = sinon.stub();
const getAlias = sinon.stub();
const callCluster = {
indices: {
getAlias,
},
fieldCaps: sinon.stub(),
};
await callIndexAliasApi(callCluster);
sinon.assert.calledOnce(callCluster);
sinon.assert.calledWith(callCluster, 'indices.getAlias');
sinon.assert.calledOnce(getAlias);
});
it('passes indices directly to es api', async () => {
const football = {};
const callCluster = sinon.stub();
const getAlias = sinon.stub();
const callCluster = {
indices: {
getAlias,
},
fieldCaps: sinon.stub(),
};
await callIndexAliasApi(callCluster, football);
sinon.assert.calledOnce(callCluster);
expect(callCluster.args[0][1].index).toBe(football);
sinon.assert.calledOnce(getAlias);
expect(getAlias.args[0][0].index).toBe(football);
});
it('returns the es response directly', async () => {
const football = {};
const callCluster = sinon.stub().returns(football);
const getAlias = sinon.stub().returns(football);
const callCluster = {
indices: {
getAlias,
},
fieldCaps: sinon.stub(),
};
const resp = await callIndexAliasApi(callCluster);
sinon.assert.calledOnce(callCluster);
sinon.assert.calledOnce(getAlias);
expect(resp).toBe(football);
});
it('sets ignoreUnavailable and allowNoIndices params', async () => {
const callCluster = sinon.stub();
const getAlias = sinon.stub();
const callCluster = {
indices: {
getAlias,
},
fieldCaps: sinon.stub(),
};
await callIndexAliasApi(callCluster);
sinon.assert.calledOnce(callCluster);
sinon.assert.calledOnce(getAlias);
const passedOpts = callCluster.args[0][1];
expect(passedOpts).toHaveProperty('ignoreUnavailable', true);
expect(passedOpts).toHaveProperty('allowNoIndices', false);
const passedOpts = getAlias.args[0][0];
expect(passedOpts).toHaveProperty('ignore_unavailable', true);
expect(passedOpts).toHaveProperty('allow_no_indices', false);
});
it('handles errors with convertEsError()', async () => {
@ -70,9 +94,15 @@ describe('server/index_patterns/service/lib/es_api', () => {
const convertedError = new Error('convertedError');
sandbox.stub(convertEsErrorNS, 'convertEsError').throws(convertedError);
const callCluster = sinon.spy(async () => {
const getAlias = sinon.stub(async () => {
throw esError;
});
const callCluster = {
indices: {
getAlias,
},
fieldCaps: sinon.stub(),
};
try {
await callIndexAliasApi(callCluster, indices);
throw new Error('expected callIndexAliasApi() to throw');
@ -91,37 +121,60 @@ describe('server/index_patterns/service/lib/es_api', () => {
afterEach(() => sandbox.restore());
it('calls fieldCaps() via callCluster', async () => {
const callCluster = sinon.stub();
const fieldCaps = sinon.stub();
const callCluster = {
indices: {
getAlias: sinon.stub(),
},
fieldCaps,
};
await callFieldCapsApi(callCluster);
sinon.assert.calledOnce(callCluster);
sinon.assert.calledWith(callCluster, 'fieldCaps');
sinon.assert.calledOnce(fieldCaps);
});
it('passes indices directly to es api', async () => {
const football = {};
const callCluster = sinon.stub();
const fieldCaps = sinon.stub();
const callCluster = {
indices: {
getAlias: sinon.stub(),
},
fieldCaps,
};
await callFieldCapsApi(callCluster, football);
sinon.assert.calledOnce(callCluster);
expect(callCluster.args[0][1].index).toBe(football);
sinon.assert.calledOnce(fieldCaps);
expect(fieldCaps.args[0][0].index).toBe(football);
});
it('returns the es response directly', async () => {
const football = {};
const callCluster = sinon.stub().returns(football);
const fieldCaps = sinon.stub().returns(football);
const callCluster = {
indices: {
getAlias: sinon.stub(),
},
fieldCaps,
};
const resp = await callFieldCapsApi(callCluster);
sinon.assert.calledOnce(callCluster);
sinon.assert.calledOnce(fieldCaps);
expect(resp).toBe(football);
});
it('sets ignoreUnavailable, allowNoIndices, and fields params', async () => {
const callCluster = sinon.stub();
const fieldCaps = sinon.stub();
const callCluster = {
indices: {
getAlias: sinon.stub(),
},
fieldCaps,
};
await callFieldCapsApi(callCluster);
sinon.assert.calledOnce(callCluster);
sinon.assert.calledOnce(fieldCaps);
const passedOpts = callCluster.args[0][1];
const passedOpts = fieldCaps.args[0][0];
expect(passedOpts).toHaveProperty('fields', '*');
expect(passedOpts).toHaveProperty('ignoreUnavailable', true);
expect(passedOpts).toHaveProperty('allowNoIndices', false);
expect(passedOpts).toHaveProperty('ignore_unavailable', true);
expect(passedOpts).toHaveProperty('allow_no_indices', false);
});
it('handles errors with convertEsError()', async () => {
@ -130,9 +183,15 @@ describe('server/index_patterns/service/lib/es_api', () => {
const convertedError = new Error('convertedError');
sandbox.stub(convertEsErrorNS, 'convertEsError').throws(convertedError);
const callCluster = sinon.spy(async () => {
const fieldCaps = sinon.spy(async () => {
throw esError;
});
const callCluster = {
indices: {
getAlias: sinon.stub(),
},
fieldCaps,
};
try {
await callFieldCapsApi(callCluster, indices);
throw new Error('expected callFieldCapsApi() to throw');

View file

@ -17,7 +17,7 @@
* under the License.
*/
import { LegacyAPICaller } from 'kibana/server';
import { ElasticsearchClient } from 'kibana/server';
import { convertEsError } from './errors';
import { FieldCapsResponse } from './field_capabilities';
@ -46,15 +46,15 @@ export interface IndexAliasResponse {
* @return {Promise<IndexAliasResponse>}
*/
export async function callIndexAliasApi(
callCluster: LegacyAPICaller,
callCluster: ElasticsearchClient,
indices: string[] | string
): Promise<IndicesAliasResponse> {
) {
try {
return (await callCluster('indices.getAlias', {
return await callCluster.indices.getAlias({
index: indices,
ignoreUnavailable: true,
allowNoIndices: false,
})) as Promise<IndicesAliasResponse>;
ignore_unavailable: true,
allow_no_indices: false,
});
} catch (error) {
throw convertEsError(indices, error);
}
@ -73,17 +73,17 @@ export async function callIndexAliasApi(
* @return {Promise<FieldCapsResponse>}
*/
export async function callFieldCapsApi(
callCluster: LegacyAPICaller,
callCluster: ElasticsearchClient,
indices: string[] | string,
fieldCapsOptions: { allowNoIndices: boolean } = { allowNoIndices: false }
fieldCapsOptions: { allow_no_indices: boolean } = { allow_no_indices: false }
) {
try {
return (await callCluster('fieldCaps', {
return await callCluster.fieldCaps<FieldCapsResponse>({
index: indices,
fields: '*',
ignoreUnavailable: true,
ignore_unavailable: true,
...fieldCapsOptions,
})) as FieldCapsResponse;
});
} catch (error) {
throw convertEsError(indices, error);
}

View file

@ -48,9 +48,11 @@ describe('index_patterns/field_capabilities/field_capabilities', () => {
};
const stubDeps = (options = {}) => {
const { esResponse = {}, fieldsFromFieldCaps = [], mergeOverrides = identity } = options;
const { esResponse = [], fieldsFromFieldCaps = [], mergeOverrides = identity } = options;
sandbox.stub(callFieldCapsApiNS, 'callFieldCapsApi').callsFake(async () => esResponse);
sandbox
.stub(callFieldCapsApiNS, 'callFieldCapsApi')
.callsFake(async () => ({ body: esResponse }));
sandbox.stub(readFieldCapsResponseNS, 'readFieldCapsResponse').returns(fieldsFromFieldCaps);
sandbox.stub(mergeOverridesNS, 'mergeOverrides').callsFake(mergeOverrides);
};

View file

@ -19,9 +19,9 @@
import { defaults, keyBy, sortBy } from 'lodash';
import { LegacyAPICaller } from 'kibana/server';
import { ElasticsearchClient } from 'kibana/server';
import { callFieldCapsApi } from '../es_api';
import { FieldCapsResponse, readFieldCapsResponse } from './field_caps_response';
import { readFieldCapsResponse } from './field_caps_response';
import { mergeOverrides } from './overrides';
import { FieldDescriptor } from '../../index_patterns_fetcher';
@ -36,17 +36,13 @@ import { FieldDescriptor } from '../../index_patterns_fetcher';
* @return {Promise<Array<FieldDescriptor>>}
*/
export async function getFieldCapabilities(
callCluster: LegacyAPICaller,
callCluster: ElasticsearchClient,
indices: string | string[] = [],
metaFields: string[] = [],
fieldCapsOptions?: { allowNoIndices: boolean }
fieldCapsOptions?: { allow_no_indices: boolean }
) {
const esFieldCaps: FieldCapsResponse = await callFieldCapsApi(
callCluster,
indices,
fieldCapsOptions
);
const fieldsFromFieldCapsByName = keyBy(readFieldCapsResponse(esFieldCaps), 'name');
const esFieldCaps = await callFieldCapsApi(callCluster, indices, fieldCapsOptions);
const fieldsFromFieldCapsByName = keyBy(readFieldCapsResponse(esFieldCaps.body), 'name');
const allFieldsUnsorted = Object.keys(fieldsFromFieldCapsByName)
.filter((name) => !name.startsWith('_'))

View file

@ -32,6 +32,11 @@ const TIME_PATTERN = '[logs-]dddd-YYYY.w';
describe('server/index_patterns/service/lib/resolve_time_pattern', () => {
let sandbox;
const esClientMock = {
indices: {
getAlias: () => ({}),
},
};
beforeEach(() => (sandbox = sinon.createSandbox()));
afterEach(() => sandbox.restore());
@ -39,7 +44,7 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => {
describe('pre request', () => {
it('uses callIndexAliasApi() fn', async () => {
sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({});
await resolveTimePattern(noop, TIME_PATTERN);
await resolveTimePattern(esClientMock, TIME_PATTERN);
sinon.assert.calledOnce(callIndexAliasApi);
});
@ -49,7 +54,7 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => {
sandbox.stub(timePatternToWildcardNS, 'timePatternToWildcard').returns(wildcard);
await resolveTimePattern(noop, timePattern);
await resolveTimePattern(esClientMock, timePattern);
sinon.assert.calledOnce(timePatternToWildcard);
expect(timePatternToWildcard.firstCall.args).toEqual([timePattern]);
});
@ -61,7 +66,7 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => {
sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({});
sandbox.stub(timePatternToWildcardNS, 'timePatternToWildcard').returns(wildcard);
await resolveTimePattern(noop, timePattern);
await resolveTimePattern(esClientMock, timePattern);
sinon.assert.calledOnce(callIndexAliasApi);
expect(callIndexAliasApi.firstCall.args[1]).toBe(wildcard);
});
@ -70,13 +75,15 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => {
describe('read response', () => {
it('returns all aliases names in result.all, ordered by time desc', async () => {
sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({
'logs-2016.2': {},
'logs-Saturday-2017.1': {},
'logs-2016.1': {},
'logs-Sunday-2017.1': {},
'logs-2015': {},
'logs-2016.3': {},
'logs-Friday-2017.1': {},
body: {
'logs-2016.2': {},
'logs-Saturday-2017.1': {},
'logs-2016.1': {},
'logs-Sunday-2017.1': {},
'logs-2015': {},
'logs-2016.3': {},
'logs-Friday-2017.1': {},
},
});
const resp = await resolveTimePattern(noop, TIME_PATTERN);
@ -94,13 +101,15 @@ describe('server/index_patterns/service/lib/resolve_time_pattern', () => {
it('returns all indices matching the time pattern in matches, ordered by time desc', async () => {
sandbox.stub(callIndexAliasApiNS, 'callIndexAliasApi').returns({
'logs-2016.2': {},
'logs-Saturday-2017.1': {},
'logs-2016.1': {},
'logs-Sunday-2017.1': {},
'logs-2015': {},
'logs-2016.3': {},
'logs-Friday-2017.1': {},
body: {
'logs-2016.2': {},
'logs-Saturday-2017.1': {},
'logs-2016.1': {},
'logs-Sunday-2017.1': {},
'logs-2015': {},
'logs-2016.3': {},
'logs-Friday-2017.1': {},
},
});
const resp = await resolveTimePattern(noop, TIME_PATTERN);

View file

@ -20,7 +20,7 @@
import { chain } from 'lodash';
import moment from 'moment';
import { LegacyAPICaller } from 'kibana/server';
import { ElasticsearchClient } from 'kibana/server';
import { timePatternToWildcard } from './time_pattern_to_wildcard';
import { callIndexAliasApi, IndicesAliasResponse } from './es_api';
@ -36,10 +36,10 @@ import { callIndexAliasApi, IndicesAliasResponse } from './es_api';
* and the indices that actually match the time
* pattern (matches);
*/
export async function resolveTimePattern(callCluster: LegacyAPICaller, timePattern: string) {
export async function resolveTimePattern(callCluster: ElasticsearchClient, timePattern: string) {
const aliases = await callIndexAliasApi(callCluster, timePatternToWildcard(timePattern));
const allIndexDetails = chain<IndicesAliasResponse>(aliases)
const allIndexDetails = chain<IndicesAliasResponse>(aliases.body)
.reduce(
(acc: string[], index: any, indexName: string) =>
acc.concat(indexName, Object.keys(index.aliases || {})),

View file

@ -46,8 +46,8 @@ export function registerRoutes(http: HttpServiceSetup) {
},
},
async (context, request, response) => {
const { callAsCurrentUser } = context.core.elasticsearch.legacy.client;
const indexPatterns = new IndexPatternsFetcher(callAsCurrentUser);
const { asCurrentUser } = context.core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser);
const { pattern, meta_fields: metaFields } = request.query;
let parsedFields: string[] = [];
@ -105,8 +105,8 @@ export function registerRoutes(http: HttpServiceSetup) {
},
},
async (context: RequestHandlerContext, request: any, response: any) => {
const { callAsCurrentUser } = context.core.elasticsearch.legacy.client;
const indexPatterns = new IndexPatternsFetcher(callAsCurrentUser);
const { asCurrentUser } = context.core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser);
const { pattern, interval, look_back: lookBack, meta_fields: metaFields } = request.query;
let parsedFields: string[] = [];

View file

@ -663,7 +663,7 @@ export const indexPatterns: {
//
// @public (undocumented)
export class IndexPatternsFetcher {
constructor(callDataCluster: LegacyAPICaller);
constructor(elasticsearchClient: ElasticsearchClient, allowNoIndices?: boolean);
getFieldsForTimePattern(options: {
pattern: string;
metaFields: string[];
@ -674,7 +674,7 @@ export class IndexPatternsFetcher {
pattern: string | string[];
metaFields?: string[];
fieldCapsOptions?: {
allowNoIndices: boolean;
allow_no_indices: boolean;
};
}): Promise<FieldDescriptor[]>;
}

View file

@ -45,7 +45,7 @@ export async function getFields(
payload: {},
pre: {
indexPatternsService: new IndexPatternsFetcher(
requestContext.core.elasticsearch.legacy.client.callAsCurrentUser
requestContext.core.elasticsearch.client.asCurrentUser
),
},
getUiSettingsService: () => requestContext.core.uiSettings.client,

View file

@ -50,7 +50,7 @@ describe('AbstractSearchStrategy', () => {
expect(fields).toBe(mockedFields);
expect(req.pre.indexPatternsService.getFieldsForWildcard).toHaveBeenCalledWith({
pattern: indexPattern,
fieldCapsOptions: { allowNoIndices: true },
fieldCapsOptions: { allow_no_indices: true },
});
});

View file

@ -86,7 +86,7 @@ export class AbstractSearchStrategy {
return await indexPatternsService!.getFieldsForWildcard({
pattern: indexPattern,
fieldCapsOptions: { allowNoIndices: true },
fieldCapsOptions: { allow_no_indices: true },
});
}

View file

@ -5,7 +5,6 @@
*/
import LRU from 'lru-cache';
import { LegacyAPICaller } from '../../../../../../src/core/server';
import {
IndexPatternsFetcher,
FieldDescriptor,
@ -45,8 +44,7 @@ export const getDynamicIndexPattern = async ({
}
const indexPatternsFetcher = new IndexPatternsFetcher(
(...rest: Parameters<LegacyAPICaller>) =>
context.core.elasticsearch.legacy.client.callAsCurrentUser(...rest)
context.core.elasticsearch.client.asCurrentUser
);
// Since `getDynamicIndexPattern` is called in setup_request (and thus by every endpoint)

View file

@ -26,7 +26,6 @@ import {
RequestHandlerContext,
KibanaResponseFactory,
RouteMethod,
LegacyAPICaller,
} from '../../../../../../../src/core/server';
import { RequestHandler } from '../../../../../../../src/core/server';
import { InfraConfig } from '../../../plugin';
@ -218,11 +217,7 @@ export class KibanaFramework {
}
public getIndexPatternsService(requestContext: RequestHandlerContext): IndexPatternsFetcher {
return new IndexPatternsFetcher((...rest: Parameters<LegacyAPICaller>) => {
rest[1] = rest[1] || {};
rest[1].allowNoIndices = true;
return requestContext.core.elasticsearch.legacy.client.callAsCurrentUser(...rest);
});
return new IndexPatternsFetcher(requestContext.core.elasticsearch.client.asCurrentUser, true);
}
public getSpaceId(request: KibanaRequest): string {

View file

@ -8,6 +8,7 @@ import { keyBy } from 'lodash';
import { schema } from '@kbn/config-schema';
import { Field } from '../../../lib/merge_capabilities_with_fields';
import { RouteDependencies } from '../../../types';
import type { IndexPatternsFetcher as IndexPatternsFetcherType } from '../../../../../../../src/plugins/data/server';
const parseMetaFields = (metaFields: string | string[]) => {
let parsedFields: string[] = [];
@ -23,10 +24,10 @@ const getFieldsForWildcardRequest = async (
context: any,
request: any,
response: any,
IndexPatternsFetcher: any
IndexPatternsFetcher: typeof IndexPatternsFetcherType
) => {
const { callAsCurrentUser } = context.core.elasticsearch.legacy.client;
const indexPatterns = new IndexPatternsFetcher(callAsCurrentUser);
const { asCurrentUser } = context.core.elasticsearch.client;
const indexPatterns = new IndexPatternsFetcher(asCurrentUser);
const { pattern, meta_fields: metaFields } = request.query;
let parsedFields: string[] = [];

View file

@ -149,14 +149,7 @@ export class KibanaBackendFrameworkAdapter implements FrameworkAdapter {
}
public getIndexPatternsService(request: FrameworkRequest): FrameworkIndexPatternsService {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const callCluster = async (endpoint: string, params?: Record<string, any>) =>
this.callWithRequest(request, endpoint, {
...params,
allowNoIndices: true,
});
return new IndexPatternsFetcher(callCluster);
return new IndexPatternsFetcher(request.context.core.elasticsearch.client.asCurrentUser, true);
}
}

View file

@ -30,9 +30,7 @@ export const securitySolutionIndexFieldsProvider = (): ISearchStrategy<
from(
new Promise<IndexFieldsStrategyResponse>(async (resolve) => {
const { elasticsearch } = context.core;
const indexPatternsFetcher = new IndexPatternsFetcher(
elasticsearch.legacy.client.callAsCurrentUser
);
const indexPatternsFetcher = new IndexPatternsFetcher(elasticsearch.client.asCurrentUser);
const dedupeIndices = dedupeIndexName(request.indices);
const responsesIndexFields = await Promise.all(

View file

@ -7,6 +7,7 @@
import { schema } from '@kbn/config-schema';
import { i18n } from '@kbn/i18n';
import Mustache from 'mustache';
import { ElasticsearchClient } from 'kibana/server';
import { UptimeAlertTypeFactory } from './types';
import { esKuery } from '../../../../../../src/plugins/data/server';
import { JsonObject } from '../../../../../../src/plugins/kibana_utils/common';
@ -81,6 +82,7 @@ export const generateFilterDSL = async (
export const formatFilterString = async (
dynamicSettings: DynamicSettings,
callES: ESAPICaller,
esClient: ElasticsearchClient,
filters: StatusCheckFilters,
search: string,
libs?: UMServerLibs
@ -88,9 +90,10 @@ export const formatFilterString = async (
await generateFilterDSL(
() =>
libs?.requests?.getIndexPattern
? libs?.requests?.getIndexPattern({ callES, dynamicSettings })
? libs?.requests?.getIndexPattern({ callES, esClient, dynamicSettings })
: getUptimeIndexPattern({
callES,
esClient,
dynamicSettings,
}),
filters,
@ -237,6 +240,7 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) =
async executor(
{ params: rawParams, state, services: { alertInstanceFactory } },
callES,
esClient,
dynamicSettings
) {
const {
@ -252,7 +256,14 @@ export const statusCheckAlertFactory: UptimeAlertTypeFactory = (_server, libs) =
timerange: oldVersionTimeRange,
} = rawParams;
const filterString = await formatFilterString(dynamicSettings, callES, filters, search, libs);
const filterString = await formatFilterString(
dynamicSettings,
callES,
esClient,
filters,
search,
libs
);
const timerange = oldVersionTimeRange || {
from: isAutoGenerated

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ILegacyScopedClusterClient } from 'kibana/server';
import { ILegacyScopedClusterClient, ElasticsearchClient } from 'kibana/server';
import { AlertExecutorOptions, AlertType, AlertTypeState } from '../../../../alerts/server';
import { savedObjectsAdapter } from '../saved_objects';
import { DynamicSettings } from '../../../common/runtime_types';
@ -13,6 +13,7 @@ export interface UptimeAlertType extends Omit<AlertType, 'executor' | 'producer'
executor: (
options: AlertExecutorOptions,
callES: ILegacyScopedClusterClient['callAsCurrentUser'],
esClient: ElasticsearchClient,
dynamicSettings: DynamicSettings
) => Promise<AlertTypeState | void>;
}
@ -22,13 +23,13 @@ export const uptimeAlertWrapper = (uptimeAlert: UptimeAlertType) => ({
producer: 'uptime',
executor: async (options: AlertExecutorOptions) => {
const {
services: { callCluster: callES },
services: { callCluster: callES, scopedClusterClient },
} = options;
const dynamicSettings = await savedObjectsAdapter.getUptimeDynamicSettings(
options.services.savedObjectsClient
);
return uptimeAlert.executor(options, callES, dynamicSettings);
return uptimeAlert.executor(options, callES, scopedClusterClient, dynamicSettings);
},
});

View file

@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { LegacyAPICaller, LegacyCallAPIOptions } from 'src/core/server';
import { ElasticsearchClient } from 'kibana/server';
import { UMElasticsearchQueryFn } from '../adapters';
import { IndexPatternsFetcher, FieldDescriptor } from '../../../../../../src/plugins/data/server';
@ -14,15 +14,10 @@ export interface IndexPatternTitleAndFields {
}
export const getUptimeIndexPattern: UMElasticsearchQueryFn<
{},
{ esClient: ElasticsearchClient },
IndexPatternTitleAndFields | undefined
> = async ({ callES, dynamicSettings }) => {
const callAsCurrentUser: LegacyAPICaller = async (
endpoint: string,
clientParams: Record<string, any> = {},
options?: LegacyCallAPIOptions
) => callES(endpoint, clientParams, options);
const indexPatternsFetcher = new IndexPatternsFetcher(callAsCurrentUser);
> = async ({ esClient, dynamicSettings }) => {
const indexPatternsFetcher = new IndexPatternsFetcher(esClient);
// Since `getDynamicIndexPattern` is called in setup_request (and thus by every endpoint)
// and since `getFieldsForWildcard` will throw if the specified indices don't exist,

View file

@ -4,6 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/
import { ElasticsearchClient } from 'kibana/server';
import { ESAPICaller, UMElasticsearchQueryFn } from '../adapters';
import { MonitorDetails, MonitorError } from '../../../common/runtime_types';
import { formatFilterString } from '../alerts/status_check';
@ -13,10 +14,12 @@ export interface GetMonitorDetailsParams {
dateStart: string;
dateEnd: string;
alertsClient: any;
esClient: ElasticsearchClient;
}
const getMonitorAlerts = async (
callES: ESAPICaller,
esClient: ElasticsearchClient,
dynamicSettings: any,
alertsClient: any,
monitorId: string
@ -67,6 +70,7 @@ const getMonitorAlerts = async (
const parsedFilters = await formatFilterString(
dynamicSettings,
callES,
esClient,
currAlert.params.filters,
currAlert.params.search
);
@ -84,7 +88,7 @@ const getMonitorAlerts = async (
export const getMonitorDetails: UMElasticsearchQueryFn<
GetMonitorDetailsParams,
MonitorDetails
> = async ({ callES, dynamicSettings, monitorId, dateStart, dateEnd, alertsClient }) => {
> = async ({ callES, esClient, dynamicSettings, monitorId, dateStart, dateEnd, alertsClient }) => {
const queryFilters: any = [
{
range: {
@ -134,7 +138,13 @@ export const getMonitorDetails: UMElasticsearchQueryFn<
const monitorError: MonitorError | undefined = data?.error;
const errorTimestamp: string | undefined = data?.['@timestamp'];
const monAlerts = await getMonitorAlerts(callES, dynamicSettings, alertsClient, monitorId);
const monAlerts = await getMonitorAlerts(
callES,
esClient,
dynamicSettings,
alertsClient,
monitorId
);
return {
monitorId,
error: monitorError,

View file

@ -16,7 +16,11 @@ export const createGetIndexPatternRoute: UMRestApiRouteFactory = (libs: UMServer
try {
return response.ok({
body: {
...(await libs.requests.getIndexPattern({ callES, dynamicSettings })),
...(await libs.requests.getIndexPattern({
callES,
esClient: _context.core.elasticsearch.client.asCurrentUser,
dynamicSettings,
})),
},
});
} catch (e) {

View file

@ -28,6 +28,7 @@ export const createGetMonitorDetailsRoute: UMRestApiRouteFactory = (libs: UMServ
body: {
...(await libs.requests.getMonitorDetails({
callES,
esClient: context.core.elasticsearch.client.asCurrentUser,
dynamicSettings,
monitorId,
dateStart,