mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
[Search] Remove calls to enterprise search config (#206971)
## Summary Updated the search plugin config endpoint to return just features and kibana version, removing the call to the enterprise search node. ### Checklist - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] [Flaky Test Runner](https://ci-stats.kibana.dev/trigger_flaky_test_runner/1) was used on any tests changed --------- Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
a6e476967e
commit
a774033bf2
28 changed files with 91 additions and 928 deletions
|
@ -25,7 +25,7 @@ export default function ({ getService }: FtrProviderContext) {
|
|||
|
||||
expect(resp.body).to.be.an('array');
|
||||
|
||||
expect(resp.body.length).to.be(21);
|
||||
expect(resp.body.length).to.be(20);
|
||||
|
||||
// Test for sample data card
|
||||
expect(resp.body.findIndex((c: { id: string }) => c.id === 'sample_data_all')).to.be.above(
|
||||
|
|
|
@ -18,7 +18,7 @@ export default function testGetGuideConfig({ getService }: FtrProviderContext) {
|
|||
|
||||
describe(`GET ${getConfigsPath}`, () => {
|
||||
// check that production guides are present
|
||||
['siem', 'websiteSearch', 'databaseSearch', 'kubernetes'].map((guideId) => {
|
||||
['siem', 'databaseSearch', 'kubernetes'].map((guideId) => {
|
||||
it(`returns config for ${guideId}`, async () => {
|
||||
const response = await supertest
|
||||
.get(`${getConfigsPath}/${guideId}`)
|
||||
|
@ -29,5 +29,16 @@ export default function testGetGuideConfig({ getService }: FtrProviderContext) {
|
|||
expect(config).to.not.be.empty();
|
||||
});
|
||||
});
|
||||
|
||||
// expecting websiteSearch to be disabled for now, but adding this test to ensure
|
||||
// it's added back to the above list when support for web crawlers is added back.
|
||||
['websiteSearch'].map((guideId) => {
|
||||
it(`does not returns config for ${guideId}`, async () => {
|
||||
await supertest
|
||||
.get(`${getConfigsPath}/${guideId}`)
|
||||
.set(X_ELASTIC_INTERNAL_ORIGIN_REQUEST, 'kibana')
|
||||
.expect(404);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -17572,7 +17572,6 @@
|
|||
"xpack.enterpriseSearch.server.routes.addCrawler.crawlerExistsError": "Un robot d'indexation existe déjà pour cet index",
|
||||
"xpack.enterpriseSearch.server.routes.addCrawler.indexExistsError": "L'index existe déjà.",
|
||||
"xpack.enterpriseSearch.server.routes.checkKibanaLogsMessage": "{errorMessage} Vérifiez les logs du serveur Kibana pour plus de détails.",
|
||||
"xpack.enterpriseSearch.server.routes.configData.errorMessage": "Erreur lors de la récupération des données à partir d'Enterprise Search",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.expensive_query_not_allowed_error": "Les requêtes de recherche lourdes ne sont pas autorisées. \"recherche.autoriser_recherches_lourdes\" est défini comme faux",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.generateConfiguration.indexAlreadyExistsError": "Impossible de trouver un nom de connecteur unique",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.resource_not_found_error": "Le connecteur avec l'ID {connectorId} est introuvable.",
|
||||
|
|
|
@ -17430,7 +17430,6 @@
|
|||
"xpack.enterpriseSearch.server.routes.addCrawler.crawlerExistsError": "このインデックスのクローラーはすでに存在します",
|
||||
"xpack.enterpriseSearch.server.routes.addCrawler.indexExistsError": "このインデックスはすでに存在します",
|
||||
"xpack.enterpriseSearch.server.routes.checkKibanaLogsMessage": "{errorMessage}詳細については、Kibanaサーバーログを確認してください。",
|
||||
"xpack.enterpriseSearch.server.routes.configData.errorMessage": "エンタープライズ サーチからのデータの取得エラー",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.expensive_query_not_allowed_error": "高コストの検索クエリーは許可されません。\"search.allow_expensive_queries\"はfalseに設定されています。",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.generateConfiguration.indexAlreadyExistsError": "一意のコネクター名が見つかりません",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.resource_not_found_error": "ID \"{connectorId}\"のコネクターが見つかりません。",
|
||||
|
|
|
@ -17151,7 +17151,6 @@
|
|||
"xpack.enterpriseSearch.server.routes.addCrawler.crawlerExistsError": "此索引的网络爬虫已存在",
|
||||
"xpack.enterpriseSearch.server.routes.addCrawler.indexExistsError": "此索引已存在",
|
||||
"xpack.enterpriseSearch.server.routes.checkKibanaLogsMessage": "{errorMessage} 请查阅 Kibana 服务器日志了解详情。",
|
||||
"xpack.enterpriseSearch.server.routes.configData.errorMessage": "从 Enterprise Search 中提取数据时出错",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.expensive_query_not_allowed_error": "不允许执行资源密集型搜索查询。已将'search.allow_expensive_queries'设置为 false",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.generateConfiguration.indexAlreadyExistsError": "找不到唯一的连接器名称",
|
||||
"xpack.enterpriseSearch.server.routes.connectors.resource_not_found_error": "找不到 ID 为 {connectorId} 的连接器。",
|
||||
|
|
|
@ -6,64 +6,13 @@
|
|||
*/
|
||||
|
||||
export const DEFAULT_INITIAL_APP_DATA = {
|
||||
kibanaVersion: '7.16.0',
|
||||
enterpriseSearchVersion: '7.16.0',
|
||||
readOnlyMode: false,
|
||||
searchOAuth: {
|
||||
clientId: 'someUID',
|
||||
redirectUrl: 'http://localhost:3002/ws/search_callback',
|
||||
},
|
||||
configuredLimits: {
|
||||
appSearch: {
|
||||
engine: {
|
||||
maxDocumentByteSize: 102400,
|
||||
maxEnginesPerMetaEngine: 15,
|
||||
},
|
||||
},
|
||||
workplaceSearch: {
|
||||
customApiSource: {
|
||||
maxDocumentByteSize: 102400,
|
||||
totalFields: 64,
|
||||
},
|
||||
},
|
||||
},
|
||||
kibanaVersion: '9.0.0',
|
||||
features: {
|
||||
hasConnectors: true,
|
||||
hasDefaultIngestPipeline: true,
|
||||
hasDocumentLevelSecurityEnabled: true,
|
||||
hasIncrementalSyncEnabled: true,
|
||||
hasNativeConnectors: true,
|
||||
hasWebCrawler: true,
|
||||
},
|
||||
appSearch: {
|
||||
accountId: 'some-id-string',
|
||||
kibanaUIsEnabled: true,
|
||||
onboardingComplete: true,
|
||||
role: {
|
||||
id: 'account_id:somestring|user_oid:somestring',
|
||||
roleType: 'owner',
|
||||
ability: {
|
||||
accessAllEngines: true,
|
||||
manage: ['account_credentials', 'account_engines'], // etc
|
||||
edit: ['LocoMoco::Account'], // etc
|
||||
view: ['Engine'], // etc
|
||||
credentialTypes: ['admin', 'private', 'search'],
|
||||
availableRoleTypes: ['owner', 'admin'],
|
||||
},
|
||||
},
|
||||
},
|
||||
workplaceSearch: {
|
||||
organization: {
|
||||
name: 'ACME Donuts',
|
||||
defaultOrgName: 'My Organization',
|
||||
kibanaUIsEnabled: false,
|
||||
},
|
||||
account: {
|
||||
id: 'some-id-string',
|
||||
groups: ['Default', 'Cats'],
|
||||
isAdmin: true,
|
||||
canCreatePrivateSources: true,
|
||||
viewedOnboardingPage: true,
|
||||
},
|
||||
hasWebCrawler: false,
|
||||
},
|
||||
};
|
||||
|
|
|
@ -1,31 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface Account {
|
||||
accountId: string;
|
||||
kibanaUIsEnabled: boolean;
|
||||
onboardingComplete: boolean;
|
||||
role: {
|
||||
id: string;
|
||||
roleType: string;
|
||||
ability: {
|
||||
accessAllEngines: boolean;
|
||||
manage: string[];
|
||||
edit: string[];
|
||||
view: string[];
|
||||
credentialTypes: string[];
|
||||
availableRoleTypes: string[];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
export interface ConfiguredLimits {
|
||||
engine: {
|
||||
maxDocumentByteSize: number;
|
||||
maxEnginesPerMetaEngine: number;
|
||||
};
|
||||
}
|
|
@ -5,29 +5,9 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import {
|
||||
Account as AppSearchAccount,
|
||||
ConfiguredLimits as AppSearchConfiguredLimits,
|
||||
} from './app_search';
|
||||
import {
|
||||
WorkplaceSearchInitialData,
|
||||
ConfiguredLimits as WorkplaceSearchConfiguredLimits,
|
||||
} from './workplace_search';
|
||||
|
||||
export interface InitialAppData {
|
||||
appSearch?: AppSearchAccount;
|
||||
configuredLimits?: ConfiguredLimits;
|
||||
enterpriseSearchVersion?: string;
|
||||
features?: ProductFeatures;
|
||||
kibanaVersion?: string;
|
||||
readOnlyMode?: boolean;
|
||||
searchOAuth?: SearchOAuth;
|
||||
workplaceSearch?: WorkplaceSearchInitialData;
|
||||
}
|
||||
|
||||
export interface ConfiguredLimits {
|
||||
appSearch: AppSearchConfiguredLimits;
|
||||
workplaceSearch: WorkplaceSearchConfiguredLimits;
|
||||
}
|
||||
|
||||
export interface ProductFeatures {
|
||||
|
|
|
@ -1,32 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export interface Account {
|
||||
id: string;
|
||||
groups: string[];
|
||||
isAdmin: boolean;
|
||||
canCreatePrivateSources: boolean;
|
||||
viewedOnboardingPage: boolean;
|
||||
}
|
||||
|
||||
export interface Organization {
|
||||
defaultOrgName: string;
|
||||
kibanaUIsEnabled: boolean;
|
||||
name: string;
|
||||
}
|
||||
|
||||
export interface WorkplaceSearchInitialData {
|
||||
account: Account;
|
||||
organization: Organization;
|
||||
}
|
||||
|
||||
export interface ConfiguredLimits {
|
||||
customApiSource: {
|
||||
maxDocumentByteSize: number;
|
||||
totalFields: number;
|
||||
};
|
||||
}
|
|
@ -1,10 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { externalUrl } from '../shared/enterprise_search_url';
|
||||
|
||||
externalUrl.enterpriseSearchUrl = 'http://localhost:3002';
|
|
@ -18,10 +18,6 @@ import { AnalyticsCollection } from '../../../../../../common/types/analytics';
|
|||
|
||||
import { AnalyticsCollectionIntegrateView } from './analytics_collection_integrate_view';
|
||||
|
||||
jest.mock('../../../../shared/enterprise_search_url', () => ({
|
||||
getEnterpriseSearchUrl: () => 'http://localhost:3002',
|
||||
}));
|
||||
|
||||
jest.mock('../../../../shared/cloud_details/cloud_details', () => ({
|
||||
useCloudDetails: () => ({
|
||||
elasticsearchUrl: 'your_deployment_url',
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import '../../../common/__mocks__';
|
||||
import '../__mocks__/kea_logic';
|
||||
import '../__mocks__/shallow_useeffect.mock';
|
||||
import '../__mocks__/enterprise_search_url.mock';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
|
||||
import { setMockValues } from '../__mocks__/kea_logic';
|
||||
import '../__mocks__/shallow_useeffect.mock';
|
||||
import '../__mocks__/enterprise_search_url.mock';
|
||||
|
||||
import React from 'react';
|
||||
|
||||
|
|
|
@ -28,9 +28,7 @@ import { DEFAULT_PRODUCT_FEATURES } from '../../common/constants';
|
|||
import { ClientConfigType, InitialAppData } from '../../common/types';
|
||||
import { PluginsStart, ClientData, ESConfig, UpdateSideNavDefinitionFn } from '../plugin';
|
||||
|
||||
import { externalUrl } from './shared/enterprise_search_url';
|
||||
import { mountFlashMessagesLogic } from './shared/flash_messages';
|
||||
import { getCloudEnterpriseSearchHost } from './shared/get_cloud_enterprise_search_host/get_cloud_enterprise_search_host';
|
||||
import { mountHttpLogic } from './shared/http';
|
||||
import { mountKibanaLogic } from './shared/kibana';
|
||||
import { mountLicensingLogic } from './shared/licensing';
|
||||
|
@ -58,18 +56,7 @@ export const renderApp = (
|
|||
},
|
||||
{ config, data, esConfig }: { config: ClientConfigType; data: ClientData; esConfig: ESConfig }
|
||||
) => {
|
||||
const {
|
||||
appSearch,
|
||||
configuredLimits,
|
||||
enterpriseSearchVersion,
|
||||
errorConnectingMessage,
|
||||
features,
|
||||
kibanaVersion,
|
||||
publicUrl,
|
||||
readOnlyMode,
|
||||
searchOAuth,
|
||||
workplaceSearch,
|
||||
} = data;
|
||||
const { errorConnectingMessage, features, kibanaVersion } = data;
|
||||
const { history } = params;
|
||||
const { application, chrome, http, notifications, uiSettings } = core;
|
||||
const { capabilities, navigateToUrl } = application;
|
||||
|
@ -85,9 +72,6 @@ export const renderApp = (
|
|||
fleet,
|
||||
} = plugins;
|
||||
|
||||
const entCloudHost = getCloudEnterpriseSearchHost(plugins.cloud);
|
||||
externalUrl.enterpriseSearchUrl = publicUrl || entCloudHost || config.host || '';
|
||||
|
||||
const productFeatures = features ?? { ...DEFAULT_PRODUCT_FEATURES };
|
||||
|
||||
const EmptyContext: FC<PropsWithChildren<unknown>> = ({ children }) => <>{children}</>;
|
||||
|
@ -141,7 +125,6 @@ export const renderApp = (
|
|||
const unmountHttpLogic = mountHttpLogic({
|
||||
errorConnectingMessage,
|
||||
http,
|
||||
readOnlyMode,
|
||||
});
|
||||
|
||||
const unmountFlashMessagesLogic = mountFlashMessagesLogic({ notifications });
|
||||
|
@ -161,16 +144,7 @@ export const renderApp = (
|
|||
<CloudContext>
|
||||
<Provider store={store}>
|
||||
<Router history={params.history}>
|
||||
<App
|
||||
appSearch={appSearch}
|
||||
configuredLimits={configuredLimits}
|
||||
enterpriseSearchVersion={enterpriseSearchVersion}
|
||||
features={features}
|
||||
kibanaVersion={kibanaVersion}
|
||||
readOnlyMode={readOnlyMode}
|
||||
searchOAuth={searchOAuth}
|
||||
workplaceSearch={workplaceSearch}
|
||||
/>
|
||||
<App features={features} kibanaVersion={kibanaVersion} />
|
||||
</Router>
|
||||
</Provider>
|
||||
</CloudContext>
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { externalUrl, getEnterpriseSearchUrl, getAppSearchUrl, getWorkplaceSearchUrl } from '.';
|
||||
|
||||
describe('Enterprise Search external URL helpers', () => {
|
||||
describe('getter/setter tests', () => {
|
||||
it('defaults to an empty string', () => {
|
||||
expect(externalUrl.enterpriseSearchUrl).toEqual('');
|
||||
});
|
||||
|
||||
it('sets the internal enterpriseSearchUrl value', () => {
|
||||
externalUrl.enterpriseSearchUrl = 'http://localhost:3002';
|
||||
expect(externalUrl.enterpriseSearchUrl).toEqual('http://localhost:3002');
|
||||
});
|
||||
|
||||
it('does not allow mutating enterpriseSearchUrl once set', () => {
|
||||
externalUrl.enterpriseSearchUrl = 'hello world';
|
||||
expect(externalUrl.enterpriseSearchUrl).toEqual('http://localhost:3002');
|
||||
});
|
||||
});
|
||||
|
||||
describe('function helpers', () => {
|
||||
it('generates a public Enterprise Search URL', () => {
|
||||
expect(getEnterpriseSearchUrl()).toEqual('http://localhost:3002');
|
||||
expect(getEnterpriseSearchUrl('/login')).toEqual('http://localhost:3002/login');
|
||||
});
|
||||
|
||||
it('generates a public App Search URL', () => {
|
||||
expect(getAppSearchUrl()).toEqual('http://localhost:3002/as');
|
||||
expect(getAppSearchUrl('/path')).toEqual('http://localhost:3002/as/path');
|
||||
});
|
||||
|
||||
it('generates a public Workplace Search URL', () => {
|
||||
expect(getWorkplaceSearchUrl()).toEqual('http://localhost:3002/ws');
|
||||
expect(getWorkplaceSearchUrl('/path')).toEqual('http://localhost:3002/ws/path');
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,38 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
/**
|
||||
* NOTE: The externalUrl obj holds the reference to externalUrl, which should
|
||||
* only ever be updated once on plugin init. We're using a getter and setter
|
||||
* here to ensure it isn't accidentally mutated.
|
||||
*
|
||||
* Someday (8.x+), when our UI is entirely on Kibana and no longer on
|
||||
* Enterprise Search's standalone UI, we can potentially deprecate this helper.
|
||||
*/
|
||||
export const externalUrl = {
|
||||
_enterpriseSearchUrl: '',
|
||||
get enterpriseSearchUrl() {
|
||||
return this._enterpriseSearchUrl;
|
||||
},
|
||||
set enterpriseSearchUrl(value) {
|
||||
if (this._enterpriseSearchUrl) {
|
||||
// enterpriseSearchUrl is set once on plugin init - we should not mutate it
|
||||
return;
|
||||
}
|
||||
this._enterpriseSearchUrl = value;
|
||||
},
|
||||
};
|
||||
|
||||
export const getEnterpriseSearchUrl = (path: string = ''): string => {
|
||||
return externalUrl.enterpriseSearchUrl + path;
|
||||
};
|
||||
export const getAppSearchUrl = (path: string = ''): string => {
|
||||
return getEnterpriseSearchUrl('/as' + path);
|
||||
};
|
||||
export const getWorkplaceSearchUrl = (path: string = ''): string => {
|
||||
return getEnterpriseSearchUrl('/ws' + path);
|
||||
};
|
|
@ -1,13 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
export {
|
||||
externalUrl,
|
||||
getEnterpriseSearchUrl,
|
||||
getAppSearchUrl,
|
||||
getWorkplaceSearchUrl,
|
||||
} from './external_url';
|
|
@ -1,91 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
|
||||
import { getCloudEnterpriseSearchHost } from './get_cloud_enterprise_search_host';
|
||||
|
||||
const defaultPortCloud = {
|
||||
cloudId:
|
||||
'gcp-cluster:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvJDhhMDI4M2FmMDQxZjE5NWY3NzI5YmMwNGM2NmEwZmNlJDBjZDVjZDU2OGVlYmU1M2M4OWViN2NhZTViYWM4YjM3',
|
||||
deploymentId: 'gcp-cluster',
|
||||
isCloudEnabled: true,
|
||||
cloudHost: 'us-central1.gcp.cloud.es.io',
|
||||
cloudDefaultPort: '443',
|
||||
registerCloudService: jest.fn(),
|
||||
onboarding: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
// 9243
|
||||
const customPortCloud = {
|
||||
cloudId:
|
||||
'custom-port:dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjkyNDMkYWMzMWViYjkwMjQxNzczMTU3MDQzYzM0ZmQyNmZkNDYkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA=',
|
||||
deploymentId: 'custom-port',
|
||||
isCloudEnabled: true,
|
||||
cloudHost: 'us-central1.gcp.cloud.es.io',
|
||||
cloudDefaultPort: '9243',
|
||||
registerCloudService: jest.fn(),
|
||||
onboarding: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
const missingDeploymentIdCloud = {
|
||||
cloudId:
|
||||
'dXMtY2VudHJhbDEuZ2NwLmNsb3VkLmVzLmlvOjkyNDMkYWMzMWViYjkwMjQxNzczMTU3MDQzYzM0ZmQyNmZkNDYkYTRjMDYyMzBlNDhjOGZjZTdiZTg4YTA3NGEzYmIzZTA=',
|
||||
isCloudEnabled: true,
|
||||
registerCloudService: jest.fn(),
|
||||
onboarding: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
const noCloud = {
|
||||
cloudId: undefined,
|
||||
isCloudEnabled: false,
|
||||
registerCloudService: jest.fn(),
|
||||
onboarding: {},
|
||||
isServerlessEnabled: false,
|
||||
serverless: {
|
||||
projectId: undefined,
|
||||
},
|
||||
fetchElasticsearchConfig: jest.fn(),
|
||||
} as CloudSetup;
|
||||
|
||||
describe('getCloudEnterpriseSearchHost', () => {
|
||||
it('uses the default port', () => {
|
||||
expect(getCloudEnterpriseSearchHost(defaultPortCloud)).toBe(
|
||||
'https://gcp-cluster.ent.us-central1.gcp.cloud.es.io'
|
||||
);
|
||||
});
|
||||
|
||||
it('allows a custom port', () => {
|
||||
expect(getCloudEnterpriseSearchHost(customPortCloud)).toBe(
|
||||
'https://custom-port.ent.us-central1.gcp.cloud.es.io:9243'
|
||||
);
|
||||
});
|
||||
|
||||
it('is undefined when there is no deployment id', () => {
|
||||
expect(getCloudEnterpriseSearchHost(missingDeploymentIdCloud)).toBe(undefined);
|
||||
});
|
||||
|
||||
it('is undefined with an undefined cloud id', () => {
|
||||
expect(getCloudEnterpriseSearchHost(noCloud)).toBe(undefined);
|
||||
});
|
||||
|
||||
it('is undefined when cloud is undefined', () => {
|
||||
expect(getCloudEnterpriseSearchHost(undefined)).toBe(undefined);
|
||||
});
|
||||
});
|
|
@ -1,17 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import type { CloudSetup } from '@kbn/cloud-plugin/public';
|
||||
|
||||
export function getCloudEnterpriseSearchHost(cloud: CloudSetup | undefined): string | undefined {
|
||||
if (cloud && cloud.isCloudEnabled && cloud.cloudId && cloud.deploymentId && cloud.cloudHost) {
|
||||
// Enterprise Search Server url are formed like this `https://<deploymentId>.ent.<host>
|
||||
return `https://${cloud.deploymentId}.ent.${cloud.cloudHost}${
|
||||
cloud.cloudDefaultPort && cloud.cloudDefaultPort !== '443' ? `:${cloud.cloudDefaultPort}` : ''
|
||||
}`;
|
||||
}
|
||||
}
|
|
@ -115,6 +115,7 @@ export const HttpLogic = kea<MakeLogicType<HttpValues, HttpActions>>({
|
|||
interface HttpLogicProps {
|
||||
errorConnectingMessage?: string;
|
||||
http: HttpSetup;
|
||||
// TODO: remove this
|
||||
readOnlyMode?: boolean;
|
||||
}
|
||||
|
||||
|
|
|
@ -66,7 +66,6 @@ import type { DynamicSideNavItems } from './navigation_tree';
|
|||
|
||||
export interface ClientData extends InitialAppData {
|
||||
errorConnectingMessage?: string;
|
||||
publicUrl?: string;
|
||||
}
|
||||
|
||||
export type EnterpriseSearchPublicSetup = ReturnType<EnterpriseSearchPlugin['setup']>;
|
||||
|
@ -150,7 +149,7 @@ export class EnterpriseSearchPlugin implements Plugin {
|
|||
this.esConfig = { elasticsearch_host: ELASTICSEARCH_URL_PLACEHOLDER };
|
||||
}
|
||||
|
||||
private data: ClientData = {} as ClientData;
|
||||
private data: ClientData = {};
|
||||
private esConfig: ESConfig;
|
||||
|
||||
private async getInitialData(http: HttpSetup) {
|
||||
|
|
|
@ -23,12 +23,25 @@ export const mockRequestHandler = {
|
|||
|
||||
export const mockMl = mlPluginServerMock.createSetupContract();
|
||||
|
||||
export const mockConfig = {
|
||||
export const mockConfig: ConfigType = {
|
||||
enabled: true,
|
||||
host: 'http://localhost:3002',
|
||||
accessCheckTimeout: 5000,
|
||||
accessCheckTimeoutWarning: 300,
|
||||
ssl: {},
|
||||
} as ConfigType;
|
||||
ssl: {
|
||||
verificationMode: 'none',
|
||||
},
|
||||
hasConnectors: true,
|
||||
hasDefaultIngestPipeline: true,
|
||||
hasDocumentLevelSecurityEnabled: true,
|
||||
hasIncrementalSyncEnabled: true,
|
||||
hasNativeConnectors: true,
|
||||
hasWebCrawler: true,
|
||||
isCloud: false,
|
||||
ui: {
|
||||
enabled: true,
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
* This is useful for tests that don't use either config or log,
|
||||
|
|
|
@ -23,7 +23,7 @@ export const configSchema = schema.object({
|
|||
hasDocumentLevelSecurityEnabled: schema.boolean({ defaultValue: true }),
|
||||
hasIncrementalSyncEnabled: schema.boolean({ defaultValue: true }),
|
||||
hasNativeConnectors: schema.boolean({ defaultValue: true }),
|
||||
hasWebCrawler: schema.boolean({ defaultValue: true }),
|
||||
hasWebCrawler: schema.boolean({ defaultValue: false }),
|
||||
host: schema.maybe(schema.string()),
|
||||
isCloud: schema.boolean({ defaultValue: false }),
|
||||
ssl: schema.object({
|
||||
|
|
|
@ -1,286 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { DEFAULT_INITIAL_APP_DATA } from '../../common/__mocks__';
|
||||
import '../__mocks__/http_agent.mock';
|
||||
|
||||
jest.mock('node-fetch');
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
const { Response } = jest.requireActual('node-fetch');
|
||||
|
||||
jest.mock('@kbn/repo-info', () => ({
|
||||
kibanaPackageJson: { version: '1.0.0' },
|
||||
}));
|
||||
|
||||
import { loggingSystemMock } from '@kbn/core-logging-server-mocks';
|
||||
|
||||
import { GlobalConfigService } from '../services/global_config_service';
|
||||
|
||||
import {
|
||||
callEnterpriseSearchConfigAPI,
|
||||
warnMismatchedVersions,
|
||||
} from './enterprise_search_config_api';
|
||||
|
||||
describe('callEnterpriseSearchConfigAPI', () => {
|
||||
const mockConfig = {
|
||||
host: 'http://localhost:3002',
|
||||
accessCheckTimeout: 200,
|
||||
accessCheckTimeoutWarning: 100,
|
||||
hasNativeConnectors: true,
|
||||
hasWebCrawler: true,
|
||||
};
|
||||
const mockRequest = {
|
||||
headers: { authorization: '==someAuth' },
|
||||
};
|
||||
const mockDependencies = {
|
||||
config: mockConfig,
|
||||
globalConfigService: new GlobalConfigService(),
|
||||
request: mockRequest,
|
||||
log: loggingSystemMock.create().get(),
|
||||
} as any;
|
||||
|
||||
const mockResponse = {
|
||||
version: {
|
||||
number: '7.16.0',
|
||||
},
|
||||
settings: {
|
||||
external_url: 'http://some.vanity.url/',
|
||||
read_only_mode: false,
|
||||
is_federated_auth: false,
|
||||
search_oauth: {
|
||||
client_id: 'someUID',
|
||||
redirect_url: 'http://localhost:3002/ws/search_callback',
|
||||
},
|
||||
configured_limits: {
|
||||
app_search: {
|
||||
engine: {
|
||||
document_size_in_bytes: 102400,
|
||||
source_engines_per_meta_engine: 15,
|
||||
},
|
||||
},
|
||||
workplace_search: {
|
||||
custom_api_source: {
|
||||
document_size_in_bytes: 102400,
|
||||
total_fields: 64,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
current_user: {
|
||||
name: 'someuser',
|
||||
access: {
|
||||
app_search: true,
|
||||
workplace_search: false,
|
||||
},
|
||||
app_search: {
|
||||
account: {
|
||||
id: 'some-id-string',
|
||||
kibana_uis_enabled: true,
|
||||
onboarding_complete: true,
|
||||
},
|
||||
role: {
|
||||
id: 'account_id:somestring|user_oid:somestring',
|
||||
role_type: 'owner',
|
||||
ability: {
|
||||
access_all_engines: true,
|
||||
manage: ['account_credentials', 'account_engines'], // etc
|
||||
edit: ['LocoMoco::Account'], // etc
|
||||
view: ['Engine'], // etc
|
||||
credential_types: ['admin', 'private', 'search'],
|
||||
available_role_types: ['owner', 'admin'],
|
||||
},
|
||||
},
|
||||
},
|
||||
workplace_search: {
|
||||
organization: {
|
||||
name: 'ACME Donuts',
|
||||
default_org_name: 'My Organization',
|
||||
kibana_uis_enabled: false,
|
||||
},
|
||||
account: {
|
||||
id: 'some-id-string',
|
||||
groups: ['Default', 'Cats'],
|
||||
is_admin: true,
|
||||
can_create_private_sources: true,
|
||||
can_create_invitations: true,
|
||||
is_curated: false,
|
||||
viewed_onboarding_page: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
beforeEach(() => {
|
||||
jest.clearAllMocks();
|
||||
});
|
||||
|
||||
it('calls the config API endpoint', async () => {
|
||||
(fetch as unknown as jest.Mock).mockImplementationOnce((url: string) => {
|
||||
expect(url).toEqual('http://localhost:3002/api/ent/v2/internal/client_config');
|
||||
return Promise.resolve(new Response(JSON.stringify(mockResponse)));
|
||||
});
|
||||
|
||||
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({
|
||||
...DEFAULT_INITIAL_APP_DATA,
|
||||
kibanaVersion: '1.0.0',
|
||||
features: {
|
||||
hasNativeConnectors: true,
|
||||
hasWebCrawler: true,
|
||||
},
|
||||
publicUrl: 'http://some.vanity.url',
|
||||
});
|
||||
});
|
||||
|
||||
it('falls back without error when data is unavailable', async () => {
|
||||
(fetch as unknown as jest.Mock).mockReturnValueOnce(Promise.resolve(new Response('{}')));
|
||||
|
||||
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({
|
||||
kibanaVersion: '1.0.0',
|
||||
features: {
|
||||
hasNativeConnectors: true,
|
||||
hasWebCrawler: true,
|
||||
},
|
||||
publicUrl: undefined,
|
||||
readOnlyMode: false,
|
||||
searchOAuth: {
|
||||
clientId: undefined,
|
||||
redirectUrl: undefined,
|
||||
},
|
||||
configuredLimits: {
|
||||
appSearch: {
|
||||
engine: {
|
||||
maxDocumentByteSize: undefined,
|
||||
maxEnginesPerMetaEngine: undefined,
|
||||
},
|
||||
},
|
||||
workplaceSearch: {
|
||||
customApiSource: {
|
||||
maxDocumentByteSize: undefined,
|
||||
totalFields: undefined,
|
||||
},
|
||||
},
|
||||
},
|
||||
appSearch: {
|
||||
accountId: undefined,
|
||||
kibanaUIsEnabled: false,
|
||||
onboardingComplete: false,
|
||||
role: {
|
||||
id: undefined,
|
||||
roleType: undefined,
|
||||
ability: {
|
||||
accessAllEngines: false,
|
||||
manage: [],
|
||||
edit: [],
|
||||
view: [],
|
||||
credentialTypes: [],
|
||||
availableRoleTypes: [],
|
||||
},
|
||||
},
|
||||
},
|
||||
workplaceSearch: {
|
||||
organization: {
|
||||
name: undefined,
|
||||
defaultOrgName: undefined,
|
||||
kibanaUIsEnabled: false,
|
||||
},
|
||||
account: {
|
||||
id: undefined,
|
||||
groups: [],
|
||||
isAdmin: false,
|
||||
canCreatePrivateSources: false,
|
||||
viewedOnboardingPage: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
|
||||
it('returns access & features if config.host is not set', async () => {
|
||||
const config = {
|
||||
hasConnectors: false,
|
||||
hasDefaultIngestPipeline: false,
|
||||
hasNativeConnectors: false,
|
||||
hasWebCrawler: false,
|
||||
host: '',
|
||||
};
|
||||
|
||||
expect(await callEnterpriseSearchConfigAPI({ ...mockDependencies, config })).toEqual({
|
||||
features: {
|
||||
hasConnectors: false,
|
||||
hasDefaultIngestPipeline: false,
|
||||
hasNativeConnectors: false,
|
||||
hasWebCrawler: false,
|
||||
},
|
||||
kibanaVersion: '1.0.0',
|
||||
});
|
||||
expect(fetch).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it('handles server errors', async () => {
|
||||
(fetch as unknown as jest.Mock).mockReturnValueOnce(Promise.reject('500'));
|
||||
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({});
|
||||
expect(mockDependencies.log.error).toHaveBeenCalledWith(
|
||||
'Could not perform access check to Enterprise Search: 500'
|
||||
);
|
||||
|
||||
(fetch as unknown as jest.Mock).mockReturnValueOnce(Promise.resolve('Bad Data'));
|
||||
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({});
|
||||
expect(mockDependencies.log.error).toHaveBeenCalledWith(
|
||||
'Could not perform access check to Enterprise Search: 500'
|
||||
);
|
||||
|
||||
(fetch as unknown as jest.Mock).mockReturnValueOnce(
|
||||
Promise.resolve(
|
||||
new Response('{}', {
|
||||
status: 500,
|
||||
statusText: 'I failed',
|
||||
})
|
||||
)
|
||||
);
|
||||
const expected = { responseStatus: 500, responseStatusText: 'I failed' };
|
||||
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual(expected);
|
||||
});
|
||||
|
||||
it('handles timeouts', async () => {
|
||||
jest.useFakeTimers({ legacyFakeTimers: true });
|
||||
|
||||
// Warning
|
||||
void callEnterpriseSearchConfigAPI(mockDependencies);
|
||||
jest.advanceTimersByTime(150);
|
||||
expect(mockDependencies.log.warn).toHaveBeenCalledWith(
|
||||
'Enterprise Search access check took over 100ms. Please ensure your Enterprise Search server is responding normally and not adversely impacting Kibana load speeds.'
|
||||
);
|
||||
|
||||
// Timeout
|
||||
(fetch as unknown as jest.Mock).mockImplementationOnce(async () => {
|
||||
jest.advanceTimersByTime(250);
|
||||
return Promise.reject({ name: 'AbortError' });
|
||||
});
|
||||
expect(await callEnterpriseSearchConfigAPI(mockDependencies)).toEqual({});
|
||||
expect(mockDependencies.log.warn).toHaveBeenCalledWith(
|
||||
"Exceeded 200ms timeout while checking http://localhost:3002. Please consider increasing your enterpriseSearch.accessCheckTimeout value so that users aren't prevented from accessing Enterprise Search plugins due to slow responses."
|
||||
);
|
||||
});
|
||||
|
||||
describe('warnMismatchedVersions', () => {
|
||||
it("logs a warning when Enterprise Search and Kibana's versions are not the same", () => {
|
||||
warnMismatchedVersions('1.1.0', mockDependencies.log);
|
||||
|
||||
expect(mockDependencies.log.warn).toHaveBeenCalledWith(
|
||||
expect.stringContaining(
|
||||
'Your Kibana instance (v1.0.0) is not the same version as your Enterprise Search instance (v1.1.0)'
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
it("does not log a warning when Enterprise Search and Kibana's versions are the same", () => {
|
||||
warnMismatchedVersions('1.0.0', mockDependencies.log);
|
||||
|
||||
expect(mockDependencies.log.warn).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
|
@ -1,190 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import fetch from 'node-fetch';
|
||||
|
||||
import { KibanaRequest, Logger } from '@kbn/core/server';
|
||||
import { kibanaPackageJson } from '@kbn/repo-info';
|
||||
|
||||
import { ConfigType } from '..';
|
||||
import { isVersionMismatch } from '../../common/is_version_mismatch';
|
||||
import { stripTrailingSlash } from '../../common/strip_slashes';
|
||||
import { InitialAppData } from '../../common/types';
|
||||
|
||||
import { entSearchHttpAgent } from './enterprise_search_http_agent';
|
||||
|
||||
interface Params {
|
||||
request: KibanaRequest;
|
||||
config: ConfigType;
|
||||
log: Logger;
|
||||
}
|
||||
interface Return extends InitialAppData {
|
||||
publicUrl?: string;
|
||||
}
|
||||
interface ResponseError {
|
||||
responseStatus: number;
|
||||
responseStatusText: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calls an internal Enterprise Search API endpoint which returns
|
||||
* useful various settings (e.g. product access, external URL)
|
||||
* needed by the Kibana plugin at the setup stage
|
||||
*/
|
||||
const ENDPOINT = '/api/ent/v2/internal/client_config';
|
||||
|
||||
export const callEnterpriseSearchConfigAPI = async ({
|
||||
config,
|
||||
log,
|
||||
request,
|
||||
}: Params): Promise<Return | ResponseError> => {
|
||||
if (!config.host)
|
||||
// Return Access and Features for when running without `ent-search`
|
||||
return {
|
||||
features: {
|
||||
hasConnectors: config.hasConnectors,
|
||||
hasDefaultIngestPipeline: config.hasDefaultIngestPipeline,
|
||||
hasDocumentLevelSecurityEnabled: config.hasDocumentLevelSecurityEnabled,
|
||||
hasIncrementalSyncEnabled: config.hasIncrementalSyncEnabled,
|
||||
hasNativeConnectors: config.hasNativeConnectors,
|
||||
hasWebCrawler: config.hasWebCrawler,
|
||||
},
|
||||
kibanaVersion: kibanaPackageJson.version,
|
||||
};
|
||||
|
||||
const TIMEOUT_WARNING = `Enterprise Search access check took over ${config.accessCheckTimeoutWarning}ms. Please ensure your Enterprise Search server is responding normally and not adversely impacting Kibana load speeds.`;
|
||||
const TIMEOUT_MESSAGE = `Exceeded ${config.accessCheckTimeout}ms timeout while checking ${config.host}. Please consider increasing your enterpriseSearch.accessCheckTimeout value so that users aren't prevented from accessing Enterprise Search plugins due to slow responses.`;
|
||||
const CONNECTION_ERROR = 'Could not perform access check to Enterprise Search';
|
||||
|
||||
const warningTimeout = setTimeout(() => {
|
||||
log.warn(TIMEOUT_WARNING);
|
||||
}, config.accessCheckTimeoutWarning);
|
||||
|
||||
const controller = new AbortController();
|
||||
const timeout = setTimeout(() => {
|
||||
controller.abort();
|
||||
}, config.accessCheckTimeout);
|
||||
|
||||
try {
|
||||
const enterpriseSearchUrl = encodeURI(`${config.host}${ENDPOINT}`);
|
||||
const options = {
|
||||
headers: {
|
||||
Authorization: request.headers.authorization as string,
|
||||
...config.customHeaders,
|
||||
},
|
||||
signal: controller.signal,
|
||||
agent: entSearchHttpAgent.getHttpAgent(),
|
||||
};
|
||||
|
||||
const response = await fetch(enterpriseSearchUrl, options);
|
||||
|
||||
if (!response.ok) {
|
||||
return {
|
||||
responseStatus: response.status,
|
||||
responseStatusText: response.statusText,
|
||||
};
|
||||
}
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
warnMismatchedVersions(data?.version?.number, log);
|
||||
|
||||
return {
|
||||
enterpriseSearchVersion: data?.version?.number,
|
||||
kibanaVersion: kibanaPackageJson.version,
|
||||
features: {
|
||||
hasConnectors: config.hasConnectors,
|
||||
hasDefaultIngestPipeline: config.hasDefaultIngestPipeline,
|
||||
hasDocumentLevelSecurityEnabled: config.hasDocumentLevelSecurityEnabled,
|
||||
hasIncrementalSyncEnabled: config.hasIncrementalSyncEnabled,
|
||||
hasNativeConnectors: config.hasNativeConnectors,
|
||||
hasWebCrawler: config.hasWebCrawler,
|
||||
},
|
||||
publicUrl: stripTrailingSlash(data?.settings?.external_url),
|
||||
readOnlyMode: !!data?.settings?.read_only_mode,
|
||||
searchOAuth: {
|
||||
clientId: data?.settings?.search_oauth?.client_id,
|
||||
redirectUrl: data?.settings?.search_oauth?.redirect_url,
|
||||
},
|
||||
configuredLimits: {
|
||||
appSearch: {
|
||||
engine: {
|
||||
maxDocumentByteSize:
|
||||
data?.settings?.configured_limits?.app_search?.engine?.document_size_in_bytes,
|
||||
maxEnginesPerMetaEngine:
|
||||
data?.settings?.configured_limits?.app_search?.engine?.source_engines_per_meta_engine,
|
||||
},
|
||||
},
|
||||
workplaceSearch: {
|
||||
customApiSource: {
|
||||
maxDocumentByteSize:
|
||||
data?.settings?.configured_limits?.workplace_search?.custom_api_source
|
||||
?.document_size_in_bytes,
|
||||
totalFields:
|
||||
data?.settings?.configured_limits?.workplace_search?.custom_api_source?.total_fields,
|
||||
},
|
||||
},
|
||||
},
|
||||
appSearch: {
|
||||
accountId: data?.current_user?.app_search?.account?.id,
|
||||
kibanaUIsEnabled: data?.current_user?.app_search?.account?.kibana_uis_enabled || false,
|
||||
onboardingComplete: !!data?.current_user?.app_search?.account?.onboarding_complete,
|
||||
role: {
|
||||
id: data?.current_user?.app_search?.role?.id,
|
||||
roleType: data?.current_user?.app_search?.role?.role_type,
|
||||
ability: {
|
||||
accessAllEngines: !!data?.current_user?.app_search?.role?.ability?.access_all_engines,
|
||||
manage: data?.current_user?.app_search?.role?.ability?.manage || [],
|
||||
edit: data?.current_user?.app_search?.role?.ability?.edit || [],
|
||||
view: data?.current_user?.app_search?.role?.ability?.view || [],
|
||||
credentialTypes: data?.current_user?.app_search?.role?.ability?.credential_types || [],
|
||||
availableRoleTypes:
|
||||
data?.current_user?.app_search?.role?.ability?.available_role_types || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
workplaceSearch: {
|
||||
organization: {
|
||||
name: data?.current_user?.workplace_search?.organization?.name,
|
||||
defaultOrgName: data?.current_user?.workplace_search?.organization?.default_org_name,
|
||||
kibanaUIsEnabled:
|
||||
data?.current_user?.workplace_search?.organization?.kibana_uis_enabled || false,
|
||||
},
|
||||
account: {
|
||||
id: data?.current_user?.workplace_search?.account?.id,
|
||||
groups: data?.current_user?.workplace_search?.account?.groups || [],
|
||||
isAdmin: !!data?.current_user?.workplace_search?.account?.is_admin,
|
||||
canCreatePrivateSources:
|
||||
!!data?.current_user?.workplace_search?.account?.can_create_private_sources,
|
||||
viewedOnboardingPage:
|
||||
!!data?.current_user?.workplace_search?.account?.viewed_onboarding_page,
|
||||
},
|
||||
},
|
||||
};
|
||||
} catch (err) {
|
||||
if (err.name === 'AbortError') {
|
||||
log.warn(TIMEOUT_MESSAGE);
|
||||
} else {
|
||||
log.error(`${CONNECTION_ERROR}: ${err.toString()}`);
|
||||
if (err instanceof Error) log.debug(err.stack as string);
|
||||
}
|
||||
return {};
|
||||
} finally {
|
||||
clearTimeout(warningTimeout);
|
||||
clearTimeout(timeout);
|
||||
}
|
||||
};
|
||||
|
||||
export const warnMismatchedVersions = (enterpriseSearchVersion: string, log: Logger) => {
|
||||
const kibanaVersion = kibanaPackageJson.version;
|
||||
|
||||
if (isVersionMismatch(enterpriseSearchVersion, kibanaVersion)) {
|
||||
log.warn(
|
||||
`Your Kibana instance (v${kibanaVersion}) is not the same version as your Enterprise Search instance (v${enterpriseSearchVersion}), which may cause unexpected behavior. Use matching versions for the best experience.`
|
||||
);
|
||||
}
|
||||
};
|
|
@ -8,55 +8,61 @@
|
|||
import { DEFAULT_INITIAL_APP_DATA } from '../../../common/__mocks__';
|
||||
import { MockRouter, mockDependencies } from '../../__mocks__';
|
||||
|
||||
jest.mock('../../lib/enterprise_search_config_api', () => ({
|
||||
callEnterpriseSearchConfigAPI: jest.fn(),
|
||||
}));
|
||||
import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api';
|
||||
|
||||
import { registerConfigDataRoute } from './config_data';
|
||||
|
||||
describe('Enterprise Search Config Data API', () => {
|
||||
let mockRouter: MockRouter;
|
||||
|
||||
beforeEach(() => {
|
||||
mockRouter = new MockRouter({
|
||||
method: 'get',
|
||||
path: '/internal/enterprise_search/config_data',
|
||||
});
|
||||
|
||||
registerConfigDataRoute({
|
||||
...mockDependencies,
|
||||
router: mockRouter.router,
|
||||
});
|
||||
});
|
||||
beforeEach(() => {});
|
||||
|
||||
describe('GET /internal/enterprise_search/config_data', () => {
|
||||
it('returns an initial set of config data from Enterprise Search', async () => {
|
||||
const mockData = {
|
||||
...DEFAULT_INITIAL_APP_DATA,
|
||||
publicUrl: 'http://localhost:3002',
|
||||
};
|
||||
|
||||
(callEnterpriseSearchConfigAPI as jest.Mock).mockImplementationOnce(() => {
|
||||
return Promise.resolve(mockData);
|
||||
it('returns an initial set of config data', async () => {
|
||||
mockRouter = new MockRouter({
|
||||
method: 'get',
|
||||
path: '/internal/enterprise_search/config_data',
|
||||
});
|
||||
|
||||
registerConfigDataRoute({
|
||||
...mockDependencies,
|
||||
router: mockRouter.router,
|
||||
});
|
||||
|
||||
await mockRouter.callRoute({});
|
||||
|
||||
expect(mockRouter.response.ok).toHaveBeenCalledWith({
|
||||
body: mockData,
|
||||
body: DEFAULT_INITIAL_APP_DATA,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
});
|
||||
|
||||
it('throws a 502 error if data returns an empty obj', async () => {
|
||||
(callEnterpriseSearchConfigAPI as jest.Mock).mockImplementationOnce(() => {
|
||||
return Promise.resolve({});
|
||||
it('return config features when changed', async () => {
|
||||
mockRouter = new MockRouter({
|
||||
method: 'get',
|
||||
path: '/internal/enterprise_search/config_data',
|
||||
});
|
||||
|
||||
registerConfigDataRoute({
|
||||
...mockDependencies,
|
||||
config: {
|
||||
...mockDependencies.config,
|
||||
hasDocumentLevelSecurityEnabled: false,
|
||||
hasIncrementalSyncEnabled: false,
|
||||
},
|
||||
router: mockRouter.router,
|
||||
});
|
||||
|
||||
await mockRouter.callRoute({});
|
||||
|
||||
expect(mockRouter.response.customError).toHaveBeenCalledWith({
|
||||
statusCode: 502,
|
||||
body: 'Error fetching data from Enterprise Search',
|
||||
expect(mockRouter.response.ok).toHaveBeenCalledWith({
|
||||
body: {
|
||||
...DEFAULT_INITIAL_APP_DATA,
|
||||
features: {
|
||||
...DEFAULT_INITIAL_APP_DATA.features,
|
||||
hasDocumentLevelSecurityEnabled: false,
|
||||
hasIncrementalSyncEnabled: false,
|
||||
},
|
||||
},
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
});
|
||||
});
|
||||
|
|
|
@ -5,19 +5,11 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
import { i18n } from '@kbn/i18n';
|
||||
import { kibanaPackageJson } from '@kbn/repo-info';
|
||||
|
||||
import { callEnterpriseSearchConfigAPI } from '../../lib/enterprise_search_config_api';
|
||||
import { RouteDependencies } from '../../plugin';
|
||||
import { elasticsearchErrorHandler } from '../../utils/elasticsearch_error_handler';
|
||||
|
||||
const errorMessage = i18n.translate(
|
||||
'xpack.enterpriseSearch.server.routes.configData.errorMessage',
|
||||
{
|
||||
defaultMessage: 'Error fetching data from Enterprise Search',
|
||||
}
|
||||
);
|
||||
|
||||
export function registerConfigDataRoute({
|
||||
router,
|
||||
config,
|
||||
|
@ -29,25 +21,24 @@ export function registerConfigDataRoute({
|
|||
path: '/internal/enterprise_search/config_data',
|
||||
validate: false,
|
||||
},
|
||||
elasticsearchErrorHandler(log, async (context, request, response) => {
|
||||
const data = await callEnterpriseSearchConfigAPI({ config, log, request });
|
||||
elasticsearchErrorHandler(log, async (_context, _request, response) => {
|
||||
const data = {
|
||||
features: {
|
||||
hasConnectors: config.hasConnectors,
|
||||
hasDefaultIngestPipeline: config.hasDefaultIngestPipeline,
|
||||
hasDocumentLevelSecurityEnabled: config.hasDocumentLevelSecurityEnabled,
|
||||
hasIncrementalSyncEnabled: config.hasIncrementalSyncEnabled,
|
||||
hasNativeConnectors: config.hasNativeConnectors,
|
||||
// 9.x Does not have ent search node, and therefore does not have support for the following
|
||||
hasWebCrawler: false,
|
||||
},
|
||||
kibanaVersion: kibanaPackageJson.version,
|
||||
};
|
||||
|
||||
if ('responseStatus' in data) {
|
||||
return response.customError({
|
||||
body: errorMessage,
|
||||
statusCode: data.responseStatus,
|
||||
});
|
||||
} else if (!Object.keys(data).length) {
|
||||
return response.customError({
|
||||
body: errorMessage,
|
||||
statusCode: 502,
|
||||
});
|
||||
} else {
|
||||
return response.ok({
|
||||
body: data,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
}
|
||||
return response.ok({
|
||||
body: data,
|
||||
headers: { 'content-type': 'application/json' },
|
||||
});
|
||||
})
|
||||
);
|
||||
|
||||
|
|
|
@ -36,7 +36,6 @@
|
|||
"@kbn/ui-theme",
|
||||
"@kbn/config-schema",
|
||||
"@kbn/custom-integrations-plugin",
|
||||
"@kbn/core-logging-server-mocks",
|
||||
"@kbn/repo-info",
|
||||
"@kbn/core-elasticsearch-server",
|
||||
"@kbn/core-http-server",
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue