[Obs AI Assistant] Use internal user when fetching connectors (#190462)

Closes https://github.com/elastic/kibana/issues/187921

The Obs AI Assistant calls the endpoint `GET _connector` to get a list
of connector indices. This works for admin users but not for users with
limited privileges like users with the `editor` role.

Currently an error is thrown but never caught. This causes the kibana
server to crash during development. In prod this problem means that
users cannot retrieve connector indices, and thus fallback to querying
`search-*`.

This PR fixes it by using the internal user to call `GET _connector`. 


Additional context:
https://elastic.slack.com/archives/C05J7LXR5DE/p1723560268104559
This commit is contained in:
Søren Louv-Jansen 2024-08-14 08:10:48 +02:00 committed by GitHub
parent a429807170
commit be26e46116
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 26 additions and 14 deletions

View file

@ -389,7 +389,7 @@ export class KnowledgeBaseService {
categories?: string[];
user?: { name: string };
namespace: string;
esClient: { asCurrentUser: ElasticsearchClient };
esClient: { asCurrentUser: ElasticsearchClient; asInternalUser: ElasticsearchClient };
uiSettingsClient: IUiSettingsClient;
}): Promise<{
entries: RecalledEntry[];
@ -417,6 +417,7 @@ export class KnowledgeBaseService {
uiSettingsClient,
queries,
modelId,
logger: this.dependencies.logger,
}).catch((error) => {
this.dependencies.logger.debug('Error getting data from search indices');
this.dependencies.logger.debug(error);

View file

@ -8,6 +8,7 @@
import { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { IUiSettingsClient } from '@kbn/core-ui-settings-server';
import { isEmpty } from 'lodash';
import type { Logger } from '@kbn/logging';
import { RecalledEntry } from '.';
import { aiAssistantSearchConnectorIndexPattern } from '../../../common';
@ -16,15 +17,17 @@ export async function recallFromConnectors({
esClient,
uiSettingsClient,
modelId,
logger,
}: {
queries: Array<{ text: string; boost?: number }>;
esClient: { asCurrentUser: ElasticsearchClient };
esClient: { asCurrentUser: ElasticsearchClient; asInternalUser: ElasticsearchClient };
uiSettingsClient: IUiSettingsClient;
modelId: string;
logger: Logger;
}): Promise<RecalledEntry[]> {
const ML_INFERENCE_PREFIX = 'ml.inference.';
const connectorIndices = await getConnectorIndices(esClient, uiSettingsClient);
const connectorIndices = await getConnectorIndices(esClient, uiSettingsClient, logger);
logger.debug(`Found connector indices: ${connectorIndices}`);
const fieldCaps = await esClient.asCurrentUser.fieldCaps({
index: connectorIndices,
@ -96,17 +99,25 @@ export async function recallFromConnectors({
}
async function getConnectorIndices(
esClient: { asCurrentUser: ElasticsearchClient },
uiSettingsClient: IUiSettingsClient
esClient: { asCurrentUser: ElasticsearchClient; asInternalUser: ElasticsearchClient },
uiSettingsClient: IUiSettingsClient,
logger: Logger
) {
// improve performance by running this in parallel with the `uiSettingsClient` request
const responsePromise = esClient.asCurrentUser.transport.request({
method: 'GET',
path: '_connector',
querystring: {
filter_path: 'results.index_name',
},
});
const responsePromise = esClient.asInternalUser.transport
.request<{
results?: Array<{ index_name: string }>;
}>({
method: 'GET',
path: '_connector',
querystring: {
filter_path: 'results.index_name',
},
})
.catch((e) => {
logger.warn(`Failed to fetch connector indices due to ${e.message}`);
return { results: [] };
});
const customSearchConnectorIndex = await uiSettingsClient.get<string>(
aiAssistantSearchConnectorIndexPattern
@ -116,7 +127,7 @@ async function getConnectorIndices(
return customSearchConnectorIndex.split(',');
}
const response = (await responsePromise) as { results?: Array<{ index_name: string }> };
const response = await responsePromise;
const connectorIndices = response.results?.map((result) => result.index_name);
// preserve backwards compatibility with 8.14 (may not be needed in the future)