From 925b6c63cc702e234ae6c185ffbf0fb9124105c7 Mon Sep 17 00:00:00 2001 From: Christos Nasikas Date: Fri, 5 Nov 2021 15:12:51 +0200 Subject: [PATCH] [Connectors][ServiceNow] Remove SN flags (#117511) (#117636) # Conflicts: # x-pack/plugins/security_solution/common/constants.ts --- .../server/builtin_action_types/index.ts | 7 +- .../servicenow/config.test.ts | 2 +- .../builtin_action_types/servicenow/config.ts | 11 +-- .../actions/server/constants/connectors.ts | 15 ---- .../cases/public/components/utils.test.ts | 41 ++++++++++ .../plugins/cases/public/components/utils.ts | 33 +++----- .../security_solution/common/constants.ts | 8 +- .../components/builtin_action_types/index.ts | 8 +- .../servicenow/helpers.test.ts | 41 ++++++++++ .../servicenow/helpers.ts | 31 +++----- .../actions_connectors_list.test.tsx | 79 +++++++++++++++++++ .../components/actions_connectors_list.tsx | 20 ++--- 12 files changed, 198 insertions(+), 98 deletions(-) delete mode 100644 x-pack/plugins/actions/server/constants/connectors.ts diff --git a/x-pack/plugins/actions/server/builtin_action_types/index.ts b/x-pack/plugins/actions/server/builtin_action_types/index.ts index 9988e951ae86d..9f48a45fc4664 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/index.ts @@ -24,7 +24,6 @@ import { import { getActionType as getJiraActionType } from './jira'; import { getActionType as getResilientActionType } from './resilient'; import { getActionType as getTeamsActionType } from './teams'; -import { ENABLE_ITOM } from '../constants/connectors'; export type { ActionParamsType as EmailActionParams } from './email'; export { ActionTypeId as EmailActionTypeId } from './email'; export type { ActionParamsType as IndexActionParams } from './es_index'; @@ -72,12 +71,8 @@ export function registerBuiltInActionTypes({ actionTypeRegistry.register(getWebhookActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getServiceNowITSMActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getServiceNowSIRActionType({ logger, configurationUtilities })); + actionTypeRegistry.register(getServiceNowITOMActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getJiraActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getResilientActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getTeamsActionType({ logger, configurationUtilities })); - - // TODO: Remove when ITOM is ready - if (ENABLE_ITOM) { - actionTypeRegistry.register(getServiceNowITOMActionType({ logger, configurationUtilities })); - } } diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts index 41f723bc9e2aa..26550f1732655 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.test.ts @@ -44,7 +44,7 @@ describe('config', () => { importSetTable: 'x_elas2_inc_int_elastic_incident', appScope: 'x_elas2_inc_int', table: 'em_event', - useImportAPI: true, + useImportAPI: false, commentFieldKey: 'work_notes', }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts index 52d2eb7662f53..ba29bcc39b25a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts @@ -5,11 +5,6 @@ * 2.0. */ -import { - ENABLE_ITOM, - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, -} from '../../constants/connectors'; import { SNProductsConfig } from './types'; export const serviceNowITSMTable = 'incident'; @@ -24,21 +19,21 @@ export const snExternalServiceConfig: SNProductsConfig = { importSetTable: 'x_elas2_inc_int_elastic_incident', appScope: 'x_elas2_inc_int', table: 'incident', - useImportAPI: ENABLE_NEW_SN_ITSM_CONNECTOR, + useImportAPI: true, commentFieldKey: 'work_notes', }, '.servicenow-sir': { importSetTable: 'x_elas2_sir_int_elastic_si_incident', appScope: 'x_elas2_sir_int', table: 'sn_si_incident', - useImportAPI: ENABLE_NEW_SN_SIR_CONNECTOR, + useImportAPI: true, commentFieldKey: 'work_notes', }, '.servicenow-itom': { importSetTable: 'x_elas2_inc_int_elastic_incident', appScope: 'x_elas2_inc_int', table: 'em_event', - useImportAPI: ENABLE_ITOM, + useImportAPI: false, commentFieldKey: 'work_notes', }, }; diff --git a/x-pack/plugins/actions/server/constants/connectors.ts b/x-pack/plugins/actions/server/constants/connectors.ts deleted file mode 100644 index 94324e4d82bc2..0000000000000 --- a/x-pack/plugins/actions/server/constants/connectors.ts +++ /dev/null @@ -1,15 +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. - */ - -// TODO: Remove when Elastic for ITSM is published. -export const ENABLE_NEW_SN_ITSM_CONNECTOR = true; - -// TODO: Remove when Elastic for Security Operations is published. -export const ENABLE_NEW_SN_SIR_CONNECTOR = true; - -// TODO: Remove when ready -export const ENABLE_ITOM = true; diff --git a/x-pack/plugins/cases/public/components/utils.test.ts b/x-pack/plugins/cases/public/components/utils.test.ts index 86d37d2e5e59e..e3cc753e75746 100644 --- a/x-pack/plugins/cases/public/components/utils.test.ts +++ b/x-pack/plugins/cases/public/components/utils.test.ts @@ -39,8 +39,49 @@ describe('Utils', () => { }); describe('isDeprecatedConnector', () => { + const connector = { + id: 'test', + actionTypeId: '.webhook', + name: 'Test', + config: { usesTableApi: false }, + secrets: {}, + isPreconfigured: false, + }; + it('returns false if the connector is not defined', () => { expect(isDeprecatedConnector()).toBe(false); }); + + it('returns false if the connector is not ITSM or SecOps', () => { + expect(isDeprecatedConnector(connector)).toBe(false); + }); + + it('returns false if the connector is .servicenow and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow' })).toBe(false); + }); + + it('returns false if the connector is .servicenow-sir and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow-sir' })).toBe(false); + }); + + it('returns true if the connector is .servicenow and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow', + config: { usesTableApi: true }, + }) + ).toBe(true); + }); + + it('returns true if the connector is .servicenow-sir and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow-sir', + config: { usesTableApi: true }, + }) + ).toBe(true); + }); }); }); diff --git a/x-pack/plugins/cases/public/components/utils.ts b/x-pack/plugins/cases/public/components/utils.ts index 3ac48135edae8..82d2682e65fad 100644 --- a/x-pack/plugins/cases/public/components/utils.ts +++ b/x-pack/plugins/cases/public/components/utils.ts @@ -12,11 +12,6 @@ import { StartPlugins } from '../types'; import { connectorValidator as swimlaneConnectorValidator } from './connectors/swimlane/validator'; import { connectorValidator as servicenowConnectorValidator } from './connectors/servicenow/validator'; import { CaseActionConnector } from './types'; -import { - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../actions/server/constants/connectors'; export const getConnectorById = ( id: string, @@ -83,24 +78,16 @@ export const isDeprecatedConnector = (connector?: CaseActionConnector): boolean return false; } - if (!ENABLE_NEW_SN_ITSM_CONNECTOR && connector.actionTypeId === '.servicenow') { - return true; + if (connector.actionTypeId === '.servicenow' || connector.actionTypeId === '.servicenow-sir') { + /** + * Connector's prior to the Elastic ServiceNow application + * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) + * Connectors after the Elastic ServiceNow application use the + * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) + * A ServiceNow connector is considered deprecated if it uses the Table API. + */ + return !!connector.config.usesTableApi; } - if (!ENABLE_NEW_SN_SIR_CONNECTOR && connector.actionTypeId === '.servicenow-sir') { - return true; - } - - /** - * Connector's prior to the Elastic ServiceNow application - * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) - * Connectors after the Elastic ServiceNow application use the - * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) - * A ServiceNow connector is considered deprecated if it uses the Table API. - * - * All other connectors do not have the usesTableApi config property - * so the function will always return false for them. - */ - - return !!connector.config.usesTableApi; + return false; }; diff --git a/x-pack/plugins/security_solution/common/constants.ts b/x-pack/plugins/security_solution/common/constants.ts index 3ebba007f6b01..08bc41315c797 100644 --- a/x-pack/plugins/security_solution/common/constants.ts +++ b/x-pack/plugins/security_solution/common/constants.ts @@ -5,8 +5,6 @@ * 2.0. */ -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ENABLE_ITOM } from '../../actions/server/constants/connectors'; import type { TransformConfigSchema } from './transforms/types'; import { ENABLE_CASE_CONNECTOR } from '../../cases/common'; import { METADATA_TRANSFORMS_PATTERN } from './endpoint/constants'; @@ -309,6 +307,7 @@ export const NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS = [ '.resilient', '.servicenow', '.servicenow-sir', + '.servicenow-itom', '.slack', '.swimlane', '.teams', @@ -319,11 +318,6 @@ if (ENABLE_CASE_CONNECTOR) { NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS.push('.case'); } -// TODO: Remove when ITOM is ready -if (ENABLE_ITOM) { - NOTIFICATION_SUPPORTED_ACTION_TYPES_IDS.push('.servicenow-itom'); -} - export const NOTIFICATION_THROTTLE_NO_ACTIONS = 'no_actions'; export const NOTIFICATION_THROTTLE_RULE = 'rule'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts index d9bad9677c6b8..a58dd84e9a32b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/index.ts @@ -22,8 +22,6 @@ import { import { getJiraActionType } from './jira'; import { getResilientActionType } from './resilient'; import { getTeamsActionType } from './teams'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ENABLE_ITOM } from '../../../../../actions/server/constants/connectors'; export function registerBuiltInActionTypes({ actionTypeRegistry, @@ -38,13 +36,9 @@ export function registerBuiltInActionTypes({ actionTypeRegistry.register(getSwimlaneActionType()); actionTypeRegistry.register(getWebhookActionType()); actionTypeRegistry.register(getServiceNowITSMActionType()); + actionTypeRegistry.register(getServiceNowITOMActionType()); actionTypeRegistry.register(getServiceNowSIRActionType()); actionTypeRegistry.register(getJiraActionType()); actionTypeRegistry.register(getResilientActionType()); actionTypeRegistry.register(getTeamsActionType()); - - // TODO: Remove when ITOM is ready - if (ENABLE_ITOM) { - actionTypeRegistry.register(getServiceNowITOMActionType()); - } } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts index 525430ea7fc64..9a8094f53d501 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.test.ts @@ -50,8 +50,49 @@ describe('helpers', () => { }); describe('isDeprecatedConnector', () => { + const connector = { + id: 'test', + actionTypeId: '.webhook', + name: 'Test', + config: { apiUrl: 'http://example.com', usesTableApi: false }, + secrets: { username: 'test', password: 'test' }, + isPreconfigured: false as const, + }; + it('returns false if the connector is not defined', () => { expect(isDeprecatedConnector()).toBe(false); }); + + it('returns false if the connector is not ITSM or SecOps', () => { + expect(isDeprecatedConnector(connector)).toBe(false); + }); + + it('returns false if the connector is .servicenow and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow' })).toBe(false); + }); + + it('returns false if the connector is .servicenow-sir and the usesTableApi=false', () => { + expect(isDeprecatedConnector({ ...connector, actionTypeId: '.servicenow-sir' })).toBe(false); + }); + + it('returns true if the connector is .servicenow and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow', + config: { ...connector.config, usesTableApi: true }, + }) + ).toBe(true); + }); + + it('returns true if the connector is .servicenow-sir and the usesTableApi=true', () => { + expect( + isDeprecatedConnector({ + ...connector, + actionTypeId: '.servicenow-sir', + config: { ...connector.config, usesTableApi: true }, + }) + ).toBe(true); + }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts index 7274c59527415..de0b30b9acb2f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/helpers.ts @@ -6,11 +6,6 @@ */ import { EuiSelectOption } from '@elastic/eui'; -import { - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../actions/server/constants/connectors'; import { IErrorObject } from '../../../../../public/types'; import { AppInfo, Choice, RESTApiError, ServiceNowActionConnector } from './types'; @@ -33,22 +28,16 @@ export const isDeprecatedConnector = (connector?: ServiceNowActionConnector): bo return false; } - if (!ENABLE_NEW_SN_ITSM_CONNECTOR && connector.actionTypeId === '.servicenow') { - return true; + if (connector.actionTypeId === '.servicenow' || connector.actionTypeId === '.servicenow-sir') { + /** + * Connector's prior to the Elastic ServiceNow application + * use the Table API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_TableAPI) + * Connectors after the Elastic ServiceNow application use the + * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) + * A ServiceNow connector is considered deprecated if it uses the Table API. + */ + return !!connector.config.usesTableApi; } - if (!ENABLE_NEW_SN_SIR_CONNECTOR && connector.actionTypeId === '.servicenow-sir') { - return true; - } - - /** - * Connectors after the Elastic ServiceNow application use the - * Import Set API (https://developer.servicenow.com/dev.do#!/reference/api/rome/rest/c_ImportSetAPI) - * A ServiceNow connector is considered deprecated if it uses the Table API. - * - * All other connectors do not have the usesTableApi config property - * so the function will always return false for them. - */ - - return !!connector.config.usesTableApi; + return false; }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx index 90eadaf5f9b8b..d477fcd0ddf74 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.test.tsx @@ -6,6 +6,8 @@ */ import * as React from 'react'; +// eslint-disable-next-line @kbn/eslint/module_migration +import { ThemeProvider } from 'styled-components'; import { mountWithIntl, nextTick } from '@kbn/test/jest'; import ActionsConnectorsList from './actions_connectors_list'; @@ -458,3 +460,80 @@ describe('actions_connectors_list component with disabled items', () => { ); }); }); + +describe('actions_connectors_list component with deprecated connectors', () => { + let wrapper: ReactWrapper; + + async function setup() { + loadAllActions.mockResolvedValueOnce([ + { + id: '1', + actionTypeId: '.servicenow', + description: 'My test', + referencedByCount: 1, + config: { usesTableApi: true }, + }, + { + id: '2', + actionTypeId: '.servicenow-sir', + description: 'My test 2', + referencedByCount: 1, + config: { usesTableApi: true }, + }, + ]); + loadActionTypes.mockResolvedValueOnce([ + { + id: 'test', + name: '.servicenow', + enabled: false, + enabledInConfig: false, + enabledInLicense: true, + }, + { + id: 'test2', + name: '.servicenow-sir', + enabled: false, + enabledInConfig: true, + enabledInLicense: false, + }, + ]); + + const [ + { + application: { capabilities }, + }, + ] = await mocks.getStartServices(); + + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.application.capabilities = { + ...capabilities, + actions: { + show: true, + save: true, + delete: true, + }, + }; + // eslint-disable-next-line react-hooks/rules-of-hooks + useKibanaMock().services.actionTypeRegistry = actionTypeRegistry; + wrapper = mountWithIntl( + ({ eui: { euiSizeS: '15px' }, darkMode: true })}> + + + ); + + // Wait for active space to resolve before requesting the component to update + await act(async () => { + await nextTick(); + wrapper.update(); + }); + + expect(loadAllActions).toHaveBeenCalled(); + } + + it('shows the warning icon', async () => { + await setup(); + expect(wrapper.find('EuiInMemoryTable')).toHaveLength(1); + expect(wrapper.find('EuiTableRow')).toHaveLength(2); + expect(wrapper.find('.euiToolTipAnchor [aria-label="Warning"]').exists()).toBe(true); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx index 5de21470fc19a..6b52479f2ac87 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/actions_connectors_list/components/actions_connectors_list.tsx @@ -48,11 +48,6 @@ import { DEFAULT_HIDDEN_ACTION_TYPES } from '../../../../'; import { CenterJustifiedSpinner } from '../../../components/center_justified_spinner'; import ConnectorEditFlyout from '../../action_connector_form/connector_edit_flyout'; import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout'; -import { - ENABLE_NEW_SN_ITSM_CONNECTOR, - ENABLE_NEW_SN_SIR_CONNECTOR, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../actions/server/constants/connectors'; const ConnectorIconTipWithSpacing = withTheme(({ theme }: { theme: EuiTheme }) => { return ( @@ -202,14 +197,19 @@ const ActionsConnectorsList: React.FunctionComponent = () => { const checkEnabledResult = checkActionTypeEnabled( actionTypesIndex && actionTypesIndex[item.actionTypeId] ); + const itemConfig = ( item as UserConfiguredActionConnector, Record> ).config; - const showDeprecatedTooltip = - itemConfig?.usesTableApi && - // TODO: Remove when applications are certified - ((ENABLE_NEW_SN_ITSM_CONNECTOR && item.actionTypeId === '.servicenow') || - (ENABLE_NEW_SN_SIR_CONNECTOR && item.actionTypeId === '.servicenow-sir')); + + /** + * TODO: Remove when connectors can provide their own UX message. + * Issue: https://github.com/elastic/kibana/issues/114507 + */ + const hasSNApplication = + item?.actionTypeId === '.servicenow' || item?.actionTypeId === '.servicenow-sir'; + + const showDeprecatedTooltip = hasSNApplication && itemConfig?.usesTableApi; const link = ( <>