[Connectors][ServiceNow] Remove SN flags (#117511) (#117636)

# Conflicts:
#	x-pack/plugins/security_solution/common/constants.ts
This commit is contained in:
Christos Nasikas 2021-11-05 15:12:51 +02:00 committed by GitHub
parent fb4b11f562
commit 925b6c63cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 198 additions and 98 deletions

View file

@ -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 }));
}
}

View file

@ -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',
});
});

View file

@ -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',
},
};

View file

@ -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;

View file

@ -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);
});
});
});

View file

@ -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;
};

View file

@ -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';

View file

@ -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());
}
}

View file

@ -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);
});
});
});

View file

@ -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;
};

View file

@ -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<any>;
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(
<ThemeProvider theme={() => ({ eui: { euiSizeS: '15px' }, darkMode: true })}>
<ActionsConnectorsList />
</ThemeProvider>
);
// 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);
});
});

View file

@ -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<string, unknown>, Record<string, unknown>>
).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 = (
<>