From 56545f746594c7fac177a3f54cb1c7a500f33860 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 10 Sep 2021 14:52:17 +0200 Subject: [PATCH 1/4] initial implementation --- .../deprecations/deprecation_provider.ts | 18 ++++ .../elasticsearch/deprecations/index.ts | 9 ++ .../deprecations/scripting_disabled.ts | 68 +++++++++++++++ .../elasticsearch_service.test.ts | 39 +++++++-- .../elasticsearch/elasticsearch_service.ts | 10 ++- .../scripting_disabled.test.ts | 82 +++++++++++++++++++ src/core/server/server.ts | 9 +- 7 files changed, 222 insertions(+), 13 deletions(-) create mode 100644 src/core/server/elasticsearch/deprecations/deprecation_provider.ts create mode 100644 src/core/server/elasticsearch/deprecations/index.ts create mode 100644 src/core/server/elasticsearch/deprecations/scripting_disabled.ts create mode 100644 src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts diff --git a/src/core/server/elasticsearch/deprecations/deprecation_provider.ts b/src/core/server/elasticsearch/deprecations/deprecation_provider.ts new file mode 100644 index 00000000000000..a3d4683617a7ef --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/deprecation_provider.ts @@ -0,0 +1,18 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import type { RegisterDeprecationsConfig } from '../../deprecations'; +import { getScriptingDisabledDeprecations } from './scripting_disabled'; + +export const getElasticsearchDeprecationsProvider = (): RegisterDeprecationsConfig => { + return { + getDeprecations: async (context) => { + return [...(await getScriptingDisabledDeprecations({ esClient: context.esClient }))]; + }, + }; +}; diff --git a/src/core/server/elasticsearch/deprecations/index.ts b/src/core/server/elasticsearch/deprecations/index.ts new file mode 100644 index 00000000000000..4f67c0103b0a13 --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/index.ts @@ -0,0 +1,9 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export { getElasticsearchDeprecationsProvider } from './deprecation_provider'; diff --git a/src/core/server/elasticsearch/deprecations/scripting_disabled.ts b/src/core/server/elasticsearch/deprecations/scripting_disabled.ts new file mode 100644 index 00000000000000..450cf4e6b7216f --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/scripting_disabled.ts @@ -0,0 +1,68 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { i18n } from '@kbn/i18n'; +import type { DeprecationsDetails } from '../../deprecations'; +import { IScopedClusterClient, ElasticsearchClient } from '../../elasticsearch'; + +const scriptAllowedTypesKey = 'script.allowed_types'; + +export const isInlineScriptingDisabled = async ({ + client, +}: { + client: ElasticsearchClient; +}): Promise => { + const { body: settings } = await client.cluster.getSettings({ + include_defaults: true, + flat_settings: true, + }); + + // priority: transient -> persistent -> default + const scriptAllowedTypes: string[] = + settings.transient[scriptAllowedTypesKey] ?? + settings.persistent[scriptAllowedTypesKey] ?? + settings.defaults![scriptAllowedTypesKey] ?? + []; + + // when unspecified, the setting as a default `[]` value that means that both scriptings are allowed. + const scriptAllowed = scriptAllowedTypes.length === 0 || scriptAllowedTypes.includes('inline'); + + return !scriptAllowed; +}; + +interface GetScriptingDisabledDeprecations { + esClient: IScopedClusterClient; +} + +export const getScriptingDisabledDeprecations = async ({ + esClient, +}: GetScriptingDisabledDeprecations): Promise => { + const deprecations: DeprecationsDetails[] = []; + if (await isInlineScriptingDisabled({ client: esClient.asInternalUser })) { + deprecations.push({ + title: i18n.translate('core.elasticsearch.deprecations.scriptingDisabled.title', { + defaultMessage: 'Inline scripting is disabled on elasticsearch', + }), + message: i18n.translate('core.elasticsearch.deprecations.scriptingDisabled.message', { + defaultMessage: + 'Starting in 8.0, Kibana will require inline scripting to be enabled,' + + 'and will fail to start otherwise.', + }), + level: 'critical', + requireRestart: false, + correctiveActions: { + manualSteps: [ + i18n.translate('core.elasticsearch.deprecations.scriptingDisabled.manualSteps.1', { + defaultMessage: 'Set `script.allowed_types=inline` in your elasticsearch config ', + }), + ], + }, + }); + } + return deprecations; +}; diff --git a/src/core/server/elasticsearch/elasticsearch_service.test.ts b/src/core/server/elasticsearch/elasticsearch_service.test.ts index 4c749cba1fd84c..d10fec01697a81 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.test.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.test.ts @@ -28,11 +28,13 @@ import { loggingSystemMock } from '../logging/logging_system.mock'; import { httpServiceMock } from '../http/http_service.mock'; import { executionContextServiceMock } from '../execution_context/execution_context_service.mock'; import { configSchema, ElasticsearchConfig } from './elasticsearch_config'; -import { ElasticsearchService } from './elasticsearch_service'; +import { ElasticsearchService, SetupDeps } from './elasticsearch_service'; import { elasticsearchClientMock } from './client/mocks'; +import { deprecationsServiceMock } from '../deprecations/deprecations_service.mock'; import { duration } from 'moment'; import { isValidConnection as isValidConnectionMock } from './is_valid_connection'; import { pollEsNodesVersion as pollEsNodesVersionMocked } from './version_check/ensure_es_version'; + const { pollEsNodesVersion: pollEsNodesVersionActual } = jest.requireActual( './version_check/ensure_es_version' ); @@ -40,20 +42,25 @@ const { pollEsNodesVersion: pollEsNodesVersionActual } = jest.requireActual( const delay = async (durationMs: number) => await new Promise((resolve) => setTimeout(resolve, durationMs)); -let elasticsearchService: ElasticsearchService; const configService = configServiceMock.create(); -const setupDeps = { - http: httpServiceMock.createInternalSetupContract(), - executionContext: executionContextServiceMock.createInternalSetupContract(), -}; +let elasticsearchService: ElasticsearchService; let env: Env; let coreContext: CoreContext; - let mockClusterClientInstance: ReturnType; - let mockConfig$: BehaviorSubject; +let setupDeps: SetupDeps; +let deprecationsSetup: ReturnType; + beforeEach(() => { + deprecationsSetup = deprecationsServiceMock.createInternalSetupContract(); + + setupDeps = { + http: httpServiceMock.createInternalSetupContract(), + executionContext: executionContextServiceMock.createInternalSetupContract(), + deprecations: deprecationsSetup, + }; + env = Env.createDefault(REPO_ROOT, getEnvOptions()); mockConfig$ = new BehaviorSubject({ @@ -174,6 +181,22 @@ describe('#setup', () => { ); }); + it('registers its deprecation provider', async () => { + const registry = deprecationsServiceMock.createSetupContract(); + + deprecationsSetup.getRegistry.mockReturnValue(registry); + + await elasticsearchService.setup(setupDeps); + + expect(deprecationsSetup.getRegistry).toHaveBeenCalledTimes(1); + expect(deprecationsSetup.getRegistry).toHaveBeenCalledWith('elasticsearch'); + + expect(registry.registerDeprecations).toHaveBeenCalledTimes(1); + expect(registry.registerDeprecations).toHaveBeenCalledWith({ + getDeprecations: expect.any(Function), + }); + }); + it('esNodeVersionCompatibility$ only starts polling when subscribed to', async (done) => { const mockedClient = mockClusterClientInstance.asInternalUser; mockedClient.nodes.info.mockImplementation(() => diff --git a/src/core/server/elasticsearch/elasticsearch_service.ts b/src/core/server/elasticsearch/elasticsearch_service.ts index 1e0aa44fcbe196..eebd7327492854 100644 --- a/src/core/server/elasticsearch/elasticsearch_service.ts +++ b/src/core/server/elasticsearch/elasticsearch_service.ts @@ -18,6 +18,7 @@ import { ClusterClient, ElasticsearchClientConfig } from './client'; import { ElasticsearchConfig, ElasticsearchConfigType } from './elasticsearch_config'; import type { InternalHttpServiceSetup, GetAuthHeaders } from '../http'; import type { InternalExecutionContextSetup, IExecutionContext } from '../execution_context'; +import type { InternalDeprecationsServiceSetup } from '../deprecations'; import { InternalElasticsearchServicePreboot, InternalElasticsearchServiceSetup, @@ -27,9 +28,11 @@ import type { NodesVersionCompatibility } from './version_check/ensure_es_versio import { pollEsNodesVersion } from './version_check/ensure_es_version'; import { calculateStatus$ } from './status'; import { isValidConnection } from './is_valid_connection'; +import { getElasticsearchDeprecationsProvider } from './deprecations'; -interface SetupDeps { +export interface SetupDeps { http: InternalHttpServiceSetup; + deprecations: InternalDeprecationsServiceSetup; executionContext: InternalExecutionContextSetup; } @@ -78,6 +81,10 @@ export class ElasticsearchService this.executionContextClient = deps.executionContext; this.client = this.createClusterClient('data', config); + deps.deprecations + .getRegistry('elasticsearch') + .registerDeprecations(getElasticsearchDeprecationsProvider()); + const esNodesCompatibility$ = pollEsNodesVersion({ internalClient: this.client.asInternalUser, log: this.log, @@ -96,6 +103,7 @@ export class ElasticsearchService status$: calculateStatus$(esNodesCompatibility$), }; } + public async start(): Promise { if (!this.client || !this.esNodesCompatibility$) { throw new Error('ElasticsearchService needs to be setup before calling start'); diff --git a/src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts b/src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts new file mode 100644 index 00000000000000..8d743929fdcdaa --- /dev/null +++ b/src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts @@ -0,0 +1,82 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { + createTestServers, + TestElasticsearchUtils, + TestKibanaUtils, +} from '../../../test_helpers/kbn_server'; +import { isInlineScriptingDisabled } from '../deprecations/scripting_disabled'; + +describe('isInlineScriptingDisabled', () => { + let esServer: TestElasticsearchUtils; + let kibanaServer: TestKibanaUtils; + + afterEach(async () => { + if (kibanaServer) { + await kibanaServer.stop(); + } + if (esServer) { + await esServer.stop(); + } + }); + + const startServers = async ({ esArgs = [] }: { esArgs?: string[] } = {}) => { + const { startES, startKibana } = createTestServers({ + adjustTimeout: jest.setTimeout, + settings: { + es: { + esArgs, + }, + }, + }); + + esServer = await startES(); + kibanaServer = await startKibana(); + }; + + it('returns false when `script.allowed_types` is unset', async () => { + await startServers({ esArgs: [] }); + + const disabled = await isInlineScriptingDisabled({ + client: kibanaServer.coreStart.elasticsearch.client.asInternalUser, + }); + + expect(disabled).toEqual(false); + }); + + it('returns false when `script.allowed_types` is `inline`', async () => { + await startServers({ esArgs: ['script.allowed_types=inline'] }); + + const disabled = await isInlineScriptingDisabled({ + client: kibanaServer.coreStart.elasticsearch.client.asInternalUser, + }); + + expect(disabled).toEqual(false); + }); + + it('returns true when `script.allowed_types` is `stored`', async () => { + await startServers({ esArgs: ['script.allowed_types=stored'] }); + + const disabled = await isInlineScriptingDisabled({ + client: kibanaServer.coreStart.elasticsearch.client.asInternalUser, + }); + + expect(disabled).toEqual(true); + }); + + it('returns true when `script.allowed_types` is `none', async () => { + await startServers({ esArgs: ['script.allowed_types=none'] }); + + const disabled = await isInlineScriptingDisabled({ + client: kibanaServer.coreStart.elasticsearch.client.asInternalUser, + }); + + expect(disabled).toEqual(true); + }); +}); diff --git a/src/core/server/server.ts b/src/core/server/server.ts index 865cc71a7e26b3..ebf3e358704215 100644 --- a/src/core/server/server.ts +++ b/src/core/server/server.ts @@ -206,6 +206,10 @@ export class Server { executionContext: executionContextSetup, }); + const deprecationsSetup = this.deprecations.setup({ + http: httpSetup, + }); + // setup i18n prior to any other service, to have translations ready const i18nServiceSetup = await this.i18n.setup({ http: httpSetup, pluginPaths }); @@ -214,6 +218,7 @@ export class Server { const elasticsearchServiceSetup = await this.elasticsearch.setup({ http: httpSetup, executionContext: executionContextSetup, + deprecations: deprecationsSetup, }); const metricsSetup = await this.metrics.setup({ http: httpSetup }); @@ -259,10 +264,6 @@ export class Server { const loggingSetup = this.logging.setup(); - const deprecationsSetup = this.deprecations.setup({ - http: httpSetup, - }); - const coreSetup: InternalCoreSetup = { capabilities: capabilitiesSetup, context: contextServiceSetup, From 5f7bb36724b7aaa84e4f20255fbe51f720afcc50 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 10 Sep 2021 14:56:26 +0200 Subject: [PATCH 2/4] extract isScriptingDisabled to own file --- .../deprecations/deprecation_provider.ts | 2 +- .../deprecations/is_scripting_disabled.ts | 34 +++++++++++++++++++ ...d.ts => scripting_disabled_deprecation.ts} | 28 ++------------- ....test.ts => is_scripting_disabled.test.ts} | 2 +- 4 files changed, 38 insertions(+), 28 deletions(-) create mode 100644 src/core/server/elasticsearch/deprecations/is_scripting_disabled.ts rename src/core/server/elasticsearch/deprecations/{scripting_disabled.ts => scripting_disabled_deprecation.ts} (65%) rename src/core/server/elasticsearch/integration_tests/{scripting_disabled.test.ts => is_scripting_disabled.test.ts} (96%) diff --git a/src/core/server/elasticsearch/deprecations/deprecation_provider.ts b/src/core/server/elasticsearch/deprecations/deprecation_provider.ts index a3d4683617a7ef..d085af0d960082 100644 --- a/src/core/server/elasticsearch/deprecations/deprecation_provider.ts +++ b/src/core/server/elasticsearch/deprecations/deprecation_provider.ts @@ -7,7 +7,7 @@ */ import type { RegisterDeprecationsConfig } from '../../deprecations'; -import { getScriptingDisabledDeprecations } from './scripting_disabled'; +import { getScriptingDisabledDeprecations } from './scripting_disabled_deprecation'; export const getElasticsearchDeprecationsProvider = (): RegisterDeprecationsConfig => { return { diff --git a/src/core/server/elasticsearch/deprecations/is_scripting_disabled.ts b/src/core/server/elasticsearch/deprecations/is_scripting_disabled.ts new file mode 100644 index 00000000000000..9f140c71da8a06 --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/is_scripting_disabled.ts @@ -0,0 +1,34 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { ElasticsearchClient } from '../../elasticsearch'; + +const scriptAllowedTypesKey = 'script.allowed_types'; + +export const isInlineScriptingDisabled = async ({ + client, +}: { + client: ElasticsearchClient; +}): Promise => { + const { body: settings } = await client.cluster.getSettings({ + include_defaults: true, + flat_settings: true, + }); + + // priority: transient -> persistent -> default + const scriptAllowedTypes: string[] = + settings.transient[scriptAllowedTypesKey] ?? + settings.persistent[scriptAllowedTypesKey] ?? + settings.defaults![scriptAllowedTypesKey] ?? + []; + + // when unspecified, the setting as a default `[]` value that means that both scriptings are allowed. + const scriptAllowed = scriptAllowedTypes.length === 0 || scriptAllowedTypes.includes('inline'); + + return !scriptAllowed; +}; diff --git a/src/core/server/elasticsearch/deprecations/scripting_disabled.ts b/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.ts similarity index 65% rename from src/core/server/elasticsearch/deprecations/scripting_disabled.ts rename to src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.ts index 450cf4e6b7216f..d1e64b8faeeab7 100644 --- a/src/core/server/elasticsearch/deprecations/scripting_disabled.ts +++ b/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.ts @@ -8,32 +8,8 @@ import { i18n } from '@kbn/i18n'; import type { DeprecationsDetails } from '../../deprecations'; -import { IScopedClusterClient, ElasticsearchClient } from '../../elasticsearch'; - -const scriptAllowedTypesKey = 'script.allowed_types'; - -export const isInlineScriptingDisabled = async ({ - client, -}: { - client: ElasticsearchClient; -}): Promise => { - const { body: settings } = await client.cluster.getSettings({ - include_defaults: true, - flat_settings: true, - }); - - // priority: transient -> persistent -> default - const scriptAllowedTypes: string[] = - settings.transient[scriptAllowedTypesKey] ?? - settings.persistent[scriptAllowedTypesKey] ?? - settings.defaults![scriptAllowedTypesKey] ?? - []; - - // when unspecified, the setting as a default `[]` value that means that both scriptings are allowed. - const scriptAllowed = scriptAllowedTypes.length === 0 || scriptAllowedTypes.includes('inline'); - - return !scriptAllowed; -}; +import { IScopedClusterClient } from '../../elasticsearch'; +import { isInlineScriptingDisabled } from './is_scripting_disabled'; interface GetScriptingDisabledDeprecations { esClient: IScopedClusterClient; diff --git a/src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts b/src/core/server/elasticsearch/integration_tests/is_scripting_disabled.test.ts similarity index 96% rename from src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts rename to src/core/server/elasticsearch/integration_tests/is_scripting_disabled.test.ts index 8d743929fdcdaa..0d235ff2429e46 100644 --- a/src/core/server/elasticsearch/integration_tests/scripting_disabled.test.ts +++ b/src/core/server/elasticsearch/integration_tests/is_scripting_disabled.test.ts @@ -11,7 +11,7 @@ import { TestElasticsearchUtils, TestKibanaUtils, } from '../../../test_helpers/kbn_server'; -import { isInlineScriptingDisabled } from '../deprecations/scripting_disabled'; +import { isInlineScriptingDisabled } from '../deprecations/is_scripting_disabled'; describe('isInlineScriptingDisabled', () => { let esServer: TestElasticsearchUtils; From dba789e600011159471d44b16762dd88f8c5b8eb Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 10 Sep 2021 15:06:34 +0200 Subject: [PATCH 3/4] add unit tests for scripting deprecation --- ...ripting_disabled_deprecation.test.mocks.ts | 12 ++++ .../scripting_disabled_deprecation.test.ts | 63 +++++++++++++++++++ 2 files changed, 75 insertions(+) create mode 100644 src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.mocks.ts create mode 100644 src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.ts diff --git a/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.mocks.ts b/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.mocks.ts new file mode 100644 index 00000000000000..3c78d2e4ab9f75 --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.mocks.ts @@ -0,0 +1,12 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +export const isInlineScriptingDisabledMock = jest.fn(); +jest.doMock('./is_scripting_disabled', () => ({ + isInlineScriptingDisabled: isInlineScriptingDisabledMock, +})); diff --git a/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.ts b/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.ts new file mode 100644 index 00000000000000..1be73310be691b --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/scripting_disabled_deprecation.test.ts @@ -0,0 +1,63 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { isInlineScriptingDisabledMock } from './scripting_disabled_deprecation.test.mocks'; +import { elasticsearchServiceMock } from '../../elasticsearch/elasticsearch_service.mock'; +import { getScriptingDisabledDeprecations } from './scripting_disabled_deprecation'; + +describe('getScriptingDisabledDeprecations', () => { + let esClient: ReturnType; + + beforeEach(() => { + esClient = elasticsearchServiceMock.createScopedClusterClient(); + }); + + afterEach(() => { + isInlineScriptingDisabledMock.mockReset(); + }); + + it('calls `isInlineScriptingDisabled` with the correct arguments', async () => { + await getScriptingDisabledDeprecations({ + esClient, + }); + + expect(isInlineScriptingDisabledMock).toHaveBeenCalledTimes(1); + expect(isInlineScriptingDisabledMock).toHaveBeenCalledWith({ + client: esClient.asInternalUser, + }); + }); + + it('returns no deprecations if scripting is not disabled', async () => { + isInlineScriptingDisabledMock.mockResolvedValue(false); + + const deprecations = await getScriptingDisabledDeprecations({ + esClient, + }); + + expect(deprecations).toHaveLength(0); + }); + + it('returns a deprecation if scripting is disabled', async () => { + isInlineScriptingDisabledMock.mockResolvedValue(true); + + const deprecations = await getScriptingDisabledDeprecations({ + esClient, + }); + + expect(deprecations).toHaveLength(1); + expect(deprecations[0]).toEqual({ + title: expect.any(String), + message: expect.any(String), + level: 'critical', + requireRestart: false, + correctiveActions: { + manualSteps: expect.any(Array), + }, + }); + }); +}); From 817156c1b296e41687fea7dbb9f99fb9a86fba19 Mon Sep 17 00:00:00 2001 From: pgayvallet Date: Fri, 10 Sep 2021 16:08:15 +0200 Subject: [PATCH 4/4] add unit tests --- .../is_scripting_disabled.test.ts | 99 +++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 src/core/server/elasticsearch/deprecations/is_scripting_disabled.test.ts diff --git a/src/core/server/elasticsearch/deprecations/is_scripting_disabled.test.ts b/src/core/server/elasticsearch/deprecations/is_scripting_disabled.test.ts new file mode 100644 index 00000000000000..90c5f022bd41c4 --- /dev/null +++ b/src/core/server/elasticsearch/deprecations/is_scripting_disabled.test.ts @@ -0,0 +1,99 @@ +/* + * 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 and the Server Side Public License, v 1; you may not use this file except + * in compliance with, at your election, the Elastic License 2.0 or the Server + * Side Public License, v 1. + */ + +import { estypes } from '@elastic/elasticsearch'; +import { elasticsearchServiceMock } from '../../elasticsearch/elasticsearch_service.mock'; +import { isInlineScriptingDisabled } from './is_scripting_disabled'; + +describe('isInlineScriptingDisabled', () => { + let client: ReturnType; + + beforeEach(() => { + client = elasticsearchServiceMock.createElasticsearchClient(); + }); + + const mockSettingsValue = (settings: estypes.ClusterGetSettingsResponse) => { + client.cluster.getSettings.mockReturnValue( + elasticsearchServiceMock.createSuccessTransportRequestPromise(settings) + ); + }; + + it('returns `false` if all settings are empty', async () => { + mockSettingsValue({ + transient: {}, + persistent: {}, + defaults: {}, + }); + + expect(await isInlineScriptingDisabled({ client })).toEqual(false); + }); + + it('returns `false` if `defaults.script.allowed_types` is `inline`', async () => { + mockSettingsValue({ + transient: {}, + persistent: {}, + defaults: { + 'script.allowed_types': ['inline'], + }, + }); + + expect(await isInlineScriptingDisabled({ client })).toEqual(false); + }); + + it('returns `true` if `defaults.script.allowed_types` is `none`', async () => { + mockSettingsValue({ + transient: {}, + persistent: {}, + defaults: { + 'script.allowed_types': ['none'], + }, + }); + + expect(await isInlineScriptingDisabled({ client })).toEqual(true); + }); + + it('returns `true` if `defaults.script.allowed_types` is `stored`', async () => { + mockSettingsValue({ + transient: {}, + persistent: {}, + defaults: { + 'script.allowed_types': ['stored'], + }, + }); + + expect(await isInlineScriptingDisabled({ client })).toEqual(true); + }); + + it('respect the persistent->defaults priority', async () => { + mockSettingsValue({ + transient: {}, + persistent: { + 'script.allowed_types': ['inline'], + }, + defaults: { + 'script.allowed_types': ['stored'], + }, + }); + + expect(await isInlineScriptingDisabled({ client })).toEqual(false); + }); + + it('respect the transient->persistent priority', async () => { + mockSettingsValue({ + transient: { + 'script.allowed_types': ['stored'], + }, + persistent: { + 'script.allowed_types': ['inline'], + }, + defaults: {}, + }); + + expect(await isInlineScriptingDisabled({ client })).toEqual(true); + }); +});