mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
# Backport This will backport the following commits from `main` to `8.17`: - [[Search] Don't error out on missing connectors permissions (#212622)](https://github.com/elastic/kibana/pull/212622) <!--- Backport version: 9.6.6 --> ### Questions ? Please refer to the [Backport tool documentation](https://github.com/sorenlouv/backport) <!--BACKPORT [{"author":{"name":"Sander Philipse","email":"94373878+sphilipse@users.noreply.github.com"},"sourceCommit":{"committedDate":"2025-02-28T12:36:37Z","message":"[Search] Don't error out on missing connectors permissions (#212622)\n\n## Summary\n\nThis stops errors on missing connectors permissions when fetching\nindices, which was preventing users without connectors permissions but\nwith listing and write permissions to indices generally from seeing\nindices in the Search UI.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"7590205f9a9dd79c8a204eb75b69782503d30937","branchLabelMapping":{"^v9.1.0$":"main","^v8.19.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","v9.0.0","Team:Search","backport:version","v8.18.0","v9.1.0","v8.19.0","v8.17.3"],"title":"[Search] Don't error out on missing connectors permissions","number":212622,"url":"https://github.com/elastic/kibana/pull/212622","mergeCommit":{"message":"[Search] Don't error out on missing connectors permissions (#212622)\n\n## Summary\n\nThis stops errors on missing connectors permissions when fetching\nindices, which was preventing users without connectors permissions but\nwith listing and write permissions to indices generally from seeing\nindices in the Search UI.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"7590205f9a9dd79c8a204eb75b69782503d30937"}},"sourceBranch":"main","suggestedTargetBranches":["8.18","8.x","8.17"],"targetPullRequestStates":[{"branch":"9.0","label":"v9.0.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"url":"https://github.com/elastic/kibana/pull/212763","number":212763,"state":"MERGED","mergeCommit":{"sha":"e32f93a3f59c104f0f658ba4d5a7fc6431cb5096","message":"[9.0] [Search] Don't error out on missing connectors permissions (#212622) (#212763)\n\n# Backport\n\nThis will backport the following commits from `main` to `9.0`:\n- [[Search] Don't error out on missing connectors permissions\n(#212622)](https://github.com/elastic/kibana/pull/212622)\n\n\n\n### Questions ?\nPlease refer to the [Backport tool\ndocumentation](https://github.com/sorenlouv/backport)\n\n\n\nCo-authored-by: Sander Philipse <94373878+sphilipse@users.noreply.github.com>"}},{"branch":"8.18","label":"v8.18.0","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"main","label":"v9.1.0","branchLabelMappingKey":"^v9.1.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/212622","number":212622,"mergeCommit":{"message":"[Search] Don't error out on missing connectors permissions (#212622)\n\n## Summary\n\nThis stops errors on missing connectors permissions when fetching\nindices, which was preventing users without connectors permissions but\nwith listing and write permissions to indices generally from seeing\nindices in the Search UI.\n\n---------\n\nCo-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>","sha":"7590205f9a9dd79c8a204eb75b69782503d30937"}},{"branch":"8.x","label":"v8.19.0","branchLabelMappingKey":"^v8.19.0$","isSourceBranch":false,"state":"NOT_CREATED"},{"branch":"8.17","label":"v8.17.3","branchLabelMappingKey":"^v(\\d+).(\\d+).\\d+$","isSourceBranch":false,"state":"NOT_CREATED"}]}] BACKPORT--> --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
79d1c6029b
commit
448cc588d8
5 changed files with 66 additions and 29 deletions
|
@ -6,7 +6,7 @@
|
|||
*/
|
||||
|
||||
import { ByteSizeValue } from '@kbn/config-schema';
|
||||
import { IScopedClusterClient } from '@kbn/core/server';
|
||||
import { IScopedClusterClient, Logger } from '@kbn/core/server';
|
||||
|
||||
import { fetchConnectorByIndexName } from '@kbn/search-connectors';
|
||||
|
||||
|
@ -55,6 +55,10 @@ describe('fetchIndex lib function', () => {
|
|||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
const logger = {
|
||||
error: jest.fn(),
|
||||
} as any as Logger;
|
||||
|
||||
const statsResponse = {
|
||||
indices: {
|
||||
index_name: {
|
||||
|
@ -110,7 +114,7 @@ describe('fetchIndex lib function', () => {
|
|||
mockClient.asCurrentUser.indices.stats.mockImplementation(() => Promise.resolve(statsResponse));
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).resolves.toEqual(result);
|
||||
});
|
||||
|
||||
|
@ -134,7 +138,7 @@ describe('fetchIndex lib function', () => {
|
|||
mockClient.asCurrentUser.indices.stats.mockImplementation(() => Promise.resolve(statsResponse));
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).resolves.toEqual({
|
||||
...result,
|
||||
connector: { doc: 'doc', service_type: 'some-service-type' },
|
||||
|
@ -159,7 +163,7 @@ describe('fetchIndex lib function', () => {
|
|||
mockClient.asCurrentUser.indices.stats.mockImplementation(() => Promise.resolve(statsResponse));
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).resolves.toEqual({
|
||||
...result,
|
||||
crawler: {
|
||||
|
@ -194,7 +198,7 @@ describe('fetchIndex lib function', () => {
|
|||
mockClient.asCurrentUser.indices.stats.mockImplementation(() => Promise.resolve(statsResponse));
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).resolves.toEqual({
|
||||
...result,
|
||||
connector: { doc: 'doc', service_type: ENTERPRISE_SEARCH_CONNECTOR_CRAWLER_SERVICE_TYPE },
|
||||
|
@ -213,7 +217,7 @@ describe('fetchIndex lib function', () => {
|
|||
mockClient.asCurrentUser.indices.stats.mockImplementation(() => Promise.resolve(statsResponse));
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).rejects.toEqual(new Error('404'));
|
||||
});
|
||||
it('should throw a 404 error if the indexStats cannot be fonud', async () => {
|
||||
|
@ -230,7 +234,7 @@ describe('fetchIndex lib function', () => {
|
|||
);
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).rejects.toEqual(new Error('404'));
|
||||
});
|
||||
it('should throw a 404 error if the index stats indices cannot be fonud', async () => {
|
||||
|
@ -245,7 +249,7 @@ describe('fetchIndex lib function', () => {
|
|||
mockClient.asCurrentUser.indices.stats.mockImplementation(() => Promise.resolve({}));
|
||||
|
||||
await expect(
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name')
|
||||
fetchIndex(mockClient as unknown as IScopedClusterClient, 'index_name', logger)
|
||||
).rejects.toEqual(new Error('404'));
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,11 +5,10 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { IScopedClusterClient } from '@kbn/core/server';
|
||||
|
||||
import {} from '../..';
|
||||
import { IScopedClusterClient, Logger } from '@kbn/core/server';
|
||||
|
||||
import {
|
||||
Connector,
|
||||
CONNECTORS_JOBS_INDEX,
|
||||
ConnectorSyncJobDocument,
|
||||
fetchConnectorByIndexName,
|
||||
|
@ -61,7 +60,8 @@ const hasInProgressSyncs = async (
|
|||
|
||||
export const fetchIndex = async (
|
||||
client: IScopedClusterClient,
|
||||
index: string
|
||||
index: string,
|
||||
logger: Logger
|
||||
): Promise<ElasticsearchIndexWithIngestion> => {
|
||||
const indexDataResult = await client.asCurrentUser.indices.get({ index });
|
||||
const indexData = indexDataResult[index];
|
||||
|
@ -73,8 +73,12 @@ export const fetchIndex = async (
|
|||
throw new Error('404');
|
||||
}
|
||||
const indexStats = indices[index];
|
||||
|
||||
const connector = await fetchConnectorByIndexName(client.asCurrentUser, index);
|
||||
let connector: Connector | undefined;
|
||||
try {
|
||||
connector = await fetchConnectorByIndexName(client.asCurrentUser, index);
|
||||
} catch (error) {
|
||||
logger.error(`Error fetching connector for index ${index}: ${error}`);
|
||||
}
|
||||
const hasInProgressSyncsResult = connector
|
||||
? await hasInProgressSyncs(client, connector.id)
|
||||
: { inProgress: false, pending: false };
|
||||
|
|
|
@ -6,8 +6,9 @@
|
|||
*/
|
||||
|
||||
import { IScopedClusterClient } from '@kbn/core/server';
|
||||
import { fetchConnectors } from '@kbn/search-connectors';
|
||||
import { Connector, fetchConnectors } from '@kbn/search-connectors';
|
||||
|
||||
import { Crawler } from '../../../common/types/crawler';
|
||||
import { isNotNullish } from '../../../common/utils/is_not_nullish';
|
||||
import { fetchCrawlers } from '../crawler/fetch_crawlers';
|
||||
|
||||
|
@ -23,8 +24,15 @@ export const fetchUnattachedIndices = async (
|
|||
totalResults: number;
|
||||
}> => {
|
||||
const { indexNames } = await getUnattachedIndexData(client, searchQuery);
|
||||
const connectors = await fetchConnectors(client.asCurrentUser, indexNames);
|
||||
const crawlers = await fetchCrawlers(client, indexNames);
|
||||
|
||||
let connectors: Connector[] = [];
|
||||
let crawlers: Crawler[] = [];
|
||||
try {
|
||||
connectors = await fetchConnectors(client.asCurrentUser, indexNames);
|
||||
crawlers = await fetchCrawlers(client, indexNames);
|
||||
} catch (error) {
|
||||
connectors = [];
|
||||
}
|
||||
|
||||
const connectedIndexNames = [
|
||||
...connectors.map((con) => con.index_name).filter(isNotNullish),
|
||||
|
|
|
@ -18,7 +18,7 @@ export const getIndexPipelineParameters = async (
|
|||
// we want to throw the error if getDefaultPipeline() fails so we're not catching it on purpose
|
||||
const [defaultPipeline, connector, customPipelineResp] = await Promise.all([
|
||||
getDefaultPipeline(client),
|
||||
fetchConnectorByIndexName(client.asCurrentUser, indexName),
|
||||
fetchConnectorByIndexName(client.asCurrentUser, indexName).catch(() => null),
|
||||
client.asCurrentUser.ingest
|
||||
.getPipeline({
|
||||
id: `${indexName}`,
|
||||
|
|
|
@ -19,6 +19,7 @@ import {
|
|||
deleteConnectorSecret,
|
||||
deleteConnectorById,
|
||||
updateConnectorIndexName,
|
||||
Connector,
|
||||
} from '@kbn/search-connectors';
|
||||
import {
|
||||
fetchConnectorByIndexName,
|
||||
|
@ -26,6 +27,7 @@ import {
|
|||
} from '@kbn/search-connectors/lib/fetch_connectors';
|
||||
|
||||
import { DEFAULT_PIPELINE_NAME } from '../../../common/constants';
|
||||
import { Crawler } from '../../../common/types/crawler';
|
||||
import { ErrorCode } from '../../../common/types/error_codes';
|
||||
import { AlwaysShowPattern } from '../../../common/types/indices';
|
||||
|
||||
|
@ -126,8 +128,17 @@ export function registerIndexRoutes({
|
|||
from,
|
||||
size
|
||||
);
|
||||
const connectors = await fetchConnectors(client.asCurrentUser, indexNames);
|
||||
const crawlers = await fetchCrawlers(client, indexNames);
|
||||
|
||||
let connectors: Connector[] = [];
|
||||
let crawlers: Crawler[] = [];
|
||||
// If the user doesn't have permissions, fetchConnectors will error out. We still want to return indices in that case.
|
||||
try {
|
||||
connectors = await fetchConnectors(client.asCurrentUser, indexNames);
|
||||
crawlers = await fetchCrawlers(client, indexNames);
|
||||
} catch {
|
||||
connectors = [];
|
||||
crawlers = [];
|
||||
}
|
||||
const enrichedIndices = indices.map((index) => ({
|
||||
...index,
|
||||
connector: connectors.find((connector) => connector.index_name === index.name),
|
||||
|
@ -164,7 +175,7 @@ export function registerIndexRoutes({
|
|||
const { client } = (await context.core).elasticsearch;
|
||||
|
||||
try {
|
||||
const index = await fetchIndex(client, indexName);
|
||||
const index = await fetchIndex(client, indexName, log);
|
||||
return response.ok({
|
||||
body: index,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
|
@ -198,8 +209,15 @@ export function registerIndexRoutes({
|
|||
const { client } = (await context.core).elasticsearch;
|
||||
|
||||
try {
|
||||
const crawler = await fetchCrawlerByIndexName(client, indexName);
|
||||
const connector = await fetchConnectorByIndexName(client.asCurrentUser, indexName);
|
||||
let connector: Connector | undefined;
|
||||
let crawler: Crawler | undefined;
|
||||
// users without permissions to fetch connectors should still see a result
|
||||
try {
|
||||
connector = await fetchConnectorByIndexName(client.asCurrentUser, indexName);
|
||||
crawler = await fetchCrawlerByIndexName(client, indexName);
|
||||
} catch (error) {
|
||||
log.error(`Error fetching connector for index ${indexName}: ${error}`);
|
||||
}
|
||||
|
||||
if (crawler) {
|
||||
const crawlerRes = await enterpriseSearchRequestHandler.createRequest({
|
||||
|
@ -588,7 +606,15 @@ export function registerIndexRoutes({
|
|||
});
|
||||
}
|
||||
|
||||
const crawler = await fetchCrawlerByIndexName(client, request.body.index_name);
|
||||
let connector: Connector | undefined;
|
||||
let crawler: Crawler | undefined;
|
||||
// users without permissions to fetch connectors should still be able to create an index
|
||||
try {
|
||||
connector = await fetchConnectorByIndexName(client.asCurrentUser, indexName);
|
||||
crawler = await fetchCrawlerByIndexName(client, request.body.index_name);
|
||||
} catch (error) {
|
||||
log.error(`Error fetching connector for index ${indexName}: ${error}`);
|
||||
}
|
||||
|
||||
if (crawler) {
|
||||
return createError({
|
||||
|
@ -604,11 +630,6 @@ export function registerIndexRoutes({
|
|||
});
|
||||
}
|
||||
|
||||
const connector = await fetchConnectorByIndexName(
|
||||
client.asCurrentUser,
|
||||
request.body.index_name
|
||||
);
|
||||
|
||||
if (connector) {
|
||||
return createError({
|
||||
errorCode: ErrorCode.CONNECTOR_DOCUMENT_ALREADY_EXISTS,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue