From d16c22e2ce8ba46c41b4b1fa2361e5ea75be5bb1 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Fri, 5 Jun 2020 20:13:42 -0700 Subject: [PATCH 01/38] Draft ServiceNow generic implementation --- .../servicenow/api.test.ts | 4 +- .../builtin_action_types/servicenow/api.ts | 110 +++++++- .../builtin_action_types/servicenow/index.ts | 112 ++++++-- .../builtin_action_types/servicenow/mocks.ts | 47 +--- .../builtin_action_types/servicenow/schema.ts | 81 ++++++ .../servicenow/service.test.ts | 50 +--- .../servicenow/service.ts | 53 ++-- .../servicenow/translations.ts | 8 + .../builtin_action_types/servicenow/types.ts | 135 ++++++++- .../servicenow/validators.ts | 21 +- x-pack/plugins/case/common/api/cases/case.ts | 2 +- .../siem/public/cases/containers/mock.ts | 2 +- .../containers/use_post_push_to_service.tsx | 2 +- .../components/builtin_action_types/index.ts | 2 + .../builtin_action_types/servicenow/config.ts | 38 +++ .../builtin_action_types/servicenow/index.ts} | 8 +- .../builtin_action_types/servicenow/logo.svg | 5 + .../servicenow/servicenow.tsx | 76 ++++++ .../servicenow/servicenow_connectors.tsx | 176 ++++++++++++ .../servicenow/servicenow_params.tsx | 258 ++++++++++++++++++ .../servicenow/translations.ts | 130 +++++++++ .../builtin_action_types/servicenow/types.ts | 36 +++ .../slack/slack_connectors.tsx | 2 +- .../sections/alert_form/alert_reducer.ts | 31 ++- 24 files changed, 1244 insertions(+), 145 deletions(-) create mode 100644 x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts rename x-pack/plugins/{actions/server/builtin_action_types/servicenow/config.ts => triggers_actions_ui/public/application/components/builtin_action_types/servicenow/index.ts} (54%) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/logo.svg create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 86a8318841271..58eed64b0c8e4 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ -import { api } from '../case/api'; import { externalServiceMock, mapping, apiParams } from './mocks'; -import { ExternalService } from '../case/types'; +import { ExternalService } from './types'; +import { api } from './api'; describe('api', () => { let externalService: jest.Mocked; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 3db66e5884af4..5884a8d1c54ac 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -3,5 +3,113 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ +import { flow } from 'lodash'; +import { + ExternalServiceParams, + PushToServiceResponse, + PushToServiceApiHandlerArgs, + HandshakeApiHandlerArgs, + GetIncidentApiHandlerArgs, + ExternalServiceApi, + PrepareFieldsForTransformArgs, + PipedField, + TransformFieldsArgs, +} from './types'; +import { transformers, Transformer } from '../case/transformers'; -export { api } from '../case/api'; +const handshakeHandler = async ({ + externalService, + mapping, + params, +}: HandshakeApiHandlerArgs) => {}; +const getIncidentHandler = async ({ + externalService, + mapping, + params, +}: GetIncidentApiHandlerArgs) => {}; + +const pushToServiceHandler = async ({ + externalService, + mapping, + params, + secrets, +}: PushToServiceApiHandlerArgs): Promise => { + const { savedObjectId, externalId } = params; + const existingIncident = await externalService.findIncidents({ user_input: savedObjectId }); + const updateIncident = existingIncident || externalId ? true : false; + const defaultPipes = updateIncident ? ['informationUpdated'] : ['informationCreated']; + let currentIncident: ExternalServiceParams | undefined; + let res: PushToServiceResponse; + + if (externalId) { + currentIncident = await externalService.getIncident(externalId); + } + + let incident = {}; + if (mapping) { + const fields = prepareFieldsForTransformation({ + params, + mapping, + defaultPipes, + }); + + incident = transformFields({ + params, + fields, + currentIncident, + }); + } + incident = params; + + if (updateIncident) { + res = await externalService.updateIncident({ incidentId: externalId, incident }); + } else { + res = await externalService.createIncident({ + incident, + caller_id: secrets.username, + user_input: savedObjectId, + }); + } + return res; +}; + +export const prepareFieldsForTransformation = ({ + params, + mapping, + defaultPipes = ['informationCreated'], +}: PrepareFieldsForTransformArgs): PipedField[] => { + return Object.keys(params.externalObject) + .filter((p) => mapping.get(p)?.actionType != null && mapping.get(p)?.actionType !== 'nothing') + .map((p) => { + const actionType = mapping.get(p)?.actionType ?? 'nothing'; + return { + key: p, + value: params.externalObject[p], + actionType, + pipes: actionType === 'append' ? [...defaultPipes, 'append'] : defaultPipes, + }; + }); +}; + +export const transformFields = ({ + params, + fields, + currentIncident, +}: TransformFieldsArgs): Record => { + return fields.reduce((prev, cur) => { + const transform = flow(...cur.pipes.map((p) => transformers[p])); + return { + ...prev, + [cur.key]: transform({ + value: cur.value, + previousValue: currentIncident ? currentIncident[cur.key] : '', + }).value, + }; + }, {}); +}; + +export const api: ExternalServiceApi = { + handshake: handshakeHandler, + pushToService: pushToServiceHandler, + getIncident: getIncidentHandler, +}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index dbb536d2fa53d..680b24e370f5a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -4,24 +4,104 @@ * you may not use this file except in compliance with the Elastic License. */ -import { createConnector } from '../case/utils'; +import { curry, get } from 'lodash'; +import { schema } from '@kbn/config-schema'; -import { api } from './api'; -import { config } from './config'; +// import { config } from './config'; import { validate } from './validators'; -import { createExternalService } from './service'; import { ExternalIncidentServiceConfiguration, ExternalIncidentServiceSecretConfiguration, -} from '../case/schema'; - -export const getActionType = createConnector({ - api, - config, - validate, - createExternalService, - validationSchema: { - config: ExternalIncidentServiceConfiguration, - secrets: ExternalIncidentServiceSecretConfiguration, - }, -}); + ExecutorParamsSchema, +} from './schema'; +import { ActionsConfigurationUtilities } from '../../actions_config'; +import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../../types'; +import { createExternalService } from './service'; +import { buildMap } from '../case/utils'; +import { api } from './api'; +import { ExecutorParams, ExecutorSubActionPushParams, MapRecord, AnyParams } from './types'; +import * as i18n from './translations'; + +interface GetActionTypeParams { + logger: Logger; + configurationUtilities: ActionsConfigurationUtilities; +} + +// action type definition +export function getActionType(params: GetActionTypeParams): ActionType { + const { logger, configurationUtilities } = params; + return { + id: '.servicenow', + minimumLicenseRequired: 'platinum', + name: i18n.NAME, + validate: { + config: schema.object(ExternalIncidentServiceConfiguration, { + validate: curry(validate.config)(configurationUtilities), + }), + secrets: schema.object(ExternalIncidentServiceSecretConfiguration, { + validate: curry(validate.secrets)(configurationUtilities), + }), + params: ExecutorParamsSchema, + }, + executor: curry(executor)({ logger }), + }; +} + +// action executor + +async function executor( + { logger }: { logger: Logger }, + execOptions: ActionTypeExecutorOptions +): Promise { + const { actionId, config, params, secrets } = execOptions; + const { subAction, subActionParams } = params as ExecutorParams; + let data = {}; + + const res: Pick & + Pick = { + status: 'ok', + actionId, + }; + + const externalService = createExternalService({ + config, + secrets, + }); + + if (!api[subAction]) { + throw new Error('[Action][ExternalService] Unsupported subAction type.'); + } + + if (subAction !== 'pushToService') { + throw new Error('[Action][ExternalService] subAction not implemented.'); + } + + const mapParams = (mapping: Map): AnyParams => { + return Object.keys(params).reduce((prev: AnyParams, curr: string): AnyParams => { + const field = mapping.get(curr); + if (field) { + prev[field.target] = get(params, curr); + } + return prev; + }, {}); + }; + + if (subAction === 'pushToService') { + const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; + + const mapping = config.indexConfiguration ? buildMap(config.indexConfiguration.mapping) : null; + const externalObject = config.indexConfiguration && mapping ? mapParams(mapping) : {}; + + data = await api.pushToService({ + externalService, + mapping, + params: { ...pushToServiceParams, externalObject }, + secrets, + }); + } + + return { + ...res, + data, + }; +} diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts index 37228380910b3..3b6d611d91451 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts @@ -9,7 +9,7 @@ import { PushToServiceApiParams, ExecutorSubActionPushParams, MapRecord, -} from '../case/types'; +} from './types'; const createMock = (): jest.Mocked => { const service = { @@ -35,22 +35,9 @@ const createMock = (): jest.Mocked => { url: 'https://instance.service-now.com/nav_to.do?uri=incident.do?sys_id=123', }) ), - createComment: jest.fn(), + findIncidents: jest.fn(), }; - service.createComment.mockImplementationOnce(() => - Promise.resolve({ - commentId: 'case-comment-1', - pushedDate: '2020-03-10T12:24:20.000Z', - }) - ); - - service.createComment.mockImplementationOnce(() => - Promise.resolve({ - commentId: 'case-comment-2', - pushedDate: '2020-03-10T12:24:20.000Z', - }) - ); return service; }; @@ -81,37 +68,19 @@ mapping.set('short_description', { }); const executorParams: ExecutorSubActionPushParams = { - caseId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', + savedObjectId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', externalId: 'incident-3', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { fullName: 'Elastic User', username: 'elastic' }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { fullName: 'Elastic User', username: 'elastic' }, title: 'Incident title', description: 'Incident description', - comments: [ - { - commentId: 'case-comment-1', - comment: 'A comment', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { fullName: 'Elastic User', username: 'elastic' }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { fullName: 'Elastic User', username: 'elastic' }, - }, - { - commentId: 'case-comment-2', - comment: 'Another comment', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { fullName: 'Elastic User', username: 'elastic' }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { fullName: 'Elastic User', username: 'elastic' }, - }, - ], + comments: 'case-comment-1', + severity: '3', + urgency: '3', + impact: '3', }; const apiParams: PushToServiceApiParams = { ...executorParams, - externalCase: { short_description: 'Incident title', description: 'Incident description' }, + externalObject: { short_description: 'Incident title', description: 'Incident description' }, }; export { externalServiceMock, mapping, executorParams, apiParams }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts new file mode 100644 index 0000000000000..c6396b6af68f9 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -0,0 +1,81 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema } from '@kbn/config-schema'; + +export const MappingActionType = schema.oneOf([ + schema.literal('nothing'), + schema.literal('overwrite'), + schema.literal('append'), +]); + +export const MapRecordSchema = schema.object({ + source: schema.string(), + target: schema.string(), + actionType: MappingActionType, +}); + +export const IncidentConfigurationSchema = schema.object({ + mapping: schema.arrayOf(MapRecordSchema), +}); + +export const ExternalIncidentServiceConfiguration = { + apiUrl: schema.string(), + // did it otional for the current stage to support Case ServiceNow implementation + incidentConfiguration: schema.maybe(IncidentConfigurationSchema), +}; + +export const ExternalIncidentServiceConfigurationSchema = schema.object( + ExternalIncidentServiceConfiguration +); + +export const ExternalIncidentServiceSecretConfiguration = { + password: schema.string(), + username: schema.string(), +}; + +export const ExternalIncidentServiceSecretConfigurationSchema = schema.object( + ExternalIncidentServiceSecretConfiguration +); + +export const ExecutorSubActionSchema = schema.oneOf([ + schema.literal('getIncident'), + schema.literal('pushToService'), + schema.literal('handshake'), +]); + +export const ExecutorSubActionPushParamsSchema = schema.object({ + savedObjectId: schema.string(), + title: schema.string(), + description: schema.nullable(schema.string()), + comments: schema.nullable(schema.string()), + externalId: schema.nullable(schema.string()), + severity: schema.nullable(schema.string()), + urgency: schema.nullable(schema.string()), + impact: schema.nullable(schema.string()), +}); + +export const ExecutorSubActionGetIncidentParamsSchema = schema.object({ + externalId: schema.string(), +}); + +// Reserved for future implementation +export const ExecutorSubActionHandshakeParamsSchema = schema.object({}); + +export const ExecutorParamsSchema = schema.oneOf([ + schema.object({ + subAction: schema.literal('getIncident'), + subActionParams: ExecutorSubActionGetIncidentParamsSchema, + }), + schema.object({ + subAction: schema.literal('handshake'), + subActionParams: ExecutorSubActionHandshakeParamsSchema, + }), + schema.object({ + subAction: schema.literal('pushToService'), + subActionParams: ExecutorSubActionPushParamsSchema, + }), +]); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts index f65cd5430560e..7bf471fb92638 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts @@ -8,7 +8,7 @@ import axios from 'axios'; import { createExternalService } from './service'; import * as utils from '../case/utils'; -import { ExternalService } from '../case/types'; +import { ExternalService } from './types'; jest.mock('axios'); jest.mock('../case/utils', () => { @@ -198,58 +198,22 @@ describe('ServiceNow service', () => { '[Action][ServiceNow]: Unable to update incident with id 1. Error: An error has occurred' ); }); - }); - - describe('createComment', () => { test('it creates the comment correctly', async () => { patchMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_updated_on: '2020-03-10 12:24:20' } }, + data: { result: { sys_id: '11', number: 'INC011', sys_updated_on: '2020-03-10 12:24:20' } }, })); - const res = await service.createComment({ + const res = await service.updateIncident({ incidentId: '1', - comment: { comment: 'comment', commentId: 'comment-1' }, - field: 'comments', + comment: 'comment-1', }); expect(res).toEqual({ - commentId: 'comment-1', + title: 'INC011', + id: '11', pushedDate: '2020-03-10T12:24:20.000Z', + url: 'https://dev102283.service-now.com/nav_to.do?uri=incident.do?sys_id=1', }); }); - - test('it should call request with correct arguments', async () => { - patchMock.mockImplementation(() => ({ - data: { result: { sys_id: '1', number: 'INC01', sys_updated_on: '2020-03-10 12:24:20' } }, - })); - - await service.createComment({ - incidentId: '1', - comment: { comment: 'comment', commentId: 'comment-1' }, - field: 'my_field', - }); - - expect(patchMock).toHaveBeenCalledWith({ - axios, - url: 'https://dev102283.service-now.com/api/now/v2/table/incident/1', - data: { my_field: 'comment' }, - }); - }); - - test('it should throw an error', async () => { - patchMock.mockImplementation(() => { - throw new Error('An error has occurred'); - }); - - expect( - service.createComment({ - incidentId: '1', - comment: { comment: 'comment', commentId: 'comment-1' }, - field: 'comments', - }) - ).rejects.toThrow( - '[Action][ServiceNow]: Unable to create comment at incident with id 1. Error: An error has occurred' - ); - }); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index 541fefce2f2ff..604d3ce067e04 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -6,7 +6,7 @@ import axios from 'axios'; -import { ExternalServiceCredentials, ExternalService, ExternalServiceParams } from '../case/types'; +import { ExternalServiceCredentials, ExternalService, ExternalServiceParams } from './types'; import { addTimeZoneToDate, patch, request, getErrorMessage } from '../case/utils'; import * as i18n from './translations'; @@ -15,12 +15,10 @@ import { ServiceNowSecretConfigurationType, CreateIncidentRequest, UpdateIncidentRequest, - CreateCommentRequest, } from './types'; const API_VERSION = 'v2'; const INCIDENT_URL = `api/now/${API_VERSION}/table/incident`; -const COMMENT_URL = `api/now/${API_VERSION}/table/incident`; // Based on: https://docs.servicenow.com/bundle/orlando-platform-user-interface/page/use/navigation/reference/r_NavigatingByURLExamples.html const VIEW_INCIDENT_URL = `nav_to.do?uri=incident.do?sys_id=`; @@ -37,7 +35,6 @@ export const createExternalService = ({ } const incidentUrl = `${url}/${INCIDENT_URL}`; - const commentUrl = `${url}/${COMMENT_URL}`; const axiosInstance = axios.create({ auth: { username, password }, }); @@ -61,6 +58,30 @@ export const createExternalService = ({ } }; + const findIncidents = async (params?: Record) => { + const query = params + ? Object.keys(params).reduce( + (pkey: string, res: string) => `${res}${pkey}:${params[pkey]}&`, + '?' + ) + : ''; + try { + const res = await request({ + axios: axiosInstance, + url: `${incidentUrl}${query}`, + }); + + return { ...res.data.result }; + } catch (error) { + throw new Error( + getErrorMessage( + i18n.NAME, + `Unable to find incidents by query ${query}. Error: ${error.message}` + ) + ); + } + }; + const createIncident = async ({ incident }: ExternalServiceParams) => { try { const res = await request({ @@ -107,32 +128,10 @@ export const createExternalService = ({ } }; - const createComment = async ({ incidentId, comment, field }: ExternalServiceParams) => { - try { - const res = await patch({ - axios: axiosInstance, - url: `${commentUrl}/${incidentId}`, - data: { [field]: comment.comment }, - }); - - return { - commentId: comment.commentId, - pushedDate: new Date(addTimeZoneToDate(res.data.result.sys_updated_on)).toISOString(), - }; - } catch (error) { - throw new Error( - getErrorMessage( - i18n.NAME, - `Unable to create comment at incident with id ${incidentId}. Error: ${error.message}` - ) - ); - } - }; - return { getIncident, createIncident, updateIncident, - createComment, + findIncidents, }; }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts index 3d6138169c4cc..856586badead3 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts @@ -9,3 +9,11 @@ import { i18n } from '@kbn/i18n'; export const NAME = i18n.translate('xpack.actions.builtin.case.servicenowTitle', { defaultMessage: 'ServiceNow', }); + +export const WHITE_LISTED_ERROR = (message: string) => + i18n.translate('xpack.actions.builtin.case.configuration.apiWhitelistError', { + defaultMessage: 'error configuring connector action: {message}', + values: { + message, + }, + }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts index d8476b7dca54a..040de32b78fe2 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts @@ -4,10 +4,31 @@ * you may not use this file except in compliance with the Elastic License. */ -export { - ExternalIncidentServiceConfiguration as ServiceNowPublicConfigurationType, - ExternalIncidentServiceSecretConfiguration as ServiceNowSecretConfigurationType, -} from '../case/types'; +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { TypeOf } from '@kbn/config-schema'; +import { + ExternalIncidentServiceConfigurationSchema, + ExternalIncidentServiceSecretConfigurationSchema, + ExecutorParamsSchema, + ExecutorSubActionPushParamsSchema, + MapRecordSchema, + IncidentConfigurationSchema, + ExecutorSubActionGetIncidentParamsSchema, + ExecutorSubActionHandshakeParamsSchema, +} from './schema'; +import { ActionsConfigurationUtilities } from '../../actions_config'; + +export interface AnyParams { + [index: string]: string | number | object | undefined | null; +} + +export type ServiceNowPublicConfigurationType = TypeOf< + typeof ExternalIncidentServiceConfigurationSchema +>; +export type ServiceNowSecretConfigurationType = TypeOf< + typeof ExternalIncidentServiceSecretConfigurationSchema +>; export interface CreateIncidentRequest { summary: string; @@ -19,3 +40,109 @@ export type UpdateIncidentRequest = Partial; export interface CreateCommentRequest { [key: string]: string; } + +export type ExecutorParams = TypeOf; +export type ExecutorSubActionPushParams = TypeOf; + +export type IncidentConfiguration = TypeOf; +export type MapRecord = TypeOf; + +export interface ExternalServiceCredentials { + config: Record; + secrets: Record; +} + +export interface ExternalServiceValidation { + config: (configurationUtilities: ActionsConfigurationUtilities, configObject: unknown) => void; + secrets: (configurationUtilities: ActionsConfigurationUtilities, secrets: unknown) => void; +} + +export interface ExternalServiceIncidentResponse { + id: string; + title: string; + url: string; + pushedDate: string; +} + +export interface ExternalServiceCommentResponse { + commentId: string; + pushedDate: string; + externalCommentId?: string; +} + +export interface ExternalServiceParams { + [index: string]: any; +} + +export interface ExternalService { + getIncident: (id: string) => Promise; + createIncident: (params: ExternalServiceParams) => Promise; + updateIncident: (params: ExternalServiceParams) => Promise; + findIncidents: (params?: Record) => Promise; +} + +export interface PushToServiceApiParams extends ExecutorSubActionPushParams { + externalObject: Record; +} + +export interface ExternalServiceApiHandlerArgs { + externalService: ExternalService; + mapping: Map | null; +} + +export type ExecutorSubActionGetIncidentParams = TypeOf< + typeof ExecutorSubActionGetIncidentParamsSchema +>; + +export type ExecutorSubActionHandshakeParams = TypeOf< + typeof ExecutorSubActionHandshakeParamsSchema +>; + +export interface PushToServiceApiHandlerArgs extends ExternalServiceApiHandlerArgs { + params: PushToServiceApiParams; + secrets: Record; +} + +export interface GetIncidentApiHandlerArgs extends ExternalServiceApiHandlerArgs { + params: ExecutorSubActionGetIncidentParams; +} + +export interface HandshakeApiHandlerArgs extends ExternalServiceApiHandlerArgs { + params: ExecutorSubActionHandshakeParams; +} + +export interface PushToServiceResponse extends ExternalServiceIncidentResponse { + comments?: ExternalServiceCommentResponse[]; +} + +export interface ExternalServiceApi { + handshake: (args: HandshakeApiHandlerArgs) => Promise; + pushToService: (args: PushToServiceApiHandlerArgs) => Promise; + getIncident: (args: GetIncidentApiHandlerArgs) => Promise; +} + +export interface PipedField { + key: string; + value: string; + actionType: string; + pipes: string[]; +} + +export interface PrepareFieldsForTransformArgs { + params: PushToServiceApiParams; + mapping: Map; + defaultPipes?: string[]; +} + +export interface TransformFieldsArgs { + params: PushToServiceApiParams; + fields: PipedField[]; + currentIncident?: ExternalServiceParams; +} + +export interface TransformerArgs { + value: string; + date?: string; + user?: string; + previousValue?: string; +} diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts index 7226071392bc6..8c01bd94713e4 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts @@ -4,8 +4,27 @@ * you may not use this file except in compliance with the Elastic License. */ -import { validateCommonConfig, validateCommonSecrets } from '../case/validators'; import { ExternalServiceValidation } from '../case/types'; +import { ActionsConfigurationUtilities } from '../../actions_config'; +import { ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType } from './types'; + +import * as i18n from './translations'; + +export const validateCommonConfig = ( + configurationUtilities: ActionsConfigurationUtilities, + configObject: ServiceNowPublicConfigurationType +) => { + try { + configurationUtilities.ensureWhitelistedUri(configObject.apiUrl); + } catch (whitelistError) { + return i18n.WHITE_LISTED_ERROR(whitelistError.message); + } +}; + +export const validateCommonSecrets = ( + configurationUtilities: ActionsConfigurationUtilities, + secrets: ServiceNowSecretConfigurationType +) => {}; export const validate: ExternalServiceValidation = { config: validateCommonConfig, diff --git a/x-pack/plugins/case/common/api/cases/case.ts b/x-pack/plugins/case/common/api/cases/case.ts index 283196373fe9f..67b296d2ba197 100644 --- a/x-pack/plugins/case/common/api/cases/case.ts +++ b/x-pack/plugins/case/common/api/cases/case.ts @@ -130,7 +130,7 @@ export const ServiceConnectorCommentParamsRt = rt.type({ }); export const ServiceConnectorCaseParamsRt = rt.type({ - caseId: rt.string, + savedObjectId: rt.string, createdAt: rt.string, createdBy: ServiceConnectorUserParams, externalId: rt.union([rt.string, rt.null]), diff --git a/x-pack/plugins/siem/public/cases/containers/mock.ts b/x-pack/plugins/siem/public/cases/containers/mock.ts index 8c55e55693963..6437f21209377 100644 --- a/x-pack/plugins/siem/public/cases/containers/mock.ts +++ b/x-pack/plugins/siem/public/cases/containers/mock.ts @@ -133,7 +133,7 @@ const basicAction = { export const casePushParams = { actionBy: elasticUser, - caseId: basicCaseId, + savedObjectId: basicCaseId, createdAt: basicCreatedAt, createdBy: elasticUser, externalId: null, diff --git a/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx b/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx index 4d25ac7fbf0db..6b8d7c9f713e3 100644 --- a/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx +++ b/x-pack/plugins/siem/public/cases/containers/use_post_push_to_service.tsx @@ -170,7 +170,7 @@ export const formatServiceRequestData = ( const actualExternalService = caseServices[connectorId] ?? null; return { - caseId, + savedObjectId: caseId, createdAt, createdBy: { fullName: createdBy.fullName ?? null, 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 8f49fa46dd54e..c241997e99dd7 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 @@ -12,6 +12,7 @@ import { getPagerDutyActionType } from './pagerduty'; import { getWebhookActionType } from './webhook'; import { TypeRegistry } from '../../type_registry'; import { ActionTypeModel } from '../../../types'; +import { getServiceNowActionType } from './servicenow'; export function registerBuiltInActionTypes({ actionTypeRegistry, @@ -24,4 +25,5 @@ export function registerBuiltInActionTypes({ actionTypeRegistry.register(getIndexActionType()); actionTypeRegistry.register(getPagerDutyActionType()); actionTypeRegistry.register(getWebhookActionType()); + actionTypeRegistry.register(getServiceNowActionType()); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts new file mode 100644 index 0000000000000..b9ccc531ae0a6 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts @@ -0,0 +1,38 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import * as i18n from './translations'; +import logo from './logo.svg'; + +export const connector = { + id: '.servicenow', + name: i18n.SERVICENOW_TITLE, + logo, + enabled: true, + enabledInConfig: true, + enabledInLicense: true, + minimumLicenseRequired: 'platinum', + fields: { + short_description: { + label: i18n.MAPPING_FIELD_SHORT_DESC, + validSourceFields: ['title', 'description'], + defaultSourceField: 'title', + defaultActionType: 'overwrite', + }, + description: { + label: i18n.MAPPING_FIELD_DESC, + validSourceFields: ['title', 'description'], + defaultSourceField: 'description', + defaultActionType: 'overwrite', + }, + comments: { + label: i18n.MAPPING_FIELD_COMMENTS, + validSourceFields: ['comments'], + defaultSourceField: 'comments', + defaultActionType: 'append', + }, + }, +}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/index.ts similarity index 54% rename from x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts rename to x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/index.ts index 4ad8108c3b137..65bb3ae4f5a37 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/config.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/index.ts @@ -4,10 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ExternalServiceConfiguration } from '../case/types'; -import * as i18n from './translations'; - -export const config: ExternalServiceConfiguration = { - id: '.servicenow', - name: i18n.NAME, -}; +export { getActionType as getServiceNowActionType } from './servicenow'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/logo.svg b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/logo.svg new file mode 100644 index 0000000000000..dcd022a8dca18 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/logo.svg @@ -0,0 +1,5 @@ + + + + + diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx new file mode 100644 index 0000000000000..416927dc35a9a --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -0,0 +1,76 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { lazy } from 'react'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { isUrlInvalid } from '../../../../../../siem/public/common/utils/validators'; +import { + ValidationResult, + ActionTypeModel, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../types'; +import { connector } from './config'; +import logo from './logo.svg'; +import { ServiceNowActionConnector, ServiceNowActionParams } from './types'; +import * as i18n from './translations'; + +const validateConnector = (action: ServiceNowActionConnector): ValidationResult => { + const validationResult = { errors: {} }; + const errors = { + apiUrl: new Array(), + username: new Array(), + password: new Array(), + }; + validationResult.errors = errors; + + if (!action.config.apiUrl) { + errors.apiUrl = [...errors.apiUrl, i18n.API_URL_REQUIRED]; + } + + if (isUrlInvalid(action.config.apiUrl)) { + errors.apiUrl = [...errors.apiUrl, i18n.API_URL_INVALID]; + } + + if (!action.secrets.username) { + errors.username = [...errors.username, i18n.USERNAME_REQUIRED]; + } + + if (!action.secrets.password) { + errors.password = [...errors.password, i18n.PASSWORD_REQUIRED]; + } + + return validationResult; +}; + +export function getActionType(): ActionTypeModel< + ServiceNowActionConnector, + ServiceNowActionParams +> { + return { + id: connector.id, + iconClass: logo, + selectMessage: i18n.SERVICENOW_DESC, + actionTypeTitle: connector.name, + validateConnector, + actionConnectorFields: lazy(() => import('./servicenow_connectors')), + validateParams: (actionParams: ServiceNowActionParams): ValidationResult => { + const validationResult = { errors: {} }; + const errors = { + description: new Array(), + title: new Array(), + }; + validationResult.errors = errors; + if (actionParams.subActionParams && !actionParams.subActionParams.description?.length) { + errors.description.push(i18n.DESCRIPTION_REQUIRED); + } + if (actionParams.subActionParams && !actionParams.subActionParams.title?.length) { + errors.title.push(i18n.TITLE_REQUIRED); + } + return validationResult; + }, + actionParamsFields: lazy(() => import('./servicenow_params')), + }; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx new file mode 100644 index 0000000000000..193effc22a114 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -0,0 +1,176 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React, { useCallback } from 'react'; + +import { + EuiFieldText, + EuiFlexGroup, + EuiFlexItem, + EuiFormRow, + EuiFieldPassword, + EuiSpacer, +} from '@elastic/eui'; + +import { isEmpty, get } from 'lodash'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ServiceNowFieldsType } from '../../../../../../case/common/api/connectors'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { FieldMapping } from '../../../../../../siem/public/cases/components/configure_cases/field_mapping'; +import { + CasesConfigurationMapping, + // eslint-disable-next-line @kbn/eslint/no-restricted-paths +} from '../../../../../../siem/public/cases/containers/configure/types'; +import { IErrorObject, ActionConnectorFieldsProps } from '../../../../types'; +import * as i18n from './translations'; +import { ServiceNowActionConnector } from './types'; +import { connector } from './config'; + +export interface ConnectorFlyoutFormProps { + errors: IErrorObject; + action: T; + onChangeSecret: (key: string, value: string) => void; + onBlurSecret: (key: string) => void; + onChangeConfig: (key: string, value: string) => void; + onBlurConfig: (key: string) => void; +} + +const ServiceNowConnectorFlyout: React.FC> = ({ action, editActionSecrets, editActionConfig, errors }) => { + const secretKeys = ['username', 'password']; + const configKeysWithDefault = ['apiUrl']; + + /* We do not provide defaults values to the fields (like empty string for apiUrl) intentionally. + * If we do, errors will be shown the first time the flyout is open even though the user did not + * interact with the form. Also, we would like to show errors for empty fields provided by the user. + /*/ + const { apiUrl, incidentConfiguration } = action.config; + + const isApiUrlInvalid: boolean = errors.apiUrl.length > 0 && apiUrl != null; + + const { username, password } = action.secrets; + + const isUsernameInvalid: boolean = errors.username.length > 0 && username != null; + const isPasswordInvalid: boolean = errors.password.length > 0 && password != null; + + const handleOnChangeActionConfig = useCallback( + (key: string, value: string) => editActionConfig(key, value), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const handleOnBlurActionConfig = useCallback( + (key: string) => { + if (!get(key, action.config)) { + editActionConfig(key, ''); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const handleOnChangeSecretConfig = useCallback( + (key: string, value: string) => editActionSecrets(key, value), + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + const handleOnBlurSecretConfig = useCallback( + (key: string) => { + if (!get(key, action.secrets)) { + editActionSecrets(key, ''); + } + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [] + ); + + return ( + <> + + + + handleOnChangeActionConfig('apiUrl', evt.target.value)} + onBlur={() => { + if (!apiUrl) { + editActionSecrets('apiUrl', ''); + } + }} + /> + + + + + + + + handleOnChangeSecretConfig('username', evt.target.value)} + onBlur={() => { + if (!username) { + editActionSecrets('username', ''); + } + }} + /> + + + + + + + + handleOnChangeSecretConfig('password', evt.target.value)} + onBlur={() => { + if (!password) { + editActionSecrets('password', ''); + } + }} + /> + + + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { ServiceNowConnectorFlyout as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx new file mode 100644 index 0000000000000..96442e0112466 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -0,0 +1,258 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { Fragment, useEffect } from 'react'; +import { EuiFormRow, EuiTextArea } from '@elastic/eui'; +import { i18n } from '@kbn/i18n'; +import { EuiSelect } from '@elastic/eui'; +import { EuiFlexGroup } from '@elastic/eui'; +import { EuiFlexItem } from '@elastic/eui'; +import { EuiFieldText } from '@elastic/eui'; +import { EuiSpacer } from '@elastic/eui'; +import { ActionParamsProps } from '../../../../types'; +import { AddMessageVariables } from '../../add_message_variables'; +import { ServiceNowActionParams } from './types'; + +const ServiceNowParamsFields: React.FunctionComponent> = ({ actionParams, editAction, index, errors, messageVariables }) => { + const { title, description, comments, severity, urgency, impact } = + actionParams.subActionParams || {}; + const selectOptions = [ + { + value: '1', + text: i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.severitySelectCriticalOptionLabel', + { + defaultMessage: 'Hight', + } + ), + }, + { + value: '2', + text: i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.severitySelectErrorOptionLabel', + { + defaultMessage: 'Medium', + } + ), + }, + { + value: '3', + text: i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.severitySelectWarningOptionLabel', + { + defaultMessage: 'Low', + } + ), + }, + ]; + + const editSubActionProperty = (key: string, value: {}) => { + const newProps = { ...actionParams.subActionParams, [key]: value }; + editAction('subActionParams', newProps, index); + }; + + useEffect(() => { + editAction('subAction', 'pushToService', index); + if (messageVariables?.find((variable) => variable === 'alertId')) { + editSubActionProperty('savedObjectId', '{{alertId}}'); + } + if (!urgency) { + editSubActionProperty('urgency', '3'); + } + if (!impact) { + editSubActionProperty('impact', '3'); + } + if (!severity) { + editSubActionProperty('severity', '3'); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + + const onSelectMessageVariable = (paramsProperty: string, variable: string) => { + editSubActionProperty( + paramsProperty, + ((actionParams as any)[paramsProperty] ?? '').concat(` {{${variable}}}`) + ); + }; + + return ( + + + { + editSubActionProperty('urgency', e.target.value); + }} + /> + + + + + + { + editSubActionProperty('severity', e.target.value); + }} + /> + + + + + { + editSubActionProperty('impact', e.target.value); + }} + /> + + + + + 0 && title !== undefined} + label={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.titleFieldLabel', + { + defaultMessage: 'Short description', + } + )} + labelAppend={ + onSelectMessageVariable('title', variable)} + paramsProperty="title" + /> + } + > + 0 && title !== undefined} + value={title || ''} + onChange={(e: React.ChangeEvent) => { + editSubActionProperty('title', e.target.value); + }} + onBlur={() => { + if (!title) { + editSubActionProperty('title', ''); + } + }} + /> + + 0 && description !== undefined} + label={i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.descriptionTextAreaFieldLabel', + { + defaultMessage: 'Description (optional)', + } + )} + labelAppend={ + + onSelectMessageVariable('description', variable) + } + paramsProperty="description" + /> + } + > + 0 && description !== undefined} + name="description" + value={description || ''} + data-test-subj="incidentDescriptionTextArea" + onChange={(e) => { + editSubActionProperty('description', e.target.value); + }} + onBlur={() => { + if (!description) { + editSubActionProperty('description', ''); + } + }} + /> + + + onSelectMessageVariable('comments', variable) + } + paramsProperty="comments" + /> + } + > + { + editSubActionProperty('comments', e.target.value); + }} + onBlur={() => { + if (!comments) { + editSubActionProperty('comments', ''); + } + }} + /> + + + ); +}; + +// eslint-disable-next-line import/no-default-export +export { ServiceNowParamsFields as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts new file mode 100644 index 0000000000000..fb918295d65cf --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts @@ -0,0 +1,130 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const SERVICENOW_DESC = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.selectMessageText', + { + defaultMessage: 'Push or update data to a new incident in ServiceNow', + } +); + +export const SERVICENOW_TITLE = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.actionTypeTitle', + { + defaultMessage: 'ServiceNow', + } +); + +export const API_URL_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.apiUrlTextFieldLabel', + { + defaultMessage: 'URL', + } +); + +export const API_URL_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredApiUrlTextField', + { + defaultMessage: 'URL is required', + } +); + +export const API_URL_INVALID = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.invalidApiUrlTextField', + { + defaultMessage: 'URL is invalid', + } +); + +export const USERNAME_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.usernameTextFieldLabel', + { + defaultMessage: 'Username', + } +); + +export const USERNAME_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredUsernameTextField', + { + defaultMessage: 'Username is required', + } +); + +export const PASSWORD_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.passwordTextFieldLabel', + { + defaultMessage: 'Password', + } +); + +export const PASSWORD_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredPasswordTextField', + { + defaultMessage: 'Password is required', + } +); + +export const API_TOKEN_LABEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.apiTokenTextFieldLabel', + { + defaultMessage: 'Api token', + } +); + +export const API_TOKEN_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredApiTokenTextField', + { + defaultMessage: 'Api token is required', + } +); + +export const EMAIL_LABEL = i18n.translate('xpack.siem.case.connectors.common.emailTextFieldLabel', { + defaultMessage: 'Email', +}); + +export const EMAIL_REQUIRED = i18n.translate( + 'xpack.siem.case.connectors.common.requiredEmailTextField', + { + defaultMessage: 'Email is required', + } +); + +export const MAPPING_FIELD_SHORT_DESC = i18n.translate( + 'xpack.siem.case.configureCases.mappingFieldShortDescription', + { + defaultMessage: 'Short Description', + } +); + +export const MAPPING_FIELD_DESC = i18n.translate( + 'xpack.siem.case.configureCases.mappingFieldDescription', + { + defaultMessage: 'Description', + } +); + +export const MAPPING_FIELD_COMMENTS = i18n.translate( + 'xpack.siem.case.configureCases.mappingFieldComments', + { + defaultMessage: 'Comments', + } +); + +export const DESCRIPTION_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredDescriptionTextField', + { + defaultMessage: 'Description is required', + } +); + +export const TITLE_REQUIRED = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredTitleTextField', + { + defaultMessage: 'Title is required', + } +); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts new file mode 100644 index 0000000000000..43133ba22d03d --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { ActionConnector } from '../../../../types'; + +export interface ServiceNowActionConnector extends ActionConnector { + config: ServiceNowConfig; + secrets: ServiceNowSecrets; +} + +export interface ServiceNowActionParams { + subAction: string; + subActionParams: { + savedObjectId: string; + title: string; + description: string; + comments: string; + externalId: string; + severity: string; + urgency: string; + impact: string; + }; +} + +interface ServiceNowConfig { + apiUrl: string; + incidentConfiguration: Record; +} + +interface ServiceNowSecrets { + username: string; + password: string; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.tsx index 11934d3af3ceb..311ae587bbe13 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.tsx @@ -12,7 +12,7 @@ import { SlackActionConnector } from '../types'; const SlackActionFields: React.FunctionComponent> = ({ action, editActionSecrets, errors, docLinks }) => { +>> = ({ action, editActionSecrets, errors }) => { const { webhookUrl } = action.secrets; return ( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts index 2e56f4b026b4a..612bd883608d7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts @@ -12,7 +12,8 @@ interface CommandType { | 'setScheduleProperty' | 'setAlertParams' | 'setAlertActionParams' - | 'setAlertActionProperty'; + | 'setAlertActionProperty' + | 'setAlertActionSubProperty'; } export interface AlertState { @@ -25,6 +26,7 @@ export interface AlertReducerAction { key: string; value: {}; index?: number; + subKey?: string; }; } @@ -135,5 +137,32 @@ export const alertReducer = (state: any, action: AlertReducerAction) => { }; } } + case 'setAlertActionSubProperty': { + const { key, subKey, value, index } = payload; + if ( + index === undefined || + subKey === undefined || + isEqual(alert.actions[index][key][subKey], value) + ) { + return state; + } else { + const oldAction = alert.actions.splice(index, 1)[0]; + const updatedAction = { + ...oldAction, + [key]: { + ...[key], + [subKey]: value, + }, + }; + alert.actions.splice(index, 0, updatedAction); + return { + ...state, + alert: { + ...alert, + actions: [...alert.actions], + }, + }; + } + } } }; From 53ac8865f3c5c82efea397eb48d13a9903611239 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 8 Jun 2020 08:08:43 -0700 Subject: [PATCH 02/38] simple working servicenow incident per alert --- .../builtin_action_types/servicenow/api.ts | 5 ++- .../builtin_action_types/servicenow/index.ts | 31 +++++++------- .../servicenow/service.ts | 5 +-- .../servicenow/servicenow.tsx | 4 +- .../servicenow/servicenow_params.tsx | 40 ++++++++----------- .../builtin_action_types/servicenow/types.ts | 22 +++++----- 6 files changed, 52 insertions(+), 55 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 5884a8d1c54ac..347cfef3c2b4e 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -62,7 +62,10 @@ const pushToServiceHandler = async ({ incident = params; if (updateIncident) { - res = await externalService.updateIncident({ incidentId: externalId, incident }); + res = await externalService.updateIncident({ + incidentId: existingIncident![0].sys_id, + incident, + }); } else { res = await externalService.createIncident({ incident, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index 680b24e370f5a..431bea96103b8 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -13,6 +13,7 @@ import { ExternalIncidentServiceConfiguration, ExternalIncidentServiceSecretConfiguration, ExecutorParamsSchema, + ExecutorSubActionPushParamsSchema, } from './schema'; import { ActionsConfigurationUtilities } from '../../actions_config'; import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../../types'; @@ -41,7 +42,7 @@ export function getActionType(params: GetActionTypeParams): ActionType { secrets: schema.object(ExternalIncidentServiceSecretConfiguration, { validate: curry(validate.secrets)(configurationUtilities), }), - params: ExecutorParamsSchema, + params: ExecutorSubActionPushParamsSchema, }, executor: curry(executor)({ logger }), }; @@ -54,7 +55,7 @@ async function executor( execOptions: ActionTypeExecutorOptions ): Promise { const { actionId, config, params, secrets } = execOptions; - const { subAction, subActionParams } = params as ExecutorParams; + // const { subAction, subActionParams } = params as ExecutorParams; let data = {}; const res: Pick & @@ -68,13 +69,14 @@ async function executor( secrets, }); - if (!api[subAction]) { + /* if (!api[subAction]) { throw new Error('[Action][ExternalService] Unsupported subAction type.'); } if (subAction !== 'pushToService') { throw new Error('[Action][ExternalService] subAction not implemented.'); } + */ const mapParams = (mapping: Map): AnyParams => { return Object.keys(params).reduce((prev: AnyParams, curr: string): AnyParams => { @@ -86,19 +88,20 @@ async function executor( }, {}); }; - if (subAction === 'pushToService') { - const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; + // if (subAction === 'pushToService') { + // const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; - const mapping = config.indexConfiguration ? buildMap(config.indexConfiguration.mapping) : null; - const externalObject = config.indexConfiguration && mapping ? mapParams(mapping) : {}; + const mapping = config.indexConfiguration ? buildMap(config.indexConfiguration.mapping) : null; + const externalObject = config.indexConfiguration && mapping ? mapParams(mapping) : {}; - data = await api.pushToService({ - externalService, - mapping, - params: { ...pushToServiceParams, externalObject }, - secrets, - }); - } + data = await api.pushToService({ + externalService, + mapping, + // eslint-disable-next-line @typescript-eslint/no-explicit-any + params: { ...params, externalObject } as any, + secrets, + }); + // } return { ...res, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index 604d3ce067e04..3c2d1d3e7f1ac 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -60,10 +60,7 @@ export const createExternalService = ({ const findIncidents = async (params?: Record) => { const query = params - ? Object.keys(params).reduce( - (pkey: string, res: string) => `${res}${pkey}:${params[pkey]}&`, - '?' - ) + ? Object.keys(params).reduce((res, pkey) => `${res}${pkey}=${params[pkey]}&`, '?') : ''; try { const res = await request({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 416927dc35a9a..f7fabc54c75b5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -63,10 +63,10 @@ export function getActionType(): ActionTypeModel< title: new Array(), }; validationResult.errors = errors; - if (actionParams.subActionParams && !actionParams.subActionParams.description?.length) { + if (!actionParams.description?.length) { errors.description.push(i18n.DESCRIPTION_REQUIRED); } - if (actionParams.subActionParams && !actionParams.subActionParams.title?.length) { + if (!actionParams.title?.length) { errors.title.push(i18n.TITLE_REQUIRED); } return validationResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index 96442e0112466..54c32d6910edd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -19,8 +19,7 @@ import { ServiceNowActionParams } from './types'; const ServiceNowParamsFields: React.FunctionComponent> = ({ actionParams, editAction, index, errors, messageVariables }) => { - const { title, description, comments, severity, urgency, impact } = - actionParams.subActionParams || {}; + const { title, description, comments, severity, urgency, impact } = actionParams; const selectOptions = [ { value: '1', @@ -51,32 +50,27 @@ const ServiceNowParamsFields: React.FunctionComponent { - const newProps = { ...actionParams.subActionParams, [key]: value }; - editAction('subActionParams', newProps, index); - }; - useEffect(() => { - editAction('subAction', 'pushToService', index); if (messageVariables?.find((variable) => variable === 'alertId')) { - editSubActionProperty('savedObjectId', '{{alertId}}'); + editAction('savedObjectId', '{{alertId}}', index); } if (!urgency) { - editSubActionProperty('urgency', '3'); + editAction('urgency', '3', index); } if (!impact) { - editSubActionProperty('impact', '3'); + editAction('impact', '3', index); } if (!severity) { - editSubActionProperty('severity', '3'); + editAction('severity', '3', index); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const onSelectMessageVariable = (paramsProperty: string, variable: string) => { - editSubActionProperty( + editAction( paramsProperty, - ((actionParams as any)[paramsProperty] ?? '').concat(` {{${variable}}}`) + ((actionParams as any)[paramsProperty] ?? '').concat(` {{${variable}}}`), + index ); }; @@ -97,7 +91,7 @@ const ServiceNowParamsFields: React.FunctionComponent { - editSubActionProperty('urgency', e.target.value); + editAction('urgency', e.target.value, index); }} /> @@ -119,7 +113,7 @@ const ServiceNowParamsFields: React.FunctionComponent { - editSubActionProperty('severity', e.target.value); + editAction('severity', e.target.value, index); }} /> @@ -140,7 +134,7 @@ const ServiceNowParamsFields: React.FunctionComponent { - editSubActionProperty('impact', e.target.value); + editAction('impact', e.target.value, index); }} /> @@ -172,11 +166,11 @@ const ServiceNowParamsFields: React.FunctionComponent 0 && title !== undefined} value={title || ''} onChange={(e: React.ChangeEvent) => { - editSubActionProperty('title', e.target.value); + editAction('title', e.target.value, index); }} onBlur={() => { if (!title) { - editSubActionProperty('title', ''); + editAction('title', '', index); } }} /> @@ -208,11 +202,11 @@ const ServiceNowParamsFields: React.FunctionComponent { - editSubActionProperty('description', e.target.value); + editAction('description', e.target.value, index); }} onBlur={() => { if (!description) { - editSubActionProperty('description', ''); + editAction('description', '', index); } }} /> @@ -241,11 +235,11 @@ const ServiceNowParamsFields: React.FunctionComponent { - editSubActionProperty('comments', e.target.value); + editAction('comments', e.target.value, index); }} onBlur={() => { if (!comments) { - editSubActionProperty('comments', ''); + editAction('comments', '', index); } }} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 43133ba22d03d..6c5b6a06afb88 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -12,17 +12,17 @@ export interface ServiceNowActionConnector extends ActionConnector { } export interface ServiceNowActionParams { - subAction: string; - subActionParams: { - savedObjectId: string; - title: string; - description: string; - comments: string; - externalId: string; - severity: string; - urgency: string; - impact: string; - }; + // subAction: string; + // subActionParams: { + savedObjectId: string; + title: string; + description: string; + comments: string; + externalId: string; + severity: string; + urgency: string; + impact: string; + // }; } interface ServiceNowConfig { From 7c529a043f6a397a0185f8b69ef60d3d4e9f933f Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 8 Jun 2020 11:25:14 -0700 Subject: [PATCH 03/38] fixed running times --- .../server/builtin_action_types/servicenow/api.ts | 10 ++++++---- .../server/builtin_action_types/servicenow/service.ts | 2 +- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 347cfef3c2b4e..4a15650238ae2 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -36,7 +36,7 @@ const pushToServiceHandler = async ({ }: PushToServiceApiHandlerArgs): Promise => { const { savedObjectId, externalId } = params; const existingIncident = await externalService.findIncidents({ user_input: savedObjectId }); - const updateIncident = existingIncident || externalId ? true : false; + const updateIncident = existingIncident ? true : false; const defaultPipes = updateIncident ? ['informationUpdated'] : ['informationCreated']; let currentIncident: ExternalServiceParams | undefined; let res: PushToServiceResponse; @@ -68,9 +68,11 @@ const pushToServiceHandler = async ({ }); } else { res = await externalService.createIncident({ - incident, - caller_id: secrets.username, - user_input: savedObjectId, + incident: { + ...incident, + caller_id: secrets.username, + user_input: savedObjectId, + }, }); } return res; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index 3c2d1d3e7f1ac..4820adc6b52d5 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -68,7 +68,7 @@ export const createExternalService = ({ url: `${incidentUrl}${query}`, }); - return { ...res.data.result }; + return res.data.result.length > 0 ? { ...res.data.result } : undefined; } catch (error) { throw new Error( getErrorMessage( From cb5e3b2fb0e1917a2b1a998fb4c2325a0954c200 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 8 Jun 2020 15:48:00 -0700 Subject: [PATCH 04/38] rely on externalId for update incident on the next execution --- .../servicenow/api.test.ts | 65 ++++++++++++------- .../builtin_action_types/servicenow/api.ts | 9 ++- 2 files changed, 44 insertions(+), 30 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 58eed64b0c8e4..f332df085d684 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -24,7 +24,7 @@ describe('api', () => { describe('create incident', () => { test('it creates an incident', async () => { const params = { ...apiParams, externalId: null }; - const res = await api.pushToService({ externalService, mapping, params }); + const res = await api.pushToService({ externalService, mapping, params, secrets: {} }); expect(res).toEqual({ id: 'incident-1', @@ -46,7 +46,12 @@ describe('api', () => { test('it creates an incident without comments', async () => { const params = { ...apiParams, externalId: null, comments: [] }; - const res = await api.pushToService({ externalService, mapping, params }); + const res = await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + }); expect(res).toEqual({ id: 'incident-1', @@ -58,7 +63,7 @@ describe('api', () => { test('it calls createIncident correctly', async () => { const params = { ...apiParams, externalId: null }; - await api.pushToService({ externalService, mapping, params }); + await api.pushToService({ externalService, mapping, params, secrets: {} }); expect(externalService.createIncident).toHaveBeenCalledWith({ incident: { @@ -73,9 +78,9 @@ describe('api', () => { test('it calls createComment correctly', async () => { const params = { ...apiParams, externalId: null }; - await api.pushToService({ externalService, mapping, params }); - expect(externalService.createComment).toHaveBeenCalledTimes(2); - expect(externalService.createComment).toHaveBeenNthCalledWith(1, { + await api.pushToService({ externalService, mapping, params, secrets: {} }); + expect(externalService.updateIncident).toHaveBeenCalledTimes(2); + expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { incidentId: 'incident-1', comment: { commentId: 'case-comment-1', @@ -94,7 +99,7 @@ describe('api', () => { field: 'comments', }); - expect(externalService.createComment).toHaveBeenNthCalledWith(2, { + expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { incidentId: 'incident-1', comment: { commentId: 'case-comment-2', @@ -117,7 +122,12 @@ describe('api', () => { describe('update incident', () => { test('it updates an incident', async () => { - const res = await api.pushToService({ externalService, mapping, params: apiParams }); + const res = await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + }); expect(res).toEqual({ id: 'incident-2', @@ -139,7 +149,12 @@ describe('api', () => { test('it updates an incident without comments', async () => { const params = { ...apiParams, comments: [] }; - const res = await api.pushToService({ externalService, mapping, params }); + const res = await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + }); expect(res).toEqual({ id: 'incident-2', @@ -151,7 +166,7 @@ describe('api', () => { test('it calls updateIncident correctly', async () => { const params = { ...apiParams }; - await api.pushToService({ externalService, mapping, params }); + await api.pushToService({ externalService, mapping, params, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', @@ -167,9 +182,9 @@ describe('api', () => { test('it calls createComment correctly', async () => { const params = { ...apiParams }; - await api.pushToService({ externalService, mapping, params }); - expect(externalService.createComment).toHaveBeenCalledTimes(2); - expect(externalService.createComment).toHaveBeenNthCalledWith(1, { + await api.pushToService({ externalService, mapping, params, secrets: {} }); + expect(externalService.updateIncident).toHaveBeenCalledTimes(2); + expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { incidentId: 'incident-2', comment: { commentId: 'case-comment-1', @@ -188,7 +203,7 @@ describe('api', () => { field: 'comments', }); - expect(externalService.createComment).toHaveBeenNthCalledWith(2, { + expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { incidentId: 'incident-2', comment: { commentId: 'case-comment-2', @@ -231,7 +246,7 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -264,7 +279,7 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -295,7 +310,7 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -328,7 +343,7 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: {}, @@ -356,7 +371,7 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -387,7 +402,7 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -420,7 +435,7 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -451,7 +466,7 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -484,7 +499,7 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams }); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -515,8 +530,8 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams }); - expect(externalService.createComment).not.toHaveBeenCalled(); + await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + expect(externalService.updateIncident).not.toHaveBeenCalled(); }); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 4a15650238ae2..8cb3bcaf2a22a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -34,9 +34,8 @@ const pushToServiceHandler = async ({ params, secrets, }: PushToServiceApiHandlerArgs): Promise => { - const { savedObjectId, externalId } = params; - const existingIncident = await externalService.findIncidents({ user_input: savedObjectId }); - const updateIncident = existingIncident ? true : false; + const { externalId } = params; + const updateIncident = externalId ? true : false; const defaultPipes = updateIncident ? ['informationUpdated'] : ['informationCreated']; let currentIncident: ExternalServiceParams | undefined; let res: PushToServiceResponse; @@ -63,15 +62,15 @@ const pushToServiceHandler = async ({ if (updateIncident) { res = await externalService.updateIncident({ - incidentId: existingIncident![0].sys_id, + incidentId: externalId, incident, }); } else { res = await externalService.createIncident({ incident: { ...incident, + short_description: params.title, caller_id: secrets.username, - user_input: savedObjectId, }, }); } From 5f9d371034b5e84377a5e35131bb6c94d2b0abf8 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 10 Jun 2020 17:38:57 -0700 Subject: [PATCH 05/38] Added consumer to the action type to be able to split ServiceNow for Cases and Alerts --- x-pack/plugins/actions/common/types.ts | 1 + .../server/action_type_registry.test.ts | 1 + .../actions/server/actions_client.test.ts | 26 ++++++ .../plugins/actions/server/actions_client.ts | 11 ++- .../servicenow/service.test.ts | 2 +- x-pack/plugins/actions/server/config.test.ts | 8 +- x-pack/plugins/actions/server/config.ts | 1 + .../server/create_execute_function.test.ts | 2 + .../actions/server/routes/create.test.ts | 3 + .../plugins/actions/server/routes/create.ts | 1 + .../plugins/actions/server/routes/get.test.ts | 4 + .../actions/server/routes/update.test.ts | 3 + .../server/saved_objects/mappings.json | 3 + x-pack/plugins/actions/server/types.ts | 2 + .../rules/rule_actions_field/index.tsx | 1 + .../components/configure_cases/index.tsx | 1 + .../containers/configure/use_connectors.tsx | 2 +- .../public/common/lib/connectors/config.ts | 5 +- .../public/common/lib/connectors/index.ts | 1 - .../lib/connectors/servicenow/config.ts | 39 --------- .../lib/connectors/servicenow/flyout.tsx | 87 ------------------- .../lib/connectors/servicenow/index.tsx | 47 ---------- .../common/lib/connectors/servicenow/logo.svg | 5 -- .../lib/connectors/servicenow/translations.ts | 30 ------- .../common/lib/connectors/servicenow/types.ts | 22 ----- .../security_solution/public/plugin.tsx | 3 +- x-pack/plugins/triggers_actions_ui/README.md | 8 +- .../builtin_action_types/servicenow/config.ts | 2 +- .../servicenow/servicenow.tsx | 6 +- .../servicenow/servicenow_connectors.tsx | 69 +++++++++------ .../builtin_action_types/servicenow/types.ts | 16 +++- .../context/actions_connectors_context.tsx | 1 + .../lib/check_action_type_enabled.test.tsx | 2 + .../action_connector_form.test.tsx | 1 + .../action_form.test.tsx | 14 +++ .../action_connector_form/action_form.tsx | 5 +- .../connector_add_flyout.test.tsx | 4 + .../connector_add_flyout.tsx | 2 + .../connector_add_modal.tsx | 3 + .../components/actions_connectors_list.tsx | 3 +- .../sections/alert_form/alert_form.tsx | 1 + .../triggers_actions_ui/public/types.ts | 1 + 42 files changed, 173 insertions(+), 276 deletions(-) delete mode 100644 x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/config.ts delete mode 100644 x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/flyout.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/index.tsx delete mode 100644 x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/logo.svg delete mode 100644 x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/translations.ts delete mode 100644 x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/types.ts diff --git a/x-pack/plugins/actions/common/types.ts b/x-pack/plugins/actions/common/types.ts index 49e8f3e80b14a..35a81e4dd7431 100644 --- a/x-pack/plugins/actions/common/types.ts +++ b/x-pack/plugins/actions/common/types.ts @@ -16,6 +16,7 @@ export interface ActionType { } export interface ActionResult { + consumer: string; id: string; actionTypeId: string; name: string; diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index ce5c1fe8500fb..d64c51619b161 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -36,6 +36,7 @@ beforeEach(() => { name: 'Slack #xyz', secrets: {}, isPreconfigured: true, + consumer: 'alerts', }, ], }; diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index bf55a1c18d169..a02f4625a9c02 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -65,6 +65,7 @@ describe('create()', () => { name: 'my name', actionTypeId: 'my-action-type', config: {}, + consumer: 'alerts', }, references: [], }; @@ -80,6 +81,7 @@ describe('create()', () => { name: 'my name', actionTypeId: 'my-action-type', config: {}, + consumer: 'alerts', secrets: {}, }, }); @@ -89,6 +91,7 @@ describe('create()', () => { name: 'my name', actionTypeId: 'my-action-type', config: {}, + consumer: 'alerts', }); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); expect(savedObjectsClient.create.mock.calls[0]).toMatchInlineSnapshot(` @@ -97,6 +100,7 @@ describe('create()', () => { Object { "actionTypeId": "my-action-type", "config": Object {}, + "consumer": "alerts", "name": "my name", "secrets": Object {}, }, @@ -123,6 +127,7 @@ describe('create()', () => { actionTypeId: 'my-action-type', config: {}, secrets: {}, + consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -138,6 +143,7 @@ describe('create()', () => { actionTypeId: 'unregistered-action-type', config: {}, secrets: {}, + consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -164,6 +170,7 @@ describe('create()', () => { c: true, }, secrets: {}, + consumer: 'alerts', }, references: [], }); @@ -177,6 +184,7 @@ describe('create()', () => { c: true, }, secrets: {}, + consumer: 'alerts', }, }); expect(result).toEqual({ @@ -189,6 +197,7 @@ describe('create()', () => { b: true, c: true, }, + consumer: 'alerts', }); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); expect(savedObjectsClient.create.mock.calls[0]).toMatchInlineSnapshot(` @@ -201,6 +210,7 @@ describe('create()', () => { "b": true, "c": true, }, + "consumer": "alerts", "name": "my name", "secrets": Object {}, }, @@ -259,6 +269,7 @@ describe('create()', () => { actionTypeId: 'my-action-type', config: {}, secrets: {}, + consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -294,6 +305,7 @@ describe('create()', () => { actionTypeId: 'my-action-type', config: {}, secrets: {}, + consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); @@ -340,6 +352,7 @@ describe('get()', () => { config: { foo: 'bar', }, + consumer: 'alerts', }, ], }); @@ -350,6 +363,7 @@ describe('get()', () => { actionTypeId: '.slack', isPreconfigured: true, name: 'test', + consumer: 'alerts', }); expect(savedObjectsClient.get).not.toHaveBeenCalled(); }); @@ -370,6 +384,7 @@ describe('getAll()', () => { config: { foo: 'bar', }, + consumer: 'alerts', }, references: [], }, @@ -398,6 +413,7 @@ describe('getAll()', () => { config: { foo: 'bar', }, + consumer: 'alerts', }, ], }); @@ -411,6 +427,7 @@ describe('getAll()', () => { foo: 'bar', }, referencedByCount: 6, + consumer: 'alerts', }, { id: 'testPreconfigured', @@ -418,6 +435,7 @@ describe('getAll()', () => { isPreconfigured: true, name: 'test', referencedByCount: 2, + consumer: 'alerts', }, ]); }); @@ -436,6 +454,7 @@ describe('getBulk()', () => { config: { foo: 'bar', }, + consumer: 'alerts', }, references: [], }, @@ -463,6 +482,7 @@ describe('getBulk()', () => { config: { foo: 'bar', }, + consumer: 'alerts', }, ], }); @@ -477,6 +497,7 @@ describe('getBulk()', () => { isPreconfigured: true, name: 'test', secrets: {}, + consumer: 'alerts', }, { actionTypeId: 'test', @@ -486,6 +507,7 @@ describe('getBulk()', () => { id: '1', isPreconfigured: false, name: 'test', + consumer: 'alerts', }, ]); }); @@ -540,6 +562,7 @@ describe('update()', () => { name: 'my name', config: {}, secrets: {}, + consumer: 'alerts', }, }); expect(result).toEqual({ @@ -598,6 +621,7 @@ describe('update()', () => { name: 'my name', config: {}, secrets: {}, + consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -617,6 +641,7 @@ describe('update()', () => { type: 'action', attributes: { actionTypeId: 'my-action-type', + consumer: 'alerts', }, references: [], }); @@ -657,6 +682,7 @@ describe('update()', () => { b: true, c: true, }, + consumer: 'alerts', }); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); expect(savedObjectsClient.update.mock.calls[0]).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 48703f01f5509..cef19f913a70c 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -30,6 +30,7 @@ interface ActionUpdate extends SavedObjectAttributes { interface Action extends ActionUpdate { actionTypeId: string; + consumer: string; } interface CreateOptions { @@ -74,7 +75,7 @@ export class ActionsClient { * Create an action */ public async create({ action }: CreateOptions): Promise { - const { actionTypeId, name, config, secrets } = action; + const { actionTypeId, name, config, secrets, consumer } = action; const actionType = this.actionTypeRegistry.get(actionTypeId); const validatedActionTypeConfig = validateConfig(actionType, config); const validatedActionTypeSecrets = validateSecrets(actionType, secrets); @@ -86,6 +87,7 @@ export class ActionsClient { name, config: validatedActionTypeConfig as SavedObjectAttributes, secrets: validatedActionTypeSecrets as SavedObjectAttributes, + consumer, }); return { @@ -94,6 +96,7 @@ export class ActionsClient { name: result.attributes.name, config: result.attributes.config, isPreconfigured: false, + consumer: result.attributes.consumer, }; } @@ -124,7 +127,7 @@ export class ActionsClient { this.actionTypeRegistry.ensureActionTypeEnabled(actionTypeId); - const result = await this.savedObjectsClient.update('action', id, { + const result = await this.savedObjectsClient.update('action', id, { actionTypeId, name, config: validatedActionTypeConfig as SavedObjectAttributes, @@ -137,6 +140,7 @@ export class ActionsClient { name: result.attributes.name as string, config: result.attributes.config as Record, isPreconfigured: false, + consumer: existingObject.attributes.consumer, }; } @@ -153,6 +157,7 @@ export class ActionsClient { actionTypeId: preconfiguredActionsList.actionTypeId, name: preconfiguredActionsList.name, isPreconfigured: true, + consumer: preconfiguredActionsList.consumer, }; } const result = await this.savedObjectsClient.get('action', id); @@ -163,6 +168,7 @@ export class ActionsClient { name: result.attributes.name, config: result.attributes.config, isPreconfigured: false, + consumer: result.attributes.consumer, }; } @@ -184,6 +190,7 @@ export class ActionsClient { actionTypeId: preconfiguredAction.actionTypeId, name: preconfiguredAction.name, isPreconfigured: true, + consumer: preconfiguredAction.consumer, })), ].sort((a, b) => a.name.localeCompare(b.name)); return await injectExtraFindData( diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts index 7bf471fb92638..d38f8b28b9fbd 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts @@ -212,7 +212,7 @@ describe('ServiceNow service', () => { title: 'INC011', id: '11', pushedDate: '2020-03-10T12:24:20.000Z', - url: 'https://dev102283.service-now.com/nav_to.do?uri=incident.do?sys_id=1', + url: 'https://dev102283.service-now.com/nav_to.do?uri=incident.do?sys_id=11', }); }); }); diff --git a/x-pack/plugins/actions/server/config.test.ts b/x-pack/plugins/actions/server/config.test.ts index e86f2d7832828..4d18b892483a1 100644 --- a/x-pack/plugins/actions/server/config.test.ts +++ b/x-pack/plugins/actions/server/config.test.ts @@ -31,6 +31,7 @@ describe('config validation', () => { config: { webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, + consumer: 'test', }, }, }; @@ -46,6 +47,7 @@ describe('config validation', () => { "config": Object { "webhookUrl": "https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz", }, + "consumer": "test", "name": "Slack #xyz", "secrets": Object {}, }, @@ -85,11 +87,13 @@ function preConfiguredActionConfig(id: string) { "preconfigured": { ${JSON.stringify(id)}: { "actionTypeId": ".server-log", - "name": "server log 1" + "name": "server log 1", + "consumer": "alerts" }, "serverLog": { "actionTypeId": ".server-log", - "name": "server log 2" + "name": "server log 2", + "consumer": "alerts" } } }`); diff --git a/x-pack/plugins/actions/server/config.ts b/x-pack/plugins/actions/server/config.ts index b2f3fa2680a9c..e94b2c531439f 100644 --- a/x-pack/plugins/actions/server/config.ts +++ b/x-pack/plugins/actions/server/config.ts @@ -12,6 +12,7 @@ const preconfiguredActionSchema = schema.object({ actionTypeId: schema.string({ minLength: 1 }), config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + consumer: schema.string({ minLength: 1 }), }); export const configSchema = schema.object({ diff --git a/x-pack/plugins/actions/server/create_execute_function.test.ts b/x-pack/plugins/actions/server/create_execute_function.test.ts index 1b7752588e3d3..3f49d0c0dbcdf 100644 --- a/x-pack/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_execute_function.test.ts @@ -84,6 +84,7 @@ describe('execute()', () => { isPreconfigured: true, name: 'x', secrets: {}, + consumer: 'alerts', }, ], }); @@ -300,6 +301,7 @@ describe('execute()', () => { name: 'Slack #xyz', secrets: {}, isPreconfigured: true, + consumer: 'alerts', }, ], }); diff --git a/x-pack/plugins/actions/server/routes/create.test.ts b/x-pack/plugins/actions/server/routes/create.test.ts index 940b8ecc61f4e..68e4c2421fa36 100644 --- a/x-pack/plugins/actions/server/routes/create.test.ts +++ b/x-pack/plugins/actions/server/routes/create.test.ts @@ -42,6 +42,7 @@ describe('createActionRoute', () => { actionTypeId: 'abc', config: { foo: true }, isPreconfigured: false, + consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -98,6 +99,7 @@ describe('createActionRoute', () => { actionTypeId: 'abc', config: { foo: true }, isPreconfigured: false, + consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); @@ -126,6 +128,7 @@ describe('createActionRoute', () => { actionTypeId: 'abc', config: { foo: true }, isPreconfigured: false, + consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); diff --git a/x-pack/plugins/actions/server/routes/create.ts b/x-pack/plugins/actions/server/routes/create.ts index 8135567157583..1732a245c6df8 100644 --- a/x-pack/plugins/actions/server/routes/create.ts +++ b/x-pack/plugins/actions/server/routes/create.ts @@ -21,6 +21,7 @@ export const bodySchema = schema.object({ actionTypeId: schema.string(), config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), + consumer: schema.string(), }); export const createActionRoute = (router: IRouter, licenseState: ILicenseState) => { diff --git a/x-pack/plugins/actions/server/routes/get.test.ts b/x-pack/plugins/actions/server/routes/get.test.ts index ee2586851366c..ba2c2b397d4b2 100644 --- a/x-pack/plugins/actions/server/routes/get.test.ts +++ b/x-pack/plugins/actions/server/routes/get.test.ts @@ -43,6 +43,7 @@ describe('getActionRoute', () => { name: 'action name', config: {}, isPreconfigured: false, + consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -61,6 +62,7 @@ describe('getActionRoute', () => { "body": Object { "actionTypeId": "2", "config": Object {}, + "consumer": "alerts", "id": "1", "isPreconfigured": false, "name": "action name", @@ -91,6 +93,7 @@ describe('getActionRoute', () => { name: 'action name', config: {}, isPreconfigured: false, + consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments( @@ -125,6 +128,7 @@ describe('getActionRoute', () => { name: 'action name', config: {}, isPreconfigured: false, + consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments( diff --git a/x-pack/plugins/actions/server/routes/update.test.ts b/x-pack/plugins/actions/server/routes/update.test.ts index 323a52f2fc6e2..a90974945847f 100644 --- a/x-pack/plugins/actions/server/routes/update.test.ts +++ b/x-pack/plugins/actions/server/routes/update.test.ts @@ -42,6 +42,7 @@ describe('updateActionRoute', () => { name: 'My name', config: { foo: true }, isPreconfigured: false, + consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -99,6 +100,7 @@ describe('updateActionRoute', () => { name: 'My name', config: { foo: true }, isPreconfigured: false, + consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -142,6 +144,7 @@ describe('updateActionRoute', () => { name: 'My name', config: { foo: true }, isPreconfigured: false, + consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); diff --git a/x-pack/plugins/actions/server/saved_objects/mappings.json b/x-pack/plugins/actions/server/saved_objects/mappings.json index ef6a0c9919920..dd711fc5581b2 100644 --- a/x-pack/plugins/actions/server/saved_objects/mappings.json +++ b/x-pack/plugins/actions/server/saved_objects/mappings.json @@ -18,6 +18,9 @@ }, "secrets": { "type": "binary" + }, + "consumer": { + "type": "keyword" } } }, diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 093d22c2c1a71..d3671e54a7b55 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -69,6 +69,7 @@ export interface ActionResult { // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: Record; isPreconfigured: boolean; + consumer: string; } export interface PreConfiguredAction extends ActionResult { @@ -121,6 +122,7 @@ export interface RawAction extends SavedObjectAttributes { name: string; config: SavedObjectAttributes; secrets: SavedObjectAttributes; + consumer: string; } export interface ActionTaskParams extends SavedObjectAttributes { diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx index c6ff25f311d9c..f03bf470dfa22 100644 --- a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx @@ -137,6 +137,7 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables actionTypes={supportedActionTypes} defaultActionMessage={DEFAULT_ACTION_MESSAGE} toastNotifications={notifications.toasts} + consumer={'security'} /> ); diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx index 256c8893be941..43922462cd092 100644 --- a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.tsx @@ -198,6 +198,7 @@ const ConfigureCasesComponent: React.FC = ({ userC capabilities: application.capabilities, reloadConnectors, docLinks, + consumer: 'case', }} > { const res = await fetchConnectors({ signal: abortCtrl.signal }); if (!didCancel) { setLoading(false); - setConnectors(res); + setConnectors(res.filter((connector) => connector.consumer === 'case')); } } catch (error) { if (!didCancel) { diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts index d8b55665f7768..f3b387090d281 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts +++ b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts @@ -4,11 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { connector as serviceNowConnectorConfig } from './servicenow/config'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { connectorConfiguration as serviceNowConnectorConfig } from '../../../../../triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config'; import { connector as jiraConnectorConfig } from './jira/config'; import { ConnectorConfiguration } from './types'; export const connectorsConfiguration: Record = { - '.servicenow': serviceNowConnectorConfig, + '.servicenow': serviceNowConnectorConfig as ConnectorConfiguration, '.jira': jiraConnectorConfig, }; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts index 2ce61bef49c5e..83b07a2905ef0 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts +++ b/x-pack/plugins/security_solution/public/common/lib/connectors/index.ts @@ -4,5 +4,4 @@ * you may not use this file except in compliance with the Elastic License. */ -export { getActionType as serviceNowActionType } from './servicenow'; export { getActionType as jiraActionType } from './jira'; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/config.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/config.ts deleted file mode 100644 index 35c677c9574e3..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/config.ts +++ /dev/null @@ -1,39 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { ConnectorConfiguration } from './types'; -import * as i18n from './translations'; -import logo from './logo.svg'; - -export const connector: ConnectorConfiguration = { - id: '.servicenow', - name: i18n.SERVICENOW_TITLE, - logo, - enabled: true, - enabledInConfig: true, - enabledInLicense: true, - minimumLicenseRequired: 'platinum', - fields: { - short_description: { - label: i18n.MAPPING_FIELD_SHORT_DESC, - validSourceFields: ['title', 'description'], - defaultSourceField: 'title', - defaultActionType: 'overwrite', - }, - description: { - label: i18n.MAPPING_FIELD_DESC, - validSourceFields: ['title', 'description'], - defaultSourceField: 'description', - defaultActionType: 'overwrite', - }, - comments: { - label: i18n.MAPPING_FIELD_COMMENTS, - validSourceFields: ['comments'], - defaultSourceField: 'comments', - defaultActionType: 'append', - }, - }, -}; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/flyout.tsx b/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/flyout.tsx deleted file mode 100644 index 1e5abbab46a06..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/flyout.tsx +++ /dev/null @@ -1,87 +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; - * you may not use this file except in compliance with the Elastic License. - */ -import React from 'react'; -import { - EuiFieldText, - EuiFlexGroup, - EuiFlexItem, - EuiFormRow, - EuiFieldPassword, - EuiSpacer, -} from '@elastic/eui'; - -import * as i18n from './translations'; -import { ConnectorFlyoutFormProps } from '../types'; -import { ServiceNowActionConnector } from './types'; -import { withConnectorFlyout } from '../components/connector_flyout'; - -const ServiceNowConnectorForm: React.FC> = ({ - errors, - action, - onChangeSecret, - onBlurSecret, -}) => { - const { username, password } = action.secrets; - const isUsernameInvalid: boolean = errors.username.length > 0 && username != null; - const isPasswordInvalid: boolean = errors.password.length > 0 && password != null; - - return ( - <> - - - - onChangeSecret('username', evt.target.value)} - onBlur={() => onBlurSecret('username')} - /> - - - - - - - - onChangeSecret('password', evt.target.value)} - onBlur={() => onBlurSecret('password')} - /> - - - - - ); -}; - -export const ServiceNowConnectorFlyout = withConnectorFlyout({ - ConnectorFormComponent: ServiceNowConnectorForm, - secretKeys: ['username', 'password'], - connectorActionTypeId: '.servicenow', -}); - -// eslint-disable-next-line import/no-default-export -export { ServiceNowConnectorFlyout as default }; diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/index.tsx b/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/index.tsx deleted file mode 100644 index c9c5298365e81..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/index.tsx +++ /dev/null @@ -1,47 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { lazy } from 'react'; -import { - ValidationResult, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../../../triggers_actions_ui/public/types'; -import { connector } from './config'; -import { createActionType } from '../utils'; -import logo from './logo.svg'; -import { ServiceNowActionConnector } from './types'; -import * as i18n from './translations'; - -interface Errors { - username: string[]; - password: string[]; -} - -const validateConnector = (action: ServiceNowActionConnector): ValidationResult => { - const errors: Errors = { - username: [], - password: [], - }; - - if (!action.secrets.username) { - errors.username = [...errors.username, i18n.USERNAME_REQUIRED]; - } - - if (!action.secrets.password) { - errors.password = [...errors.password, i18n.PASSWORD_REQUIRED]; - } - - return { errors }; -}; - -export const getActionType = createActionType({ - id: connector.id, - iconClass: logo, - selectMessage: i18n.SERVICENOW_DESC, - actionTypeTitle: connector.name, - validateConnector, - actionConnectorFields: lazy(() => import('./flyout')), -}); diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/logo.svg b/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/logo.svg deleted file mode 100644 index dcd022a8dca18..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/logo.svg +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/translations.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/translations.ts deleted file mode 100644 index 0f06a4259e070..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/translations.ts +++ /dev/null @@ -1,30 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -import { i18n } from '@kbn/i18n'; - -export * from '../translations'; - -export const SERVICENOW_DESC = i18n.translate( - 'xpack.securitySolution.case.connectors.servicenow.selectMessageText', - { - defaultMessage: 'Push or update SIEM case data to a new incident in ServiceNow', - } -); - -export const SERVICENOW_TITLE = i18n.translate( - 'xpack.securitySolution.case.connectors.servicenow.actionTypeTitle', - { - defaultMessage: 'ServiceNow', - } -); - -export const MAPPING_FIELD_SHORT_DESC = i18n.translate( - 'xpack.securitySolution.case.configureCases.mappingFieldShortDescription', - { - defaultMessage: 'Short Description', - } -); diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/types.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/types.ts deleted file mode 100644 index b4a80e28c8d15..0000000000000 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/servicenow/types.ts +++ /dev/null @@ -1,22 +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; - * you may not use this file except in compliance with the Elastic License. - */ - -/* eslint-disable no-restricted-imports */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ - -import { - ServiceNowPublicConfigurationType, - ServiceNowSecretConfigurationType, -} from '../../../../../../actions/server/builtin_action_types/servicenow/types'; - -export { ServiceNowFieldsType } from '../../../../../../case/common/api/connectors'; - -export * from '../types'; - -export interface ServiceNowActionConnector { - config: ServiceNowPublicConfigurationType; - secrets: ServiceNowSecretConfigurationType; -} diff --git a/x-pack/plugins/security_solution/public/plugin.tsx b/x-pack/plugins/security_solution/public/plugin.tsx index 33bcbb748e05a..479e6c82a4937 100644 --- a/x-pack/plugins/security_solution/public/plugin.tsx +++ b/x-pack/plugins/security_solution/public/plugin.tsx @@ -17,7 +17,7 @@ import { import { FeatureCatalogueCategory } from '../../../../src/plugins/home/public'; import { initTelemetry } from './common/lib/telemetry'; import { KibanaServices } from './common/lib/kibana/services'; -import { serviceNowActionType, jiraActionType } from './common/lib/connectors'; +import { jiraActionType } from './common/lib/connectors'; import { PluginSetup, PluginStart, SetupPlugins, StartPlugins, StartServices } from './types'; import { APP_ID, APP_NAME, APP_ICON, APP_PATH } from '../common/constants'; import { ConfigureEndpointDatasource } from './management/pages/policy/view/ingest_manager_integration/configure_datasource'; @@ -46,7 +46,6 @@ export class Plugin implements IPlugin { diff --git a/x-pack/plugins/triggers_actions_ui/README.md b/x-pack/plugins/triggers_actions_ui/README.md index 5a25f7b94050e..4bbcb528eb91b 100644 --- a/x-pack/plugins/triggers_actions_ui/README.md +++ b/x-pack/plugins/triggers_actions_ui/README.md @@ -1295,6 +1295,7 @@ Then this dependencies will be used to embed Actions form or register your own a defaultActionMessage={'Alert [{{ctx.metadata.name}}] has exceeded the threshold'} actionTypes={ALOWED_BY_PLUGIN_ACTION_TYPES} toastNotifications={toastNotifications} + consumer={initialAlert.consumer} /> ); }; @@ -1317,6 +1318,7 @@ interface ActionAccordionFormProps { actionTypes?: ActionType[]; messageVariables?: string[]; defaultActionMessage?: string; + consumer: string; } ``` @@ -1334,6 +1336,7 @@ interface ActionAccordionFormProps { |actionTypes|Optional property, which allowes to define a list of available actions specific for a current plugin.| |actionTypes|Optional property, which allowes to define a list of variables for action 'message' property.| |defaultActionMessage|Optional property, which allowes to define a message value for action with 'message' property.| +|consumer|Name of the plugin that creates an action.| AlertsContextProvider value options: @@ -1425,7 +1428,8 @@ const connector = { toastNotifications: toastNotifications, actionTypeRegistry: triggers_actions_ui.actionTypeRegistry, capabilities: capabilities, - docLinks, + docLinks, + consumer: 'alerts', }} > Promise; + consumer: string; } ``` @@ -1479,6 +1484,7 @@ export interface ActionsConnectorsContextValue { |capabilities|Property, which is defining action current user usage capabilities like canSave or canDelete.| |toastNotifications|Toast messages.| |reloadConnectors|Optional function, which will be executed if connector was saved sucsessfuly, like reload list of connecotrs.| +|consumer|Name of the plugin that creates an action.| ## Embed the Edit Connector flyout within any Kibana plugin diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts index b9ccc531ae0a6..7f810cf5eb38f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config.ts @@ -7,7 +7,7 @@ import * as i18n from './translations'; import logo from './logo.svg'; -export const connector = { +export const connectorConfiguration = { id: '.servicenow', name: i18n.SERVICENOW_TITLE, logo, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 1910fb8cd155d..45595bc0f77ad 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -12,7 +12,7 @@ import { ActionTypeModel, // eslint-disable-next-line @kbn/eslint/no-restricted-paths } from '../../../../types'; -import { connector } from './config'; +import { connectorConfiguration } from './config'; import logo from './logo.svg'; import { ServiceNowActionConnector, ServiceNowActionParams } from './types'; import * as i18n from './translations'; @@ -50,10 +50,10 @@ export function getActionType(): ActionTypeModel< ServiceNowActionParams > { return { - id: connector.id, + id: connectorConfiguration.id, iconClass: logo, selectMessage: i18n.SERVICENOW_DESC, - actionTypeTitle: connector.name, + actionTypeTitle: connectorConfiguration.name, // minimumLicenseRequired: 'platinum', validateConnector, actionConnectorFields: lazy(() => import('./servicenow_connectors')), diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 7c90d85498523..50fd0300f5fbf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -14,11 +14,19 @@ import { EuiSpacer, } from '@elastic/eui'; -import { isEmpty, get } from 'lodash'; +import { isEmpty } from 'lodash'; + +// TODO: remove FieldMapping, createDefaultMapping later +// when Case ServiceNow will move their fields to the level of action execution +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { FieldMapping } from '../../../../../../security_solution/public/cases/components/configure_cases/field_mapping'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { createDefaultMapping } from '../../../../../../security_solution/public/common/lib/connectors/utils'; + import { IErrorObject, ActionConnectorFieldsProps } from '../../../../types'; import * as i18n from './translations'; -import { ServiceNowActionConnector } from './types'; -import { connector } from './config'; +import { ServiceNowActionConnector, CasesConfigurationMapping } from './types'; +import { connectorConfiguration } from './config'; export interface ConnectorFlyoutFormProps { errors: IErrorObject; @@ -32,14 +40,9 @@ export interface ConnectorFlyoutFormProps { const ServiceNowConnectorFlyout: React.FC> = ({ action, editActionSecrets, editActionConfig, errors }) => { - const secretKeys = ['username', 'password']; - const configKeysWithDefault = ['apiUrl']; - - /* We do not provide defaults values to the fields (like empty string for apiUrl) intentionally. - * If we do, errors will be shown the first time the flyout is open even though the user did not - * interact with the form. Also, we would like to show errors for empty fields provided by the user. - /*/ + // TODO: remove incidentConfiguration later, when Case ServiceNow will move their fields to the level of action execution const { apiUrl, incidentConfiguration } = action.config; + const mapping = incidentConfiguration ? incidentConfiguration.mapping : []; const isApiUrlInvalid: boolean = errors.apiUrl.length > 0 && apiUrl != null; @@ -48,36 +51,33 @@ const ServiceNowConnectorFlyout: React.FC 0 && username != null; const isPasswordInvalid: boolean = errors.password.length > 0 && password != null; + // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution + if (action.consumer === 'case' && isEmpty(mapping)) { + editActionConfig('incidentConfiguration', { + mapping: createDefaultMapping(connectorConfiguration.fields as any), + }); + } + const handleOnChangeActionConfig = useCallback( (key: string, value: string) => editActionConfig(key, value), // eslint-disable-next-line react-hooks/exhaustive-deps [] ); - const handleOnBlurActionConfig = useCallback( - (key: string) => { - if (!get(key, action.config)) { - editActionConfig(key, ''); - } - }, - // eslint-disable-next-line react-hooks/exhaustive-deps - [] - ); - const handleOnChangeSecretConfig = useCallback( (key: string, value: string) => editActionSecrets(key, value), // eslint-disable-next-line react-hooks/exhaustive-deps [] ); - const handleOnBlurSecretConfig = useCallback( - (key: string) => { - if (!get(key, action.secrets)) { - editActionSecrets(key, ''); - } - }, + const handleOnChangeMappingConfig = useCallback( + (newMapping: CasesConfigurationMapping[]) => + editActionConfig('incidentConfiguration', { + ...action.config.incidentConfiguration, + mapping: newMapping, + }), // eslint-disable-next-line react-hooks/exhaustive-deps - [] + [action.config] ); return ( @@ -160,6 +160,21 @@ const ServiceNowConnectorFlyout: React.FC + {incidentConfiguration && ( // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution + <> + + + + + + + + )} ); }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 6c5b6a06afb88..1ed72a1ba5804 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -4,6 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ +// to remove +import { CaseField, ThirdPartyField, ActionType } from '../../../../../../case/common/api'; + import { ActionConnector } from '../../../../types'; export interface ServiceNowActionConnector extends ActionConnector { @@ -25,12 +28,23 @@ export interface ServiceNowActionParams { // }; } +interface IncidentConfiguration { + mapping: CasesConfigurationMapping[]; +} + interface ServiceNowConfig { apiUrl: string; - incidentConfiguration: Record; + incidentConfiguration?: IncidentConfiguration; } interface ServiceNowSecrets { username: string; password: string; } + +// to remove +export interface CasesConfigurationMapping { + source: CaseField; + target: ThirdPartyField; + actionType: ActionType; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx index f8a9085a88656..fc3e3e1ae84c4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx @@ -19,6 +19,7 @@ export interface ActionsConnectorsContextValue { capabilities: ApplicationStart['capabilities']; reloadConnectors?: () => Promise; docLinks: DocLinksStart; + consumer: string; } const ActionsConnectorsContext = createContext(null as any); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx index 9c017aa6fd31f..28305e0fe7bb9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx @@ -102,6 +102,7 @@ describe('checkActionFormActionTypeEnabled', () => { name: 'test', secrets: {}, referencedByCount: 0, + consumer: 'alerts', }, { actionTypeId: '2', @@ -111,6 +112,7 @@ describe('checkActionFormActionTypeEnabled', () => { name: 'test', secrets: {}, referencedByCount: 0, + consumer: 'alerts', }, ]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index 17a1d929a0def..bc3be039e5a0c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -44,6 +44,7 @@ describe('action_connector_form', () => { actionTypeId: actionType.id, config: {}, secrets: {}, + consumer: 'alerts', } as ActionConnector; let wrapper; if (deps) { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 7db6b5145f895..f551a4e10515a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -124,6 +124,7 @@ describe('action_form', () => { name: 'Test connector', config: {}, isPreconfigured: false, + consumer: 'alerts', }, { secrets: {}, @@ -132,6 +133,7 @@ describe('action_form', () => { name: 'Test connector 2', config: {}, isPreconfigured: true, + consumer: 'alerts', }, { secrets: {}, @@ -140,6 +142,7 @@ describe('action_form', () => { name: 'Preconfigured Only', config: {}, isPreconfigured: true, + consumer: 'alerts', }, { secrets: {}, @@ -148,6 +151,16 @@ describe('action_form', () => { name: 'Regular connector', config: {}, isPreconfigured: false, + consumer: 'alerts', + }, + { + secrets: {}, + id: 'test5', + actionTypeId: actionType.id, + name: 'Non consumer connector', + config: {}, + isPreconfigured: false, + consumer: 'case', }, ]); const mocks = coreMock.createSetup(); @@ -272,6 +285,7 @@ describe('action_form', () => { toastNotifications={deps!.toastNotifications} docLinks={deps.docLinks} capabilities={deps.capabilities} + consumer={'alerts'} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 201852ddeee48..198e381592fdf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -64,6 +64,7 @@ interface ActionAccordionFormProps { defaultActionMessage?: string; setHasActionsDisabled?: (value: boolean) => void; capabilities: ApplicationStart['capabilities']; + consumer: string; } interface ActiveActionConnectorState { @@ -86,6 +87,7 @@ export const ActionForm = ({ setHasActionsDisabled, capabilities, docLinks, + consumer, }: ActionAccordionFormProps) => { const [addModalVisible, setAddModalVisibility] = useState(false); const [activeActionItem, setActiveActionItem] = useState( @@ -131,7 +133,7 @@ export const ActionForm = ({ try { setIsLoadingConnectors(true); const loadedConnectors = await loadConnectors({ http }); - setConnectors(loadedConnectors); + setConnectors(loadedConnectors.filter((connector) => connector.consumer === 'alerts')); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( @@ -709,6 +711,7 @@ export const ActionForm = ({ toastNotifications={toastNotifications} docLinks={docLinks} capabilities={capabilities} + consumer={consumer} /> ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx index f60199bc47f4b..cfb85d41571a5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.test.tsx @@ -55,6 +55,7 @@ describe('connector_add_flyout', () => { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 1d19f436950c7..631f3d1c5014b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -40,6 +40,7 @@ interface ConnectorAddModalProps { >; capabilities: ApplicationStart['capabilities']; docLinks: DocLinksStart; + consumer: string; } export const ConnectorAddModal = ({ @@ -52,12 +53,14 @@ export const ConnectorAddModal = ({ actionTypeRegistry, capabilities, docLinks, + consumer, }: ConnectorAddModalProps) => { let hasErrors = false; const initialConnector = { actionTypeId: actionType.id, config: {}, secrets: {}, + consumer, } as ActionConnector; const [isSaving, setIsSaving] = useState(false); const canSave = hasSaveActionsCapability(capabilities); 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 6379c4e94866a..c85e18b3873e5 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 @@ -118,7 +118,7 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { setIsLoadingActions(true); try { const actionsResponse = await loadAllActions({ http }); - setActions(actionsResponse); + setActions(actionsResponse.filter((action) => action.consumer === 'alerts')); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( @@ -403,6 +403,7 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { toastNotifications, reloadConnectors: loadActions, docLinks, + consumer: 'alerts', }} > ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 52179dd35767c..187eb3519ed13 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -75,6 +75,7 @@ export interface ActionConnector { referencedByCount?: number; config: Record; isPreconfigured: boolean; + consumer: string; } export type ActionConnectorWithoutId = Omit; From d3db873dc3916f79e9668836b766a5eac57c44db Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Thu, 11 Jun 2020 09:41:25 -0700 Subject: [PATCH 06/38] Added subActions support for ServiceNow action form --- .../servicenow/servicenow.tsx | 5 +-- .../servicenow/servicenow_params.tsx | 42 +++++++++++-------- .../builtin_action_types/servicenow/types.ts | 22 +++++----- .../sections/alert_form/alert_reducer.ts | 30 +------------ 4 files changed, 37 insertions(+), 62 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 45595bc0f77ad..ce4e124e2e43e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -64,10 +64,7 @@ export function getActionType(): ActionTypeModel< title: new Array(), }; validationResult.errors = errors; - if (!actionParams.description?.length) { - errors.description.push(i18n.DESCRIPTION_REQUIRED); - } - if (!actionParams.title?.length) { + if (actionParams.subActionParams && !actionParams.subActionParams.title?.length) { errors.title.push(i18n.TITLE_REQUIRED); } return validationResult; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index 54c32d6910edd..cab234c00bde5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -19,14 +19,15 @@ import { ServiceNowActionParams } from './types'; const ServiceNowParamsFields: React.FunctionComponent> = ({ actionParams, editAction, index, errors, messageVariables }) => { - const { title, description, comments, severity, urgency, impact } = actionParams; + const { title, description, comments, severity, urgency, impact } = + actionParams.subActionParams || {}; const selectOptions = [ { value: '1', text: i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.pagerDutyAction.severitySelectCriticalOptionLabel', { - defaultMessage: 'Hight', + defaultMessage: 'High', } ), }, @@ -50,27 +51,32 @@ const ServiceNowParamsFields: React.FunctionComponent { + const newProps = { ...actionParams.subActionParams, [key]: value }; + editAction('subActionParams', newProps, index); + }; + useEffect(() => { + editAction('subAction', 'pushToService', index); if (messageVariables?.find((variable) => variable === 'alertId')) { - editAction('savedObjectId', '{{alertId}}', index); + editSubActionProperty('savedObjectId', '{{alertId}}'); } if (!urgency) { - editAction('urgency', '3', index); + editSubActionProperty('urgency', '3'); } if (!impact) { - editAction('impact', '3', index); + editSubActionProperty('impact', '3'); } if (!severity) { - editAction('severity', '3', index); + editSubActionProperty('severity', '3'); } // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const onSelectMessageVariable = (paramsProperty: string, variable: string) => { - editAction( + editSubActionProperty( paramsProperty, - ((actionParams as any)[paramsProperty] ?? '').concat(` {{${variable}}}`), - index + ((actionParams as any).subActionParams[paramsProperty] ?? '').concat(` {{${variable}}}`) ); }; @@ -91,7 +97,7 @@ const ServiceNowParamsFields: React.FunctionComponent { - editAction('urgency', e.target.value, index); + editSubActionProperty('urgency', e.target.value); }} /> @@ -113,7 +119,7 @@ const ServiceNowParamsFields: React.FunctionComponent { - editAction('severity', e.target.value, index); + editSubActionProperty('severity', e.target.value); }} /> @@ -134,7 +140,7 @@ const ServiceNowParamsFields: React.FunctionComponent { - editAction('impact', e.target.value, index); + editSubActionProperty('impact', e.target.value); }} /> @@ -166,11 +172,11 @@ const ServiceNowParamsFields: React.FunctionComponent 0 && title !== undefined} value={title || ''} onChange={(e: React.ChangeEvent) => { - editAction('title', e.target.value, index); + editSubActionProperty('title', e.target.value); }} onBlur={() => { if (!title) { - editAction('title', '', index); + editSubActionProperty('title', ''); } }} /> @@ -202,11 +208,11 @@ const ServiceNowParamsFields: React.FunctionComponent { - editAction('description', e.target.value, index); + editSubActionProperty('description', e.target.value); }} onBlur={() => { if (!description) { - editAction('description', '', index); + editSubActionProperty('description', ''); } }} /> @@ -235,11 +241,11 @@ const ServiceNowParamsFields: React.FunctionComponent { - editAction('comments', e.target.value, index); + editSubActionProperty('comments', e.target.value); }} onBlur={() => { if (!comments) { - editAction('comments', '', index); + editSubActionProperty('comments', ''); } }} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 1ed72a1ba5804..48491d79a5dc9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -15,17 +15,17 @@ export interface ServiceNowActionConnector extends ActionConnector { } export interface ServiceNowActionParams { - // subAction: string; - // subActionParams: { - savedObjectId: string; - title: string; - description: string; - comments: string; - externalId: string; - severity: string; - urgency: string; - impact: string; - // }; + subAction: string; + subActionParams: { + savedObjectId: string; + title: string; + description: string; + comments: string; + externalId: string; + severity: string; + urgency: string; + impact: string; + }; } interface IncidentConfiguration { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts index 612bd883608d7..7bc148c2dc31a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts @@ -12,8 +12,7 @@ interface CommandType { | 'setScheduleProperty' | 'setAlertParams' | 'setAlertActionParams' - | 'setAlertActionProperty' - | 'setAlertActionSubProperty'; + | 'setAlertActionProperty'; } export interface AlertState { @@ -137,32 +136,5 @@ export const alertReducer = (state: any, action: AlertReducerAction) => { }; } } - case 'setAlertActionSubProperty': { - const { key, subKey, value, index } = payload; - if ( - index === undefined || - subKey === undefined || - isEqual(alert.actions[index][key][subKey], value) - ) { - return state; - } else { - const oldAction = alert.actions.splice(index, 1)[0]; - const updatedAction = { - ...oldAction, - [key]: { - ...[key], - [subKey]: value, - }, - }; - alert.actions.splice(index, 0, updatedAction); - return { - ...state, - alert: { - ...alert, - actions: [...alert.actions], - }, - }; - } - } } }; From 9ea34508cf20ac60722f9044e1e38353b5be14fe Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Thu, 11 Jun 2020 11:34:28 -0700 Subject: [PATCH 07/38] Basic version for Alerts part for ServiceNow --- .../builtin_action_types/servicenow/api.ts | 5 +-- .../builtin_action_types/servicenow/index.ts | 31 +++++++++---------- .../servicenow/servicenow_params.tsx | 15 ++++++--- 3 files changed, 28 insertions(+), 23 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 8cb3bcaf2a22a..83f4b2357a1ca 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -45,6 +45,7 @@ const pushToServiceHandler = async ({ } let incident = {}; + // TODO: should be removed later but currently keep it for the Case implementation support if (mapping) { const fields = prepareFieldsForTransformation({ params, @@ -57,8 +58,9 @@ const pushToServiceHandler = async ({ fields, currentIncident, }); + } else { + incident = { ...params, short_description: params.title }; } - incident = params; if (updateIncident) { res = await externalService.updateIncident({ @@ -69,7 +71,6 @@ const pushToServiceHandler = async ({ res = await externalService.createIncident({ incident: { ...incident, - short_description: params.title, caller_id: secrets.username, }, }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index 431bea96103b8..680b24e370f5a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -13,7 +13,6 @@ import { ExternalIncidentServiceConfiguration, ExternalIncidentServiceSecretConfiguration, ExecutorParamsSchema, - ExecutorSubActionPushParamsSchema, } from './schema'; import { ActionsConfigurationUtilities } from '../../actions_config'; import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../../types'; @@ -42,7 +41,7 @@ export function getActionType(params: GetActionTypeParams): ActionType { secrets: schema.object(ExternalIncidentServiceSecretConfiguration, { validate: curry(validate.secrets)(configurationUtilities), }), - params: ExecutorSubActionPushParamsSchema, + params: ExecutorParamsSchema, }, executor: curry(executor)({ logger }), }; @@ -55,7 +54,7 @@ async function executor( execOptions: ActionTypeExecutorOptions ): Promise { const { actionId, config, params, secrets } = execOptions; - // const { subAction, subActionParams } = params as ExecutorParams; + const { subAction, subActionParams } = params as ExecutorParams; let data = {}; const res: Pick & @@ -69,14 +68,13 @@ async function executor( secrets, }); - /* if (!api[subAction]) { + if (!api[subAction]) { throw new Error('[Action][ExternalService] Unsupported subAction type.'); } if (subAction !== 'pushToService') { throw new Error('[Action][ExternalService] subAction not implemented.'); } - */ const mapParams = (mapping: Map): AnyParams => { return Object.keys(params).reduce((prev: AnyParams, curr: string): AnyParams => { @@ -88,20 +86,19 @@ async function executor( }, {}); }; - // if (subAction === 'pushToService') { - // const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; + if (subAction === 'pushToService') { + const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; - const mapping = config.indexConfiguration ? buildMap(config.indexConfiguration.mapping) : null; - const externalObject = config.indexConfiguration && mapping ? mapParams(mapping) : {}; + const mapping = config.indexConfiguration ? buildMap(config.indexConfiguration.mapping) : null; + const externalObject = config.indexConfiguration && mapping ? mapParams(mapping) : {}; - data = await api.pushToService({ - externalService, - mapping, - // eslint-disable-next-line @typescript-eslint/no-explicit-any - params: { ...params, externalObject } as any, - secrets, - }); - // } + data = await api.pushToService({ + externalService, + mapping, + params: { ...pushToServiceParams, externalObject }, + secrets, + }); + } return { ...res, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index cab234c00bde5..54a9f16a141fb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -12,6 +12,7 @@ import { EuiFlexGroup } from '@elastic/eui'; import { EuiFlexItem } from '@elastic/eui'; import { EuiFieldText } from '@elastic/eui'; import { EuiSpacer } from '@elastic/eui'; +import { EuiTitle } from '@elastic/eui'; import { ActionParamsProps } from '../../../../types'; import { AddMessageVariables } from '../../add_message_variables'; import { ServiceNowActionParams } from './types'; @@ -19,7 +20,7 @@ import { ServiceNowActionParams } from './types'; const ServiceNowParamsFields: React.FunctionComponent> = ({ actionParams, editAction, index, errors, messageVariables }) => { - const { title, description, comments, severity, urgency, impact } = + const { title, description, comments, severity, urgency, impact, savedObjectId } = actionParams.subActionParams || {}; const selectOptions = [ { @@ -57,8 +58,10 @@ const ServiceNowParamsFields: React.FunctionComponent { - editAction('subAction', 'pushToService', index); - if (messageVariables?.find((variable) => variable === 'alertId')) { + if (!actionParams.subAction) { + editAction('subAction', 'pushToService', index); + } + if (!savedObjectId && messageVariables?.find((variable) => variable === 'alertId')) { editSubActionProperty('savedObjectId', '{{alertId}}'); } if (!urgency) { @@ -71,7 +74,7 @@ const ServiceNowParamsFields: React.FunctionComponent { editSubActionProperty( @@ -82,6 +85,10 @@ const ServiceNowParamsFields: React.FunctionComponent + +

Incident

+
+ Date: Thu, 11 Jun 2020 17:57:42 -0700 Subject: [PATCH 08/38] Keep Case ServiceNow functionality working --- .../server/builtin_action_types/case/api.ts | 2 +- .../builtin_action_types/case/schema.ts | 2 +- .../server/builtin_action_types/case/types.ts | 2 +- .../builtin_action_types/case/utils.test.ts | 139 ++---------------- .../server/builtin_action_types/case/utils.ts | 54 +------ .../server/builtin_action_types/jira/mocks.ts | 2 +- .../builtin_action_types/jira/service.ts | 2 +- .../lib/axios_utils.test.ts | 105 +++++++++++++ .../builtin_action_types/lib/axios_utils.ts | 58 ++++++++ .../servicenow/api.test.ts | 4 +- .../builtin_action_types/servicenow/api.ts | 87 +++++++---- .../servicenow/case_shema.ts | 36 +++++ .../servicenow/case_types.ts | 68 +++++++++ .../builtin_action_types/servicenow/index.ts | 26 ++-- .../builtin_action_types/servicenow/mocks.ts | 11 +- .../builtin_action_types/servicenow/schema.ts | 24 +-- .../servicenow/service.test.ts | 6 +- .../servicenow/service.ts | 13 +- .../servicenow/translations.ts | 4 +- .../builtin_action_types/servicenow/types.ts | 56 +------ .../servicenow/validators.ts | 7 +- .../containers/use_post_push_to_service.tsx | 2 +- .../servicenow/servicenow_params.tsx | 20 +-- .../builtin_action_types/servicenow/types.ts | 2 +- 24 files changed, 393 insertions(+), 339 deletions(-) create mode 100644 x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts create mode 100644 x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts create mode 100644 x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts create mode 100644 x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/api.ts b/x-pack/plugins/actions/server/builtin_action_types/case/api.ts index 6dc8a9cc9af6a..de4b7edaed3da 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/api.ts @@ -41,7 +41,7 @@ const pushToServiceHandler = async ({ } const fields = prepareFieldsForTransformation({ - params, + externalCase: params.externalCase, mapping, defaultPipes, }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/case/schema.ts index 33b2ad6d18684..f47686c911ff0 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/schema.ts @@ -67,7 +67,7 @@ export const ExecutorSubActionSchema = schema.oneOf([ ]); export const ExecutorSubActionPushParamsSchema = schema.object({ - caseId: schema.string(), + savedObjectId: schema.string(), title: schema.string(), description: schema.nullable(schema.string()), comments: schema.nullable(schema.arrayOf(CommentSchema)), diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/types.ts b/x-pack/plugins/actions/server/builtin_action_types/case/types.ts index 992b2cb16fb06..de96864d0b295 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/types.ts @@ -144,7 +144,7 @@ export interface PipedField { } export interface PrepareFieldsForTransformArgs { - params: PushToServiceApiParams; + externalCase: Record; mapping: Map; defaultPipes?: string[]; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/utils.test.ts b/x-pack/plugins/actions/server/builtin_action_types/case/utils.test.ts index 017fc73efae20..dbb18fa5c695c 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/utils.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/utils.test.ts @@ -4,8 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -import axios from 'axios'; - import { normalizeMapping, buildMap, @@ -13,19 +11,11 @@ import { prepareFieldsForTransformation, transformFields, transformComments, - addTimeZoneToDate, - throwIfNotAlive, - request, - patch, - getErrorMessage, } from './utils'; import { SUPPORTED_SOURCE_FIELDS } from './constants'; import { Comment, MapRecord, PushToServiceApiParams } from './types'; -jest.mock('axios'); -const axiosMock = (axios as unknown) as jest.Mock; - const mapping: MapRecord[] = [ { source: 'title', target: 'short_description', actionType: 'overwrite' }, { source: 'description', target: 'description', actionType: 'append' }, @@ -63,7 +53,7 @@ const maliciousMapping: MapRecord[] = [ ]; const fullParams: PushToServiceApiParams = { - caseId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', + savedObjectId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', title: 'a title', description: 'a description', createdAt: '2020-03-13T08:34:53.450Z', @@ -132,7 +122,7 @@ describe('buildMap', () => { describe('mapParams', () => { test('maps params correctly', () => { const params = { - caseId: '123', + savedObjectId: '123', incidentId: '456', title: 'Incident title', description: 'Incident description', @@ -148,7 +138,7 @@ describe('mapParams', () => { test('do not add fields not in mapping', () => { const params = { - caseId: '123', + savedObjectId: '123', incidentId: '456', title: 'Incident title', description: 'Incident description', @@ -164,7 +154,7 @@ describe('mapParams', () => { describe('prepareFieldsForTransformation', () => { test('prepare fields with defaults', () => { const res = prepareFieldsForTransformation({ - params: fullParams, + externalCase: fullParams.externalCase, mapping: finalMapping, }); expect(res).toEqual([ @@ -185,7 +175,7 @@ describe('prepareFieldsForTransformation', () => { test('prepare fields with default pipes', () => { const res = prepareFieldsForTransformation({ - params: fullParams, + externalCase: fullParams.externalCase, mapping: finalMapping, defaultPipes: ['myTestPipe'], }); @@ -209,7 +199,7 @@ describe('prepareFieldsForTransformation', () => { describe('transformFields', () => { test('transform fields for creation correctly', () => { const fields = prepareFieldsForTransformation({ - params: fullParams, + externalCase: fullParams.externalCase, mapping: finalMapping, }); @@ -226,14 +216,7 @@ describe('transformFields', () => { test('transform fields for update correctly', () => { const fields = prepareFieldsForTransformation({ - params: { - ...fullParams, - updatedAt: '2020-03-15T08:34:53.450Z', - updatedBy: { - username: 'anotherUser', - fullName: 'Another User', - }, - }, + externalCase: fullParams.externalCase, mapping: finalMapping, defaultPipes: ['informationUpdated'], }); @@ -262,7 +245,7 @@ describe('transformFields', () => { test('add newline character to descripton', () => { const fields = prepareFieldsForTransformation({ - params: fullParams, + externalCase: fullParams.externalCase, mapping: finalMapping, defaultPipes: ['informationUpdated'], }); @@ -280,7 +263,7 @@ describe('transformFields', () => { test('append username if fullname is undefined when create', () => { const fields = prepareFieldsForTransformation({ - params: fullParams, + externalCase: fullParams.externalCase, mapping: finalMapping, }); @@ -300,14 +283,7 @@ describe('transformFields', () => { test('append username if fullname is undefined when update', () => { const fields = prepareFieldsForTransformation({ - params: { - ...fullParams, - updatedAt: '2020-03-15T08:34:53.450Z', - updatedBy: { - username: 'anotherUser', - fullName: 'Another User', - }, - }, + externalCase: fullParams.externalCase, mapping: finalMapping, defaultPipes: ['informationUpdated'], }); @@ -479,98 +455,3 @@ describe('transformComments', () => { ]); }); }); - -describe('addTimeZoneToDate', () => { - test('adds timezone with default', () => { - const date = addTimeZoneToDate('2020-04-14T15:01:55.456Z'); - expect(date).toBe('2020-04-14T15:01:55.456Z GMT'); - }); - - test('adds timezone correctly', () => { - const date = addTimeZoneToDate('2020-04-14T15:01:55.456Z', 'PST'); - expect(date).toBe('2020-04-14T15:01:55.456Z PST'); - }); -}); - -describe('throwIfNotAlive ', () => { - test('throws correctly when status is invalid', async () => { - expect(() => { - throwIfNotAlive(404, 'application/json'); - }).toThrow('Instance is not alive.'); - }); - - test('throws correctly when content is invalid', () => { - expect(() => { - throwIfNotAlive(200, 'application/html'); - }).toThrow('Instance is not alive.'); - }); - - test('do NOT throws with custom validStatusCodes', async () => { - expect(() => { - throwIfNotAlive(404, 'application/json', [404]); - }).not.toThrow('Instance is not alive.'); - }); -}); - -describe('request', () => { - beforeEach(() => { - axiosMock.mockImplementation(() => ({ - status: 200, - headers: { 'content-type': 'application/json' }, - data: { incidentId: '123' }, - })); - }); - - test('it fetch correctly with defaults', async () => { - const res = await request({ axios, url: '/test' }); - - expect(axiosMock).toHaveBeenCalledWith('/test', { method: 'get', data: {} }); - expect(res).toEqual({ - status: 200, - headers: { 'content-type': 'application/json' }, - data: { incidentId: '123' }, - }); - }); - - test('it fetch correctly', async () => { - const res = await request({ axios, url: '/test', method: 'post', data: { id: '123' } }); - - expect(axiosMock).toHaveBeenCalledWith('/test', { method: 'post', data: { id: '123' } }); - expect(res).toEqual({ - status: 200, - headers: { 'content-type': 'application/json' }, - data: { incidentId: '123' }, - }); - }); - - test('it throws correctly', async () => { - axiosMock.mockImplementation(() => ({ - status: 404, - headers: { 'content-type': 'application/json' }, - data: { incidentId: '123' }, - })); - - await expect(request({ axios, url: '/test' })).rejects.toThrow(); - }); -}); - -describe('patch', () => { - beforeEach(() => { - axiosMock.mockImplementation(() => ({ - status: 200, - headers: { 'content-type': 'application/json' }, - })); - }); - - test('it fetch correctly', async () => { - await patch({ axios, url: '/test', data: { id: '123' } }); - expect(axiosMock).toHaveBeenCalledWith('/test', { method: 'patch', data: { id: '123' } }); - }); -}); - -describe('getErrorMessage', () => { - test('it returns the correct error message', () => { - const msg = getErrorMessage('My connector name', 'An error has occurred'); - expect(msg).toBe('[Action][My connector name]: An error has occurred'); - }); -}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts index dd8d971b7df44..20869d5ef0d7c 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/case/utils.ts @@ -6,7 +6,6 @@ import { curry, flow, get } from 'lodash'; import { schema } from '@kbn/config-schema'; -import { AxiosInstance, Method, AxiosResponse } from 'axios'; import { ActionTypeExecutorOptions, ActionTypeExecutorResult, ActionType } from '../../types'; @@ -134,65 +133,18 @@ export const createConnector = ({ }); }; -export const throwIfNotAlive = ( - status: number, - contentType: string, - validStatusCodes: number[] = [200, 201, 204] -) => { - if (!validStatusCodes.includes(status) || !contentType.includes('application/json')) { - throw new Error('Instance is not alive.'); - } -}; - -export const request = async ({ - axios, - url, - method = 'get', - data, -}: { - axios: AxiosInstance; - url: string; - method?: Method; - data?: T; -}): Promise => { - const res = await axios(url, { method, data: data ?? {} }); - throwIfNotAlive(res.status, res.headers['content-type']); - return res; -}; - -export const patch = async ({ - axios, - url, - data, -}: { - axios: AxiosInstance; - url: string; - data: T; -}): Promise => { - return request({ - axios, - url, - method: 'patch', - data, - }); -}; - -export const addTimeZoneToDate = (date: string, timezone = 'GMT'): string => { - return `${date} ${timezone}`; -}; - export const prepareFieldsForTransformation = ({ - params, + externalCase, mapping, defaultPipes = ['informationCreated'], }: PrepareFieldsForTransformArgs): PipedField[] => { - return Object.keys(params.externalCase) + return Object.keys(externalCase) .filter((p) => mapping.get(p)?.actionType != null && mapping.get(p)?.actionType !== 'nothing') .map((p) => { const actionType = mapping.get(p)?.actionType ?? 'nothing'; return { key: p, - value: params.externalCase[p], + value: externalCase[p], actionType, pipes: actionType === 'append' ? [...defaultPipes, 'append'] : defaultPipes, }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts index 3ae0e9db36de0..709d490a5227f 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts @@ -88,7 +88,7 @@ mapping.set('summary', { }); const executorParams: ExecutorSubActionPushParams = { - caseId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', + savedObjectId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', externalId: 'incident-3', createdAt: '2020-04-27T10:59:46.202Z', createdBy: { fullName: 'Elastic User', username: 'elastic' }, diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts index ff22b8368e7dd..240b645c3a7dc 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.ts @@ -16,7 +16,7 @@ import { } from './types'; import * as i18n from './translations'; -import { getErrorMessage, request } from '../case/utils'; +import { request, getErrorMessage } from '../lib/axios_utils'; const VERSION = '2'; const BASE_URL = `rest/api/${VERSION}`; diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts new file mode 100644 index 0000000000000..4a52ae60bcdda --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.test.ts @@ -0,0 +1,105 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import axios from 'axios'; +import { addTimeZoneToDate, throwIfNotAlive, request, patch, getErrorMessage } from './axios_utils'; +jest.mock('axios'); +const axiosMock = (axios as unknown) as jest.Mock; + +describe('addTimeZoneToDate', () => { + test('adds timezone with default', () => { + const date = addTimeZoneToDate('2020-04-14T15:01:55.456Z'); + expect(date).toBe('2020-04-14T15:01:55.456Z GMT'); + }); + + test('adds timezone correctly', () => { + const date = addTimeZoneToDate('2020-04-14T15:01:55.456Z', 'PST'); + expect(date).toBe('2020-04-14T15:01:55.456Z PST'); + }); +}); + +describe('throwIfNotAlive ', () => { + test('throws correctly when status is invalid', async () => { + expect(() => { + throwIfNotAlive(404, 'application/json'); + }).toThrow('Instance is not alive.'); + }); + + test('throws correctly when content is invalid', () => { + expect(() => { + throwIfNotAlive(200, 'application/html'); + }).toThrow('Instance is not alive.'); + }); + + test('do NOT throws with custom validStatusCodes', async () => { + expect(() => { + throwIfNotAlive(404, 'application/json', [404]); + }).not.toThrow('Instance is not alive.'); + }); +}); + +describe('request', () => { + beforeEach(() => { + axiosMock.mockImplementation(() => ({ + status: 200, + headers: { 'content-type': 'application/json' }, + data: { incidentId: '123' }, + })); + }); + + test('it fetch correctly with defaults', async () => { + const res = await request({ axios, url: '/test' }); + + expect(axiosMock).toHaveBeenCalledWith('/test', { method: 'get', data: {} }); + expect(res).toEqual({ + status: 200, + headers: { 'content-type': 'application/json' }, + data: { incidentId: '123' }, + }); + }); + + test('it fetch correctly', async () => { + const res = await request({ axios, url: '/test', method: 'post', data: { id: '123' } }); + + expect(axiosMock).toHaveBeenCalledWith('/test', { method: 'post', data: { id: '123' } }); + expect(res).toEqual({ + status: 200, + headers: { 'content-type': 'application/json' }, + data: { incidentId: '123' }, + }); + }); + + test('it throws correctly', async () => { + axiosMock.mockImplementation(() => ({ + status: 404, + headers: { 'content-type': 'application/json' }, + data: { incidentId: '123' }, + })); + + await expect(request({ axios, url: '/test' })).rejects.toThrow(); + }); +}); + +describe('patch', () => { + beforeEach(() => { + axiosMock.mockImplementation(() => ({ + status: 200, + headers: { 'content-type': 'application/json' }, + })); + }); + + test('it fetch correctly', async () => { + await patch({ axios, url: '/test', data: { id: '123' } }); + expect(axiosMock).toHaveBeenCalledWith('/test', { method: 'patch', data: { id: '123' } }); + }); +}); + +describe('getErrorMessage', () => { + test('it returns the correct error message', () => { + const msg = getErrorMessage('My connector name', 'An error has occurred'); + expect(msg).toBe('[Action][My connector name]: An error has occurred'); + }); +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts new file mode 100644 index 0000000000000..8b21a0d711a1c --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts @@ -0,0 +1,58 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { AxiosInstance, Method, AxiosResponse } from 'axios'; + +export const throwIfNotAlive = ( + status: number, + contentType: string, + validStatusCodes: number[] = [200, 201, 204] +) => { + if (!validStatusCodes.includes(status) || !contentType.includes('application/json')) { + throw new Error('Instance is not alive.'); + } +}; + +export const request = async ({ + axios, + url, + method = 'get', + data, +}: { + axios: AxiosInstance; + url: string; + method?: Method; + data?: T; +}): Promise => { + const res = await axios(url, { method, data: data ?? {} }); + throwIfNotAlive(res.status, res.headers['content-type']); + return res; +}; + +export const patch = async ({ + axios, + url, + data, +}: { + axios: AxiosInstance; + url: string; + data: T; +}): Promise => { + return request({ + axios, + url, + method: 'patch', + data, + }); +}; + +export const addTimeZoneToDate = (date: string, timezone = 'GMT'): string => { + return `${date} ${timezone}`; +}; + +export const getErrorMessage = (connector: string, msg: string) => { + return `[Action][${connector}]: ${msg}`; +}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index f332df085d684..8e9288c94f6a6 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -49,7 +49,7 @@ describe('api', () => { const res = await api.pushToService({ externalService, mapping, - params: apiParams, + params, secrets: {}, }); @@ -152,7 +152,7 @@ describe('api', () => { const res = await api.pushToService({ externalService, mapping, - params: apiParams, + params, secrets: {}, }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 83f4b2357a1ca..9cbce63ea0993 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -6,16 +6,16 @@ import { flow } from 'lodash'; import { ExternalServiceParams, - PushToServiceResponse, PushToServiceApiHandlerArgs, HandshakeApiHandlerArgs, GetIncidentApiHandlerArgs, ExternalServiceApi, - PrepareFieldsForTransformArgs, - PipedField, - TransformFieldsArgs, } from './types'; + +// TODO: to remove, need to support Case import { transformers, Transformer } from '../case/transformers'; +import { PushToServiceResponse, TransformFieldsArgs } from './case_types'; +import { prepareFieldsForTransformation } from '../case/utils'; const handshakeHandler = async ({ externalService, @@ -34,7 +34,7 @@ const pushToServiceHandler = async ({ params, secrets, }: PushToServiceApiHandlerArgs): Promise => { - const { externalId } = params; + const { externalId, comments } = params; const updateIncident = externalId ? true : false; const defaultPipes = updateIncident ? ['informationUpdated'] : ['informationCreated']; let currentIncident: ExternalServiceParams | undefined; @@ -48,7 +48,7 @@ const pushToServiceHandler = async ({ // TODO: should be removed later but currently keep it for the Case implementation support if (mapping) { const fields = prepareFieldsForTransformation({ - params, + externalCase: params.externalObject, mapping, defaultPipes, }); @@ -59,41 +59,55 @@ const pushToServiceHandler = async ({ currentIncident, }); } else { - incident = { ...params, short_description: params.title }; + incident = { ...params, short_description: params.title, comments: params.comment }; } - if (updateIncident) { + // TODO: should temporary keep it for a Case usage + if ( + updateIncident && + comments && + Array.isArray(comments) && + comments.length > 0 && + mapping && + mapping.get('comments')?.actionType !== 'nothing' + ) { + const resComments = []; + const fieldsKey = mapping.get('comments')?.target ?? 'comments'; res = await externalService.updateIncident({ incidentId: externalId, - incident, - }); - } else { - res = await externalService.createIncident({ incident: { ...incident, - caller_id: secrets.username, + [fieldsKey]: comments[0].comment, }, }); - } - return res; -}; - -export const prepareFieldsForTransformation = ({ - params, - mapping, - defaultPipes = ['informationCreated'], -}: PrepareFieldsForTransformArgs): PipedField[] => { - return Object.keys(params.externalObject) - .filter((p) => mapping.get(p)?.actionType != null && mapping.get(p)?.actionType !== 'nothing') - .map((p) => { - const actionType = mapping.get(p)?.actionType ?? 'nothing'; - return { - key: p, - value: params.externalObject[p], - actionType, - pipes: actionType === 'append' ? [...defaultPipes, 'append'] : defaultPipes, - }; + for (let i = 1; i < comments.length; i++) { + const currentComment = comments[i]; + await externalService.updateIncident({ + incidentId: externalId, + incident: { + ...incident, + [fieldsKey]: currentComment.comment, + }, + }); + resComments.push(...(res.comments ?? []), { + commentId: currentComment.commentId, + pushedDate: res.pushedDate, + }); + } + res.comments = resComments; + return res; + } else if (updateIncident) { + return await externalService.updateIncident({ + incidentId: externalId, + incident, }); + } + return await externalService.createIncident({ + incident: { + ...incident, + caller_id: secrets.username, + }, + }); }; export const transformFields = ({ @@ -107,6 +121,15 @@ export const transformFields = ({ ...prev, [cur.key]: transform({ value: cur.value, + date: params.updatedAt ?? params.createdAt, + user: + (params.updatedBy != null + ? params.updatedBy.fullName + ? params.updatedBy.fullName + : params.updatedBy.username + : params.createdBy.fullName + ? params.createdBy.fullName + : params.createdBy.username) ?? '', previousValue: currentIncident ? currentIncident[cur.key] : '', }).value, }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts new file mode 100644 index 0000000000000..2df8c8156cde8 --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_shema.ts @@ -0,0 +1,36 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { schema } from '@kbn/config-schema'; + +export const MappingActionType = schema.oneOf([ + schema.literal('nothing'), + schema.literal('overwrite'), + schema.literal('append'), +]); + +export const MapRecordSchema = schema.object({ + source: schema.string(), + target: schema.string(), + actionType: MappingActionType, +}); + +export const IncidentConfigurationSchema = schema.object({ + mapping: schema.arrayOf(MapRecordSchema), +}); + +export const EntityInformation = { + createdAt: schema.maybe(schema.string()), + createdBy: schema.maybe(schema.any()), + updatedAt: schema.nullable(schema.string()), + updatedBy: schema.nullable(schema.any()), +}; + +export const CommentSchema = schema.object({ + commentId: schema.string(), + comment: schema.string(), + ...EntityInformation, +}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts new file mode 100644 index 0000000000000..29bf9b4a9d26c --- /dev/null +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.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; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable @typescript-eslint/no-explicit-any */ + +import { TypeOf } from '@kbn/config-schema'; +import { + ExecutorSubActionGetIncidentParamsSchema, + ExecutorSubActionHandshakeParamsSchema, +} from './schema'; +import { IncidentConfigurationSchema, MapRecordSchema } from './case_shema'; +import { + PushToServiceApiParams, + ExternalServiceIncidentResponse, + ExternalServiceParams, +} from './types'; + +export interface AnyParams { + [index: string]: string | number | object | undefined | null; +} + +export interface CreateCommentRequest { + [key: string]: string; +} + +export type IncidentConfiguration = TypeOf; +export type MapRecord = TypeOf; + +export interface ExternalServiceCommentResponse { + commentId: string; + pushedDate: string; + externalCommentId?: string; +} + +export type ExecutorSubActionGetIncidentParams = TypeOf< + typeof ExecutorSubActionGetIncidentParamsSchema +>; + +export type ExecutorSubActionHandshakeParams = TypeOf< + typeof ExecutorSubActionHandshakeParamsSchema +>; + +export interface PushToServiceResponse extends ExternalServiceIncidentResponse { + comments?: ExternalServiceCommentResponse[]; +} + +export interface PipedField { + key: string; + value: string; + actionType: string; + pipes: string[]; +} + +export interface TransformFieldsArgs { + params: PushToServiceApiParams; + fields: PipedField[]; + currentIncident?: ExternalServiceParams; +} + +export interface TransformerArgs { + value: string; + date?: string; + user?: string; + previousValue?: string; +} diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index 680b24e370f5a..d78f211f81c6b 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { curry, get } from 'lodash'; +import { curry } from 'lodash'; import { schema } from '@kbn/config-schema'; // import { config } from './config'; @@ -17,11 +17,13 @@ import { import { ActionsConfigurationUtilities } from '../../actions_config'; import { ActionType, ActionTypeExecutorOptions, ActionTypeExecutorResult } from '../../types'; import { createExternalService } from './service'; -import { buildMap } from '../case/utils'; import { api } from './api'; -import { ExecutorParams, ExecutorSubActionPushParams, MapRecord, AnyParams } from './types'; +import { ExecutorParams, ExecutorSubActionPushParams } from './types'; import * as i18n from './translations'; +// TODO: to remove, need to support Case +import { buildMap, mapParams } from '../case/utils'; + interface GetActionTypeParams { logger: Logger; configurationUtilities: ActionsConfigurationUtilities; @@ -76,21 +78,15 @@ async function executor( throw new Error('[Action][ExternalService] subAction not implemented.'); } - const mapParams = (mapping: Map): AnyParams => { - return Object.keys(params).reduce((prev: AnyParams, curr: string): AnyParams => { - const field = mapping.get(curr); - if (field) { - prev[field.target] = get(params, curr); - } - return prev; - }, {}); - }; - if (subAction === 'pushToService') { const pushToServiceParams = subActionParams as ExecutorSubActionPushParams; - const mapping = config.indexConfiguration ? buildMap(config.indexConfiguration.mapping) : null; - const externalObject = config.indexConfiguration && mapping ? mapParams(mapping) : {}; + const { comments, externalId, ...restParams } = pushToServiceParams; + const mapping = config.incidentConfiguration + ? buildMap(config.incidentConfiguration.mapping) + : null; + const externalObject = + config.incidentConfiguration && mapping ? mapParams(restParams, mapping) : {}; data = await api.pushToService({ externalService, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts index 3b6d611d91451..229241cd544b3 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts @@ -4,12 +4,8 @@ * you may not use this file except in compliance with the Elastic License. */ -import { - ExternalService, - PushToServiceApiParams, - ExecutorSubActionPushParams, - MapRecord, -} from './types'; +import { ExternalService, PushToServiceApiParams, ExecutorSubActionPushParams } from './types'; +import { MapRecord } from './case_types'; const createMock = (): jest.Mocked => { const service = { @@ -72,10 +68,11 @@ const executorParams: ExecutorSubActionPushParams = { externalId: 'incident-3', title: 'Incident title', description: 'Incident description', - comments: 'case-comment-1', + comment: 'comment-1', severity: '3', urgency: '3', impact: '3', + updatedAt: null, }; const apiParams: PushToServiceApiParams = { diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index c6396b6af68f9..8559ba24018dc 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -5,26 +5,11 @@ */ import { schema } from '@kbn/config-schema'; - -export const MappingActionType = schema.oneOf([ - schema.literal('nothing'), - schema.literal('overwrite'), - schema.literal('append'), -]); - -export const MapRecordSchema = schema.object({ - source: schema.string(), - target: schema.string(), - actionType: MappingActionType, -}); - -export const IncidentConfigurationSchema = schema.object({ - mapping: schema.arrayOf(MapRecordSchema), -}); +import { CommentSchema, EntityInformation, IncidentConfigurationSchema } from './case_shema'; export const ExternalIncidentServiceConfiguration = { apiUrl: schema.string(), - // did it otional for the current stage to support Case ServiceNow implementation + // TODO: to remove - set it otional for the current stage to support Case ServiceNow implementation incidentConfiguration: schema.maybe(IncidentConfigurationSchema), }; @@ -51,11 +36,14 @@ export const ExecutorSubActionPushParamsSchema = schema.object({ savedObjectId: schema.string(), title: schema.string(), description: schema.nullable(schema.string()), - comments: schema.nullable(schema.string()), + comment: schema.nullable(schema.string()), externalId: schema.nullable(schema.string()), severity: schema.nullable(schema.string()), urgency: schema.nullable(schema.string()), impact: schema.nullable(schema.string()), + // TODO: remove later - need for support Case push multiple comments + comments: schema.maybe(schema.arrayOf(CommentSchema)), + ...EntityInformation, }); export const ExecutorSubActionGetIncidentParamsSchema = schema.object({ diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts index d38f8b28b9fbd..07d60ec9f7a05 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.test.ts @@ -7,12 +7,12 @@ import axios from 'axios'; import { createExternalService } from './service'; -import * as utils from '../case/utils'; +import * as utils from '../lib/axios_utils'; import { ExternalService } from './types'; jest.mock('axios'); -jest.mock('../case/utils', () => { - const originalUtils = jest.requireActual('../case/utils'); +jest.mock('../lib/axios_utils', () => { + const originalUtils = jest.requireActual('../lib/axios_utils'); return { ...originalUtils, request: jest.fn(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index 4820adc6b52d5..152243b978d34 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -7,15 +7,10 @@ import axios from 'axios'; import { ExternalServiceCredentials, ExternalService, ExternalServiceParams } from './types'; -import { addTimeZoneToDate, patch, request, getErrorMessage } from '../case/utils'; import * as i18n from './translations'; -import { - ServiceNowPublicConfigurationType, - ServiceNowSecretConfigurationType, - CreateIncidentRequest, - UpdateIncidentRequest, -} from './types'; +import { ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType } from './types'; +import { request, getErrorMessage, addTimeZoneToDate, patch } from '../lib/axios_utils'; const API_VERSION = 'v2'; const INCIDENT_URL = `api/now/${API_VERSION}/table/incident`; @@ -81,7 +76,7 @@ export const createExternalService = ({ const createIncident = async ({ incident }: ExternalServiceParams) => { try { - const res = await request({ + const res = await request({ axios: axiosInstance, url: `${incidentUrl}`, method: 'post', @@ -103,7 +98,7 @@ export const createExternalService = ({ const updateIncident = async ({ incidentId, incident }: ExternalServiceParams) => { try { - const res = await patch({ + const res = await patch({ axios: axiosInstance, url: `${incidentUrl}/${incidentId}`, data: { ...incident }, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts index 856586badead3..ea9651dffdc26 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts @@ -6,12 +6,12 @@ import { i18n } from '@kbn/i18n'; -export const NAME = i18n.translate('xpack.actions.builtin.case.servicenowTitle', { +export const NAME = i18n.translate('xpack.actions.builtin.servicenowTitle', { defaultMessage: 'ServiceNow', }); export const WHITE_LISTED_ERROR = (message: string) => - i18n.translate('xpack.actions.builtin.case.configuration.apiWhitelistError', { + i18n.translate('xpack.actions.builtin.configuration.apiWhitelistError', { defaultMessage: 'error configuring connector action: {message}', values: { message, diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts index 040de32b78fe2..385ab3509bcd8 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts @@ -12,16 +12,12 @@ import { ExternalIncidentServiceSecretConfigurationSchema, ExecutorParamsSchema, ExecutorSubActionPushParamsSchema, - MapRecordSchema, - IncidentConfigurationSchema, ExecutorSubActionGetIncidentParamsSchema, ExecutorSubActionHandshakeParamsSchema, } from './schema'; import { ActionsConfigurationUtilities } from '../../actions_config'; - -export interface AnyParams { - [index: string]: string | number | object | undefined | null; -} +import { IncidentConfigurationSchema } from './case_shema'; +import { PushToServiceResponse } from './case_types'; export type ServiceNowPublicConfigurationType = TypeOf< typeof ExternalIncidentServiceConfigurationSchema @@ -30,13 +26,6 @@ export type ServiceNowSecretConfigurationType = TypeOf< typeof ExternalIncidentServiceSecretConfigurationSchema >; -export interface CreateIncidentRequest { - summary: string; - description: string; -} - -export type UpdateIncidentRequest = Partial; - export interface CreateCommentRequest { [key: string]: string; } @@ -45,7 +34,6 @@ export type ExecutorParams = TypeOf; export type ExecutorSubActionPushParams = TypeOf; export type IncidentConfiguration = TypeOf; -export type MapRecord = TypeOf; export interface ExternalServiceCredentials { config: Record; @@ -53,8 +41,8 @@ export interface ExternalServiceCredentials { } export interface ExternalServiceValidation { - config: (configurationUtilities: ActionsConfigurationUtilities, configObject: unknown) => void; - secrets: (configurationUtilities: ActionsConfigurationUtilities, secrets: unknown) => void; + config: (configurationUtilities: ActionsConfigurationUtilities, configObject: any) => void; + secrets: (configurationUtilities: ActionsConfigurationUtilities, secrets: any) => void; } export interface ExternalServiceIncidentResponse { @@ -64,12 +52,6 @@ export interface ExternalServiceIncidentResponse { pushedDate: string; } -export interface ExternalServiceCommentResponse { - commentId: string; - pushedDate: string; - externalCommentId?: string; -} - export interface ExternalServiceParams { [index: string]: any; } @@ -111,38 +93,8 @@ export interface HandshakeApiHandlerArgs extends ExternalServiceApiHandlerArgs { params: ExecutorSubActionHandshakeParams; } -export interface PushToServiceResponse extends ExternalServiceIncidentResponse { - comments?: ExternalServiceCommentResponse[]; -} - export interface ExternalServiceApi { handshake: (args: HandshakeApiHandlerArgs) => Promise; pushToService: (args: PushToServiceApiHandlerArgs) => Promise; getIncident: (args: GetIncidentApiHandlerArgs) => Promise; } - -export interface PipedField { - key: string; - value: string; - actionType: string; - pipes: string[]; -} - -export interface PrepareFieldsForTransformArgs { - params: PushToServiceApiParams; - mapping: Map; - defaultPipes?: string[]; -} - -export interface TransformFieldsArgs { - params: PushToServiceApiParams; - fields: PipedField[]; - currentIncident?: ExternalServiceParams; -} - -export interface TransformerArgs { - value: string; - date?: string; - user?: string; - previousValue?: string; -} diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts index 8c01bd94713e4..6f307b57c4817 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts @@ -4,9 +4,12 @@ * you may not use this file except in compliance with the Elastic License. */ -import { ExternalServiceValidation } from '../case/types'; import { ActionsConfigurationUtilities } from '../../actions_config'; -import { ServiceNowPublicConfigurationType, ServiceNowSecretConfigurationType } from './types'; +import { + ServiceNowPublicConfigurationType, + ServiceNowSecretConfigurationType, + ExternalServiceValidation, +} from './types'; import * as i18n from './translations'; diff --git a/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx index 0d8a4c04ca7cd..346390bd2a49f 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.tsx @@ -171,7 +171,7 @@ export const formatServiceRequestData = ( const actualExternalService = caseServices[connectorId] ?? null; return { - caseId, + savedObjectId: caseId, createdAt, createdBy: { fullName: createdBy.fullName ?? null, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index 54a9f16a141fb..e8be8e6b36d37 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -20,7 +20,7 @@ import { ServiceNowActionParams } from './types'; const ServiceNowParamsFields: React.FunctionComponent> = ({ actionParams, editAction, index, errors, messageVariables }) => { - const { title, description, comments, severity, urgency, impact, savedObjectId } = + const { title, description, comment, severity, urgency, impact, savedObjectId } = actionParams.subActionParams || {}; const selectOptions = [ { @@ -74,7 +74,7 @@ const ServiceNowParamsFields: React.FunctionComponent { editSubActionProperty( @@ -229,30 +229,30 @@ const ServiceNowParamsFields: React.FunctionComponent - onSelectMessageVariable('comments', variable) + onSelectMessageVariable('comment', variable) } - paramsProperty="comments" + paramsProperty="comment" /> } > { - editSubActionProperty('comments', e.target.value); + editSubActionProperty('comment', e.target.value); }} onBlur={() => { - if (!comments) { - editSubActionProperty('comments', ''); + if (!comment) { + editSubActionProperty('comment', ''); } }} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 48491d79a5dc9..0ebf2fcf71c3b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -20,7 +20,7 @@ export interface ServiceNowActionParams { savedObjectId: string; title: string; description: string; - comments: string; + comment: string; externalId: string; severity: string; urgency: string; From 2a988e1a9ef98c95c8aa9cc8f4e69d7ed6fd0437 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Fri, 12 Jun 2020 09:38:25 -0700 Subject: [PATCH 09/38] Revert changes on app_router --- src/core/public/application/ui/app_router.tsx | 30 +++++++++---------- 1 file changed, 14 insertions(+), 16 deletions(-) diff --git a/src/core/public/application/ui/app_router.tsx b/src/core/public/application/ui/app_router.tsx index f76ec2b8d71e5..5d02f96134b27 100644 --- a/src/core/public/application/ui/app_router.tsx +++ b/src/core/public/application/ui/app_router.tsx @@ -59,22 +59,20 @@ export const AppRouter: FunctionComponent = ({ // legacy apps can have multiple sub-apps registered with the same route // which needs additional logic that is handled in the catch-all route below .filter(([_, mounter]) => !mounter.legacy) - .map(([appId, mounter]) => { - return ( - ( - - )} - /> - ); - })} + .map(([appId, mounter]) => ( + ( + + )} + /> + ))} {/* handler for legacy apps and used as a catch-all to display 404 page on not existing /app/appId apps*/} Date: Mon, 15 Jun 2020 11:55:29 -0700 Subject: [PATCH 10/38] Fixed type checks --- .../pre-configured-connectors.asciidoc | 7 +++++-- .../actions/server/builtin_action_types/index.ts | 2 +- .../builtin_action_types/jira/service.test.ts | 6 +++--- .../builtin_action_types/servicenow/index.ts | 16 ++++++++++++---- x-pack/plugins/actions/server/plugin.test.ts | 1 + .../plugins/alerts/server/alerts_client.test.ts | 3 +++ .../routes/api/__mocks__/request_responses.ts | 2 ++ .../alerts/configuration/step1.test.tsx | 2 ++ .../public/cases/containers/configure/mock.ts | 3 +++ .../routes/__mocks__/request_responses.ts | 2 ++ .../builtin_action_types/email/email.test.tsx | 4 ++++ .../email/email_connector.test.tsx | 1 + .../es_index/es_index.test.tsx | 2 ++ .../es_index/es_index_connector.test.tsx | 1 + .../pagerduty/pagerduty.test.tsx | 2 ++ .../pagerduty/pagerduty_connectors.test.tsx | 1 + .../server_log/server_log.test.tsx | 1 + .../builtin_action_types/slack/slack.test.tsx | 2 ++ .../slack/slack_connectors.test.tsx | 1 + .../webhook/webhook.test.tsx | 2 ++ .../webhook/webhook_connectors.test.tsx | 1 + .../application/lib/action_connector_api.test.ts | 2 ++ .../action_type_menu.test.tsx | 3 +++ .../connector_add_modal.test.tsx | 1 + .../connector_edit_flyout.test.tsx | 4 ++++ .../connector_reducer.test.ts | 1 + .../security_and_spaces/tests/actions/get.ts | 1 + .../security_and_spaces/tests/actions/get_all.ts | 12 ++++++++++++ .../spaces_only/tests/actions/get.ts | 1 + .../spaces_only/tests/actions/get_all.ts | 4 ++++ x-pack/test/functional_with_es_ssl/config.ts | 2 ++ 31 files changed, 83 insertions(+), 10 deletions(-) diff --git a/docs/user/alerting/action-types/pre-configured-connectors.asciidoc b/docs/user/alerting/action-types/pre-configured-connectors.asciidoc index b1cf2d650e576..fbee979281093 100644 --- a/docs/user/alerting/action-types/pre-configured-connectors.asciidoc +++ b/docs/user/alerting/action-types/pre-configured-connectors.asciidoc @@ -28,12 +28,13 @@ two out-of-the box connectors: <> and < actionTypeId: .slack <2> name: 'Slack #xyz' <3> - secrets: <4> + secrets: webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz' + consumer: 'alerts' webhook-service: actionTypeId: .webhook name: 'Email service' - config: + config: <4> url: 'https://email-alert-service.elastic.co' method: post headers: @@ -42,6 +43,7 @@ two out-of-the box connectors: <> and < user: elastic password: changeme + consumer: 'alerts', <6> ``` <1> The key is the action connector identifier, `my-slack1` in this example. @@ -49,6 +51,7 @@ two out-of-the box connectors: <> and < `name` is the name of the preconfigured connector. <4> `config` is the action type specific to the configuration. <5> `secrets` is sensitive configuration, such as username, password, and keys. +<6> `consumer` is Kibana plugin owned the action. [NOTE] ============================================== 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 6ba4d7cfc7de0..0020161789d71 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/index.ts @@ -32,6 +32,6 @@ export function registerBuiltInActionTypes({ actionTypeRegistry.register(getServerLogActionType({ logger })); actionTypeRegistry.register(getSlackActionType({ configurationUtilities })); actionTypeRegistry.register(getWebhookActionType({ logger, configurationUtilities })); - actionTypeRegistry.register(getServiceNowActionType({ configurationUtilities })); + actionTypeRegistry.register(getServiceNowActionType({ logger, configurationUtilities })); actionTypeRegistry.register(getJiraActionType({ configurationUtilities })); } diff --git a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts index b9225b043d526..3de3926b7d821 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/jira/service.test.ts @@ -7,12 +7,12 @@ import axios from 'axios'; import { createExternalService } from './service'; -import * as utils from '../case/utils'; +import * as utils from '../lib/axios_utils'; import { ExternalService } from '../case/types'; jest.mock('axios'); -jest.mock('../case/utils', () => { - const originalUtils = jest.requireActual('../case/utils'); +jest.mock('../lib/axios_utils', () => { + const originalUtils = jest.requireActual('../lib/axios_utils'); return { ...originalUtils, request: jest.fn(), diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index d78f211f81c6b..171c207cca344 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -20,9 +20,11 @@ import { createExternalService } from './service'; import { api } from './api'; import { ExecutorParams, ExecutorSubActionPushParams } from './types'; import * as i18n from './translations'; +import { Logger } from '../../../../../../src/core/server'; // TODO: to remove, need to support Case import { buildMap, mapParams } from '../case/utils'; +import { PushToServiceResponse } from './case_types'; interface GetActionTypeParams { logger: Logger; @@ -57,7 +59,7 @@ async function executor( ): Promise { const { actionId, config, params, secrets } = execOptions; const { subAction, subActionParams } = params as ExecutorParams; - let data = {}; + let data: PushToServiceResponse | null = null; const res: Pick & Pick = { @@ -71,11 +73,15 @@ async function executor( }); if (!api[subAction]) { - throw new Error('[Action][ExternalService] Unsupported subAction type.'); + const errorMessage = '[Action][ExternalService] Unsupported subAction type.'; + logger.error(errorMessage); + throw new Error(errorMessage); } if (subAction !== 'pushToService') { - throw new Error('[Action][ExternalService] subAction not implemented.'); + const errorMessage = '[Action][ExternalService] subAction not implemented.'; + logger.error(errorMessage); + throw new Error(errorMessage); } if (subAction === 'pushToService') { @@ -94,10 +100,12 @@ async function executor( params: { ...pushToServiceParams, externalObject }, secrets, }); + + logger.debug(`response push to service for incident id: ${data.id}`); } return { ...res, - data, + data: data ?? {}, }; } diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index 1602b26559bed..a295a3e42627f 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -188,6 +188,7 @@ describe('Actions Plugin', () => { name: 'preconfigured-server-log', config: {}, secrets: {}, + consumer: 'alerts', }, }, }); diff --git a/x-pack/plugins/alerts/server/alerts_client.test.ts b/x-pack/plugins/alerts/server/alerts_client.test.ts index 9685f58b8fb31..09b8119f16e8f 100644 --- a/x-pack/plugins/alerts/server/alerts_client.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client.test.ts @@ -53,6 +53,7 @@ beforeEach(() => { config: { foo: 'bar', }, + consumer: 'alerts', }, { id: '2', @@ -62,12 +63,14 @@ beforeEach(() => { config: { foo: 'bar', }, + consumer: 'alerts', }, { id: 'testPreconfigured', actionTypeId: '.slack', isPreconfigured: true, name: 'test', + consumer: 'alerts', }, ]); alertsClientParams.getActionsClient.mockResolvedValue(actionsClient); diff --git a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts index 4aa6725159043..bf253da02d12c 100644 --- a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts +++ b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts @@ -25,6 +25,7 @@ export const getActions = (): FindActionResult[] => [ }, isPreconfigured: false, referencedByCount: 0, + consumer: 'alerts', }, { id: '123', @@ -54,6 +55,7 @@ export const getActions = (): FindActionResult[] => [ }, isPreconfigured: false, referencedByCount: 0, + consumer: 'alerts', }, ]; diff --git a/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx b/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx index 1be66ce4ccfef..0b39f00a1c8c7 100644 --- a/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx +++ b/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx @@ -28,6 +28,7 @@ describe('Step1', () => { name: 'Testing', config: {}, isPreconfigured: false, + consumer: 'alerts', }, ]; const selectedEmailActionId = emailActions[0].id; @@ -89,6 +90,7 @@ describe('Step1', () => { name: '', config: {}, isPreconfigured: false, + consumer: 'alerts', }, ], selectedEmailActionId: NEW_ACTION_ID, diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts index 88e1793aa15c1..d729a3feed2a7 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts @@ -40,6 +40,7 @@ export const connectorsMock: Connector[] = [ }, }, isPreconfigured: false, + consumer: 'case', }, { id: 'servicenow-2', @@ -68,6 +69,7 @@ export const connectorsMock: Connector[] = [ }, }, isPreconfigured: false, + consumer: 'case', }, { id: 'jira-1', @@ -96,6 +98,7 @@ export const connectorsMock: Connector[] = [ }, }, isPreconfigured: false, + consumer: 'case', }, ]; diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index fe66496f70dcd..6a3340fd663b8 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -325,6 +325,7 @@ export const createActionResult = (): ActionResult => ({ name: '', config: {}, isPreconfigured: false, + consumer: 'alerts', }); export const nonRuleAlert = () => ({ @@ -462,6 +463,7 @@ export const updateActionResult = (): ActionResult => ({ name: '', config: {}, isPreconfigured: false, + consumer: 'alerts', }); export const getMockPrivilegesResult = () => ({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx index e823e848f52c2..846c738bf8aba 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email.test.tsx @@ -44,6 +44,7 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, + consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -73,6 +74,7 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, + consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -125,6 +127,7 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, + consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -153,6 +156,7 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, + consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx index 8ee953c00795e..575067fa37295 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx @@ -22,6 +22,7 @@ describe('EmailActionConnectorFields renders', () => { config: { from: 'test@test.com', }, + consumer: 'alerts', } as EmailActionConnector; const wrapper = mountWithIntl( { refresh: false, executionTimeField: '1', }, + consumer: 'alerts', } as EsIndexActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -59,6 +60,7 @@ describe('index connector validation with minimal config', () => { config: { index: 'test_es_index', }, + consumer: 'alerts', } as EsIndexActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx index 4cb397927b53e..576fe65632c04 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx @@ -79,6 +79,7 @@ describe('IndexActionConnectorFields renders', () => { refresh: false, executionTimeField: 'test1', }, + consumer: 'alerts', } as EsIndexActionConnector; const wrapper = mountWithIntl( { config: { apiUrl: 'http:\\test', }, + consumer: 'alerts', } as PagerDutyActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -65,6 +66,7 @@ describe('pagerduty connector validation', () => { config: { apiUrl: 'http:\\test', }, + consumer: 'alerts', } as PagerDutyActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx index 86730c0ab4ac7..f0c0093cddbb7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx @@ -22,6 +22,7 @@ describe('PagerDutyActionConnectorFields renders', () => { config: { apiUrl: 'http:\\test', }, + consumer: 'alerts', } as PagerDutyActionConnector; const deps = { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx index 3bb5ea68a3040..cbf1427a4988d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx @@ -34,6 +34,7 @@ describe('server-log connector validation', () => { actionTypeId: '.server-log', name: 'server-log', config: {}, + consumer: 'alerts', } as ActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx index 78f4161cac827..add2ae001eb83 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx @@ -37,6 +37,7 @@ describe('slack connector validation', () => { actionTypeId: '.email', name: 'email', config: {}, + consumer: 'alerts', } as SlackActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -53,6 +54,7 @@ describe('slack connector validation', () => { actionTypeId: '.email', name: 'email', config: {}, + consumer: 'alerts', } as SlackActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx index bd905c1c95650..15ad64db9e99a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx @@ -20,6 +20,7 @@ describe('SlackActionFields renders', () => { actionTypeId: '.email', name: 'email', config: {}, + consumer: 'alerts', } as SlackActionConnector; const deps = { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx index 3413465d70d93..7662cfd93bb0b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx @@ -43,6 +43,7 @@ describe('webhook connector validation', () => { url: 'http:\\test', headers: { 'content-type': 'text' }, }, + consumer: 'alerts', } as WebhookActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -66,6 +67,7 @@ describe('webhook connector validation', () => { config: { method: 'PUT', }, + consumer: 'alerts', } as WebhookActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx index 3b7865e59b9e6..8550ede680d02 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx @@ -25,6 +25,7 @@ describe('WebhookActionConnectorFields renders', () => { url: 'http:\\test', headers: { 'content-type': 'text' }, }, + consumer: 'alerts', } as WebhookActionConnector; const wrapper = mountWithIntl( { name: 'My test', config: {}, secrets: {}, + consumer: 'alerts', }; const resolvedValue: ActionConnector = { ...connector, id: '123' }; http.post.mockResolvedValueOnce(resolvedValue); @@ -90,6 +91,7 @@ describe('updateActionConnector', () => { name: 'My test', config: {}, secrets: {}, + consumer: 'alerts', }; const resolvedValue = { ...connector, id }; http.put.mockResolvedValueOnce(resolvedValue); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx index a5e9cdc65cfa6..f0890dcab8dbb 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx @@ -67,6 +67,7 @@ describe('connector_add_flyout', () => { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, + consumer: 'alerts', }} > { toastNotifications={deps!.toastNotifications} docLinks={deps!.docLinks} capabilities={deps!.capabilities} + consumer={'alerts'} /> ); expect(wrapper.exists('.euiModalHeader')).toBeTruthy(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx index dd9eeae266987..f29acbd0ccdaf 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.test.tsx @@ -51,6 +51,7 @@ describe('connector_edit_flyout', () => { isPreconfigured: false, referencedByCount: 0, config: {}, + consumer: 'alerts', }; const actionType = { @@ -82,6 +83,7 @@ describe('connector_edit_flyout', () => { return new Promise(() => {}); }, docLinks: deps.docLinks, + consumer: 'alerts', }} > { isPreconfigured: true, referencedByCount: 0, config: {}, + consumer: 'alerts', }; const actionType = { @@ -139,6 +142,7 @@ describe('connector_edit_flyout', () => { return new Promise(() => {}); }, docLinks: deps.docLinks, + consumer: 'alerts', }} > { referencedByCount: 0, isPreconfigured: false, config: {}, + consumer: 'alerts', }; }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts index c610ac670f690..edf2bc9c4ea54 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts @@ -141,6 +141,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', isPreconfigured: true, + consumer: 'alerts', }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts index 45491aa2d28fc..936349f547202 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts @@ -67,6 +67,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { unencrypted: `This value shouldn't get encrypted`, }, referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured-es-index-action', @@ -74,6 +75,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, + consumer: 'alerts', }, { id: 'my-slack1', @@ -81,6 +83,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, + consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -172,6 +175,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { unencrypted: `This value shouldn't get encrypted`, }, referencedByCount: 1, + consumer: 'alerts', }, { id: 'preconfigured-es-index-action', @@ -179,6 +183,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, + consumer: 'alerts', }, { id: 'my-slack1', @@ -186,6 +191,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 1, + consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -193,6 +199,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -200,6 +207,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, + consumer: 'alerts', }, ]); break; @@ -221,6 +229,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -257,6 +266,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, + consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -264,6 +274,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -271,6 +282,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, + consumer: 'alerts', }, ]); break; diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 2f965d422bfd9..1854eaeff137e 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -81,6 +81,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, actionTypeId: '.slack', name: 'Slack#xyz', + consumer: 'alerts', }); }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index 60766ff4bc926..da04f382daca9 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -100,6 +100,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, + consumer: 'alerts', }, { id: 'my-slack1', @@ -107,6 +108,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, + consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -114,6 +116,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -121,6 +124,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, + consumer: 'alerts', }, ]); }); diff --git a/x-pack/test/functional_with_es_ssl/config.ts b/x-pack/test/functional_with_es_ssl/config.ts index 43192d906336d..8b566eb424abc 100644 --- a/x-pack/test/functional_with_es_ssl/config.ts +++ b/x-pack/test/functional_with_es_ssl/config.ts @@ -72,10 +72,12 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { secrets: { webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, + consumer: 'alerts', }, 'my-server-log': { actionTypeId: '.server-log', name: 'Serverlog#xyz', + consumer: 'alerts', }, })}`, ], From 819e002bfa41032c598025fb1a493bb329e3392c Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 15 Jun 2020 13:23:14 -0700 Subject: [PATCH 11/38] Fixed language check issues --- .../translations/translations/ja-JP.json | 4 --- .../translations/translations/zh-CN.json | 4 --- .../servicenow/servicenow_params.tsx | 6 ++-- .../servicenow/translations.ts | 35 ++++++++++--------- .../actions/builtin_action_types/email.ts | 1 + .../actions/builtin_action_types/es_index.ts | 1 + .../actions/builtin_action_types/pagerduty.ts | 1 + .../builtin_action_types/server_log.ts | 1 + .../builtin_action_types/servicenow.ts | 1 + .../actions/builtin_action_types/slack.ts | 1 + .../actions/builtin_action_types/webhook.ts | 1 + .../alerting_api_integration/common/config.ts | 4 +++ 12 files changed, 33 insertions(+), 27 deletions(-) diff --git a/x-pack/plugins/translations/translations/ja-JP.json b/x-pack/plugins/translations/translations/ja-JP.json index 8888120d59f88..3437ae5e3bc90 100644 --- a/x-pack/plugins/translations/translations/ja-JP.json +++ b/x-pack/plugins/translations/translations/ja-JP.json @@ -3923,7 +3923,6 @@ "xpack.actions.builtin.case.configuration.emptyMapping": "[casesConfiguration.mapping]:空以外の値が必要ですが空でした", "xpack.actions.builtin.case.connectorApiNullError": "コネクター[apiUrl]が必要です", "xpack.actions.builtin.case.jiraTitle": "Jira", - "xpack.actions.builtin.case.servicenowTitle": "ServiceNow", "xpack.actions.builtin.email.errorSendingErrorMessage": "エラー送信メールアドレス", "xpack.actions.builtin.emailTitle": "メール", "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "エラーインデックス作成ドキュメント", @@ -13650,7 +13649,6 @@ "xpack.securitySolution.case.configureCases.mappingFieldComments": "コメント", "xpack.securitySolution.case.configureCases.mappingFieldDescription": "説明", "xpack.securitySolution.case.configureCases.mappingFieldNotMapped": "マップされません", - "xpack.securitySolution.case.configureCases.mappingFieldShortDescription": "短い説明", "xpack.securitySolution.case.configureCases.mappingFieldSummary": "まとめ", "xpack.securitySolution.case.configureCases.noConnector": "コネクターを選択していません", "xpack.securitySolution.case.configureCases.updateConnector": "コネクターを更新", @@ -13679,8 +13677,6 @@ "xpack.securitySolution.case.connectors.jira.projectKey": "プロジェクトキー", "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "プロジェクトキーが必要です", "xpack.securitySolution.case.connectors.jira.selectMessageText": "JiraでSIEMケースデータを更新するか、新しいインシデントにプッシュ", - "xpack.securitySolution.case.connectors.servicenow.actionTypeTitle": "ServiceNow", - "xpack.securitySolution.case.connectors.servicenow.selectMessageText": "ServiceNow で Security ケースデータをb\\更新するか、または新しいインシデントにプッシュする", "xpack.securitySolution.case.createCase.descriptionFieldRequiredError": "説明が必要です。", "xpack.securitySolution.case.createCase.fieldTagsHelpText": "このケースの 1 つ以上のカスタム識別タグを入力します。新しいタグを開始するには、各タグの後でEnterを押します。", "xpack.securitySolution.case.createCase.titleFieldRequiredError": "タイトルが必要です。", diff --git a/x-pack/plugins/translations/translations/zh-CN.json b/x-pack/plugins/translations/translations/zh-CN.json index 3109bab4b9426..befb1c4e273ba 100644 --- a/x-pack/plugins/translations/translations/zh-CN.json +++ b/x-pack/plugins/translations/translations/zh-CN.json @@ -3926,7 +3926,6 @@ "xpack.actions.builtin.case.configuration.emptyMapping": "[casesConfiguration.mapping]:应为非空,但却为空", "xpack.actions.builtin.case.connectorApiNullError": "需要指定连接器 [apiUrl]", "xpack.actions.builtin.case.jiraTitle": "Jira", - "xpack.actions.builtin.case.servicenowTitle": "ServiceNow", "xpack.actions.builtin.email.errorSendingErrorMessage": "发送电子邮件时出错", "xpack.actions.builtin.emailTitle": "电子邮件", "xpack.actions.builtin.esIndex.errorIndexingErrorMessage": "索引文档时出错", @@ -13655,7 +13654,6 @@ "xpack.securitySolution.case.configureCases.mappingFieldComments": "注释", "xpack.securitySolution.case.configureCases.mappingFieldDescription": "描述", "xpack.securitySolution.case.configureCases.mappingFieldNotMapped": "未映射", - "xpack.securitySolution.case.configureCases.mappingFieldShortDescription": "简短描述", "xpack.securitySolution.case.configureCases.mappingFieldSummary": "摘要", "xpack.securitySolution.case.configureCases.noConnector": "未选择连接器", "xpack.securitySolution.case.configureCases.updateConnector": "更新连接器", @@ -13684,8 +13682,6 @@ "xpack.securitySolution.case.connectors.jira.projectKey": "项目键", "xpack.securitySolution.case.connectors.jira.requiredProjectKeyTextField": "项目键必填。", "xpack.securitySolution.case.connectors.jira.selectMessageText": "将 Security 案例数据推送或更新到 Jira 中的新问题", - "xpack.securitySolution.case.connectors.servicenow.actionTypeTitle": "ServiceNow", - "xpack.securitySolution.case.connectors.servicenow.selectMessageText": "将 Security 案例数据推送或更新到 ServiceNow 中的新事件", "xpack.securitySolution.case.createCase.descriptionFieldRequiredError": "描述必填。", "xpack.securitySolution.case.createCase.fieldTagsHelpText": "为此案例键入一个或多个定制识别标记。在每个标记后按 Enter 键可开始新的标记。", "xpack.securitySolution.case.createCase.titleFieldRequiredError": "标题必填。", diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index e8be8e6b36d37..2e1e23fe96c75 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -26,7 +26,7 @@ const ServiceNowParamsFields: React.FunctionComponent { let servicenowSimulatorURL: string = ''; diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts index 90660cc99507d..e803fa60607cc 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts @@ -36,6 +36,7 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: slackSimulatorURL, }, + consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts index af1d413ff3c46..4a91c51223cac 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts @@ -39,6 +39,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { config: { url: webhookSimulatorURL, }, + consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index bc209e2bb4925..cefa97581c27a 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -91,6 +91,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) secrets: { webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, + consumer: 'alerts', }, 'custom-system-abc-connector': { actionTypeId: 'system-abc-action-type', @@ -104,6 +105,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) xyzSecret1: 'credential1', xyzSecret2: 'credential2', }, + consumer: 'alerts', }, 'preconfigured-es-index-action': { actionTypeId: '.index', @@ -113,6 +115,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) refresh: true, executionTimeField: 'timestamp', }, + consumer: 'alerts', }, 'preconfigured.test.index-record': { actionTypeId: 'test.index-record', @@ -123,6 +126,7 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) secrets: { encrypted: 'this-is-also-ignored-and-also-required', }, + consumer: 'alerts', }, })}`, ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), From ff50f73337aab42f2c10e10c36ae3e1698c46754 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 15 Jun 2020 16:43:09 -0700 Subject: [PATCH 12/38] Fixed actions unit tests --- .../servicenow/api.test.ts | 95 ++++++------------- .../builtin_action_types/servicenow/api.ts | 52 +++++----- .../builtin_action_types/servicenow/mocks.ts | 31 +++++- 3 files changed, 81 insertions(+), 97 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 8e9288c94f6a6..ccab9331050ba 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -62,7 +62,7 @@ describe('api', () => { }); test('it calls createIncident correctly', async () => { - const params = { ...apiParams, externalId: null }; + const params = { ...apiParams, externalId: null, comments: undefined }; await api.pushToService({ externalService, mapping, params, secrets: {} }); expect(externalService.createIncident).toHaveBeenCalledWith({ @@ -81,41 +81,25 @@ describe('api', () => { await api.pushToService({ externalService, mapping, params, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledTimes(2); expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { - incidentId: 'incident-1', - comment: { - commentId: 'case-comment-1', - comment: 'A comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { - fullName: 'Elastic User', - username: 'elastic', - }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { - fullName: 'Elastic User', - username: 'elastic', - }, + incident: { + comments: 'A comment', + description: + 'Incident description (created at 2020-03-13T08:34:53.450Z by Elastic User)', + short_description: + 'Incident title (created at 2020-03-13T08:34:53.450Z by Elastic User)', }, - field: 'comments', + incidentId: null, }); expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { - incidentId: 'incident-1', - comment: { - commentId: 'case-comment-2', - comment: 'Another comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { - fullName: 'Elastic User', - username: 'elastic', - }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { - fullName: 'Elastic User', - username: 'elastic', - }, + incident: { + comments: 'Another comment', + description: + 'Incident description (created at 2020-03-13T08:34:53.450Z by Elastic User)', + short_description: + 'Incident title (created at 2020-03-13T08:34:53.450Z by Elastic User)', }, - field: 'comments', + incidentId: null, }); }); }); @@ -180,46 +164,29 @@ describe('api', () => { expect(externalService.createIncident).not.toHaveBeenCalled(); }); - test('it calls createComment correctly', async () => { + test('it calls updateIncident to create a comments correctly', async () => { const params = { ...apiParams }; await api.pushToService({ externalService, mapping, params, secrets: {} }); - expect(externalService.updateIncident).toHaveBeenCalledTimes(2); + expect(externalService.updateIncident).toHaveBeenCalledTimes(3); expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { - incidentId: 'incident-2', - comment: { - commentId: 'case-comment-1', - comment: 'A comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { - fullName: 'Elastic User', - username: 'elastic', - }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { - fullName: 'Elastic User', - username: 'elastic', - }, + incidentId: 'incident-3', + incident: { + description: + 'Incident description (updated at 2020-03-13T08:34:53.450Z by Elastic User)', + short_description: + 'Incident title (updated at 2020-03-13T08:34:53.450Z by Elastic User)', }, - field: 'comments', }); expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { - incidentId: 'incident-2', - comment: { - commentId: 'case-comment-2', - comment: 'Another comment (added at 2020-03-13T08:34:53.450Z by Elastic User)', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { - fullName: 'Elastic User', - username: 'elastic', - }, - updatedAt: '2020-03-13T08:34:53.450Z', - updatedBy: { - fullName: 'Elastic User', - username: 'elastic', - }, + incident: { + comments: 'A comment', + description: + 'Incident description (updated at 2020-03-13T08:34:53.450Z by Elastic User)', + short_description: + 'Incident title (updated at 2020-03-13T08:34:53.450Z by Elastic User)', }, - field: 'comments', + incidentId: 'incident-3', }); }); }); @@ -531,7 +498,7 @@ describe('api', () => { }); await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); - expect(externalService.updateIncident).not.toHaveBeenCalled(); + expect(externalService.updateIncident).toHaveBeenCalledTimes(1); }); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 9cbce63ea0993..ecbd8a109db9b 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -63,25 +63,30 @@ const pushToServiceHandler = async ({ } // TODO: should temporary keep it for a Case usage + if (updateIncident) { + res = await externalService.updateIncident({ + incidentId: externalId, + incident, + }); + } else { + res = await externalService.createIncident({ + incident: { + ...incident, + caller_id: secrets.username, + }, + }); + } if ( - updateIncident && comments && Array.isArray(comments) && comments.length > 0 && mapping && mapping.get('comments')?.actionType !== 'nothing' ) { - const resComments = []; + res.comments = []; + const fieldsKey = mapping.get('comments')?.target ?? 'comments'; - res = await externalService.updateIncident({ - incidentId: externalId, - incident: { - ...incident, - [fieldsKey]: comments[0].comment, - }, - }); - for (let i = 1; i < comments.length; i++) { - const currentComment = comments[i]; + for (const currentComment of comments) { await externalService.updateIncident({ incidentId: externalId, incident: { @@ -89,25 +94,16 @@ const pushToServiceHandler = async ({ [fieldsKey]: currentComment.comment, }, }); - resComments.push(...(res.comments ?? []), { - commentId: currentComment.commentId, - pushedDate: res.pushedDate, - }); + res.comments = [ + ...(res.comments ?? []), + { + commentId: currentComment.commentId, + pushedDate: res.pushedDate, + }, + ]; } - res.comments = resComments; - return res; - } else if (updateIncident) { - return await externalService.updateIncident({ - incidentId: externalId, - incident, - }); } - return await externalService.createIncident({ - incident: { - ...incident, - caller_id: secrets.username, - }, - }); + return res; }; export const transformFields = ({ diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts index 229241cd544b3..5f22fcd4fdc85 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/mocks.ts @@ -66,13 +66,34 @@ mapping.set('short_description', { const executorParams: ExecutorSubActionPushParams = { savedObjectId: 'd4387ac5-0899-4dc2-bbfa-0dd605c934aa', externalId: 'incident-3', + createdAt: '2020-03-13T08:34:53.450Z', + createdBy: { fullName: 'Elastic User', username: 'elastic' }, + updatedAt: '2020-03-13T08:34:53.450Z', + updatedBy: { fullName: 'Elastic User', username: 'elastic' }, title: 'Incident title', description: 'Incident description', - comment: 'comment-1', - severity: '3', - urgency: '3', - impact: '3', - updatedAt: null, + comment: 'test-alert comment', + severity: '1', + urgency: '2', + impact: '1', + comments: [ + { + commentId: 'case-comment-1', + comment: 'A comment', + createdAt: '2020-03-13T08:34:53.450Z', + createdBy: { fullName: 'Elastic User', username: 'elastic' }, + updatedAt: '2020-03-13T08:34:53.450Z', + updatedBy: { fullName: 'Elastic User', username: 'elastic' }, + }, + { + commentId: 'case-comment-2', + comment: 'Another comment', + createdAt: '2020-03-13T08:34:53.450Z', + createdBy: { fullName: 'Elastic User', username: 'elastic' }, + updatedAt: '2020-03-13T08:34:53.450Z', + updatedBy: { fullName: 'Elastic User', username: 'elastic' }, + }, + ], }; const apiParams: PushToServiceApiParams = { From 41604dfe6aa3dd7d2c7d8369e2bdb2ebbbbbc197 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 15 Jun 2020 17:41:22 -0700 Subject: [PATCH 13/38] Fixed functional tests --- .../tests/actions/builtin_action_types/email.ts | 8 ++++++++ .../actions/builtin_action_types/es_index.ts | 11 +++++++++++ .../tests/actions/builtin_action_types/jira.ts | 11 +++++++++++ .../actions/builtin_action_types/pagerduty.ts | 6 ++++++ .../actions/builtin_action_types/server_log.ts | 3 +++ .../actions/builtin_action_types/servicenow.ts | 17 ++++++++++++++++- .../tests/actions/builtin_action_types/slack.ts | 7 +++++++ .../actions/builtin_action_types/webhook.ts | 5 +++++ .../security_and_spaces/tests/actions/create.ts | 5 +++++ .../security_and_spaces/tests/actions/delete.ts | 2 ++ .../tests/actions/execute.ts | 5 +++++ .../security_and_spaces/tests/actions/get.ts | 3 +++ .../tests/actions/get_all.ts | 5 +++++ .../security_and_spaces/tests/actions/update.ts | 4 ++++ .../actions/builtin_action_types/es_index.ts | 7 +++++++ .../actions/builtin_action_types/webhook.ts | 1 + .../spaces_only/tests/actions/create.ts | 2 ++ .../spaces_only/tests/actions/delete.ts | 2 ++ .../spaces_only/tests/actions/execute.ts | 4 ++++ .../spaces_only/tests/actions/get.ts | 3 +++ .../spaces_only/tests/actions/get_all.ts | 7 +++++++ .../spaces_only/tests/actions/update.ts | 3 +++ .../apps/triggers_actions_ui/connectors.ts | 1 + .../apps/triggers_actions_ui/details.ts | 6 ++++++ .../apps/triggers_actions_ui/home_page.ts | 1 + .../services/alerting/actions.ts | 1 + 26 files changed, 129 insertions(+), 1 deletion(-) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts index ffbb29b431d8d..0ef762e257fa3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts @@ -33,6 +33,7 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'supersecret', }, + consumer: 'alerts', }) .expect(200); @@ -49,6 +50,7 @@ export default function emailTest({ getService }: FtrProviderContext) { secure: null, from: 'bob@example.com', }, + consumer: 'alerts', }); expect(typeof createdActionId).to.be('string'); @@ -69,6 +71,7 @@ export default function emailTest({ getService }: FtrProviderContext) { port: null, secure: null, }, + consumer: 'alerts', }); }); @@ -144,6 +147,7 @@ export default function emailTest({ getService }: FtrProviderContext) { name: 'An email action', actionTypeId: '.email', config: {}, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -171,6 +175,7 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'changeme', }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -197,6 +202,7 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'changeme', }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -225,6 +231,7 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'changeme', }, + consumer: 'alerts', }) .expect(200); expect(typeof createdAction.id).to.be('string'); @@ -241,6 +248,7 @@ export default function emailTest({ getService }: FtrProviderContext) { service: '__json', from: 'jim@example.com', }, + consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index c1dc155c17238..f732577159547 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -35,6 +35,7 @@ export default function indexTest({ getService }: FtrProviderContext) { index: ES_TEST_INDEX_NAME, }, secrets: {}, + consumer: 'alerts', }) .expect(200); @@ -48,6 +49,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: false, executionTimeField: null, }, + consumer: 'alerts', }); createdActionID = createdAction.id; expect(typeof createdActionID).to.be('string'); @@ -62,6 +64,7 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, + consumer: 'alerts', }); // create action with all config props @@ -76,6 +79,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, + consumer: 'alerts', }) .expect(200); @@ -89,6 +93,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, + consumer: 'alerts', }); createdActionIDWithIndex = createdActionWithIndex.id; expect(typeof createdActionIDWithIndex).to.be('string'); @@ -107,6 +112,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, + consumer: 'alerts', }); }); @@ -118,6 +124,7 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { index: 666 }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -142,6 +149,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, + consumer: 'alerts', }) .expect(200); const { body: result } = await supertest @@ -172,6 +180,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, + consumer: 'alerts', }) .expect(200); const { body: result } = await supertest @@ -217,6 +226,7 @@ export default function indexTest({ getService }: FtrProviderContext) { executionTimeField: 'test', }, secrets: {}, + consumer: 'alerts', }) .expect(200); const { body: result } = await supertest @@ -245,6 +255,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, + consumer: 'alerts', }) .expect(200); const { body: result2 } = await supertest diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 093f09c24bad3..459cf87984bc6 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -97,6 +97,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { apiUrl: jiraSimulatorURL, }, secrets: mockJira.secrets, + consumer: 'alerts', }) .expect(200); @@ -110,6 +111,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, casesConfiguration: mockJira.config.casesConfiguration, }, + consumer: 'alerts', }); const { body: fetchedAction } = await supertest @@ -126,6 +128,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, casesConfiguration: mockJira.config.casesConfiguration, }, + consumer: 'alerts', }); }); @@ -137,6 +140,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { name: 'A jira action', actionTypeId: '.jira', config: { projectKey: 'CK' }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -157,6 +161,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { name: 'A jira action', actionTypeId: '.jira', config: { apiUrl: jiraSimulatorURL }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -182,6 +187,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { casesConfiguration: mockJira.config.casesConfiguration, }, secrets: mockJira.secrets, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -206,6 +212,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, casesConfiguration: mockJira.config.casesConfiguration, }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -230,6 +237,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, }, secrets: mockJira.secrets, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -255,6 +263,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { casesConfiguration: { mapping: [] }, }, secrets: mockJira.secrets, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -288,6 +297,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { }, }, secrets: mockJira.secrets, + consumer: 'alerts', }) .expect(400); }); @@ -308,6 +318,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { casesConfiguration: mockJira.config.casesConfiguration, }, secrets: mockJira.secrets, + consumer: 'alerts', }); simulatedActionId = body.id; }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index 71ceb731da9f0..d748e27694a36 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -45,6 +45,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { secrets: { routingKey: 'pager-duty-routing-key', }, + consumer: 'alerts', }) .expect(200); @@ -56,6 +57,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { config: { apiUrl: pagerdutySimulatorURL, }, + consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -72,6 +74,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { config: { apiUrl: pagerdutySimulatorURL, }, + consumer: 'alerts', }); }); @@ -86,6 +89,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { apiUrl: pagerdutySimulatorURL, }, secrets: {}, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -106,6 +110,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { name: 'A pagerduty action', actionTypeId: '.pagerduty', secrets: {}, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -131,6 +136,7 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { secrets: { routingKey: 'pager-duty-routing-key', }, + consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts index a915987ce5feb..9b079c45e350b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts @@ -25,6 +25,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { .send({ name: 'A server.log action', actionTypeId: '.server-log', + consumer: 'alerts', }) .expect(200); @@ -35,6 +36,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { name: 'A server.log action', actionTypeId: '.server-log', config: {}, + consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -49,6 +51,7 @@ export default function serverLogTest({ getService }: FtrProviderContext) { name: 'A server.log action', actionTypeId: '.server-log', config: {}, + consumer: 'alerts', }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 531a362fa2bab..38061ea13fbde 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -49,7 +49,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { params: { subAction: 'pushToService', subActionParams: { - caseId: '123', + savedObjectId: '123', title: 'a title', description: 'a description', createdAt: '2020-03-13T08:34:53.450Z', @@ -57,6 +57,10 @@ export default function servicenowTest({ getService }: FtrProviderContext) { updatedAt: null, updatedBy: null, externalId: null, + comment: 'test-alert comment', + severity: '1', + urgency: '2', + impact: '1', comments: [ { commentId: '456', @@ -70,6 +74,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { ], }, }, + consumer: 'alerts', }; let servicenowSimulatorURL: string = ''; @@ -96,6 +101,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { casesConfiguration: mockServiceNow.config.casesConfiguration, }, secrets: mockServiceNow.secrets, + consumer: mockServiceNow.consumer, }) .expect(200); @@ -108,6 +114,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { apiUrl: servicenowSimulatorURL, casesConfiguration: mockServiceNow.config.casesConfiguration, }, + consumer: mockServiceNow.consumer, }); const { body: fetchedAction } = await supertest @@ -123,6 +130,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { apiUrl: servicenowSimulatorURL, casesConfiguration: mockServiceNow.config.casesConfiguration, }, + consumer: mockServiceNow.consumer, }); }); @@ -134,6 +142,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { name: 'A servicenow action', actionTypeId: '.servicenow', config: {}, + consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -158,6 +167,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { casesConfiguration: mockServiceNow.config.casesConfiguration, }, secrets: mockServiceNow.secrets, + consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -181,6 +191,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { apiUrl: servicenowSimulatorURL, casesConfiguration: mockServiceNow.config.casesConfiguration, }, + consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -204,6 +215,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { apiUrl: servicenowSimulatorURL, }, secrets: mockServiceNow.secrets, + consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -228,6 +240,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { casesConfiguration: { mapping: [] }, }, secrets: mockServiceNow.secrets, + consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -260,6 +273,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }, }, secrets: mockServiceNow.secrets, + consumer: mockServiceNow.consumer, }) .expect(400); }); @@ -279,6 +293,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { casesConfiguration: mockServiceNow.config.casesConfiguration, }, secrets: mockServiceNow.secrets, + consumer: mockServiceNow.consumer, }); simulatedActionId = body.id; }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index 537205360f4aa..9b28d0306ebbb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -42,6 +42,7 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: slackSimulatorURL, }, + consumer: 'alerts', }) .expect(200); @@ -51,6 +52,7 @@ export default function slackTest({ getService }: FtrProviderContext) { name: 'A slack action', actionTypeId: '.slack', config: {}, + consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -65,6 +67,7 @@ export default function slackTest({ getService }: FtrProviderContext) { name: 'A slack action', actionTypeId: '.slack', config: {}, + consumer: 'alerts', }); }); @@ -76,6 +79,7 @@ export default function slackTest({ getService }: FtrProviderContext) { name: 'A slack action', actionTypeId: '.slack', secrets: {}, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -98,6 +102,7 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: 'http://slack.mynonexistent.com/other/stuff/in/the/path', }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -120,6 +125,7 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: 'fee-fi-fo-fum', }, + consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -142,6 +148,7 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: slackSimulatorURL, }, + consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index 10adf12baf652..28493996eed2f 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -55,6 +55,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { password, }, config: composedConfig, + consumer: 'alerts', }) .expect(200); @@ -87,6 +88,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { config: { url: webhookSimulatorURL, }, + consumer: 'alerts', }) .expect(200); @@ -99,6 +101,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { ...defaultValues, url: webhookSimulatorURL, }, + consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -116,6 +119,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { ...defaultValues, url: webhookSimulatorURL, }, + consumer: 'alerts', }); }); @@ -178,6 +182,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { config: { url: 'http://a.none.whitelisted.webhook/endpoint', }, + consumer: 'alerts', }) .expect(400); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts index 69dcb7c813815..623c8ddd630ae 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts @@ -36,6 +36,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }); switch (scenario.id) { @@ -61,6 +62,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, + consumer: 'alerts', }); expect(typeof response.body.id).to.be('string'); // Ensure AAD isn't broken @@ -85,6 +87,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { name: 'My action', actionTypeId: 'test.unregistered-action-type', config: {}, + consumer: 'alerts', }); switch (scenario.id) { @@ -155,6 +158,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { config: { unencrypted: 'my unencrypted text', }, + consumer: 'alerts', }); switch (scenario.id) { @@ -191,6 +195,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { .send({ name: 'my name', actionTypeId: 'test.not-enabled', + consumer: 'alerts', }); switch (scenario.id) { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts index d96ffc5bb3be3..c75fbb35ef5e2 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts @@ -36,6 +36,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); @@ -79,6 +80,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts index 70a3663c1c798..6d756e65b0f1b 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts @@ -54,6 +54,7 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -126,6 +127,7 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -180,6 +182,7 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -338,6 +341,7 @@ export default function ({ getService }: FtrProviderContext) { user: 'email-user', password: 'email-password', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -400,6 +404,7 @@ export default function ({ getService }: FtrProviderContext) { .send({ name: 'My action', actionTypeId: 'test.authorization', + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts index edf2bc9c4ea54..aab11c06ff769 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts @@ -35,6 +35,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -65,6 +66,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, + consumer: 'alerts', }); break; default: @@ -85,6 +87,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts index 936349f547202..5f545c1dfa573 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts @@ -35,6 +35,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -91,6 +92,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -98,6 +100,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, + consumer: 'alerts', }, ]); break; @@ -119,6 +122,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -259,6 +263,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, + consumer: 'alerts', }, { id: 'my-slack1', diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts index cb0e0efda0b1a..31c447c2b3cc1 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts @@ -35,6 +35,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -75,6 +76,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, + consumer: 'alerts', }); // Ensure AAD isn't broken await checkAAD({ @@ -102,6 +104,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -265,6 +268,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts index 0822e614464cb..9ad03924692e2 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts @@ -33,6 +33,7 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME }, secrets: {}, + consumer: 'alerts', }) .expect(200); @@ -46,6 +47,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: false, executionTimeField: null, }, + consumer: 'alerts', }); createdActionID = createdAction.id; expect(typeof createdActionID).to.be('string'); @@ -60,6 +62,7 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, + consumer: 'alerts', }); // create action with all config props @@ -74,6 +77,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, + consumer: 'alerts', }) .expect(200); @@ -87,6 +91,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, + consumer: 'alerts', }); createdActionIDWithIndex = createdActionWithIndex.id; expect(typeof createdActionIDWithIndex).to.be('string'); @@ -105,6 +110,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, + consumer: 'alerts', }); }); @@ -120,6 +126,7 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, + consumer: 'alerts', }) .expect(200); const { body: result } = await supertest diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts index fb8460068cbcf..5dc519dcf4282 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts @@ -39,6 +39,7 @@ export default function webhookTest({ getService }: FtrProviderContext) { actionTypeId: '.webhook', secrets: {}, config: composedConfig, + consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index f3542c728845d..9946b8b03bb0b 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -31,6 +31,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }); expect(response.status).to.eql(200); @@ -43,6 +44,7 @@ export default function createActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, + consumer: 'alerts', }); expect(typeof response.body.id).to.be('string'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts index 6e7f8d6f2a4b1..e84ad7277b561 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts @@ -30,6 +30,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); @@ -52,6 +53,7 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index 7bbeab7cc8726..6950dc84b92d1 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -50,6 +50,7 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -95,6 +96,7 @@ export default function ({ getService }: FtrProviderContext) { .send({ name: 'failing action', actionTypeId: 'test.failing', + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -133,6 +135,7 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -163,6 +166,7 @@ export default function ({ getService }: FtrProviderContext) { .send({ name: 'My action', actionTypeId: 'test.authorization', + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 1854eaeff137e..8b2889380f4f0 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -30,6 +30,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -44,6 +45,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, + consumer: 'alerts', }); }); @@ -60,6 +62,7 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index da04f382daca9..c7dbe7087e893 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -30,6 +30,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -44,6 +45,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { unencrypted: `This value shouldn't get encrypted`, }, referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured-es-index-action', @@ -51,6 +53,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, + consumer: 'alerts', }, { id: 'my-slack1', @@ -58,6 +61,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, + consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -65,6 +69,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, + consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -72,6 +77,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, + consumer: 'alerts', }, ]); }); @@ -89,6 +95,7 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index 81db8177b2c11..7839cdec661b5 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -30,6 +30,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -54,6 +55,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, + consumer: 'alerts', }); // Ensure AAD isn't broken @@ -78,6 +80,7 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, + consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts index 41be67592cbeb..8a1f0ee1433d3 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts @@ -27,6 +27,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }); await pageObjects.common.navigateToApp('triggersActions'); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index e22b098e6ee0c..52ee2cccc04c3 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -33,6 +33,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }), alerting.actions.createAction({ name: `slack-${testRunUuid}-${1}`, @@ -41,6 +42,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }), ]); @@ -321,6 +323,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }), alerting.actions.createAction({ name: `slack-${testRunUuid}-${1}`, @@ -329,6 +332,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }), ]); @@ -539,6 +543,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }), alerting.actions.createAction({ name: `slack-${testRunUuid}-${1}`, @@ -547,6 +552,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }), ]); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts index 3b93607832670..09da66496a87b 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts @@ -65,6 +65,7 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, + consumer: 'alerts', }); const alert = await alerting.alerts.createAlwaysFiringWithAction( diff --git a/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts b/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts index cff5b3c3ce9c3..3936f4e7c7f20 100644 --- a/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts +++ b/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts @@ -27,6 +27,7 @@ export class Actions { actionTypeId: string; config: Record; secrets: Record; + consumer: string; }) { this.log.debug(`creating action ${actionParams.name}`); From 752904fc944102c39d2665187e53b481ef2265fc Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 15 Jun 2020 21:20:11 -0700 Subject: [PATCH 14/38] Fixed jest tests --- .../__snapshots__/step1.test.tsx.snap | 1 + .../use_post_push_to_service.test.tsx | 2 +- .../lib/action_connector_api.test.ts | 2 +- .../actions_connectors_list.test.tsx | 137 ++++++++++-------- 4 files changed, 81 insertions(+), 61 deletions(-) diff --git a/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap b/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap index cb1081c0c14da..34b4a79e48280 100644 --- a/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap +++ b/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap @@ -24,6 +24,7 @@ exports[`Step1 editing should allow for editing 1`] = ` Object { "actionTypeId": "1abc", "config": Object {}, + "consumer": "alerts", "id": "1", "isPreconfigured": false, "name": "Testing", diff --git a/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.test.tsx b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.test.tsx index 96fa824c1cadd..1720396f2a73c 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/use_post_push_to_service.test.tsx @@ -42,7 +42,7 @@ describe('usePostPushToService', () => { updateCase, }; const sampleServiceRequestData = { - caseId: pushedCase.id, + savedObjectId: pushedCase.id, createdAt: pushedCase.createdAt, createdBy: serviceConnectorUser, comments: [ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts index 9b95fa0e2f490..8753bd89170c0 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts @@ -75,7 +75,7 @@ describe('createActionConnector', () => { Array [ "/api/actions/action", Object { - "body": "{\\"actionTypeId\\":\\"test\\",\\"isPreconfigured\\":false,\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{}}", + "body": "{\\"actionTypeId\\":\\"test\\",\\"isPreconfigured\\":false,\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{},\\"consumer\\":\\"alerts\\"}", }, ] `); 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 09d94e2418cb8..cd3403b81d78c 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 @@ -4,9 +4,9 @@ * you may not use this file except in compliance with the Elastic License. */ import * as React from 'react'; +import { mountWithIntl, nextTick } from 'test_utils/enzyme_helpers'; import { ScopedHistory } from 'kibana/public'; -import { mountWithIntl } from 'test_utils/enzyme_helpers'; import { ActionsConnectorsList } from './actions_connectors_list'; import { coreMock, scopedHistoryMock } from '../../../../../../../../src/core/public/mocks'; import { ReactWrapper } from 'enzyme'; @@ -27,7 +27,7 @@ const actionTypeRegistry = actionTypeRegistryMock.create(); describe('actions_connectors_list component empty', () => { let wrapper: ReactWrapper; - beforeAll(async () => { + async function setup() { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); @@ -75,25 +75,29 @@ describe('actions_connectors_list component empty', () => { }; actionTypeRegistry.has.mockReturnValue(true); + wrapper = mountWithIntl( + + + + ); + + // Wait for active space to resolve before requesting the component to update await act(async () => { - wrapper = mountWithIntl( - - - - ); + await nextTick(); + wrapper.update(); }); + } - await waitForRender(wrapper); - }); - - it('renders empty prompt', () => { + it('renders empty prompt', async () => { + await setup(); expect(wrapper.find('EuiEmptyPrompt')).toHaveLength(1); expect( wrapper.find('[data-test-subj="createFirstActionButton"]').find('EuiButton') ).toHaveLength(1); }); - test('if click create button should render ConnectorAddFlyout', () => { + test('if click create button should render ConnectorAddFlyout', async () => { + await setup(); wrapper.find('[data-test-subj="createFirstActionButton"]').first().simulate('click'); expect(wrapper.find('ConnectorAddFlyout')).toHaveLength(1); }); @@ -102,7 +106,7 @@ describe('actions_connectors_list component empty', () => { describe('actions_connectors_list component with items', () => { let wrapper: ReactWrapper; - beforeAll(async () => { + async function setup() { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); @@ -114,6 +118,7 @@ describe('actions_connectors_list component with items', () => { isPreconfigured: false, referencedByCount: 1, config: {}, + consumer: 'alerts', }, { id: '2', @@ -122,6 +127,7 @@ describe('actions_connectors_list component with items', () => { referencedByCount: 1, isPreconfigured: false, config: {}, + consumer: 'alerts', }, { id: '3', @@ -130,6 +136,7 @@ describe('actions_connectors_list component with items', () => { referencedByCount: 1, isPreconfigured: true, config: {}, + consumer: 'alerts', }, ]); loadActionTypes.mockResolvedValueOnce([ @@ -181,29 +188,34 @@ describe('actions_connectors_list component with items', () => { alertTypeRegistry: {} as any, }; + wrapper = mountWithIntl( + + + + ); + + // Wait for active space to resolve before requesting the component to update await act(async () => { - wrapper = mountWithIntl( - - - - ); + await nextTick(); + wrapper.update(); }); - await waitForRender(wrapper); - expect(loadAllActions).toHaveBeenCalled(); - }); + } - it('renders table of connectors', () => { + it('renders table of connectors', async () => { + await setup(); expect(wrapper.find('EuiInMemoryTable')).toHaveLength(1); expect(wrapper.find('EuiTableRow')).toHaveLength(3); }); - it('renders table with preconfigured connectors', () => { + it('renders table with preconfigured connectors', async () => { + await setup(); expect(wrapper.find('[data-test-subj="preConfiguredTitleMessage"]')).toHaveLength(2); }); test('if select item for edit should render ConnectorEditFlyout', async () => { + await setup(); await wrapper.find('[data-test-subj="edit1"]').first().simulate('click'); expect(wrapper.find('ConnectorEditFlyout')).toHaveLength(1); @@ -213,7 +225,7 @@ describe('actions_connectors_list component with items', () => { describe('actions_connectors_list component empty with show only capability', () => { let wrapper: ReactWrapper; - beforeAll(async () => { + async function setup() { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); @@ -264,18 +276,21 @@ describe('actions_connectors_list component empty with show only capability', () alertTypeRegistry: {} as any, }; + wrapper = mountWithIntl( + + + + ); + + // Wait for active space to resolve before requesting the component to update await act(async () => { - wrapper = mountWithIntl( - - - - ); + await nextTick(); + wrapper.update(); }); + } - await waitForRender(wrapper); - }); - - it('renders no permissions to create connector', () => { + it('renders no permissions to create connector', async () => { + await setup(); expect(wrapper.find('[defaultMessage="No permissions to create connector"]')).toHaveLength(1); expect(wrapper.find('[data-test-subj="createActionButton"]')).toHaveLength(0); }); @@ -284,7 +299,7 @@ describe('actions_connectors_list component empty with show only capability', () describe('actions_connectors_list with show only capability', () => { let wrapper: ReactWrapper; - beforeAll(async () => { + async function setup() { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); @@ -295,6 +310,7 @@ describe('actions_connectors_list with show only capability', () => { description: 'My test', referencedByCount: 1, config: {}, + consumer: 'alerts', }, { id: '2', @@ -302,6 +318,7 @@ describe('actions_connectors_list with show only capability', () => { description: 'My test 2', referencedByCount: 1, config: {}, + consumer: 'alerts', }, ]); loadActionTypes.mockResolvedValueOnce([ @@ -350,18 +367,21 @@ describe('actions_connectors_list with show only capability', () => { alertTypeRegistry: {} as any, }; + wrapper = mountWithIntl( + + + + ); + + // Wait for active space to resolve before requesting the component to update await act(async () => { - wrapper = mountWithIntl( - - - - ); + await nextTick(); + wrapper.update(); }); + } - await waitForRender(wrapper); - }); - - it('renders table of connectors with delete button disabled', () => { + it('renders table of connectors with delete button disabled', async () => { + await setup(); expect(wrapper.find('EuiInMemoryTable')).toHaveLength(1); expect(wrapper.find('EuiTableRow')).toHaveLength(2); wrapper.find('EuiTableRow').forEach((elem) => { @@ -375,7 +395,7 @@ describe('actions_connectors_list with show only capability', () => { describe('actions_connectors_list component with disabled items', () => { let wrapper: ReactWrapper; - beforeAll(async () => { + async function setup() { const { loadAllActions, loadActionTypes } = jest.requireMock( '../../../lib/action_connector_api' ); @@ -386,6 +406,7 @@ describe('actions_connectors_list component with disabled items', () => { description: 'My test', referencedByCount: 1, config: {}, + consumer: 'alerts', }, { id: '2', @@ -393,6 +414,7 @@ describe('actions_connectors_list component with disabled items', () => { description: 'My test 2', referencedByCount: 1, config: {}, + consumer: 'alerts', }, ]); loadActionTypes.mockResolvedValueOnce([ @@ -448,20 +470,23 @@ describe('actions_connectors_list component with disabled items', () => { alertTypeRegistry: {} as any, }; + wrapper = mountWithIntl( + + + + ); + + // Wait for active space to resolve before requesting the component to update await act(async () => { - wrapper = mountWithIntl( - - - - ); + await nextTick(); + wrapper.update(); }); - await waitForRender(wrapper); - expect(loadAllActions).toHaveBeenCalled(); - }); + } - it('renders table of connectors', () => { + it('renders table of connectors', async () => { + await setup(); expect(wrapper.find('EuiInMemoryTable')).toHaveLength(1); expect(wrapper.find('EuiTableRow')).toHaveLength(2); expect(wrapper.find('EuiTableRow').at(0).prop('className')).toEqual( @@ -472,9 +497,3 @@ describe('actions_connectors_list component with disabled items', () => { ); }); }); - -async function waitForRender(wrapper: ReactWrapper) { - await Promise.resolve(); - await Promise.resolve(); - wrapper.update(); -} From c2836b460e232cb395b24c23680836231d9fb339 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 09:06:35 -0700 Subject: [PATCH 15/38] fixed tests --- .../builtin_action_types/servicenow/api.ts | 5 +++-- .../actions/builtin_action_types/servicenow.ts | 1 + .../tests/actions/builtin_action_types/jira.ts | 18 +++++++++--------- .../actions/builtin_action_types/servicenow.ts | 18 +++++++++--------- 4 files changed, 22 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index ecbd8a109db9b..789cc474cd5fa 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -62,7 +62,6 @@ const pushToServiceHandler = async ({ incident = { ...params, short_description: params.title, comments: params.comment }; } - // TODO: should temporary keep it for a Case usage if (updateIncident) { res = await externalService.updateIncident({ incidentId: externalId, @@ -76,6 +75,8 @@ const pushToServiceHandler = async ({ }, }); } + + // TODO: should temporary keep comments for a Case usage if ( comments && Array.isArray(comments) && @@ -88,7 +89,7 @@ const pushToServiceHandler = async ({ const fieldsKey = mapping.get('comments')?.target ?? 'comments'; for (const currentComment of comments) { await externalService.updateIncident({ - incidentId: externalId, + incidentId: res.id, incident: { ...incident, [fieldsKey]: currentComment.comment, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts index 20c3d2de9ab79..070c253a61cb2 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts @@ -72,6 +72,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { casesConfiguration: { ...mockServiceNow.config.casesConfiguration }, }, secrets: mockServiceNow.secrets, + consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 459cf87984bc6..57bca19b7e074 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -50,7 +50,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { params: { subAction: 'pushToService', subActionParams: { - caseId: '123', + savedObjectId: '123', title: 'a title', description: 'a description', createdAt: '2020-03-13T08:34:53.450Z', @@ -372,12 +372,12 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.caseId]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]', }); }); }); - it('should handle failing with a simulated success without caseId', async () => { + it('should handle failing with a simulated success without savedObjectId', async () => { await supertest .post(`/api/actions/action/${simulatedActionId}/_execute`) .set('kbn-xsrf', 'foo') @@ -390,7 +390,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.caseId]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]', }); }); }); @@ -403,7 +403,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { params: { ...mockJira.params, subActionParams: { - caseId: 'success', + savedObjectId: 'success', }, }, }) @@ -426,7 +426,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { params: { ...mockJira.params, subActionParams: { - caseId: 'success', + savedObjectId: 'success', title: 'success', }, }, @@ -451,7 +451,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { ...mockJira.params, subActionParams: { ...mockJira.params.subActionParams, - caseId: 'success', + savedObjectId: 'success', title: 'success', createdAt: 'success', createdBy: { username: 'elastic' }, @@ -479,7 +479,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { ...mockJira.params, subActionParams: { ...mockJira.params.subActionParams, - caseId: 'success', + savedObjectId: 'success', title: 'success', createdAt: 'success', createdBy: { username: 'elastic' }, @@ -507,7 +507,7 @@ export default function jiraTest({ getService }: FtrProviderContext) { ...mockJira.params, subActionParams: { ...mockJira.params.subActionParams, - caseId: 'success', + savedObjectId: 'success', title: 'success', createdAt: 'success', createdBy: { username: 'elastic' }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 38061ea13fbde..fcd70ee7ac5ae 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -74,7 +74,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { ], }, }, - consumer: 'alerts', + consumer: 'case', }; let servicenowSimulatorURL: string = ''; @@ -347,12 +347,12 @@ export default function servicenowTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.caseId]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]', }); }); }); - it('should handle failing with a simulated success without caseId', async () => { + it('should handle failing with a simulated success without savedObjectId', async () => { await supertest .post(`/api/actions/action/${simulatedActionId}/_execute`) .set('kbn-xsrf', 'foo') @@ -365,7 +365,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.caseId]: expected value of type [string] but got [undefined]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.savedObjectId]: expected value of type [string] but got [undefined]', }); }); }); @@ -378,7 +378,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { params: { ...mockServiceNow.params, subActionParams: { - caseId: 'success', + savedObjectId: 'success', }, }, }) @@ -401,7 +401,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { params: { ...mockServiceNow.params, subActionParams: { - caseId: 'success', + savedObjectId: 'success', title: 'success', }, }, @@ -426,7 +426,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { ...mockServiceNow.params, subActionParams: { ...mockServiceNow.params.subActionParams, - caseId: 'success', + savedObjectId: 'success', title: 'success', createdAt: 'success', createdBy: { username: 'elastic' }, @@ -454,7 +454,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { ...mockServiceNow.params, subActionParams: { ...mockServiceNow.params.subActionParams, - caseId: 'success', + savedObjectId: 'success', title: 'success', createdAt: 'success', createdBy: { username: 'elastic' }, @@ -482,7 +482,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { ...mockServiceNow.params, subActionParams: { ...mockServiceNow.params.subActionParams, - caseId: 'success', + savedObjectId: 'success', title: 'success', createdAt: 'success', createdBy: { username: 'elastic' }, From beda51dc6c9312b6cb58dd0fd51fdc5370ed16e3 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 14:33:08 -0700 Subject: [PATCH 16/38] Copied case mappings to alerting plugin --- .../servicenow/api.test.ts | 8 +- .../case_mappings/field_mapping.tsx | 147 ++++++++++++++ .../case_mappings/field_mapping_row.tsx | 80 ++++++++ .../servicenow/case_mappings/translations.ts | 184 ++++++++++++++++++ .../servicenow/case_mappings/types.ts | 63 ++++++ .../servicenow/case_mappings/utils.ts | 40 ++++ .../servicenow/servicenow.tsx | 3 +- .../servicenow/servicenow_connectors.tsx | 19 +- .../application/lib/value_validators.test.ts | 12 +- .../application/lib/value_validators.ts | 11 +- .../plugins/alerts/server/action_types.ts | 1 + 11 files changed, 552 insertions(+), 16 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index ccab9331050ba..21aee53637818 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -88,7 +88,7 @@ describe('api', () => { short_description: 'Incident title (created at 2020-03-13T08:34:53.450Z by Elastic User)', }, - incidentId: null, + incidentId: 'incident-1', }); expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { @@ -99,7 +99,7 @@ describe('api', () => { short_description: 'Incident title (created at 2020-03-13T08:34:53.450Z by Elastic User)', }, - incidentId: null, + incidentId: 'incident-1', }); }); }); @@ -169,13 +169,13 @@ describe('api', () => { await api.pushToService({ externalService, mapping, params, secrets: {} }); expect(externalService.updateIncident).toHaveBeenCalledTimes(3); expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { - incidentId: 'incident-3', incident: { description: 'Incident description (updated at 2020-03-13T08:34:53.450Z by Elastic User)', short_description: 'Incident title (updated at 2020-03-13T08:34:53.450Z by Elastic User)', }, + incidentId: 'incident-3', }); expect(externalService.updateIncident).toHaveBeenNthCalledWith(2, { @@ -186,7 +186,7 @@ describe('api', () => { short_description: 'Incident title (updated at 2020-03-13T08:34:53.450Z by Elastic User)', }, - incidentId: 'incident-3', + incidentId: 'incident-2', }); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx new file mode 100644 index 0000000000000..04a30af5e3b2b --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx @@ -0,0 +1,147 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useCallback, useMemo } from 'react'; +import { EuiFormRow, EuiFlexItem, EuiFlexGroup, EuiSuperSelectOption } from '@elastic/eui'; +import styled from 'styled-components'; + +import { CaseField, ActionType, ThirdPartyField } from '../../../../../../../case/common/api'; +import { FieldMappingRow } from './field_mapping_row'; +import * as i18n from './translations'; + +import { setActionTypeToMapping, setThirdPartyToMapping } from './utils'; +import { + ThirdPartyField as ConnectorConfigurationThirdPartyField, + AllThirdPartyFields, +} from './types'; +import { CasesConfigurationMapping } from '../types'; +import { connectorConfiguration } from '../config'; +import { createDefaultMapping } from '../servicenow_connectors'; + +const FieldRowWrapper = styled.div` + margin-top: 8px; + font-size: 14px; +`; + +const actionTypeOptions: Array> = [ + { + value: 'nothing', + inputDisplay: <>{i18n.FIELD_MAPPING_EDIT_NOTHING}, + 'data-test-subj': 'edit-update-option-nothing', + }, + { + value: 'overwrite', + inputDisplay: <>{i18n.FIELD_MAPPING_EDIT_OVERWRITE}, + 'data-test-subj': 'edit-update-option-overwrite', + }, + { + value: 'append', + inputDisplay: <>{i18n.FIELD_MAPPING_EDIT_APPEND}, + 'data-test-subj': 'edit-update-option-append', + }, +]; + +const getThirdPartyOptions = ( + caseField: CaseField, + thirdPartyFields: Record +): Array> => + (Object.keys(thirdPartyFields) as AllThirdPartyFields[]).reduce< + Array> + >( + (acc, key) => { + if (thirdPartyFields[key].validSourceFields.includes(caseField)) { + return [ + ...acc, + { + value: key, + inputDisplay: {thirdPartyFields[key].label}, + 'data-test-subj': `dropdown-mapping-${key}`, + }, + ]; + } + return acc; + }, + [ + { + value: 'not_mapped', + inputDisplay: i18n.MAPPING_FIELD_NOT_MAPPED, + 'data-test-subj': 'dropdown-mapping-not_mapped', + }, + ] + ); + +export interface FieldMappingProps { + disabled: boolean; + mapping: CasesConfigurationMapping[] | null; + connectorActionTypeId: string; + onChangeMapping: (newMapping: CasesConfigurationMapping[]) => void; +} + +const FieldMappingComponent: React.FC = ({ + disabled, + mapping, + onChangeMapping, + connectorActionTypeId, +}) => { + const onChangeActionType = useCallback( + (caseField: CaseField, newActionType: ActionType) => { + const myMapping = mapping ?? defaultMapping; + onChangeMapping(setActionTypeToMapping(caseField, newActionType, myMapping)); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [mapping] + ); + + const onChangeThirdParty = useCallback( + (caseField: CaseField, newThirdPartyField: ThirdPartyField) => { + const myMapping = mapping ?? defaultMapping; + onChangeMapping(setThirdPartyToMapping(caseField, newThirdPartyField, myMapping)); + }, + // eslint-disable-next-line react-hooks/exhaustive-deps + [mapping] + ); + + const selectedConnector = connectorConfiguration ?? { fields: {} }; + const defaultMapping = useMemo(() => createDefaultMapping(selectedConnector.fields), [ + selectedConnector.fields, + ]); + + return ( + <> + + + + {i18n.FIELD_MAPPING_FIRST_COL} + + + {i18n.FIELD_MAPPING_SECOND_COL} + + + {i18n.FIELD_MAPPING_THIRD_COL} + + + + + {(mapping ?? defaultMapping).map((item) => ( + + ))} + + + ); +}; + +export const FieldMapping = React.memo(FieldMappingComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx new file mode 100644 index 0000000000000..495b47410d2f9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx @@ -0,0 +1,80 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import React, { useMemo } from 'react'; +import { + EuiFlexItem, + EuiFlexGroup, + EuiSuperSelect, + EuiIcon, + EuiSuperSelectOption, +} from '@elastic/eui'; + +import { capitalize } from 'lodash'; +import { CaseField, ActionType, ThirdPartyField } from '../../../../../../../case/common/api/cases'; +import { AllThirdPartyFields } from './types'; + +export interface RowProps { + id: string; + disabled: boolean; + securitySolutionField: CaseField; + thirdPartyOptions: Array>; + actionTypeOptions: Array>; + onChangeActionType: (caseField: CaseField, newActionType: ActionType) => void; + onChangeThirdParty: (caseField: CaseField, newThirdPartyField: ThirdPartyField) => void; + selectedActionType: ActionType; + selectedThirdParty: ThirdPartyField; +} + +const FieldMappingRowComponent: React.FC = ({ + id, + disabled, + securitySolutionField, + thirdPartyOptions, + actionTypeOptions, + onChangeActionType, + onChangeThirdParty, + selectedActionType, + selectedThirdParty, +}) => { + const securitySolutionFieldCapitalized = useMemo(() => capitalize(securitySolutionField), [ + securitySolutionField, + ]); + return ( + + + + + {securitySolutionFieldCapitalized} + + + + + + + + + + + + + + ); +}; + +export const FieldMappingRow = React.memo(FieldMappingRowComponent); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts new file mode 100644 index 0000000000000..9ef6ce2f3d4a9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts @@ -0,0 +1,184 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ + +import { i18n } from '@kbn/i18n'; + +export const INCIDENT_MANAGEMENT_SYSTEM_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.incidentManagementSystemTitle', + { + defaultMessage: 'Connect to external incident management system', + } +); + +export const INCIDENT_MANAGEMENT_SYSTEM_DESC = i18n.translate( + 'xpack.securitySolution.case.configureCases.incidentManagementSystemDesc', + { + defaultMessage: + 'You may optionally connect Security cases to an external incident management system of your choosing. This will allow you to push case data as an incident in your chosen third-party system.', + } +); + +export const INCIDENT_MANAGEMENT_SYSTEM_LABEL = i18n.translate( + 'xpack.securitySolution.case.configureCases.incidentManagementSystemLabel', + { + defaultMessage: 'Incident management system', + } +); + +export const NO_CONNECTOR = i18n.translate( + 'xpack.securitySolution.case.configureCases.noConnector', + { + defaultMessage: 'No connector selected', + } +); + +export const ADD_NEW_CONNECTOR = i18n.translate( + 'xpack.securitySolution.case.configureCases.addNewConnector', + { + defaultMessage: 'Add new connector', + } +); + +export const CASE_CLOSURE_OPTIONS_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsTitle', + { + defaultMessage: 'Case Closures', + } +); + +export const CASE_CLOSURE_OPTIONS_DESC = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsDesc', + { + defaultMessage: + 'Define how you wish Security cases to be closed. Automated case closures require an established connection to an external incident management system.', + } +); + +export const CASE_CLOSURE_OPTIONS_LABEL = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsLabel', + { + defaultMessage: 'Case closure options', + } +); + +export const CASE_CLOSURE_OPTIONS_MANUAL = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsManual', + { + defaultMessage: 'Manually close Security cases', + } +); + +export const CASE_CLOSURE_OPTIONS_NEW_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsNewIncident', + { + defaultMessage: + 'Automatically close Security cases when pushing new incident to external system', + } +); + +export const CASE_CLOSURE_OPTIONS_CLOSED_INCIDENT = i18n.translate( + 'xpack.securitySolution.case.configureCases.caseClosureOptionsClosedIncident', + { + defaultMessage: 'Automatically close Security cases when incident is closed in external system', + } +); + +export const FIELD_MAPPING_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingTitle', + { + defaultMessage: 'Field mappings', + } +); + +export const FIELD_MAPPING_DESC = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingDesc', + { + defaultMessage: + 'Map Security case fields when pushing data to a third-party. Field mappings require an established connection to an external incident management system.', + } +); + +export const FIELD_MAPPING_FIRST_COL = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingFirstCol', + { + defaultMessage: 'Security case field', + } +); + +export const FIELD_MAPPING_SECOND_COL = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingSecondCol', + { + defaultMessage: 'External incident field', + } +); + +export const FIELD_MAPPING_THIRD_COL = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingThirdCol', + { + defaultMessage: 'On edit and update', + } +); + +export const FIELD_MAPPING_EDIT_NOTHING = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingEditNothing', + { + defaultMessage: 'Nothing', + } +); + +export const FIELD_MAPPING_EDIT_OVERWRITE = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingEditOverwrite', + { + defaultMessage: 'Overwrite', + } +); + +export const FIELD_MAPPING_EDIT_APPEND = i18n.translate( + 'xpack.securitySolution.case.configureCases.fieldMappingEditAppend', + { + defaultMessage: 'Append', + } +); + +export const CANCEL = i18n.translate('xpack.securitySolution.case.configureCases.cancelButton', { + defaultMessage: 'Cancel', +}); + +export const WARNING_NO_CONNECTOR_TITLE = i18n.translate( + 'xpack.securitySolution.case.configureCases.warningTitle', + { + defaultMessage: 'Warning', + } +); + +export const WARNING_NO_CONNECTOR_MESSAGE = i18n.translate( + 'xpack.securitySolution.case.configureCases.warningMessage', + { + defaultMessage: + 'The selected connector has been deleted. Either select a different connector or create a new one.', + } +); + +export const MAPPING_FIELD_NOT_MAPPED = i18n.translate( + 'xpack.securitySolution.case.configureCases.mappingFieldNotMapped', + { + defaultMessage: 'Not mapped', + } +); + +export const UPDATE_CONNECTOR = i18n.translate( + 'xpack.securitySolution.case.configureCases.updateConnector', + { + defaultMessage: 'Update connector', + } +); + +export const UPDATE_SELECTED_CONNECTOR = (connectorName: string): string => { + return i18n.translate('xpack.securitySolution.case.configureCases.updateSelectedConnector', { + values: { connectorName }, + defaultMessage: 'Update { connectorName }', + }); +}; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts new file mode 100644 index 0000000000000..413d792ab2f7f --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.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; + * you may not use this file except in compliance with the Elastic License. + */ + +/* eslint-disable no-restricted-imports */ +/* eslint-disable @kbn/eslint/no-restricted-paths */ + +import { ExternalIncidentServiceConfiguration } from '../../../../../../../actions/server/builtin_action_types/case/types'; +import { IErrorObject, ActionType } from '../../../../../types'; + +import { + ActionType as ThirdPartySupportedActions, + CaseField, +} from '../../../../../../../case/common/api'; + +export { ThirdPartyField as AllThirdPartyFields } from '../../../../../../../case/common/api'; + +export { ActionType, CaseField }; + +export interface ThirdPartyField { + label: string; + validSourceFields: CaseField[]; + defaultSourceField: CaseField; + defaultActionType: ThirdPartySupportedActions; +} + +export interface ConnectorConfiguration extends ActionType { + logo: string; + fields: Record; +} + +export interface ActionConnector { + config: ExternalIncidentServiceConfiguration; + secrets: {}; +} + +export interface ActionConnectorParams { + message: string; +} + +export interface ActionConnectorValidationErrors { + apiUrl: string[]; +} + +export type Optional = Omit & Partial; + +export interface ConnectorFlyoutFormProps { + errors: IErrorObject; + action: T; + onChangeSecret: (key: string, value: string) => void; + onBlurSecret: (key: string) => void; + onChangeConfig: (key: string, value: string) => void; + onBlurConfig: (key: string) => void; +} + +export interface ConnectorFlyoutHOCProps { + ConnectorFormComponent: React.FC>; + connectorActionTypeId: string; + configKeys?: string[]; + secretKeys?: string[]; +} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts new file mode 100644 index 0000000000000..d3139e80ae3b1 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts @@ -0,0 +1,40 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { ActionType, ThirdPartyField } from '../../../../../../../case/common/api'; +import { CaseField } from './types'; +import { CasesConfigurationMapping } from '../types'; + +export const setActionTypeToMapping = ( + caseField: CaseField, + newActionType: ActionType, + mapping: CasesConfigurationMapping[] +): CasesConfigurationMapping[] => { + const findItemIndex = mapping.findIndex((item) => item.source === caseField); + + if (findItemIndex >= 0) { + return [ + ...mapping.slice(0, findItemIndex), + { ...mapping[findItemIndex], actionType: newActionType }, + ...mapping.slice(findItemIndex + 1), + ]; + } + + return [...mapping]; +}; + +export const setThirdPartyToMapping = ( + caseField: CaseField, + newThirdPartyField: ThirdPartyField, + mapping: CasesConfigurationMapping[] +): CasesConfigurationMapping[] => + mapping.map((item) => { + if (item.source !== caseField && item.target === newThirdPartyField) { + return { ...item, target: 'not_mapped' }; + } else if (item.source === caseField) { + return { ...item, target: newThirdPartyField }; + } + return item; + }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index ce4e124e2e43e..57d0049803c06 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -5,8 +5,6 @@ */ import { lazy } from 'react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { isUrlInvalid } from '../../../../../../security_solution/public/common/lib/connectors/validators'; import { ValidationResult, ActionTypeModel, @@ -16,6 +14,7 @@ import { connectorConfiguration } from './config'; import logo from './logo.svg'; import { ServiceNowActionConnector, ServiceNowActionParams } from './types'; import * as i18n from './translations'; +import { isUrlInvalid } from '../../../lib/value_validators'; const validateConnector = (action: ServiceNowActionConnector): ValidationResult => { const validationResult = { errors: {} }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 50fd0300f5fbf..314e0fc3f50b9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -15,18 +15,11 @@ import { } from '@elastic/eui'; import { isEmpty } from 'lodash'; - -// TODO: remove FieldMapping, createDefaultMapping later -// when Case ServiceNow will move their fields to the level of action execution -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { FieldMapping } from '../../../../../../security_solution/public/cases/components/configure_cases/field_mapping'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { createDefaultMapping } from '../../../../../../security_solution/public/common/lib/connectors/utils'; - import { IErrorObject, ActionConnectorFieldsProps } from '../../../../types'; import * as i18n from './translations'; import { ServiceNowActionConnector, CasesConfigurationMapping } from './types'; import { connectorConfiguration } from './config'; +import { FieldMapping } from './case_mappings/field_mapping'; export interface ConnectorFlyoutFormProps { errors: IErrorObject; @@ -179,5 +172,15 @@ const ServiceNowConnectorFlyout: React.FC): CasesConfigurationMapping[] => + Object.keys(fields).map( + (key) => + ({ + source: fields[key].defaultSourceField, + target: key, + actionType: fields[key].defaultActionType, + } as CasesConfigurationMapping) + ); + // eslint-disable-next-line import/no-default-export export { ServiceNowConnectorFlyout as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts index 9d628adc1db6b..eba22eae0c06b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { throwIfAbsent, throwIfIsntContained } from './value_validators'; +import { throwIfAbsent, throwIfIsntContained, isUrlInvalid } from './value_validators'; import uuid from 'uuid'; describe('throwIfAbsent', () => { @@ -79,3 +79,13 @@ describe('throwIfIsntContained', () => { ).toEqual(values); }); }); + +describe('isUrlInvalid', () => { + test('verifies invalid url', () => { + expect(isUrlInvalid('this is not a url')).toBeTruthy(); + }); + + test('verifies valid url', () => { + expect(isUrlInvalid('https://www.elastic.co/')).toBeFalsy(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts index 7ee7359086406..ff3ffae233faa 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { constant } from 'lodash'; +import { constant, isEmpty } from 'lodash'; export function throwIfAbsent(message: string) { return (value: T | undefined): T => { @@ -31,3 +31,12 @@ export function throwIfIsntContained( return values; }; } + +const urlExpression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi; + +export const isUrlInvalid = (url: string | null | undefined) => { + if (!isEmpty(url) && url != null && url.match(urlExpression) == null) { + return true; + } + return false; +}; diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts index 3b6befb3fe807..8c89970dbd082 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts @@ -40,6 +40,7 @@ export function defineActionTypes( secrets: schema.object({ encrypted: schema.string(), }), + consumer: schema.string(), }, async executor({ config, secrets, params, services, actionId }: ActionTypeExecutorOptions) { await services.callCluster('index', { From 0e96eb94659a3f85197dc87373a972f83793a885 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 17:17:36 -0700 Subject: [PATCH 17/38] made consumer optional --- .../pre-configured-connectors.asciidoc | 3 -- .../server/action_type_registry.test.ts | 1 - .../actions/server/actions_client.test.ts | 28 ++----------------- .../plugins/actions/server/actions_client.ts | 2 +- .../builtin_action_types/servicenow/schema.ts | 4 +-- x-pack/plugins/actions/server/config.test.ts | 8 ++---- x-pack/plugins/actions/server/config.ts | 2 +- .../server/create_execute_function.test.ts | 2 -- x-pack/plugins/actions/server/plugin.test.ts | 1 - .../plugins/actions/server/routes/create.ts | 2 +- .../actions/server/routes/update.test.ts | 3 -- x-pack/plugins/actions/server/types.ts | 4 +-- .../containers/configure/use_connectors.tsx | 4 ++- .../servicenow/servicenow_connectors.tsx | 13 +++++++-- .../context/actions_connectors_context.tsx | 2 +- .../lib/action_connector_api.test.ts | 1 - .../action_connector_form.tsx | 1 + .../action_form.test.tsx | 5 ---- .../action_connector_form/action_form.tsx | 6 +++- .../action_type_menu.test.tsx | 1 - .../connector_add_flyout.test.tsx | 4 --- .../connector_edit_flyout.test.tsx | 4 --- .../components/actions_connectors_list.tsx | 5 ++-- .../triggers_actions_ui/public/types.ts | 3 +- .../actions/builtin_action_types/email.ts | 1 - .../actions/builtin_action_types/es_index.ts | 1 - .../actions/builtin_action_types/pagerduty.ts | 1 - .../builtin_action_types/server_log.ts | 1 - .../builtin_action_types/servicenow.ts | 2 -- .../actions/builtin_action_types/slack.ts | 1 - .../actions/builtin_action_types/webhook.ts | 1 - .../alerting_api_integration/common/config.ts | 4 --- .../actions/builtin_action_types/email.ts | 8 ------ .../actions/builtin_action_types/es_index.ts | 11 -------- .../actions/builtin_action_types/jira.ts | 11 -------- .../actions/builtin_action_types/pagerduty.ts | 6 ---- .../builtin_action_types/server_log.ts | 3 -- .../actions/builtin_action_types/slack.ts | 7 ----- .../actions/builtin_action_types/webhook.ts | 5 ---- .../tests/actions/create.ts | 5 ---- .../tests/actions/delete.ts | 2 -- .../tests/actions/execute.ts | 5 ---- .../security_and_spaces/tests/actions/get.ts | 4 --- .../tests/actions/get_all.ts | 17 ----------- .../tests/actions/update.ts | 4 --- .../actions/builtin_action_types/es_index.ts | 7 ----- .../actions/builtin_action_types/webhook.ts | 1 - .../spaces_only/tests/actions/create.ts | 2 -- .../spaces_only/tests/actions/delete.ts | 2 -- .../spaces_only/tests/actions/execute.ts | 4 --- .../spaces_only/tests/actions/get.ts | 4 --- .../spaces_only/tests/actions/get_all.ts | 11 -------- .../spaces_only/tests/actions/update.ts | 3 -- .../apps/triggers_actions_ui/connectors.ts | 1 - .../apps/triggers_actions_ui/details.ts | 6 ---- .../apps/triggers_actions_ui/home_page.ts | 1 - x-pack/test/functional_with_es_ssl/config.ts | 2 -- .../services/alerting/actions.ts | 2 +- 58 files changed, 37 insertions(+), 218 deletions(-) diff --git a/docs/user/alerting/action-types/pre-configured-connectors.asciidoc b/docs/user/alerting/action-types/pre-configured-connectors.asciidoc index fbee979281093..e3f1703f08e88 100644 --- a/docs/user/alerting/action-types/pre-configured-connectors.asciidoc +++ b/docs/user/alerting/action-types/pre-configured-connectors.asciidoc @@ -30,7 +30,6 @@ two out-of-the box connectors: <> and < secrets: webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz' - consumer: 'alerts' webhook-service: actionTypeId: .webhook name: 'Email service' @@ -43,7 +42,6 @@ two out-of-the box connectors: <> and < user: elastic password: changeme - consumer: 'alerts', <6> ``` <1> The key is the action connector identifier, `my-slack1` in this example. @@ -51,7 +49,6 @@ two out-of-the box connectors: <> and < `name` is the name of the preconfigured connector. <4> `config` is the action type specific to the configuration. <5> `secrets` is sensitive configuration, such as username, password, and keys. -<6> `consumer` is Kibana plugin owned the action. [NOTE] ============================================== diff --git a/x-pack/plugins/actions/server/action_type_registry.test.ts b/x-pack/plugins/actions/server/action_type_registry.test.ts index d64c51619b161..ce5c1fe8500fb 100644 --- a/x-pack/plugins/actions/server/action_type_registry.test.ts +++ b/x-pack/plugins/actions/server/action_type_registry.test.ts @@ -36,7 +36,6 @@ beforeEach(() => { name: 'Slack #xyz', secrets: {}, isPreconfigured: true, - consumer: 'alerts', }, ], }; diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index c3909bfcda7d3..164beffd2dcc7 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -74,7 +74,6 @@ describe('create()', () => { name: 'my name', actionTypeId: 'my-action-type', config: {}, - consumer: 'alerts', }, references: [], }; @@ -90,7 +89,6 @@ describe('create()', () => { name: 'my name', actionTypeId: 'my-action-type', config: {}, - consumer: 'alerts', secrets: {}, }, }); @@ -100,7 +98,6 @@ describe('create()', () => { name: 'my name', actionTypeId: 'my-action-type', config: {}, - consumer: 'alerts', }); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); expect(savedObjectsClient.create.mock.calls[0]).toMatchInlineSnapshot(` @@ -109,7 +106,7 @@ describe('create()', () => { Object { "actionTypeId": "my-action-type", "config": Object {}, - "consumer": "alerts", + "consumer": undefined, "name": "my name", "secrets": Object {}, }, @@ -136,7 +133,6 @@ describe('create()', () => { actionTypeId: 'my-action-type', config: {}, secrets: {}, - consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -152,7 +148,6 @@ describe('create()', () => { actionTypeId: 'unregistered-action-type', config: {}, secrets: {}, - consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -179,7 +174,6 @@ describe('create()', () => { c: true, }, secrets: {}, - consumer: 'alerts', }, references: [], }); @@ -193,7 +187,6 @@ describe('create()', () => { c: true, }, secrets: {}, - consumer: 'alerts', }, }); expect(result).toEqual({ @@ -206,7 +199,6 @@ describe('create()', () => { b: true, c: true, }, - consumer: 'alerts', }); expect(savedObjectsClient.create).toHaveBeenCalledTimes(1); expect(savedObjectsClient.create.mock.calls[0]).toMatchInlineSnapshot(` @@ -219,7 +211,7 @@ describe('create()', () => { "b": true, "c": true, }, - "consumer": "alerts", + "consumer": undefined, "name": "my name", "secrets": Object {}, }, @@ -281,7 +273,6 @@ describe('create()', () => { actionTypeId: 'my-action-type', config: {}, secrets: {}, - consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -317,7 +308,6 @@ describe('create()', () => { actionTypeId: 'my-action-type', config: {}, secrets: {}, - consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot(`"Fail"`); @@ -367,7 +357,6 @@ describe('get()', () => { config: { foo: 'bar', }, - consumer: 'alerts', }, ], }); @@ -378,7 +367,6 @@ describe('get()', () => { actionTypeId: '.slack', isPreconfigured: true, name: 'test', - consumer: 'alerts', }); expect(savedObjectsClient.get).not.toHaveBeenCalled(); }); @@ -399,7 +387,6 @@ describe('getAll()', () => { config: { foo: 'bar', }, - consumer: 'alerts', }, references: [], }, @@ -431,7 +418,6 @@ describe('getAll()', () => { config: { foo: 'bar', }, - consumer: 'alerts', }, ], }); @@ -445,7 +431,6 @@ describe('getAll()', () => { foo: 'bar', }, referencedByCount: 6, - consumer: 'alerts', }, { id: 'testPreconfigured', @@ -453,7 +438,6 @@ describe('getAll()', () => { isPreconfigured: true, name: 'test', referencedByCount: 2, - consumer: 'alerts', }, ]); }); @@ -472,7 +456,6 @@ describe('getBulk()', () => { config: { foo: 'bar', }, - consumer: 'alerts', }, references: [], }, @@ -503,7 +486,6 @@ describe('getBulk()', () => { config: { foo: 'bar', }, - consumer: 'alerts', }, ], }); @@ -518,7 +500,6 @@ describe('getBulk()', () => { isPreconfigured: true, name: 'test', secrets: {}, - consumer: 'alerts', }, { actionTypeId: 'test', @@ -528,7 +509,6 @@ describe('getBulk()', () => { id: '1', isPreconfigured: false, name: 'test', - consumer: 'alerts', }, ]); }); @@ -583,7 +563,6 @@ describe('update()', () => { name: 'my name', config: {}, secrets: {}, - consumer: 'alerts', }, }); expect(result).toEqual({ @@ -642,7 +621,6 @@ describe('update()', () => { name: 'my name', config: {}, secrets: {}, - consumer: 'alerts', }, }) ).rejects.toThrowErrorMatchingInlineSnapshot( @@ -662,7 +640,6 @@ describe('update()', () => { type: 'action', attributes: { actionTypeId: 'my-action-type', - consumer: 'alerts', }, references: [], }); @@ -703,7 +680,6 @@ describe('update()', () => { b: true, c: true, }, - consumer: 'alerts', }); expect(savedObjectsClient.update).toHaveBeenCalledTimes(1); expect(savedObjectsClient.update.mock.calls[0]).toMatchInlineSnapshot(` diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index d4dd4ee177483..501fe4ac5bc2b 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -42,7 +42,7 @@ interface ActionUpdate extends SavedObjectAttributes { interface Action extends ActionUpdate { actionTypeId: string; - consumer: string; + consumer?: string; } interface CreateOptions { diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index 8559ba24018dc..bcaf1f7523b9d 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -9,8 +9,8 @@ import { CommentSchema, EntityInformation, IncidentConfigurationSchema } from '. export const ExternalIncidentServiceConfiguration = { apiUrl: schema.string(), - // TODO: to remove - set it otional for the current stage to support Case ServiceNow implementation - incidentConfiguration: schema.maybe(IncidentConfigurationSchema), + // TODO: to remove - set it optional for the current stage to support Case ServiceNow implementation + incidentConfiguration: schema.nullable(IncidentConfigurationSchema), }; export const ExternalIncidentServiceConfigurationSchema = schema.object( diff --git a/x-pack/plugins/actions/server/config.test.ts b/x-pack/plugins/actions/server/config.test.ts index 4d18b892483a1..e86f2d7832828 100644 --- a/x-pack/plugins/actions/server/config.test.ts +++ b/x-pack/plugins/actions/server/config.test.ts @@ -31,7 +31,6 @@ describe('config validation', () => { config: { webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, - consumer: 'test', }, }, }; @@ -47,7 +46,6 @@ describe('config validation', () => { "config": Object { "webhookUrl": "https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz", }, - "consumer": "test", "name": "Slack #xyz", "secrets": Object {}, }, @@ -87,13 +85,11 @@ function preConfiguredActionConfig(id: string) { "preconfigured": { ${JSON.stringify(id)}: { "actionTypeId": ".server-log", - "name": "server log 1", - "consumer": "alerts" + "name": "server log 1" }, "serverLog": { "actionTypeId": ".server-log", - "name": "server log 2", - "consumer": "alerts" + "name": "server log 2" } } }`); diff --git a/x-pack/plugins/actions/server/config.ts b/x-pack/plugins/actions/server/config.ts index e94b2c531439f..8c006ec474053 100644 --- a/x-pack/plugins/actions/server/config.ts +++ b/x-pack/plugins/actions/server/config.ts @@ -12,7 +12,7 @@ const preconfiguredActionSchema = schema.object({ actionTypeId: schema.string({ minLength: 1 }), config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - consumer: schema.string({ minLength: 1 }), + consumer: schema.maybe(schema.string()), }); export const configSchema = schema.object({ diff --git a/x-pack/plugins/actions/server/create_execute_function.test.ts b/x-pack/plugins/actions/server/create_execute_function.test.ts index f1838a325eda2..04d4d92945cdb 100644 --- a/x-pack/plugins/actions/server/create_execute_function.test.ts +++ b/x-pack/plugins/actions/server/create_execute_function.test.ts @@ -79,7 +79,6 @@ describe('execute()', () => { isPreconfigured: true, name: 'x', secrets: {}, - consumer: 'alerts', }, ], }); @@ -190,7 +189,6 @@ describe('execute()', () => { name: 'Slack #xyz', secrets: {}, isPreconfigured: true, - consumer: 'alerts', }, ], }); diff --git a/x-pack/plugins/actions/server/plugin.test.ts b/x-pack/plugins/actions/server/plugin.test.ts index a295a3e42627f..1602b26559bed 100644 --- a/x-pack/plugins/actions/server/plugin.test.ts +++ b/x-pack/plugins/actions/server/plugin.test.ts @@ -188,7 +188,6 @@ describe('Actions Plugin', () => { name: 'preconfigured-server-log', config: {}, secrets: {}, - consumer: 'alerts', }, }, }); diff --git a/x-pack/plugins/actions/server/routes/create.ts b/x-pack/plugins/actions/server/routes/create.ts index 1732a245c6df8..9188279ffc69b 100644 --- a/x-pack/plugins/actions/server/routes/create.ts +++ b/x-pack/plugins/actions/server/routes/create.ts @@ -21,7 +21,7 @@ export const bodySchema = schema.object({ actionTypeId: schema.string(), config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - consumer: schema.string(), + consumer: schema.maybe(schema.string()), }); export const createActionRoute = (router: IRouter, licenseState: ILicenseState) => { diff --git a/x-pack/plugins/actions/server/routes/update.test.ts b/x-pack/plugins/actions/server/routes/update.test.ts index a90974945847f..323a52f2fc6e2 100644 --- a/x-pack/plugins/actions/server/routes/update.test.ts +++ b/x-pack/plugins/actions/server/routes/update.test.ts @@ -42,7 +42,6 @@ describe('updateActionRoute', () => { name: 'My name', config: { foo: true }, isPreconfigured: false, - consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -100,7 +99,6 @@ describe('updateActionRoute', () => { name: 'My name', config: { foo: true }, isPreconfigured: false, - consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -144,7 +142,6 @@ describe('updateActionRoute', () => { name: 'My name', config: { foo: true }, isPreconfigured: false, - consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index d3671e54a7b55..949b102d749eb 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -69,7 +69,7 @@ export interface ActionResult { // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: Record; isPreconfigured: boolean; - consumer: string; + consumer?: string; } export interface PreConfiguredAction extends ActionResult { @@ -122,7 +122,7 @@ export interface RawAction extends SavedObjectAttributes { name: string; config: SavedObjectAttributes; secrets: SavedObjectAttributes; - consumer: string; + consumer?: string; } export interface ActionTaskParams extends SavedObjectAttributes { diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx index d4a51d79c0f64..e32aef372268a 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx @@ -31,7 +31,9 @@ export const useConnectors = (): ReturnConnectors => { const res = await fetchConnectors({ signal: abortCtrl.signal }); if (!didCancel) { setLoading(false); - setConnectors(res.filter((connector) => connector.consumer === 'case')); + setConnectors( + res.filter((connector) => !connector.consumer || connector.consumer === 'case') + ); } } catch (error) { if (!didCancel) { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 314e0fc3f50b9..79eb2a3e858d9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback } from 'react'; +import React, { useCallback, useEffect } from 'react'; import { EuiFieldText, @@ -32,7 +32,7 @@ export interface ConnectorFlyoutFormProps { const ServiceNowConnectorFlyout: React.FC> = ({ action, editActionSecrets, editActionConfig, errors }) => { +>> = ({ action, editActionSecrets, editActionConfig, errors, editActionProperty }) => { // TODO: remove incidentConfiguration later, when Case ServiceNow will move their fields to the level of action execution const { apiUrl, incidentConfiguration } = action.config; const mapping = incidentConfiguration ? incidentConfiguration.mapping : []; @@ -44,6 +44,13 @@ const ServiceNowConnectorFlyout: React.FC 0 && username != null; const isPasswordInvalid: boolean = errors.password.length > 0 && password != null; + useEffect(() => { + if (!action.consumer && editActionProperty) { + editActionProperty('consumer', 'alerts'); + } + // eslint-disable-next-line react-hooks/exhaustive-deps + }, []); + // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution if (action.consumer === 'case' && isEmpty(mapping)) { editActionConfig('incidentConfiguration', { @@ -94,7 +101,7 @@ const ServiceNowConnectorFlyout: React.FC handleOnChangeActionConfig('apiUrl', evt.target.value)} onBlur={() => { if (!apiUrl) { - editActionSecrets('apiUrl', ''); + editActionConfig('apiUrl', ''); } }} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx index fc3e3e1ae84c4..d78930344a673 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx @@ -19,7 +19,7 @@ export interface ActionsConnectorsContextValue { capabilities: ApplicationStart['capabilities']; reloadConnectors?: () => Promise; docLinks: DocLinksStart; - consumer: string; + consumer?: string; } const ActionsConnectorsContext = createContext(null as any); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts index 8753bd89170c0..c4b757f136e06 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/action_connector_api.test.ts @@ -91,7 +91,6 @@ describe('updateActionConnector', () => { name: 'My test', config: {}, secrets: {}, - consumer: 'alerts', }; const resolvedValue = { ...connector, id }; http.put.mockResolvedValueOnce(resolvedValue); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index 489cdf167b283..f9f141a44c8cc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -168,6 +168,7 @@ export const ActionConnectorForm = ({ errors={errors} editActionConfig={setActionConfigProperty} editActionSecrets={setActionSecretsProperty} + editActionProperty={setActionProperty} http={http} docLinks={docLinks} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index f551a4e10515a..9d197cb71f5c5 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -124,7 +124,6 @@ describe('action_form', () => { name: 'Test connector', config: {}, isPreconfigured: false, - consumer: 'alerts', }, { secrets: {}, @@ -133,7 +132,6 @@ describe('action_form', () => { name: 'Test connector 2', config: {}, isPreconfigured: true, - consumer: 'alerts', }, { secrets: {}, @@ -142,7 +140,6 @@ describe('action_form', () => { name: 'Preconfigured Only', config: {}, isPreconfigured: true, - consumer: 'alerts', }, { secrets: {}, @@ -151,7 +148,6 @@ describe('action_form', () => { name: 'Regular connector', config: {}, isPreconfigured: false, - consumer: 'alerts', }, { secrets: {}, @@ -160,7 +156,6 @@ describe('action_form', () => { name: 'Non consumer connector', config: {}, isPreconfigured: false, - consumer: 'case', }, ]); const mocks = coreMock.createSetup(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 198e381592fdf..371f76dc886f1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -133,7 +133,11 @@ export const ActionForm = ({ try { setIsLoadingConnectors(true); const loadedConnectors = await loadConnectors({ http }); - setConnectors(loadedConnectors.filter((connector) => connector.consumer === 'alerts')); + setConnectors( + loadedConnectors.filter( + (connector) => !connector.consumer || connector.consumer === 'alerts' + ) + ); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx index f0890dcab8dbb..443be37e0a956 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx @@ -67,7 +67,6 @@ describe('connector_add_flyout', () => { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { isPreconfigured: false, referencedByCount: 0, config: {}, - consumer: 'alerts', }; const actionType = { @@ -83,7 +82,6 @@ describe('connector_edit_flyout', () => { return new Promise(() => {}); }, docLinks: deps.docLinks, - consumer: 'alerts', }} > { isPreconfigured: true, referencedByCount: 0, config: {}, - consumer: 'alerts', }; const actionType = { @@ -142,7 +139,6 @@ describe('connector_edit_flyout', () => { return new Promise(() => {}); }, docLinks: deps.docLinks, - consumer: 'alerts', }} > { setIsLoadingActions(true); try { const actionsResponse = await loadAllActions({ http }); - setActions(actionsResponse.filter((action) => action.consumer === 'alerts')); + setActions( + actionsResponse.filter((action) => !action.consumer || action.consumer === 'alerts') + ); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( @@ -403,7 +405,6 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { toastNotifications, reloadConnectors: loadActions, docLinks, - consumer: 'alerts', }} > { action: TActionConnector; editActionConfig: (property: string, value: any) => void; editActionSecrets: (property: string, value: any) => void; + editActionProperty?: (property: string, value: any) => void; errors: IErrorObject; docLinks: DocLinksStart; http?: HttpSetup; @@ -75,7 +76,7 @@ export interface ActionConnector { referencedByCount?: number; config: Record; isPreconfigured: boolean; - consumer: string; + consumer?: string | null; } export type ActionConnectorWithoutId = Omit; diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/email.ts index 2305aad0b8c9b..3de628b6f44bf 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/email.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/email.ts @@ -26,7 +26,6 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'supersecret', }, - consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/es_index.ts index 6b2e293ecd79d..d92af5afc103b 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/es_index.ts @@ -23,7 +23,6 @@ export default function indexTest({ getService }: FtrProviderContext) { index: 'foo', }, secrets: {}, - consumer: 'alerts', }) .expect(200); }); diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/pagerduty.ts index 131cdaa83ad9a..d962a0e72027d 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/pagerduty.ts @@ -24,7 +24,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { secrets: { routingKey: 'pager-duty-routing-key', }, - consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/server_log.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/server_log.ts index 9097c4a465094..ea5f523b396b4 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/server_log.ts @@ -21,7 +21,6 @@ export default function serverLogTest({ getService }: FtrProviderContext) { .send({ name: 'A server.log action', actionTypeId: '.server-log', - consumer: 'alerts', }) .expect(200); }); diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts index 070c253a61cb2..3356b3e3d5828 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts @@ -48,7 +48,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { comments: 'hello cool service now incident', short_description: 'this is a cool service now incident', }, - consumer: 'alerts', }; describe('servicenow', () => { let servicenowSimulatorURL: string = ''; @@ -72,7 +71,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { casesConfiguration: { ...mockServiceNow.config.casesConfiguration }, }, secrets: mockServiceNow.secrets, - consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts index e803fa60607cc..90660cc99507d 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/slack.ts @@ -36,7 +36,6 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: slackSimulatorURL, }, - consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts index 4a91c51223cac..af1d413ff3c46 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/webhook.ts @@ -39,7 +39,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { config: { url: webhookSimulatorURL, }, - consumer: 'alerts', }) .expect(403, { statusCode: 403, diff --git a/x-pack/test/alerting_api_integration/common/config.ts b/x-pack/test/alerting_api_integration/common/config.ts index cefa97581c27a..bc209e2bb4925 100644 --- a/x-pack/test/alerting_api_integration/common/config.ts +++ b/x-pack/test/alerting_api_integration/common/config.ts @@ -91,7 +91,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) secrets: { webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, - consumer: 'alerts', }, 'custom-system-abc-connector': { actionTypeId: 'system-abc-action-type', @@ -105,7 +104,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) xyzSecret1: 'credential1', xyzSecret2: 'credential2', }, - consumer: 'alerts', }, 'preconfigured-es-index-action': { actionTypeId: '.index', @@ -115,7 +113,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) refresh: true, executionTimeField: 'timestamp', }, - consumer: 'alerts', }, 'preconfigured.test.index-record': { actionTypeId: 'test.index-record', @@ -126,7 +123,6 @@ export function createTestConfig(name: string, options: CreateTestConfigOptions) secrets: { encrypted: 'this-is-also-ignored-and-also-required', }, - consumer: 'alerts', }, })}`, ...disabledPlugins.map((key) => `--xpack.${key}.enabled=false`), diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts index 0ef762e257fa3..ffbb29b431d8d 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/email.ts @@ -33,7 +33,6 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'supersecret', }, - consumer: 'alerts', }) .expect(200); @@ -50,7 +49,6 @@ export default function emailTest({ getService }: FtrProviderContext) { secure: null, from: 'bob@example.com', }, - consumer: 'alerts', }); expect(typeof createdActionId).to.be('string'); @@ -71,7 +69,6 @@ export default function emailTest({ getService }: FtrProviderContext) { port: null, secure: null, }, - consumer: 'alerts', }); }); @@ -147,7 +144,6 @@ export default function emailTest({ getService }: FtrProviderContext) { name: 'An email action', actionTypeId: '.email', config: {}, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -175,7 +171,6 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'changeme', }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -202,7 +197,6 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'changeme', }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -231,7 +225,6 @@ export default function emailTest({ getService }: FtrProviderContext) { user: 'bob', password: 'changeme', }, - consumer: 'alerts', }) .expect(200); expect(typeof createdAction.id).to.be('string'); @@ -248,7 +241,6 @@ export default function emailTest({ getService }: FtrProviderContext) { service: '__json', from: 'jim@example.com', }, - consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts index f732577159547..c1dc155c17238 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/es_index.ts @@ -35,7 +35,6 @@ export default function indexTest({ getService }: FtrProviderContext) { index: ES_TEST_INDEX_NAME, }, secrets: {}, - consumer: 'alerts', }) .expect(200); @@ -49,7 +48,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: false, executionTimeField: null, }, - consumer: 'alerts', }); createdActionID = createdAction.id; expect(typeof createdActionID).to.be('string'); @@ -64,7 +62,6 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, - consumer: 'alerts', }); // create action with all config props @@ -79,7 +76,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, - consumer: 'alerts', }) .expect(200); @@ -93,7 +89,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, - consumer: 'alerts', }); createdActionIDWithIndex = createdActionWithIndex.id; expect(typeof createdActionIDWithIndex).to.be('string'); @@ -112,7 +107,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, - consumer: 'alerts', }); }); @@ -124,7 +118,6 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { index: 666 }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -149,7 +142,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, - consumer: 'alerts', }) .expect(200); const { body: result } = await supertest @@ -180,7 +172,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, - consumer: 'alerts', }) .expect(200); const { body: result } = await supertest @@ -226,7 +217,6 @@ export default function indexTest({ getService }: FtrProviderContext) { executionTimeField: 'test', }, secrets: {}, - consumer: 'alerts', }) .expect(200); const { body: result } = await supertest @@ -255,7 +245,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, - consumer: 'alerts', }) .expect(200); const { body: result2 } = await supertest diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts index 57bca19b7e074..19206ce681000 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/jira.ts @@ -97,7 +97,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { apiUrl: jiraSimulatorURL, }, secrets: mockJira.secrets, - consumer: 'alerts', }) .expect(200); @@ -111,7 +110,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, casesConfiguration: mockJira.config.casesConfiguration, }, - consumer: 'alerts', }); const { body: fetchedAction } = await supertest @@ -128,7 +126,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, casesConfiguration: mockJira.config.casesConfiguration, }, - consumer: 'alerts', }); }); @@ -140,7 +137,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { name: 'A jira action', actionTypeId: '.jira', config: { projectKey: 'CK' }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -161,7 +157,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { name: 'A jira action', actionTypeId: '.jira', config: { apiUrl: jiraSimulatorURL }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -187,7 +182,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { casesConfiguration: mockJira.config.casesConfiguration, }, secrets: mockJira.secrets, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -212,7 +206,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, casesConfiguration: mockJira.config.casesConfiguration, }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -237,7 +230,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { projectKey: mockJira.config.projectKey, }, secrets: mockJira.secrets, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -263,7 +255,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { casesConfiguration: { mapping: [] }, }, secrets: mockJira.secrets, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -297,7 +288,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { }, }, secrets: mockJira.secrets, - consumer: 'alerts', }) .expect(400); }); @@ -318,7 +308,6 @@ export default function jiraTest({ getService }: FtrProviderContext) { casesConfiguration: mockJira.config.casesConfiguration, }, secrets: mockJira.secrets, - consumer: 'alerts', }); simulatedActionId = body.id; }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts index d748e27694a36..71ceb731da9f0 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/pagerduty.ts @@ -45,7 +45,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { secrets: { routingKey: 'pager-duty-routing-key', }, - consumer: 'alerts', }) .expect(200); @@ -57,7 +56,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { config: { apiUrl: pagerdutySimulatorURL, }, - consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -74,7 +72,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { config: { apiUrl: pagerdutySimulatorURL, }, - consumer: 'alerts', }); }); @@ -89,7 +86,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { apiUrl: pagerdutySimulatorURL, }, secrets: {}, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -110,7 +106,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { name: 'A pagerduty action', actionTypeId: '.pagerduty', secrets: {}, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -136,7 +131,6 @@ export default function pagerdutyTest({ getService }: FtrProviderContext) { secrets: { routingKey: 'pager-duty-routing-key', }, - consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts index 9b079c45e350b..a915987ce5feb 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/server_log.ts @@ -25,7 +25,6 @@ export default function serverLogTest({ getService }: FtrProviderContext) { .send({ name: 'A server.log action', actionTypeId: '.server-log', - consumer: 'alerts', }) .expect(200); @@ -36,7 +35,6 @@ export default function serverLogTest({ getService }: FtrProviderContext) { name: 'A server.log action', actionTypeId: '.server-log', config: {}, - consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -51,7 +49,6 @@ export default function serverLogTest({ getService }: FtrProviderContext) { name: 'A server.log action', actionTypeId: '.server-log', config: {}, - consumer: 'alerts', }); }); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts index 9b28d0306ebbb..537205360f4aa 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/slack.ts @@ -42,7 +42,6 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: slackSimulatorURL, }, - consumer: 'alerts', }) .expect(200); @@ -52,7 +51,6 @@ export default function slackTest({ getService }: FtrProviderContext) { name: 'A slack action', actionTypeId: '.slack', config: {}, - consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -67,7 +65,6 @@ export default function slackTest({ getService }: FtrProviderContext) { name: 'A slack action', actionTypeId: '.slack', config: {}, - consumer: 'alerts', }); }); @@ -79,7 +76,6 @@ export default function slackTest({ getService }: FtrProviderContext) { name: 'A slack action', actionTypeId: '.slack', secrets: {}, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -102,7 +98,6 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: 'http://slack.mynonexistent.com/other/stuff/in/the/path', }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -125,7 +120,6 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: 'fee-fi-fo-fum', }, - consumer: 'alerts', }) .expect(400) .then((resp: any) => { @@ -148,7 +142,6 @@ export default function slackTest({ getService }: FtrProviderContext) { secrets: { webhookUrl: slackSimulatorURL, }, - consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts index 28493996eed2f..10adf12baf652 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/webhook.ts @@ -55,7 +55,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { password, }, config: composedConfig, - consumer: 'alerts', }) .expect(200); @@ -88,7 +87,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { config: { url: webhookSimulatorURL, }, - consumer: 'alerts', }) .expect(200); @@ -101,7 +99,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { ...defaultValues, url: webhookSimulatorURL, }, - consumer: 'alerts', }); expect(typeof createdAction.id).to.be('string'); @@ -119,7 +116,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { ...defaultValues, url: webhookSimulatorURL, }, - consumer: 'alerts', }); }); @@ -182,7 +178,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { config: { url: 'http://a.none.whitelisted.webhook/endpoint', }, - consumer: 'alerts', }) .expect(400); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts index 623c8ddd630ae..69dcb7c813815 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/create.ts @@ -36,7 +36,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }); switch (scenario.id) { @@ -62,7 +61,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, - consumer: 'alerts', }); expect(typeof response.body.id).to.be('string'); // Ensure AAD isn't broken @@ -87,7 +85,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { name: 'My action', actionTypeId: 'test.unregistered-action-type', config: {}, - consumer: 'alerts', }); switch (scenario.id) { @@ -158,7 +155,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { config: { unencrypted: 'my unencrypted text', }, - consumer: 'alerts', }); switch (scenario.id) { @@ -195,7 +191,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { .send({ name: 'my name', actionTypeId: 'test.not-enabled', - consumer: 'alerts', }); switch (scenario.id) { diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts index c75fbb35ef5e2..d96ffc5bb3be3 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/delete.ts @@ -36,7 +36,6 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); @@ -80,7 +79,6 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts index 6d756e65b0f1b..70a3663c1c798 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/execute.ts @@ -54,7 +54,6 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -127,7 +126,6 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -182,7 +180,6 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -341,7 +338,6 @@ export default function ({ getService }: FtrProviderContext) { user: 'email-user', password: 'email-password', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -404,7 +400,6 @@ export default function ({ getService }: FtrProviderContext) { .send({ name: 'My action', actionTypeId: 'test.authorization', - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts index aab11c06ff769..c610ac670f690 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get.ts @@ -35,7 +35,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -66,7 +65,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, - consumer: 'alerts', }); break; default: @@ -87,7 +85,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -144,7 +141,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', isPreconfigured: true, - consumer: 'alerts', }); break; default: diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts index 5f545c1dfa573..45491aa2d28fc 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/get_all.ts @@ -35,7 +35,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -68,7 +67,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { unencrypted: `This value shouldn't get encrypted`, }, referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured-es-index-action', @@ -76,7 +74,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, - consumer: 'alerts', }, { id: 'my-slack1', @@ -84,7 +81,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, - consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -92,7 +88,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -100,7 +95,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, - consumer: 'alerts', }, ]); break; @@ -122,7 +116,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -179,7 +172,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { unencrypted: `This value shouldn't get encrypted`, }, referencedByCount: 1, - consumer: 'alerts', }, { id: 'preconfigured-es-index-action', @@ -187,7 +179,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, - consumer: 'alerts', }, { id: 'my-slack1', @@ -195,7 +186,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 1, - consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -203,7 +193,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -211,7 +200,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, - consumer: 'alerts', }, ]); break; @@ -233,7 +221,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -263,7 +250,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, - consumer: 'alerts', }, { id: 'my-slack1', @@ -271,7 +257,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, - consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -279,7 +264,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -287,7 +271,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, - consumer: 'alerts', }, ]); break; diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts index 31c447c2b3cc1..cb0e0efda0b1a 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/update.ts @@ -35,7 +35,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -76,7 +75,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, - consumer: 'alerts', }); // Ensure AAD isn't broken await checkAAD({ @@ -104,7 +102,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); @@ -268,7 +265,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(space.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts index 9ad03924692e2..0822e614464cb 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/es_index.ts @@ -33,7 +33,6 @@ export default function indexTest({ getService }: FtrProviderContext) { actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME }, secrets: {}, - consumer: 'alerts', }) .expect(200); @@ -47,7 +46,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: false, executionTimeField: null, }, - consumer: 'alerts', }); createdActionID = createdAction.id; expect(typeof createdActionID).to.be('string'); @@ -62,7 +60,6 @@ export default function indexTest({ getService }: FtrProviderContext) { name: 'An index action', actionTypeId: '.index', config: { index: ES_TEST_INDEX_NAME, refresh: false, executionTimeField: null }, - consumer: 'alerts', }); // create action with all config props @@ -77,7 +74,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, - consumer: 'alerts', }) .expect(200); @@ -91,7 +87,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, - consumer: 'alerts', }); createdActionIDWithIndex = createdActionWithIndex.id; expect(typeof createdActionIDWithIndex).to.be('string'); @@ -110,7 +105,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, executionTimeField: 'test', }, - consumer: 'alerts', }); }); @@ -126,7 +120,6 @@ export default function indexTest({ getService }: FtrProviderContext) { refresh: true, }, secrets: {}, - consumer: 'alerts', }) .expect(200); const { body: result } = await supertest diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts index 5dc519dcf4282..fb8460068cbcf 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/builtin_action_types/webhook.ts @@ -39,7 +39,6 @@ export default function webhookTest({ getService }: FtrProviderContext) { actionTypeId: '.webhook', secrets: {}, config: composedConfig, - consumer: 'alerts', }) .expect(200); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts index 9946b8b03bb0b..f3542c728845d 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/create.ts @@ -31,7 +31,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }); expect(response.status).to.eql(200); @@ -44,7 +43,6 @@ export default function createActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, - consumer: 'alerts', }); expect(typeof response.body.id).to.be('string'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts index e84ad7277b561..6e7f8d6f2a4b1 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/delete.ts @@ -30,7 +30,6 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); @@ -53,7 +52,6 @@ export default function deleteActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts index 6950dc84b92d1..7bbeab7cc8726 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/execute.ts @@ -50,7 +50,6 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -96,7 +95,6 @@ export default function ({ getService }: FtrProviderContext) { .send({ name: 'failing action', actionTypeId: 'test.failing', - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -135,7 +133,6 @@ export default function ({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -166,7 +163,6 @@ export default function ({ getService }: FtrProviderContext) { .send({ name: 'My action', actionTypeId: 'test.authorization', - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts index 8b2889380f4f0..2f965d422bfd9 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get.ts @@ -30,7 +30,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -45,7 +44,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, - consumer: 'alerts', }); }); @@ -62,7 +60,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -84,7 +81,6 @@ export default function getActionTests({ getService }: FtrProviderContext) { isPreconfigured: true, actionTypeId: '.slack', name: 'Slack#xyz', - consumer: 'alerts', }); }); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts index c7dbe7087e893..60766ff4bc926 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/get_all.ts @@ -30,7 +30,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -45,7 +44,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { unencrypted: `This value shouldn't get encrypted`, }, referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured-es-index-action', @@ -53,7 +51,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, - consumer: 'alerts', }, { id: 'my-slack1', @@ -61,7 +58,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, - consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -69,7 +65,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -77,7 +72,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, - consumer: 'alerts', }, ]); }); @@ -95,7 +89,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -107,7 +100,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.index', name: 'preconfigured_es_index_action', referencedByCount: 0, - consumer: 'alerts', }, { id: 'my-slack1', @@ -115,7 +107,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: '.slack', name: 'Slack#xyz', referencedByCount: 0, - consumer: 'alerts', }, { id: 'custom-system-abc-connector', @@ -123,7 +114,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'system-abc-action-type', name: 'SystemABC', referencedByCount: 0, - consumer: 'alerts', }, { id: 'preconfigured.test.index-record', @@ -131,7 +121,6 @@ export default function getAllActionTests({ getService }: FtrProviderContext) { actionTypeId: 'test.index-record', name: 'Test:_Preconfigured_Index_Record', referencedByCount: 0, - consumer: 'alerts', }, ]); }); diff --git a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts index 7839cdec661b5..81db8177b2c11 100644 --- a/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts +++ b/x-pack/test/alerting_api_integration/spaces_only/tests/actions/update.ts @@ -30,7 +30,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); @@ -55,7 +54,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { config: { unencrypted: `This value shouldn't get encrypted`, }, - consumer: 'alerts', }); // Ensure AAD isn't broken @@ -80,7 +78,6 @@ export default function updateActionTests({ getService }: FtrProviderContext) { secrets: { encrypted: 'This value should be encrypted', }, - consumer: 'alerts', }) .expect(200); objectRemover.add(Spaces.space1.id, createdAction.id, 'action', 'actions'); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts index 8a1f0ee1433d3..41be67592cbeb 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/connectors.ts @@ -27,7 +27,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }); await pageObjects.common.navigateToApp('triggersActions'); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts index 52ee2cccc04c3..e22b098e6ee0c 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/details.ts @@ -33,7 +33,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }), alerting.actions.createAction({ name: `slack-${testRunUuid}-${1}`, @@ -42,7 +41,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }), ]); @@ -323,7 +321,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }), alerting.actions.createAction({ name: `slack-${testRunUuid}-${1}`, @@ -332,7 +329,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }), ]); @@ -543,7 +539,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }), alerting.actions.createAction({ name: `slack-${testRunUuid}-${1}`, @@ -552,7 +547,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }), ]); diff --git a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts index 09da66496a87b..3b93607832670 100644 --- a/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts +++ b/x-pack/test/functional_with_es_ssl/apps/triggers_actions_ui/home_page.ts @@ -65,7 +65,6 @@ export default ({ getPageObjects, getService }: FtrProviderContext) => { secrets: { webhookUrl: 'https://test', }, - consumer: 'alerts', }); const alert = await alerting.alerts.createAlwaysFiringWithAction( diff --git a/x-pack/test/functional_with_es_ssl/config.ts b/x-pack/test/functional_with_es_ssl/config.ts index 8b566eb424abc..43192d906336d 100644 --- a/x-pack/test/functional_with_es_ssl/config.ts +++ b/x-pack/test/functional_with_es_ssl/config.ts @@ -72,12 +72,10 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) { secrets: { webhookUrl: 'https://hooks.slack.com/services/abcd/efgh/ijklmnopqrstuvwxyz', }, - consumer: 'alerts', }, 'my-server-log': { actionTypeId: '.server-log', name: 'Serverlog#xyz', - consumer: 'alerts', }, })}`, ], diff --git a/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts b/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts index 3936f4e7c7f20..303738e34ffdb 100644 --- a/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts +++ b/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts @@ -27,7 +27,7 @@ export class Actions { actionTypeId: string; config: Record; secrets: Record; - consumer: string; + consumer?: string; }) { this.log.debug(`creating action ${actionParams.name}`); From 6c8e0070a8c8282738f3b9b5b74b0b845002b903 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 17:31:01 -0700 Subject: [PATCH 18/38] Cleanup tests --- x-pack/plugins/actions/server/routes/get.test.ts | 4 ---- x-pack/plugins/alerts/server/alerts_client.test.ts | 3 --- .../case/server/routes/api/__mocks__/request_responses.ts | 2 -- .../public/components/alerts/configuration/step1.test.tsx | 2 -- .../detection_engine/routes/__mocks__/request_responses.ts | 2 -- x-pack/plugins/triggers_actions_ui/README.md | 3 +-- .../components/builtin_action_types/email/email.test.tsx | 4 ---- .../builtin_action_types/email/email_connector.test.tsx | 1 - .../builtin_action_types/es_index/es_index.test.tsx | 2 -- .../es_index/es_index_connector.test.tsx | 1 - .../builtin_action_types/pagerduty/pagerduty.test.tsx | 2 -- .../pagerduty/pagerduty_connectors.test.tsx | 1 - .../builtin_action_types/server_log/server_log.test.tsx | 1 - .../components/builtin_action_types/slack/slack.test.tsx | 2 -- .../builtin_action_types/slack/slack_connectors.test.tsx | 1 - .../builtin_action_types/webhook/webhook.test.tsx | 2 -- .../webhook/webhook_connectors.test.tsx | 1 - .../public/application/lib/action_connector_api.test.ts | 3 +-- .../application/lib/check_action_type_enabled.test.tsx | 2 -- .../action_connector_form/action_connector_form.test.tsx | 1 - .../sections/action_connector_form/action_form.test.tsx | 6 +++--- .../action_connector_form/action_type_menu.test.tsx | 2 -- .../action_connector_form/connector_reducer.test.ts | 1 - .../components/actions_connectors_list.test.tsx | 7 ------- 24 files changed, 5 insertions(+), 51 deletions(-) diff --git a/x-pack/plugins/actions/server/routes/get.test.ts b/x-pack/plugins/actions/server/routes/get.test.ts index ba2c2b397d4b2..ee2586851366c 100644 --- a/x-pack/plugins/actions/server/routes/get.test.ts +++ b/x-pack/plugins/actions/server/routes/get.test.ts @@ -43,7 +43,6 @@ describe('getActionRoute', () => { name: 'action name', config: {}, isPreconfigured: false, - consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -62,7 +61,6 @@ describe('getActionRoute', () => { "body": Object { "actionTypeId": "2", "config": Object {}, - "consumer": "alerts", "id": "1", "isPreconfigured": false, "name": "action name", @@ -93,7 +91,6 @@ describe('getActionRoute', () => { name: 'action name', config: {}, isPreconfigured: false, - consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments( @@ -128,7 +125,6 @@ describe('getActionRoute', () => { name: 'action name', config: {}, isPreconfigured: false, - consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments( diff --git a/x-pack/plugins/alerts/server/alerts_client.test.ts b/x-pack/plugins/alerts/server/alerts_client.test.ts index 09b8119f16e8f..9685f58b8fb31 100644 --- a/x-pack/plugins/alerts/server/alerts_client.test.ts +++ b/x-pack/plugins/alerts/server/alerts_client.test.ts @@ -53,7 +53,6 @@ beforeEach(() => { config: { foo: 'bar', }, - consumer: 'alerts', }, { id: '2', @@ -63,14 +62,12 @@ beforeEach(() => { config: { foo: 'bar', }, - consumer: 'alerts', }, { id: 'testPreconfigured', actionTypeId: '.slack', isPreconfigured: true, name: 'test', - consumer: 'alerts', }, ]); alertsClientParams.getActionsClient.mockResolvedValue(actionsClient); diff --git a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts index bf253da02d12c..4aa6725159043 100644 --- a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts +++ b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts @@ -25,7 +25,6 @@ export const getActions = (): FindActionResult[] => [ }, isPreconfigured: false, referencedByCount: 0, - consumer: 'alerts', }, { id: '123', @@ -55,7 +54,6 @@ export const getActions = (): FindActionResult[] => [ }, isPreconfigured: false, referencedByCount: 0, - consumer: 'alerts', }, ]; diff --git a/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx b/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx index 0b39f00a1c8c7..1be66ce4ccfef 100644 --- a/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx +++ b/x-pack/plugins/monitoring/public/components/alerts/configuration/step1.test.tsx @@ -28,7 +28,6 @@ describe('Step1', () => { name: 'Testing', config: {}, isPreconfigured: false, - consumer: 'alerts', }, ]; const selectedEmailActionId = emailActions[0].id; @@ -90,7 +89,6 @@ describe('Step1', () => { name: '', config: {}, isPreconfigured: false, - consumer: 'alerts', }, ], selectedEmailActionId: NEW_ACTION_ID, diff --git a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts index 6a3340fd663b8..fe66496f70dcd 100644 --- a/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts +++ b/x-pack/plugins/security_solution/server/lib/detection_engine/routes/__mocks__/request_responses.ts @@ -325,7 +325,6 @@ export const createActionResult = (): ActionResult => ({ name: '', config: {}, isPreconfigured: false, - consumer: 'alerts', }); export const nonRuleAlert = () => ({ @@ -463,7 +462,6 @@ export const updateActionResult = (): ActionResult => ({ name: '', config: {}, isPreconfigured: false, - consumer: 'alerts', }); export const getMockPrivilegesResult = () => ({ diff --git a/x-pack/plugins/triggers_actions_ui/README.md b/x-pack/plugins/triggers_actions_ui/README.md index 4bbcb528eb91b..4b6e596b8d657 100644 --- a/x-pack/plugins/triggers_actions_ui/README.md +++ b/x-pack/plugins/triggers_actions_ui/README.md @@ -1429,7 +1429,6 @@ const connector = { actionTypeRegistry: triggers_actions_ui.actionTypeRegistry, capabilities: capabilities, docLinks, - consumer: 'alerts', }} > { host: 'localhost', test: 'test', }, - consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -74,7 +73,6 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, - consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -127,7 +125,6 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, - consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -156,7 +153,6 @@ describe('connector validation', () => { host: 'localhost', test: 'test', }, - consumer: 'alerts', } as EmailActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx index 575067fa37295..8ee953c00795e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/email/email_connector.test.tsx @@ -22,7 +22,6 @@ describe('EmailActionConnectorFields renders', () => { config: { from: 'test@test.com', }, - consumer: 'alerts', } as EmailActionConnector; const wrapper = mountWithIntl( { refresh: false, executionTimeField: '1', }, - consumer: 'alerts', } as EsIndexActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -60,7 +59,6 @@ describe('index connector validation with minimal config', () => { config: { index: 'test_es_index', }, - consumer: 'alerts', } as EsIndexActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx index 576fe65632c04..4cb397927b53e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/es_index/es_index_connector.test.tsx @@ -79,7 +79,6 @@ describe('IndexActionConnectorFields renders', () => { refresh: false, executionTimeField: 'test1', }, - consumer: 'alerts', } as EsIndexActionConnector; const wrapper = mountWithIntl( { config: { apiUrl: 'http:\\test', }, - consumer: 'alerts', } as PagerDutyActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -66,7 +65,6 @@ describe('pagerduty connector validation', () => { config: { apiUrl: 'http:\\test', }, - consumer: 'alerts', } as PagerDutyActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx index f0c0093cddbb7..86730c0ab4ac7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/pagerduty/pagerduty_connectors.test.tsx @@ -22,7 +22,6 @@ describe('PagerDutyActionConnectorFields renders', () => { config: { apiUrl: 'http:\\test', }, - consumer: 'alerts', } as PagerDutyActionConnector; const deps = { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx index cbf1427a4988d..3bb5ea68a3040 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/server_log/server_log.test.tsx @@ -34,7 +34,6 @@ describe('server-log connector validation', () => { actionTypeId: '.server-log', name: 'server-log', config: {}, - consumer: 'alerts', } as ActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx index add2ae001eb83..78f4161cac827 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack.test.tsx @@ -37,7 +37,6 @@ describe('slack connector validation', () => { actionTypeId: '.email', name: 'email', config: {}, - consumer: 'alerts', } as SlackActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -54,7 +53,6 @@ describe('slack connector validation', () => { actionTypeId: '.email', name: 'email', config: {}, - consumer: 'alerts', } as SlackActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx index 15ad64db9e99a..bd905c1c95650 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/slack/slack_connectors.test.tsx @@ -20,7 +20,6 @@ describe('SlackActionFields renders', () => { actionTypeId: '.email', name: 'email', config: {}, - consumer: 'alerts', } as SlackActionConnector; const deps = { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx index 7662cfd93bb0b..3413465d70d93 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook.test.tsx @@ -43,7 +43,6 @@ describe('webhook connector validation', () => { url: 'http:\\test', headers: { 'content-type': 'text' }, }, - consumer: 'alerts', } as WebhookActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ @@ -67,7 +66,6 @@ describe('webhook connector validation', () => { config: { method: 'PUT', }, - consumer: 'alerts', } as WebhookActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx index 8550ede680d02..3b7865e59b9e6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/webhook/webhook_connectors.test.tsx @@ -25,7 +25,6 @@ describe('WebhookActionConnectorFields renders', () => { url: 'http:\\test', headers: { 'content-type': 'text' }, }, - consumer: 'alerts', } as WebhookActionConnector; const wrapper = mountWithIntl( { name: 'My test', config: {}, secrets: {}, - consumer: 'alerts', }; const resolvedValue: ActionConnector = { ...connector, id: '123' }; http.post.mockResolvedValueOnce(resolvedValue); @@ -75,7 +74,7 @@ describe('createActionConnector', () => { Array [ "/api/actions/action", Object { - "body": "{\\"actionTypeId\\":\\"test\\",\\"isPreconfigured\\":false,\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{},\\"consumer\\":\\"alerts\\"}", + "body": "{\\"actionTypeId\\":\\"test\\",\\"isPreconfigured\\":false,\\"name\\":\\"My test\\",\\"config\\":{},\\"secrets\\":{}}", }, ] `); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx index 28305e0fe7bb9..9c017aa6fd31f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/check_action_type_enabled.test.tsx @@ -102,7 +102,6 @@ describe('checkActionFormActionTypeEnabled', () => { name: 'test', secrets: {}, referencedByCount: 0, - consumer: 'alerts', }, { actionTypeId: '2', @@ -112,7 +111,6 @@ describe('checkActionFormActionTypeEnabled', () => { name: 'test', secrets: {}, referencedByCount: 0, - consumer: 'alerts', }, ]; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx index bc3be039e5a0c..17a1d929a0def 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.test.tsx @@ -44,7 +44,6 @@ describe('action_connector_form', () => { actionTypeId: actionType.id, config: {}, secrets: {}, - consumer: 'alerts', } as ActionConnector; let wrapper; if (deps) { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 9d197cb71f5c5..9962f4008de97 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -333,9 +333,9 @@ describe('action_form', () => { "label": "Test connector ", }, Object { - "id": "test2", - "key": "test2", - "label": "Test connector 2 (preconfigured)", + "id": "test5", + "key": "test5", + "label": "Non consumer connector", }, ] `); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx index 443be37e0a956..a5e9cdc65cfa6 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_type_menu.test.tsx @@ -117,7 +117,6 @@ describe('connector_add_flyout', () => { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { return new Promise(() => {}); }, docLinks: deps!.docLinks, - consumer: 'alerts', }} > { referencedByCount: 0, isPreconfigured: false, config: {}, - consumer: 'alerts', }; }); 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 cd3403b81d78c..40505ac3fe76c 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 @@ -118,7 +118,6 @@ describe('actions_connectors_list component with items', () => { isPreconfigured: false, referencedByCount: 1, config: {}, - consumer: 'alerts', }, { id: '2', @@ -127,7 +126,6 @@ describe('actions_connectors_list component with items', () => { referencedByCount: 1, isPreconfigured: false, config: {}, - consumer: 'alerts', }, { id: '3', @@ -136,7 +134,6 @@ describe('actions_connectors_list component with items', () => { referencedByCount: 1, isPreconfigured: true, config: {}, - consumer: 'alerts', }, ]); loadActionTypes.mockResolvedValueOnce([ @@ -310,7 +307,6 @@ describe('actions_connectors_list with show only capability', () => { description: 'My test', referencedByCount: 1, config: {}, - consumer: 'alerts', }, { id: '2', @@ -318,7 +314,6 @@ describe('actions_connectors_list with show only capability', () => { description: 'My test 2', referencedByCount: 1, config: {}, - consumer: 'alerts', }, ]); loadActionTypes.mockResolvedValueOnce([ @@ -406,7 +401,6 @@ describe('actions_connectors_list component with disabled items', () => { description: 'My test', referencedByCount: 1, config: {}, - consumer: 'alerts', }, { id: '2', @@ -414,7 +408,6 @@ describe('actions_connectors_list component with disabled items', () => { description: 'My test 2', referencedByCount: 1, config: {}, - consumer: 'alerts', }, ]); loadActionTypes.mockResolvedValueOnce([ From 5d832f6e941a5c96fdd115aa056a939983378db8 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 17:36:07 -0700 Subject: [PATCH 19/38] more cleanup --- .../alerts/components/rules/rule_actions_field/index.tsx | 1 - .../sections/action_connector_form/action_form.test.tsx | 7 ++++--- .../sections/action_connector_form/action_form.tsx | 2 +- .../action_connector_form/connector_add_modal.test.tsx | 1 - .../sections/action_connector_form/connector_add_modal.tsx | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx index f03bf470dfa22..c6ff25f311d9c 100644 --- a/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx +++ b/x-pack/plugins/security_solution/public/alerts/components/rules/rule_actions_field/index.tsx @@ -137,7 +137,6 @@ export const RuleActionsField: ThrottleSelectField = ({ field, messageVariables actionTypes={supportedActionTypes} defaultActionMessage={DEFAULT_ACTION_MESSAGE} toastNotifications={notifications.toasts} - consumer={'security'} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 9962f4008de97..00f31260ee4ed 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -156,6 +156,7 @@ describe('action_form', () => { name: 'Non consumer connector', config: {}, isPreconfigured: false, + consumer: 'case', }, ]); const mocks = coreMock.createSetup(); @@ -333,9 +334,9 @@ describe('action_form', () => { "label": "Test connector ", }, Object { - "id": "test5", - "key": "test5", - "label": "Non consumer connector", + "id": "test2", + "key": "test2", + "label": "Test connector 2 (preconfigured)", }, ] `); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 371f76dc886f1..de66616674793 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -64,7 +64,7 @@ interface ActionAccordionFormProps { defaultActionMessage?: string; setHasActionsDisabled?: (value: boolean) => void; capabilities: ApplicationStart['capabilities']; - consumer: string; + consumer?: string; } interface ActiveActionConnectorState { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx index 806ee04a72d6d..1b35b5636872d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.test.tsx @@ -73,7 +73,6 @@ describe('connector_add_modal', () => { toastNotifications={deps!.toastNotifications} docLinks={deps!.docLinks} capabilities={deps!.capabilities} - consumer={'alerts'} /> ); expect(wrapper.exists('.euiModalHeader')).toBeTruthy(); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 631f3d1c5014b..0e7f0cee0541c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -40,7 +40,7 @@ interface ConnectorAddModalProps { >; capabilities: ApplicationStart['capabilities']; docLinks: DocLinksStart; - consumer: string; + consumer?: string; } export const ConnectorAddModal = ({ From 9627b9b9d662eed46d3ed816b6236bf7ee979669 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 18:51:05 -0700 Subject: [PATCH 20/38] Fixed jest tests and type checks --- x-pack/plugins/actions/common/types.ts | 2 +- .../alerts/configuration/__snapshots__/step1.test.tsx.snap | 1 - .../common/fixtures/plugins/alerts/server/action_types.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/plugins/actions/common/types.ts b/x-pack/plugins/actions/common/types.ts index 35a81e4dd7431..1372f5874cfd6 100644 --- a/x-pack/plugins/actions/common/types.ts +++ b/x-pack/plugins/actions/common/types.ts @@ -16,7 +16,7 @@ export interface ActionType { } export interface ActionResult { - consumer: string; + consumer?: string; id: string; actionTypeId: string; name: string; diff --git a/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap b/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap index 34b4a79e48280..cb1081c0c14da 100644 --- a/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap +++ b/x-pack/plugins/monitoring/public/components/alerts/configuration/__snapshots__/step1.test.tsx.snap @@ -24,7 +24,6 @@ exports[`Step1 editing should allow for editing 1`] = ` Object { "actionTypeId": "1abc", "config": Object {}, - "consumer": "alerts", "id": "1", "isPreconfigured": false, "name": "Testing", diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts index 8c89970dbd082..3b6befb3fe807 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/alerts/server/action_types.ts @@ -40,7 +40,6 @@ export function defineActionTypes( secrets: schema.object({ encrypted: schema.string(), }), - consumer: schema.string(), }, async executor({ config, secrets, params, services, actionId }: ActionTypeExecutorOptions) { await services.callCluster('index', { From 9d330cdf6de510e6f88ba94590071aa3b5627d4f Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 16 Jun 2020 21:48:48 -0700 Subject: [PATCH 21/38] fixed tests --- .../servicenow/case_mappings/translations.ts | 66 ++++++++++--------- .../builtin_action_types/servicenow.ts | 19 ++++-- .../builtin_action_types/servicenow.ts | 62 ++++++++++------- 3 files changed, 89 insertions(+), 58 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts index 9ef6ce2f3d4a9..665ccbcfa114d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/translations.ts @@ -7,14 +7,14 @@ import { i18n } from '@kbn/i18n'; export const INCIDENT_MANAGEMENT_SYSTEM_TITLE = i18n.translate( - 'xpack.securitySolution.case.configureCases.incidentManagementSystemTitle', + 'xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemTitle', { defaultMessage: 'Connect to external incident management system', } ); export const INCIDENT_MANAGEMENT_SYSTEM_DESC = i18n.translate( - 'xpack.securitySolution.case.configureCases.incidentManagementSystemDesc', + 'xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemDesc', { defaultMessage: 'You may optionally connect Security cases to an external incident management system of your choosing. This will allow you to push case data as an incident in your chosen third-party system.', @@ -22,35 +22,35 @@ export const INCIDENT_MANAGEMENT_SYSTEM_DESC = i18n.translate( ); export const INCIDENT_MANAGEMENT_SYSTEM_LABEL = i18n.translate( - 'xpack.securitySolution.case.configureCases.incidentManagementSystemLabel', + 'xpack.triggersActionsUI.components.builtinActionTypes.incidentManagementSystemLabel', { defaultMessage: 'Incident management system', } ); export const NO_CONNECTOR = i18n.translate( - 'xpack.securitySolution.case.configureCases.noConnector', + 'xpack.triggersActionsUI.components.builtinActionTypes.noConnector', { defaultMessage: 'No connector selected', } ); export const ADD_NEW_CONNECTOR = i18n.translate( - 'xpack.securitySolution.case.configureCases.addNewConnector', + 'xpack.triggersActionsUI.components.builtinActionTypes.addNewConnector', { defaultMessage: 'Add new connector', } ); export const CASE_CLOSURE_OPTIONS_TITLE = i18n.translate( - 'xpack.securitySolution.case.configureCases.caseClosureOptionsTitle', + 'xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsTitle', { defaultMessage: 'Case Closures', } ); export const CASE_CLOSURE_OPTIONS_DESC = i18n.translate( - 'xpack.securitySolution.case.configureCases.caseClosureOptionsDesc', + 'xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsDesc', { defaultMessage: 'Define how you wish Security cases to be closed. Automated case closures require an established connection to an external incident management system.', @@ -58,21 +58,21 @@ export const CASE_CLOSURE_OPTIONS_DESC = i18n.translate( ); export const CASE_CLOSURE_OPTIONS_LABEL = i18n.translate( - 'xpack.securitySolution.case.configureCases.caseClosureOptionsLabel', + 'xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsLabel', { defaultMessage: 'Case closure options', } ); export const CASE_CLOSURE_OPTIONS_MANUAL = i18n.translate( - 'xpack.securitySolution.case.configureCases.caseClosureOptionsManual', + 'xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsManual', { defaultMessage: 'Manually close Security cases', } ); export const CASE_CLOSURE_OPTIONS_NEW_INCIDENT = i18n.translate( - 'xpack.securitySolution.case.configureCases.caseClosureOptionsNewIncident', + 'xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsNewIncident', { defaultMessage: 'Automatically close Security cases when pushing new incident to external system', @@ -80,21 +80,21 @@ export const CASE_CLOSURE_OPTIONS_NEW_INCIDENT = i18n.translate( ); export const CASE_CLOSURE_OPTIONS_CLOSED_INCIDENT = i18n.translate( - 'xpack.securitySolution.case.configureCases.caseClosureOptionsClosedIncident', + 'xpack.triggersActionsUI.components.builtinActionTypes.caseClosureOptionsClosedIncident', { defaultMessage: 'Automatically close Security cases when incident is closed in external system', } ); export const FIELD_MAPPING_TITLE = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingTitle', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingTitle', { defaultMessage: 'Field mappings', } ); export const FIELD_MAPPING_DESC = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingDesc', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingDesc', { defaultMessage: 'Map Security case fields when pushing data to a third-party. Field mappings require an established connection to an external incident management system.', @@ -102,60 +102,63 @@ export const FIELD_MAPPING_DESC = i18n.translate( ); export const FIELD_MAPPING_FIRST_COL = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingFirstCol', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingFirstCol', { defaultMessage: 'Security case field', } ); export const FIELD_MAPPING_SECOND_COL = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingSecondCol', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingSecondCol', { defaultMessage: 'External incident field', } ); export const FIELD_MAPPING_THIRD_COL = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingThirdCol', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingThirdCol', { defaultMessage: 'On edit and update', } ); export const FIELD_MAPPING_EDIT_NOTHING = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingEditNothing', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditNothing', { defaultMessage: 'Nothing', } ); export const FIELD_MAPPING_EDIT_OVERWRITE = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingEditOverwrite', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditOverwrite', { defaultMessage: 'Overwrite', } ); export const FIELD_MAPPING_EDIT_APPEND = i18n.translate( - 'xpack.securitySolution.case.configureCases.fieldMappingEditAppend', + 'xpack.triggersActionsUI.components.builtinActionTypes.fieldMappingEditAppend', { defaultMessage: 'Append', } ); -export const CANCEL = i18n.translate('xpack.securitySolution.case.configureCases.cancelButton', { - defaultMessage: 'Cancel', -}); +export const CANCEL = i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.cancelButton', + { + defaultMessage: 'Cancel', + } +); export const WARNING_NO_CONNECTOR_TITLE = i18n.translate( - 'xpack.securitySolution.case.configureCases.warningTitle', + 'xpack.triggersActionsUI.components.builtinActionTypes.warningTitle', { defaultMessage: 'Warning', } ); export const WARNING_NO_CONNECTOR_MESSAGE = i18n.translate( - 'xpack.securitySolution.case.configureCases.warningMessage', + 'xpack.triggersActionsUI.components.builtinActionTypes.warningMessage', { defaultMessage: 'The selected connector has been deleted. Either select a different connector or create a new one.', @@ -163,22 +166,25 @@ export const WARNING_NO_CONNECTOR_MESSAGE = i18n.translate( ); export const MAPPING_FIELD_NOT_MAPPED = i18n.translate( - 'xpack.securitySolution.case.configureCases.mappingFieldNotMapped', + 'xpack.triggersActionsUI.components.builtinActionTypes.mappingFieldNotMapped', { defaultMessage: 'Not mapped', } ); export const UPDATE_CONNECTOR = i18n.translate( - 'xpack.securitySolution.case.configureCases.updateConnector', + 'xpack.triggersActionsUI.components.builtinActionTypes.updateConnector', { defaultMessage: 'Update connector', } ); export const UPDATE_SELECTED_CONNECTOR = (connectorName: string): string => { - return i18n.translate('xpack.securitySolution.case.configureCases.updateSelectedConnector', { - values: { connectorName }, - defaultMessage: 'Update { connectorName }', - }); + return i18n.translate( + 'xpack.triggersActionsUI.components.builtinActionTypes.updateSelectedConnector', + { + values: { connectorName }, + defaultMessage: 'Update { connectorName }', + } + ); }; diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts index 3356b3e3d5828..d8383cc573174 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts @@ -38,15 +38,26 @@ export default function servicenowTest({ getService }: FtrProviderContext) { const mockServiceNow = { config: { apiUrl: 'www.servicenowisinkibanaactions.com', - casesConfiguration: { mapping: [...mapping] }, + incidentConfiguration: { mapping: [...mapping] }, }, secrets: { password: 'elastic', username: 'changeme', }, params: { - comments: 'hello cool service now incident', - short_description: 'this is a cool service now incident', + savedObjectId: '123', + title: 'a title', + description: 'a description', + comment: 'test-alert comment', + severity: '1', + urgency: '2', + impact: '1', + comments: [ + { + commentId: '456', + comment: 'first comment', + }, + ], }, }; describe('servicenow', () => { @@ -68,7 +79,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: { ...mockServiceNow.config.casesConfiguration }, + incidentConfiguration: { ...mockServiceNow.config.incidentConfiguration }, }, secrets: mockServiceNow.secrets, }) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index fcd70ee7ac5ae..a268c176c1f13 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -40,13 +40,13 @@ export default function servicenowTest({ getService }: FtrProviderContext) { const mockServiceNow = { config: { apiUrl: 'www.servicenowisinkibanaactions.com', - casesConfiguration: { mapping }, + incidentConfiguration: { mapping }, }, secrets: { password: 'elastic', username: 'changeme', }, - params: { + /* params: { subAction: 'pushToService', subActionParams: { savedObjectId: '123', @@ -64,7 +64,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { comments: [ { commentId: '456', - version: 'WzU3LDFd', comment: 'first comment', createdAt: '2020-03-13T08:34:53.450Z', createdBy: { fullName: 'Elastic User', username: 'elastic' }, @@ -73,6 +72,29 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }, ], }, + },*/ + params: { + subAction: 'pushToService', + subActionParams: { + savedObjectId: '123', + createdAt: '2020-03-13T08:34:53.450Z', + createdBy: { fullName: 'Elastic User', username: 'elastic' }, + comments: [ + { + commentId: '456', + comment: 'first comment', + createdAt: '2020-03-13T08:34:53.450Z', + createdBy: { fullName: 'Elastic User', username: 'elastic' }, + updatedAt: null, + updatedBy: null, + }, + ], + description: 'a description', + externalId: null, + title: 'a title', + updatedAt: '2020-06-17T04:37:45.147Z', + updatedBy: { fullName: null, username: 'elastic' }, + }, }, consumer: 'case', }; @@ -98,7 +120,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: mockServiceNow.config.casesConfiguration, + incidentConfiguration: mockServiceNow.config.incidentConfiguration, }, secrets: mockServiceNow.secrets, consumer: mockServiceNow.consumer, @@ -112,7 +134,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: mockServiceNow.config.casesConfiguration, + incidentConfiguration: mockServiceNow.config.incidentConfiguration, }, consumer: mockServiceNow.consumer, }); @@ -128,7 +150,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: mockServiceNow.config.casesConfiguration, + incidentConfiguration: mockServiceNow.config.incidentConfiguration, }, consumer: mockServiceNow.consumer, }); @@ -164,7 +186,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: 'http://servicenow.mynonexistent.com', - casesConfiguration: mockServiceNow.config.casesConfiguration, + incidentConfiguration: mockServiceNow.config.incidentConfiguration, }, secrets: mockServiceNow.secrets, consumer: mockServiceNow.consumer, @@ -189,7 +211,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: mockServiceNow.config.casesConfiguration, + incidentConfiguration: mockServiceNow.config.incidentConfiguration, }, consumer: mockServiceNow.consumer, }) @@ -204,7 +226,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }); }); - it('should respond with a 400 Bad Request when creating a servicenow action without casesConfiguration', async () => { + it('should create a servicenow action without incidentConfiguration', async () => { await supertest .post('/api/actions/action') .set('kbn-xsrf', 'foo') @@ -217,15 +239,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { secrets: mockServiceNow.secrets, consumer: mockServiceNow.consumer, }) - .expect(400) - .then((resp: any) => { - expect(resp.body).to.eql({ - statusCode: 400, - error: 'Bad Request', - message: - 'error validating action type config: [casesConfiguration.mapping]: expected value of type [array] but got [undefined]', - }); - }); + .expect(200); }); it('should respond with a 400 Bad Request when creating a servicenow action with empty mapping', async () => { @@ -237,7 +251,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: { mapping: [] }, + incidentConfiguration: { mapping: [] }, }, secrets: mockServiceNow.secrets, consumer: mockServiceNow.consumer, @@ -248,7 +262,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { statusCode: 400, error: 'Bad Request', message: - 'error validating action type config: [casesConfiguration.mapping]: expected non-empty but got empty', + 'error validating action type config: [incidentConfiguration.mapping]: expected non-empty but got empty', }); }); }); @@ -262,7 +276,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: { + incidentConfiguration: { mapping: [ { source: 'title', @@ -290,7 +304,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, - casesConfiguration: mockServiceNow.config.casesConfiguration, + incidentConfiguration: mockServiceNow.config.incidentConfiguration, }, secrets: mockServiceNow.secrets, consumer: mockServiceNow.consumer, @@ -440,7 +454,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.commentId]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments.0.commentId]: expected value of type [string] but got [undefined]', }); }); }); @@ -468,7 +482,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { status: 'error', retry: false, message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.comment]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]', + 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments.0.comment]: expected value of type [string] but got [undefined]', }); }); }); From 298d0569fdecd0272b3281ca40cbd18cd15551ac Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 17 Jun 2020 08:40:17 -0700 Subject: [PATCH 22/38] fixed servicenow validation tests --- .../servicenow/translations.ts | 8 ++ .../servicenow/validators.ts | 8 ++ .../server/servicenow_simulation.ts | 4 + .../builtin_action_types/servicenow.ts | 79 ------------------- 4 files changed, 20 insertions(+), 79 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts index ea9651dffdc26..05c7d805a1852 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/translations.ts @@ -17,3 +17,11 @@ export const WHITE_LISTED_ERROR = (message: string) => message, }, }); + +// TODO: remove when Case mappings will be removed +export const MAPPING_EMPTY = i18n.translate( + 'xpack.actions.builtin.servicenow.configuration.emptyMapping', + { + defaultMessage: '[incidentConfiguration.mapping]: expected non-empty but got empty', + } +); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts index 6f307b57c4817..65bbe9aea8119 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/validators.ts @@ -4,6 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ +import { isEmpty } from 'lodash'; import { ActionsConfigurationUtilities } from '../../actions_config'; import { ServiceNowPublicConfigurationType, @@ -17,6 +18,13 @@ export const validateCommonConfig = ( configurationUtilities: ActionsConfigurationUtilities, configObject: ServiceNowPublicConfigurationType ) => { + if ( + configObject.incidentConfiguration !== null && + isEmpty(configObject.incidentConfiguration.mapping) + ) { + return i18n.MAPPING_EMPTY; + } + try { configurationUtilities.ensureWhitelistedUri(configObject.apiUrl); } catch (whitelistError) { diff --git a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts index 8a675ec10aa8c..e2f31da1c8064 100644 --- a/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts +++ b/x-pack/test/alerting_api_integration/common/fixtures/plugins/actions_simulators/server/servicenow_simulation.ts @@ -25,6 +25,10 @@ export function initPlugin(router: IRouter, path: string) { short_description: schema.string(), description: schema.maybe(schema.string()), comments: schema.maybe(schema.string()), + caller_id: schema.string(), + severity: schema.string({ defaultValue: '1' }), + urgency: schema.string({ defaultValue: '1' }), + impact: schema.string({ defaultValue: '1' }), }), }, }, diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index a268c176c1f13..7a331855cf1ab 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -46,33 +46,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { password: 'elastic', username: 'changeme', }, - /* params: { - subAction: 'pushToService', - subActionParams: { - savedObjectId: '123', - title: 'a title', - description: 'a description', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { fullName: 'Elastic User', username: 'elastic' }, - updatedAt: null, - updatedBy: null, - externalId: null, - comment: 'test-alert comment', - severity: '1', - urgency: '2', - impact: '1', - comments: [ - { - commentId: '456', - comment: 'first comment', - createdAt: '2020-03-13T08:34:53.450Z', - createdBy: { fullName: 'Elastic User', username: 'elastic' }, - updatedAt: null, - updatedBy: null, - }, - ], - }, - },*/ params: { subAction: 'pushToService', subActionParams: { @@ -407,30 +380,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }); }); - it('should handle failing with a simulated success without createdAt', async () => { - await supertest - .post(`/api/actions/action/${simulatedActionId}/_execute`) - .set('kbn-xsrf', 'foo') - .send({ - params: { - ...mockServiceNow.params, - subActionParams: { - savedObjectId: 'success', - title: 'success', - }, - }, - }) - .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.createdAt]: expected value of type [string] but got [undefined]', - }); - }); - }); - it('should handle failing with a simulated success without commentId', async () => { await supertest .post(`/api/actions/action/${simulatedActionId}/_execute`) @@ -486,34 +435,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }); }); }); - - it('should handle failing with a simulated success without comment.createdAt', async () => { - await supertest - .post(`/api/actions/action/${simulatedActionId}/_execute`) - .set('kbn-xsrf', 'foo') - .send({ - params: { - ...mockServiceNow.params, - subActionParams: { - ...mockServiceNow.params.subActionParams, - savedObjectId: 'success', - title: 'success', - createdAt: 'success', - createdBy: { username: 'elastic' }, - comments: [{ commentId: 'success', comment: 'success' }], - }, - }, - }) - .then((resp: any) => { - expect(resp.body).to.eql({ - actionId: simulatedActionId, - status: 'error', - retry: false, - message: - 'error validating action params: types that failed validation:\n- [0.subAction]: expected value to equal [getIncident]\n- [1.subAction]: expected value to equal [handshake]\n- [2.subActionParams.comments]: types that failed validation:\n - [subActionParams.comments.0.0.createdAt]: expected value of type [string] but got [undefined]\n - [subActionParams.comments.1]: expected value to equal [null]', - }); - }); - }); }); describe('Execution', () => { From 18a8807ab448beda92714eb3a1576e48d874b6c7 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Wed, 17 Jun 2020 11:42:20 -0700 Subject: [PATCH 23/38] Added ServiceNow unit tests --- .../servicenow/servicenow.test.tsx | 97 +++++++++++++++++++ .../servicenow/servicenow.tsx | 1 - .../servicenow/servicenow_connectors.test.tsx | 85 ++++++++++++++++ .../servicenow/servicenow_connectors.tsx | 6 +- .../servicenow/servicenow_params.test.tsx | 43 ++++++++ .../servicenow/servicenow_params.tsx | 3 - .../servicenow/translations.ts | 18 ++-- .../builtin_action_types/servicenow/types.ts | 2 +- 8 files changed, 238 insertions(+), 17 deletions(-) create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx create mode 100644 x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.test.tsx diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx new file mode 100644 index 0000000000000..20bd68ba32d37 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -0,0 +1,97 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import { TypeRegistry } from '../../../type_registry'; +import { registerBuiltInActionTypes } from '.././index'; +import { ActionTypeModel } from '../../../../types'; +import { ServiceNowActionConnector } from './types'; + +const ACTION_TYPE_ID = '.servicenow'; +let actionTypeModel: ActionTypeModel; + +beforeAll(() => { + const actionTypeRegistry = new TypeRegistry(); + registerBuiltInActionTypes({ actionTypeRegistry }); + const getResult = actionTypeRegistry.get(ACTION_TYPE_ID); + if (getResult !== null) { + actionTypeModel = getResult; + } +}); + +describe('actionTypeRegistry.get() works', () => { + test('action type static data is as expected', () => { + expect(actionTypeModel.id).toEqual(ACTION_TYPE_ID); + }); +}); + +describe('servicenow connector validation', () => { + test('connector validation succeeds when connector config is valid', () => { + const actionConnector = { + secrets: { + username: 'user', + password: 'pass', + }, + id: 'test', + actionTypeId: '.servicenow', + name: 'ServiceNow', + isPreconfigured: false, + config: { + apiUrl: 'https://dev94428.service-now.com/', + }, + } as ServiceNowActionConnector; + + expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ + errors: { + apiUrl: [], + username: [], + password: [], + }, + }); + }); + + test('connector validation fails when connector config is not valid', () => { + const actionConnector = { + secrets: { + username: 'user', + }, + id: 'test', + actionTypeId: '.servicenow', + name: 'servicenow', + config: {}, + } as ServiceNowActionConnector; + + expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ + errors: { + apiUrl: ['URL is required.'], + username: [], + password: ['Password is required.'], + }, + }); + }); +}); + +describe('servicenow action params validation', () => { + test('action params validation succeeds when action params is valid', () => { + const actionParams = { + subActionParams: { title: 'some title {{test}}' }, + }; + + expect(actionTypeModel.validateParams(actionParams)).toEqual({ + errors: { title: [] }, + }); + }); + + test('params validation fails when body is not valid', () => { + const actionParams = { + subActionParams: { title: '' }, + }; + + expect(actionTypeModel.validateParams(actionParams)).toEqual({ + errors: { + title: ['Title is required.'], + }, + }); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 57d0049803c06..73c1097e97343 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -59,7 +59,6 @@ export function getActionType(): ActionTypeModel< validateParams: (actionParams: ServiceNowActionParams): ValidationResult => { const validationResult = { errors: {} }; const errors = { - description: new Array(), title: new Array(), }; validationResult.errors = errors; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx new file mode 100644 index 0000000000000..d422945267fa9 --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx @@ -0,0 +1,85 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import { DocLinksStart } from 'kibana/public'; +import ServiceNowConnectorFields from './servicenow_connectors'; +import { ServiceNowActionConnector } from './types'; + +describe('ServiceNowActionConnectorFields renders', () => { + test('alerting servicenow connector fields is rendered', () => { + const actionConnector = { + secrets: { + username: 'user', + password: 'pass', + }, + id: 'test', + actionTypeId: '.webhook', + isPreconfigured: false, + name: 'webhook', + config: { + apiUrl: 'https://test/', + }, + } as ServiceNowActionConnector; + const deps = { + docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, + }; + const wrapper = mountWithIntl( + {}} + editActionSecrets={() => {}} + editActionProperty={() => {}} + docLinks={deps!.docLinks} + /> + ); + expect( + wrapper.find('[data-test-subj="connector-servicenow-username-form-input"]').length > 0 + ).toBeTruthy(); + + expect(wrapper.find('[data-test-subj="apiUrlFromInput"]').length > 0).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="connector-servicenow-password-form-input"]').length > 0 + ).toBeTruthy(); + }); + + test('case specific servicenow connector fields is rendered', () => { + const actionConnector = { + secrets: { + username: 'user', + password: 'pass', + }, + id: 'test', + actionTypeId: '.webhook', + isPreconfigured: false, + name: 'webhook', + config: { + apiUrl: 'https://test/', + incidentConfiguration: { mapping: [] }, + }, + consumer: 'case', + } as ServiceNowActionConnector; + const deps = { + docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, + }; + const wrapper = mountWithIntl( + {}} + editActionSecrets={() => {}} + editActionProperty={() => {}} + docLinks={deps!.docLinks} + /> + ); + expect(wrapper.find('[data-test-subj="case-servicenow-mappings"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="apiUrlFromInput"]').length > 0).toBeTruthy(); + expect( + wrapper.find('[data-test-subj="connector-servicenow-password-form-input"]').length > 0 + ).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 79eb2a3e858d9..1c1440d007f67 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -30,7 +30,7 @@ export interface ConnectorFlyoutFormProps { onBlurConfig: (key: string) => void; } -const ServiceNowConnectorFlyout: React.FC> = ({ action, editActionSecrets, editActionConfig, errors, editActionProperty }) => { // TODO: remove incidentConfiguration later, when Case ServiceNow will move their fields to the level of action execution @@ -164,7 +164,7 @@ const ServiceNowConnectorFlyout: React.FC - + ): CasesConfigur ); // eslint-disable-next-line import/no-default-export -export { ServiceNowConnectorFlyout as default }; +export { ServiceNowConnectorFields as default }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.test.tsx new file mode 100644 index 0000000000000..57d50cf7e5bdd --- /dev/null +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.test.tsx @@ -0,0 +1,43 @@ +/* + * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one + * or more contributor license agreements. Licensed under the Elastic License; + * you may not use this file except in compliance with the Elastic License. + */ +import React from 'react'; +import { mountWithIntl } from 'test_utils/enzyme_helpers'; +import ServiceNowParamsFields from './servicenow_params'; + +describe('ServiceNowParamsFields renders', () => { + test('all params fields is rendered', () => { + const actionParams = { + subAction: 'pushToService', + subActionParams: { + title: 'sn title', + description: 'some description', + comment: 'comment for sn', + severity: '1', + urgency: '2', + impact: '3', + savedObjectId: '123', + externalId: null, + }, + }; + const wrapper = mountWithIntl( + {}} + index={0} + messageVariables={[]} + /> + ); + expect(wrapper.find('[data-test-subj="urgencySelect"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="severitySelect"]').first().prop('value')).toStrictEqual( + '1' + ); + expect(wrapper.find('[data-test-subj="impactSelect"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="titleInput"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="incidentDescriptionTextArea"]').length > 0).toBeTruthy(); + expect(wrapper.find('[data-test-subj="incidentCommentTextArea"]').length > 0).toBeTruthy(); + }); +}); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx index 2e1e23fe96c75..67070b6dc8907 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_params.tsx @@ -190,8 +190,6 @@ const ServiceNowParamsFields: React.FunctionComponent 0 && description !== undefined} label={i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.serviceNow.descriptionTextAreaFieldLabel', { @@ -210,7 +208,6 @@ const ServiceNowParamsFields: React.FunctionComponent 0 && description !== undefined} name="description" value={description || ''} data-test-subj="incidentDescriptionTextArea" diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts index 8558084357b5e..f5670f432d4d4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/translations.ts @@ -9,7 +9,7 @@ import { i18n } from '@kbn/i18n'; export const SERVICENOW_DESC = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.selectMessageText', { - defaultMessage: 'Push or update data to a new incident in ServiceNow', + defaultMessage: 'Push or update data to a new incident in ServiceNow.', } ); @@ -30,14 +30,14 @@ export const API_URL_LABEL = i18n.translate( export const API_URL_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredApiUrlTextField', { - defaultMessage: 'URL is required', + defaultMessage: 'URL is required.', } ); export const API_URL_INVALID = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.invalidApiUrlTextField', { - defaultMessage: 'URL is invalid', + defaultMessage: 'URL is invalid.', } ); @@ -51,7 +51,7 @@ export const USERNAME_LABEL = i18n.translate( export const USERNAME_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredUsernameTextField', { - defaultMessage: 'Username is required', + defaultMessage: 'Username is required.', } ); @@ -65,7 +65,7 @@ export const PASSWORD_LABEL = i18n.translate( export const PASSWORD_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredPasswordTextField', { - defaultMessage: 'Password is required', + defaultMessage: 'Password is required.', } ); @@ -79,7 +79,7 @@ export const API_TOKEN_LABEL = i18n.translate( export const API_TOKEN_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredApiTokenTextField', { - defaultMessage: 'Api token is required', + defaultMessage: 'Api token is required.', } ); @@ -93,7 +93,7 @@ export const EMAIL_LABEL = i18n.translate( export const EMAIL_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.servicenow.requiredEmailTextField', { - defaultMessage: 'Email is required', + defaultMessage: 'Email is required.', } ); @@ -121,13 +121,13 @@ export const MAPPING_FIELD_COMMENTS = i18n.translate( export const DESCRIPTION_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredDescriptionTextField', { - defaultMessage: 'Description is required', + defaultMessage: 'Description is required.', } ); export const TITLE_REQUIRED = i18n.translate( 'xpack.triggersActionsUI.components.builtinActionTypes.common.requiredTitleTextField', { - defaultMessage: 'Title is required', + defaultMessage: 'Title is required.', } ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 0ebf2fcf71c3b..8dcfa45002d5d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -21,7 +21,7 @@ export interface ServiceNowActionParams { title: string; description: string; comment: string; - externalId: string; + externalId: string | null; severity: string; urgency: string; impact: string; From cac96dfe5aaff7aa359bfd5f3172c56163a7fab6 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 11:06:53 -0700 Subject: [PATCH 24/38] Removed consumer for actions --- x-pack/plugins/actions/common/types.ts | 1 - .../actions/server/actions_client.test.ts | 2 -- .../plugins/actions/server/actions_client.ts | 9 +------- .../builtin_action_types/servicenow/schema.ts | 1 + .../actions/server/routes/create.test.ts | 3 --- .../plugins/actions/server/routes/create.ts | 1 - .../server/saved_objects/mappings.json | 3 --- x-pack/plugins/actions/server/types.ts | 2 -- .../servicenow/servicenow_connectors.test.tsx | 6 +++--- .../servicenow/servicenow_connectors.tsx | 13 +++--------- .../builtin_action_types/servicenow/types.ts | 1 + .../context/actions_connectors_context.tsx | 1 - .../action_form.test.tsx | 10 --------- .../action_connector_form/action_form.tsx | 8 +------ .../connector_add_flyout.tsx | 2 -- .../connector_add_modal.tsx | 3 --- .../components/actions_connectors_list.tsx | 4 +--- .../builtin_action_types/servicenow.ts | 2 ++ .../builtin_action_types/servicenow.ts | 21 +++++++++---------- .../services/alerting/actions.ts | 1 - 20 files changed, 23 insertions(+), 71 deletions(-) diff --git a/x-pack/plugins/actions/common/types.ts b/x-pack/plugins/actions/common/types.ts index 1372f5874cfd6..49e8f3e80b14a 100644 --- a/x-pack/plugins/actions/common/types.ts +++ b/x-pack/plugins/actions/common/types.ts @@ -16,7 +16,6 @@ export interface ActionType { } export interface ActionResult { - consumer?: string; id: string; actionTypeId: string; name: string; diff --git a/x-pack/plugins/actions/server/actions_client.test.ts b/x-pack/plugins/actions/server/actions_client.test.ts index c9aa3612ac087..69fab828e63de 100644 --- a/x-pack/plugins/actions/server/actions_client.test.ts +++ b/x-pack/plugins/actions/server/actions_client.test.ts @@ -106,7 +106,6 @@ describe('create()', () => { Object { "actionTypeId": "my-action-type", "config": Object {}, - "consumer": undefined, "name": "my name", "secrets": Object {}, }, @@ -211,7 +210,6 @@ describe('create()', () => { "b": true, "c": true, }, - "consumer": undefined, "name": "my name", "secrets": Object {}, }, diff --git a/x-pack/plugins/actions/server/actions_client.ts b/x-pack/plugins/actions/server/actions_client.ts index 501fe4ac5bc2b..9e3e326b76b54 100644 --- a/x-pack/plugins/actions/server/actions_client.ts +++ b/x-pack/plugins/actions/server/actions_client.ts @@ -42,7 +42,6 @@ interface ActionUpdate extends SavedObjectAttributes { interface Action extends ActionUpdate { actionTypeId: string; - consumer?: string; } interface CreateOptions { @@ -99,7 +98,7 @@ export class ActionsClient { * Create an action */ public async create({ action }: CreateOptions): Promise { - const { actionTypeId, name, config, secrets, consumer } = action; + const { actionTypeId, name, config, secrets } = action; const actionType = this.actionTypeRegistry.get(actionTypeId); const validatedActionTypeConfig = validateConfig(actionType, config); const validatedActionTypeSecrets = validateSecrets(actionType, secrets); @@ -111,7 +110,6 @@ export class ActionsClient { name, config: validatedActionTypeConfig as SavedObjectAttributes, secrets: validatedActionTypeSecrets as SavedObjectAttributes, - consumer, }); return { @@ -120,7 +118,6 @@ export class ActionsClient { name: result.attributes.name, config: result.attributes.config, isPreconfigured: false, - consumer: result.attributes.consumer, }; } @@ -164,7 +161,6 @@ export class ActionsClient { name: result.attributes.name as string, config: result.attributes.config as Record, isPreconfigured: false, - consumer: existingObject.attributes.consumer, }; } @@ -181,7 +177,6 @@ export class ActionsClient { actionTypeId: preconfiguredActionsList.actionTypeId, name: preconfiguredActionsList.name, isPreconfigured: true, - consumer: preconfiguredActionsList.consumer, }; } const result = await this.savedObjectsClient.get('action', id); @@ -192,7 +187,6 @@ export class ActionsClient { name: result.attributes.name, config: result.attributes.config, isPreconfigured: false, - consumer: result.attributes.consumer, }; } @@ -214,7 +208,6 @@ export class ActionsClient { actionTypeId: preconfiguredAction.actionTypeId, name: preconfiguredAction.name, isPreconfigured: true, - consumer: preconfiguredAction.consumer, })), ].sort((a, b) => a.name.localeCompare(b.name)); return await injectExtraFindData( diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index bcaf1f7523b9d..13bb004bd1526 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -11,6 +11,7 @@ export const ExternalIncidentServiceConfiguration = { apiUrl: schema.string(), // TODO: to remove - set it optional for the current stage to support Case ServiceNow implementation incidentConfiguration: schema.nullable(IncidentConfigurationSchema), + isCaseOwned: schema.nullable(schema.boolean()), }; export const ExternalIncidentServiceConfigurationSchema = schema.object( diff --git a/x-pack/plugins/actions/server/routes/create.test.ts b/x-pack/plugins/actions/server/routes/create.test.ts index 68e4c2421fa36..940b8ecc61f4e 100644 --- a/x-pack/plugins/actions/server/routes/create.test.ts +++ b/x-pack/plugins/actions/server/routes/create.test.ts @@ -42,7 +42,6 @@ describe('createActionRoute', () => { actionTypeId: 'abc', config: { foo: true }, isPreconfigured: false, - consumer: 'alerts', }; const actionsClient = actionsClientMock.create(); @@ -99,7 +98,6 @@ describe('createActionRoute', () => { actionTypeId: 'abc', config: { foo: true }, isPreconfigured: false, - consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); @@ -128,7 +126,6 @@ describe('createActionRoute', () => { actionTypeId: 'abc', config: { foo: true }, isPreconfigured: false, - consumer: 'alerts', }); const [context, req, res] = mockHandlerArguments({ actionsClient }, {}); diff --git a/x-pack/plugins/actions/server/routes/create.ts b/x-pack/plugins/actions/server/routes/create.ts index 9188279ffc69b..8135567157583 100644 --- a/x-pack/plugins/actions/server/routes/create.ts +++ b/x-pack/plugins/actions/server/routes/create.ts @@ -21,7 +21,6 @@ export const bodySchema = schema.object({ actionTypeId: schema.string(), config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - consumer: schema.maybe(schema.string()), }); export const createActionRoute = (router: IRouter, licenseState: ILicenseState) => { diff --git a/x-pack/plugins/actions/server/saved_objects/mappings.json b/x-pack/plugins/actions/server/saved_objects/mappings.json index dd711fc5581b2..ef6a0c9919920 100644 --- a/x-pack/plugins/actions/server/saved_objects/mappings.json +++ b/x-pack/plugins/actions/server/saved_objects/mappings.json @@ -18,9 +18,6 @@ }, "secrets": { "type": "binary" - }, - "consumer": { - "type": "keyword" } } }, diff --git a/x-pack/plugins/actions/server/types.ts b/x-pack/plugins/actions/server/types.ts index 949b102d749eb..093d22c2c1a71 100644 --- a/x-pack/plugins/actions/server/types.ts +++ b/x-pack/plugins/actions/server/types.ts @@ -69,7 +69,6 @@ export interface ActionResult { // eslint-disable-next-line @typescript-eslint/no-explicit-any config?: Record; isPreconfigured: boolean; - consumer?: string; } export interface PreConfiguredAction extends ActionResult { @@ -122,7 +121,6 @@ export interface RawAction extends SavedObjectAttributes { name: string; config: SavedObjectAttributes; secrets: SavedObjectAttributes; - consumer?: string; } export interface ActionTaskParams extends SavedObjectAttributes { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx index d422945267fa9..2eaa31a111a47 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx @@ -54,14 +54,14 @@ describe('ServiceNowActionConnectorFields renders', () => { password: 'pass', }, id: 'test', - actionTypeId: '.webhook', + actionTypeId: '.servicenow', isPreconfigured: false, - name: 'webhook', + name: 'servicenow', config: { apiUrl: 'https://test/', incidentConfiguration: { mapping: [] }, + isCaseOwned: true, }, - consumer: 'case', } as ServiceNowActionConnector; const deps = { docLinks: { ELASTIC_WEBSITE_URL: '', DOC_LINK_VERSION: '' } as DocLinksStart, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 1c1440d007f67..e665f071d7ba9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -34,7 +34,7 @@ const ServiceNowConnectorFields: React.FC> = ({ action, editActionSecrets, editActionConfig, errors, editActionProperty }) => { // TODO: remove incidentConfiguration later, when Case ServiceNow will move their fields to the level of action execution - const { apiUrl, incidentConfiguration } = action.config; + const { apiUrl, incidentConfiguration, isCaseOwned } = action.config; const mapping = incidentConfiguration ? incidentConfiguration.mapping : []; const isApiUrlInvalid: boolean = errors.apiUrl.length > 0 && apiUrl != null; @@ -44,15 +44,8 @@ const ServiceNowConnectorFields: React.FC 0 && username != null; const isPasswordInvalid: boolean = errors.password.length > 0 && password != null; - useEffect(() => { - if (!action.consumer && editActionProperty) { - editActionProperty('consumer', 'alerts'); - } - // eslint-disable-next-line react-hooks/exhaustive-deps - }, []); - // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution - if (action.consumer === 'case' && isEmpty(mapping)) { + if (action.isCaseOwned && isEmpty(mapping)) { editActionConfig('incidentConfiguration', { mapping: createDefaultMapping(connectorConfiguration.fields as any), }); @@ -160,7 +153,7 @@ const ServiceNowConnectorFields: React.FC - {incidentConfiguration && ( // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution + {isCaseOwned && ( // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution <> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 8dcfa45002d5d..d4f0688cc51d1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -35,6 +35,7 @@ interface IncidentConfiguration { interface ServiceNowConfig { apiUrl: string; incidentConfiguration?: IncidentConfiguration; + isCaseOwned?: boolean; } interface ServiceNowSecrets { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx index d78930344a673..f8a9085a88656 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx @@ -19,7 +19,6 @@ export interface ActionsConnectorsContextValue { capabilities: ApplicationStart['capabilities']; reloadConnectors?: () => Promise; docLinks: DocLinksStart; - consumer?: string; } const ActionsConnectorsContext = createContext(null as any); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 00f31260ee4ed..7db6b5145f895 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -149,15 +149,6 @@ describe('action_form', () => { config: {}, isPreconfigured: false, }, - { - secrets: {}, - id: 'test5', - actionTypeId: actionType.id, - name: 'Non consumer connector', - config: {}, - isPreconfigured: false, - consumer: 'case', - }, ]); const mocks = coreMock.createSetup(); const [ @@ -281,7 +272,6 @@ describe('action_form', () => { toastNotifications={deps!.toastNotifications} docLinks={deps.docLinks} capabilities={deps.capabilities} - consumer={'alerts'} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index de66616674793..f06722e8478ee 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -64,7 +64,6 @@ interface ActionAccordionFormProps { defaultActionMessage?: string; setHasActionsDisabled?: (value: boolean) => void; capabilities: ApplicationStart['capabilities']; - consumer?: string; } interface ActiveActionConnectorState { @@ -87,7 +86,6 @@ export const ActionForm = ({ setHasActionsDisabled, capabilities, docLinks, - consumer, }: ActionAccordionFormProps) => { const [addModalVisible, setAddModalVisibility] = useState(false); const [activeActionItem, setActiveActionItem] = useState( @@ -133,11 +131,7 @@ export const ActionForm = ({ try { setIsLoadingConnectors(true); const loadedConnectors = await loadConnectors({ http }); - setConnectors( - loadedConnectors.filter( - (connector) => !connector.consumer || connector.consumer === 'alerts' - ) - ); + setConnectors(loadedConnectors); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx index c1afa905aa6e4..2dd1f83749372 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx @@ -47,7 +47,6 @@ export const ConnectorAddFlyout = ({ let hasErrors = false; const { http, - consumer, toastNotifications, capabilities, actionTypeRegistry, @@ -62,7 +61,6 @@ export const ConnectorAddFlyout = ({ actionTypeId: actionType?.id ?? '', config: {}, secrets: {}, - consumer, } as ActionConnector; const [{ connector }, dispatch] = useReducer(connectorReducer, { connector: initialConnector }); const setActionProperty = (key: string, value: any) => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 0e7f0cee0541c..1d19f436950c7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -40,7 +40,6 @@ interface ConnectorAddModalProps { >; capabilities: ApplicationStart['capabilities']; docLinks: DocLinksStart; - consumer?: string; } export const ConnectorAddModal = ({ @@ -53,14 +52,12 @@ export const ConnectorAddModal = ({ actionTypeRegistry, capabilities, docLinks, - consumer, }: ConnectorAddModalProps) => { let hasErrors = false; const initialConnector = { actionTypeId: actionType.id, config: {}, secrets: {}, - consumer, } as ActionConnector; const [isSaving, setIsSaving] = useState(false); const canSave = hasSaveActionsCapability(capabilities); 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 7db34da779829..5d52896cc628f 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 @@ -118,9 +118,7 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { setIsLoadingActions(true); try { const actionsResponse = await loadAllActions({ http }); - setActions( - actionsResponse.filter((action) => !action.consumer || action.consumer === 'alerts') - ); + setActions(actionsResponse); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( diff --git a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts index d8383cc573174..a451edea76d83 100644 --- a/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/basic/tests/actions/builtin_action_types/servicenow.ts @@ -39,6 +39,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: 'www.servicenowisinkibanaactions.com', incidentConfiguration: { mapping: [...mapping] }, + isCaseOwned: true, }, secrets: { password: 'elastic', @@ -80,6 +81,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: { ...mockServiceNow.config.incidentConfiguration }, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, }) diff --git a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts index 7a331855cf1ab..8205b75cabed5 100644 --- a/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts +++ b/x-pack/test/alerting_api_integration/security_and_spaces/tests/actions/builtin_action_types/servicenow.ts @@ -41,6 +41,7 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: 'www.servicenowisinkibanaactions.com', incidentConfiguration: { mapping }, + isCaseOwned: true, }, secrets: { password: 'elastic', @@ -69,7 +70,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { updatedBy: { fullName: null, username: 'elastic' }, }, }, - consumer: 'case', }; let servicenowSimulatorURL: string = ''; @@ -94,9 +94,9 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: mockServiceNow.config.incidentConfiguration, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, - consumer: mockServiceNow.consumer, }) .expect(200); @@ -108,8 +108,8 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: mockServiceNow.config.incidentConfiguration, + isCaseOwned: true, }, - consumer: mockServiceNow.consumer, }); const { body: fetchedAction } = await supertest @@ -124,8 +124,8 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: mockServiceNow.config.incidentConfiguration, + isCaseOwned: true, }, - consumer: mockServiceNow.consumer, }); }); @@ -137,7 +137,6 @@ export default function servicenowTest({ getService }: FtrProviderContext) { name: 'A servicenow action', actionTypeId: '.servicenow', config: {}, - consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -160,9 +159,9 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: 'http://servicenow.mynonexistent.com', incidentConfiguration: mockServiceNow.config.incidentConfiguration, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, - consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -185,8 +184,8 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: mockServiceNow.config.incidentConfiguration, + isCaseOwned: true, }, - consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -208,9 +207,9 @@ export default function servicenowTest({ getService }: FtrProviderContext) { actionTypeId: '.servicenow', config: { apiUrl: servicenowSimulatorURL, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, - consumer: mockServiceNow.consumer, }) .expect(200); }); @@ -225,9 +224,9 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: { mapping: [] }, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, - consumer: mockServiceNow.consumer, }) .expect(400) .then((resp: any) => { @@ -258,9 +257,9 @@ export default function servicenowTest({ getService }: FtrProviderContext) { }, ], }, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, - consumer: mockServiceNow.consumer, }) .expect(400); }); @@ -278,9 +277,9 @@ export default function servicenowTest({ getService }: FtrProviderContext) { config: { apiUrl: servicenowSimulatorURL, incidentConfiguration: mockServiceNow.config.incidentConfiguration, + isCaseOwned: true, }, secrets: mockServiceNow.secrets, - consumer: mockServiceNow.consumer, }); simulatedActionId = body.id; }); diff --git a/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts b/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts index 303738e34ffdb..cff5b3c3ce9c3 100644 --- a/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts +++ b/x-pack/test/functional_with_es_ssl/services/alerting/actions.ts @@ -27,7 +27,6 @@ export class Actions { actionTypeId: string; config: Record; secrets: Record; - consumer?: string; }) { this.log.debug(`creating action ${actionParams.name}`); From 59fe7acd24cc7bc438e4fbe33b40bd49cc700989 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 14:20:57 -0700 Subject: [PATCH 25/38] fixed client side isCaseOwned support --- .../builtin_action_types/servicenow/schema.ts | 2 +- .../containers/configure/use_connectors.tsx | 2 +- .../public/common/lib/connectors/config.ts | 4 ++-- .../servicenow/case_mappings/types.ts | 22 ------------------- .../servicenow/servicenow.test.tsx | 8 ++++--- .../servicenow/servicenow.tsx | 6 +---- .../servicenow/servicenow_connectors.tsx | 17 +++++++++----- .../builtin_action_types/servicenow/types.ts | 4 +--- .../context/actions_connectors_context.tsx | 1 + .../action_connector_form.tsx | 3 +++ .../action_form.test.tsx | 10 +++++++++ .../action_connector_form/action_form.tsx | 5 +++-- .../connector_add_flyout.tsx | 2 ++ .../connector_add_modal.tsx | 3 +++ .../connector_edit_flyout.tsx | 2 ++ .../components/actions_connectors_list.tsx | 2 +- .../sections/alert_form/alert_form.tsx | 1 - .../public/common/constants/index.ts | 1 + .../triggers_actions_ui/public/types.ts | 1 + 19 files changed, 49 insertions(+), 47 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts index 13bb004bd1526..82afebaaee445 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/schema.ts @@ -11,7 +11,7 @@ export const ExternalIncidentServiceConfiguration = { apiUrl: schema.string(), // TODO: to remove - set it optional for the current stage to support Case ServiceNow implementation incidentConfiguration: schema.nullable(IncidentConfigurationSchema), - isCaseOwned: schema.nullable(schema.boolean()), + isCaseOwned: schema.maybe(schema.boolean()), }; export const ExternalIncidentServiceConfigurationSchema = schema.object( diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx index e32aef372268a..2895033f0c3bd 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx @@ -32,7 +32,7 @@ export const useConnectors = (): ReturnConnectors => { if (!didCancel) { setLoading(false); setConnectors( - res.filter((connector) => !connector.consumer || connector.consumer === 'case') + res.filter((connector) => !connector.config || connector.config.isCaseOwned) ); } } catch (error) { diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts index f3b387090d281..386c63aca4d78 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts +++ b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts @@ -5,11 +5,11 @@ */ // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { connectorConfiguration as serviceNowConnectorConfig } from '../../../../../triggers_actions_ui/public/application/components/builtin_action_types/servicenow/config'; +import { ServiceNowConnectorConfiguration } from '../../../../../triggers_actions_ui/public/common/constants'; import { connector as jiraConnectorConfig } from './jira/config'; import { ConnectorConfiguration } from './types'; export const connectorsConfiguration: Record = { - '.servicenow': serviceNowConnectorConfig as ConnectorConfiguration, + '.servicenow': ServiceNowConnectorConfiguration as ConnectorConfiguration, '.jira': jiraConnectorConfig, }; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts index 413d792ab2f7f..4c30932077a61 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts @@ -4,10 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -/* eslint-disable no-restricted-imports */ -/* eslint-disable @kbn/eslint/no-restricted-paths */ - -import { ExternalIncidentServiceConfiguration } from '../../../../../../../actions/server/builtin_action_types/case/types'; import { IErrorObject, ActionType } from '../../../../../types'; import { @@ -26,24 +22,6 @@ export interface ThirdPartyField { defaultActionType: ThirdPartySupportedActions; } -export interface ConnectorConfiguration extends ActionType { - logo: string; - fields: Record; -} - -export interface ActionConnector { - config: ExternalIncidentServiceConfiguration; - secrets: {}; -} - -export interface ActionConnectorParams { - message: string; -} - -export interface ActionConnectorValidationErrors { - apiUrl: string[]; -} - export type Optional = Omit & Partial; export interface ConnectorFlyoutFormProps { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx index 20bd68ba32d37..28178d4da6486 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -52,15 +52,17 @@ describe('servicenow connector validation', () => { }); test('connector validation fails when connector config is not valid', () => { - const actionConnector = { + const actionConnector = ({ secrets: { username: 'user', }, id: 'test', actionTypeId: '.servicenow', name: 'servicenow', - config: {}, - } as ServiceNowActionConnector; + config: { + apiUrl: '', + }, + } as unknown) as ServiceNowActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ errors: { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index 73c1097e97343..c7ed5522372bd 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -5,11 +5,7 @@ */ import { lazy } from 'react'; -import { - ValidationResult, - ActionTypeModel, - // eslint-disable-next-line @kbn/eslint/no-restricted-paths -} from '../../../../types'; +import { ValidationResult, ActionTypeModel } from '../../../../types'; import { connectorConfiguration } from './config'; import logo from './logo.svg'; import { ServiceNowActionConnector, ServiceNowActionParams } from './types'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index e665f071d7ba9..66e4bf7d38443 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import React, { useCallback, useEffect } from 'react'; +import React, { useCallback } from 'react'; import { EuiFieldText, @@ -32,7 +32,7 @@ export interface ConnectorFlyoutFormProps { const ServiceNowConnectorFields: React.FC> = ({ action, editActionSecrets, editActionConfig, errors, editActionProperty }) => { +>> = ({ action, editActionSecrets, editActionConfig, errors, consumer }) => { // TODO: remove incidentConfiguration later, when Case ServiceNow will move their fields to the level of action execution const { apiUrl, incidentConfiguration, isCaseOwned } = action.config; const mapping = incidentConfiguration ? incidentConfiguration.mapping : []; @@ -45,10 +45,15 @@ const ServiceNowConnectorFields: React.FC 0 && password != null; // TODO: remove this block later, when Case ServiceNow will move their fields to the level of action execution - if (action.isCaseOwned && isEmpty(mapping)) { - editActionConfig('incidentConfiguration', { - mapping: createDefaultMapping(connectorConfiguration.fields as any), - }); + if (consumer === 'case') { + if (isEmpty(mapping)) { + editActionConfig('incidentConfiguration', { + mapping: createDefaultMapping(connectorConfiguration.fields as any), + }); + } + if (!isCaseOwned) { + editActionConfig('isCaseOwned', true); + } } const handleOnChangeActionConfig = useCallback( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index d4f0688cc51d1..7be249440b743 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -7,9 +7,7 @@ // to remove import { CaseField, ThirdPartyField, ActionType } from '../../../../../../case/common/api'; -import { ActionConnector } from '../../../../types'; - -export interface ServiceNowActionConnector extends ActionConnector { +export interface ServiceNowActionConnector { config: ServiceNowConfig; secrets: ServiceNowSecrets; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx index f8a9085a88656..d78930344a673 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/context/actions_connectors_context.tsx @@ -19,6 +19,7 @@ export interface ActionsConnectorsContextValue { capabilities: ApplicationStart['capabilities']; reloadConnectors?: () => Promise; docLinks: DocLinksStart; + consumer?: string; } const ActionsConnectorsContext = createContext(null as any); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index f9f141a44c8cc..cf39b072c222a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -53,6 +53,7 @@ interface ActionConnectorProps { http: HttpSetup; actionTypeRegistry: TypeRegistry; docLinks: DocLinksStart; + consumer?: string; } export const ActionConnectorForm = ({ @@ -64,6 +65,7 @@ export const ActionConnectorForm = ({ http, actionTypeRegistry, docLinks, + consumer, }: ActionConnectorProps) => { const setActionProperty = (key: string, value: any) => { dispatch({ command: { type: 'setProperty' }, payload: { key, value } }); @@ -171,6 +173,7 @@ export const ActionConnectorForm = ({ editActionProperty={setActionProperty} http={http} docLinks={docLinks} + consumer={consumer} /> ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 7db6b5145f895..9f59d15a9341a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -149,6 +149,16 @@ describe('action_form', () => { config: {}, isPreconfigured: false, }, + { + secrets: {}, + id: 'test5', + actionTypeId: actionType.id, + name: 'Non consumer connector', + config: { + isCaseOwned: true, + }, + isPreconfigured: false, + }, ]); const mocks = coreMock.createSetup(); const [ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index f06722e8478ee..210f85b666eed 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -131,7 +131,9 @@ export const ActionForm = ({ try { setIsLoadingConnectors(true); const loadedConnectors = await loadConnectors({ http }); - setConnectors(loadedConnectors); + setConnectors( + loadedConnectors.filter((action) => !action.config || !action.config.isCaseOwned) + ); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( @@ -709,7 +711,6 @@ export const ActionForm = ({ toastNotifications={toastNotifications} docLinks={docLinks} capabilities={capabilities} - consumer={consumer} /> ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx index 2dd1f83749372..60ec0cfa6955e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_flyout.tsx @@ -52,6 +52,7 @@ export const ConnectorAddFlyout = ({ actionTypeRegistry, reloadConnectors, docLinks, + consumer, } = useActionsConnectorsContext(); const [actionType, setActionType] = useState(undefined); const [hasActionsUpgradeableByTrial, setHasActionsUpgradeableByTrial] = useState(false); @@ -117,6 +118,7 @@ export const ConnectorAddFlyout = ({ actionTypeRegistry={actionTypeRegistry} http={http} docLinks={docLinks} + consumer={consumer} /> ); } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx index 1d19f436950c7..67c836fc12cf7 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_add_modal.tsx @@ -40,6 +40,7 @@ interface ConnectorAddModalProps { >; capabilities: ApplicationStart['capabilities']; docLinks: DocLinksStart; + consumer?: string; } export const ConnectorAddModal = ({ @@ -52,6 +53,7 @@ export const ConnectorAddModal = ({ actionTypeRegistry, capabilities, docLinks, + consumer, }: ConnectorAddModalProps) => { let hasErrors = false; const initialConnector = { @@ -164,6 +166,7 @@ export const ConnectorAddModal = ({ actionTypeRegistry={actionTypeRegistry} docLinks={docLinks} http={http} + consumer={consumer} /> diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx index cbbbbfaea7ea3..68fd8b65f1a41 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/connector_edit_flyout.tsx @@ -48,6 +48,7 @@ export const ConnectorEditFlyout = ({ actionTypeRegistry, reloadConnectors, docLinks, + consumer, } = useActionsConnectorsContext(); const canSave = hasSaveActionsCapability(capabilities); const closeFlyout = useCallback(() => setEditFlyoutVisibility(false), [setEditFlyoutVisibility]); @@ -185,6 +186,7 @@ export const ConnectorEditFlyout = ({ actionTypeRegistry={actionTypeRegistry} http={http} docLinks={docLinks} + consumer={consumer} /> ) : ( 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 5d52896cc628f..61b85061a50f8 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 @@ -118,7 +118,7 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { setIsLoadingActions(true); try { const actionsResponse = await loadAllActions({ http }); - setActions(actionsResponse); + setActions(actionsResponse.filter((action) => !action.config || !action.config.isCaseOwned)); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx index 2b6cc9ed6c42a..874091b2bb7a8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_form.tsx @@ -282,7 +282,6 @@ export const AlertForm = ({ toastNotifications={toastNotifications} docLinks={docLinks} capabilities={capabilities} - consumer={alert.consumer} /> ) : null} diff --git a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts index a2a1657a1f4cc..1b5ecf2513a04 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts @@ -7,5 +7,6 @@ export { COMPARATORS, builtInComparators } from './comparators'; export { AGGREGATION_TYPES, builtInAggregationTypes } from './aggregation_types'; export { builtInGroupByTypes } from './group_by_types'; +export { connectorConfiguration as ServiceNowConnectorConfiguration } from '../../application/components/builtin_action_types/servicenow/config'; export const VIEW_LICENSE_OPTIONS_LINK = 'https://www.elastic.co/subscriptions'; diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 205e07bef082f..37ba9f5cc7c48 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -33,6 +33,7 @@ export interface ActionConnectorFieldsProps { errors: IErrorObject; docLinks: DocLinksStart; http?: HttpSetup; + consumer?: string; } export interface ActionParamsProps { From 42b60da976309a2cc9fbde89e1d25191dcf2a435 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 16:39:21 -0700 Subject: [PATCH 26/38] fixed failing tests --- .../servicenow/api.test.ts | 127 +++++++++++++++--- .../builtin_action_types/servicenow/api.ts | 9 +- .../servicenow/case_types.ts | 4 - .../builtin_action_types/servicenow/index.ts | 12 +- .../builtin_action_types/servicenow/types.ts | 2 + .../public/cases/containers/configure/mock.ts | 9 +- .../containers/configure/use_connectors.tsx | 10 +- .../action_connector_form/action_form.tsx | 12 +- .../components/actions_connectors_list.tsx | 10 +- 9 files changed, 155 insertions(+), 40 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 21aee53637818..8e18f03e02b20 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -4,9 +4,11 @@ * you may not use this file except in compliance with the Elastic License. */ +import { Logger } from 'src/core/server'; import { externalServiceMock, mapping, apiParams } from './mocks'; import { ExternalService } from './types'; import { api } from './api'; +let mockedLogger: jest.Mocked; describe('api', () => { let externalService: jest.Mocked; @@ -24,7 +26,13 @@ describe('api', () => { describe('create incident', () => { test('it creates an incident', async () => { const params = { ...apiParams, externalId: null }; - const res = await api.pushToService({ externalService, mapping, params, secrets: {} }); + const res = await api.pushToService({ + externalService, + mapping, + params, + secrets: {}, + logger: mockedLogger, + }); expect(res).toEqual({ id: 'incident-1', @@ -51,6 +59,7 @@ describe('api', () => { mapping, params, secrets: {}, + logger: mockedLogger, }); expect(res).toEqual({ @@ -63,7 +72,13 @@ describe('api', () => { test('it calls createIncident correctly', async () => { const params = { ...apiParams, externalId: null, comments: undefined }; - await api.pushToService({ externalService, mapping, params, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.createIncident).toHaveBeenCalledWith({ incident: { @@ -76,9 +91,15 @@ describe('api', () => { expect(externalService.updateIncident).not.toHaveBeenCalled(); }); - test('it calls createComment correctly', async () => { + test('it calls updateIncident correctly', async () => { const params = { ...apiParams, externalId: null }; - await api.pushToService({ externalService, mapping, params, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledTimes(2); expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { incident: { @@ -111,6 +132,7 @@ describe('api', () => { mapping, params: apiParams, secrets: {}, + logger: mockedLogger, }); expect(res).toEqual({ @@ -138,6 +160,7 @@ describe('api', () => { mapping, params, secrets: {}, + logger: mockedLogger, }); expect(res).toEqual({ @@ -150,7 +173,13 @@ describe('api', () => { test('it calls updateIncident correctly', async () => { const params = { ...apiParams }; - await api.pushToService({ externalService, mapping, params, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', @@ -166,7 +195,13 @@ describe('api', () => { test('it calls updateIncident to create a comments correctly', async () => { const params = { ...apiParams }; - await api.pushToService({ externalService, mapping, params, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledTimes(3); expect(externalService.updateIncident).toHaveBeenNthCalledWith(1, { incident: { @@ -213,7 +248,13 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -246,7 +287,13 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -277,7 +324,13 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -310,7 +363,13 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: {}, @@ -338,7 +397,13 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -369,7 +434,13 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -402,7 +473,13 @@ describe('api', () => { actionType: 'nothing', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -433,7 +510,13 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -466,7 +549,13 @@ describe('api', () => { actionType: 'append', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledWith({ incidentId: 'incident-3', incident: { @@ -497,7 +586,13 @@ describe('api', () => { actionType: 'overwrite', }); - await api.pushToService({ externalService, mapping, params: apiParams, secrets: {} }); + await api.pushToService({ + externalService, + mapping, + params: apiParams, + secrets: {}, + logger: mockedLogger, + }); expect(externalService.updateIncident).toHaveBeenCalledTimes(1); }); }); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index 789cc474cd5fa..a6f97726e4dcf 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -33,6 +33,7 @@ const pushToServiceHandler = async ({ mapping, params, secrets, + logger, }: PushToServiceApiHandlerArgs): Promise => { const { externalId, comments } = params; const updateIncident = externalId ? true : false; @@ -41,7 +42,13 @@ const pushToServiceHandler = async ({ let res: PushToServiceResponse; if (externalId) { - currentIncident = await externalService.getIncident(externalId); + try { + currentIncident = await externalService.getIncident(externalId); + } catch (ex) { + logger.debug( + `Retrieving Incident by id ${externalId} from ServiceNow was failed with exception: ${ex}` + ); + } } let incident = {}; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts index 29bf9b4a9d26c..7e659125af7b2 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/case_types.ts @@ -18,10 +18,6 @@ import { ExternalServiceParams, } from './types'; -export interface AnyParams { - [index: string]: string | number | object | undefined | null; -} - export interface CreateCommentRequest { [key: string]: string; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index 171c207cca344..c0b0d92dc8b99 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -61,12 +61,6 @@ async function executor( const { subAction, subActionParams } = params as ExecutorParams; let data: PushToServiceResponse | null = null; - const res: Pick & - Pick = { - status: 'ok', - actionId, - }; - const externalService = createExternalService({ config, secrets, @@ -99,13 +93,11 @@ async function executor( mapping, params: { ...pushToServiceParams, externalObject }, secrets, + logger, }); logger.debug(`response push to service for incident id: ${data.id}`); } - return { - ...res, - data: data ?? {}, - }; + return { status: 'ok', data: data ?? {}, actionId }; } diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts index 385ab3509bcd8..c265bef42d127 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts @@ -18,6 +18,7 @@ import { import { ActionsConfigurationUtilities } from '../../actions_config'; import { IncidentConfigurationSchema } from './case_shema'; import { PushToServiceResponse } from './case_types'; +import { Logger } from '../../../../../../src/core/server'; export type ServiceNowPublicConfigurationType = TypeOf< typeof ExternalIncidentServiceConfigurationSchema @@ -83,6 +84,7 @@ export type ExecutorSubActionHandshakeParams = TypeOf< export interface PushToServiceApiHandlerArgs extends ExternalServiceApiHandlerArgs { params: PushToServiceApiParams; secrets: Record; + logger: Logger; } export interface GetIncidentApiHandlerArgs extends ExternalServiceApiHandlerArgs { diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts b/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts index d729a3feed2a7..9b9e978ffca4b 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/mock.ts @@ -35,12 +35,12 @@ export const connectorsMock: Connector[] = [ name: 'My Connector', config: { apiUrl: 'https://instance1.service-now.com', - casesConfiguration: { + incidentConfiguration: { mapping, }, + isCaseOwned: true, }, isPreconfigured: false, - consumer: 'case', }, { id: 'servicenow-2', @@ -48,7 +48,7 @@ export const connectorsMock: Connector[] = [ name: 'My Connector 2', config: { apiUrl: 'https://instance2.service-now.com', - casesConfiguration: { + incidentConfiguration: { mapping: [ { source: 'title', @@ -67,9 +67,9 @@ export const connectorsMock: Connector[] = [ }, ], }, + isCaseOwned: true, }, isPreconfigured: false, - consumer: 'case', }, { id: 'jira-1', @@ -98,7 +98,6 @@ export const connectorsMock: Connector[] = [ }, }, isPreconfigured: false, - consumer: 'case', }, ]; diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx index 2895033f0c3bd..e59610562433d 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx @@ -6,6 +6,8 @@ import { useState, useEffect, useCallback } from 'react'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ServiceNowConnectorConfiguration } from '../../../../../triggers_actions_ui/public/common/constants'; import { useStateToaster, errorToToaster } from '../../../common/components/toasters'; import * as i18n from '../translations'; import { fetchConnectors } from './api'; @@ -32,7 +34,13 @@ export const useConnectors = (): ReturnConnectors => { if (!didCancel) { setLoading(false); setConnectors( - res.filter((connector) => !connector.config || connector.config.isCaseOwned) + res.filter( + (connector) => + // Need this filtering temporary to display only Case owned ServiceNow connectors + connector.actionTypeId !== ServiceNowConnectorConfiguration.id || + (connector.actionTypeId === ServiceNowConnectorConfiguration.id && + connector.config.isCaseOwned) + ) ); } } catch (error) { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index 210f85b666eed..e72866e2dafba 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -44,7 +44,10 @@ import { ConnectorAddModal } from './connector_add_modal'; import { TypeRegistry } from '../../type_registry'; import { actionTypeCompare } from '../../lib/action_type_compare'; import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_enabled'; -import { VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; +import { + VIEW_LICENSE_OPTIONS_LINK, + ServiceNowConnectorConfiguration, +} from '../../../common/constants'; interface ActionAccordionFormProps { actions: AlertAction[]; @@ -132,7 +135,12 @@ export const ActionForm = ({ setIsLoadingConnectors(true); const loadedConnectors = await loadConnectors({ http }); setConnectors( - loadedConnectors.filter((action) => !action.config || !action.config.isCaseOwned) + loadedConnectors.filter( + (action) => + action.actionTypeId !== ServiceNowConnectorConfiguration.id || + (action.actionTypeId === ServiceNowConnectorConfiguration.id && + !action.config.isCaseOwned) + ) ); } catch (e) { toastNotifications.addDanger({ 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 61b85061a50f8..0382cd46e0588 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 @@ -20,6 +20,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; +import { ServiceNowConnectorConfiguration } from '../../../../common/constants'; import { useAppDependencies } from '../../../app_context'; import { loadAllActions, loadActionTypes, deleteActions } from '../../../lib/action_connector_api'; import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout'; @@ -118,7 +119,14 @@ export const ActionsConnectorsList: React.FunctionComponent = () => { setIsLoadingActions(true); try { const actionsResponse = await loadAllActions({ http }); - setActions(actionsResponse.filter((action) => !action.config || !action.config.isCaseOwned)); + setActions( + actionsResponse.filter( + (action) => + action.actionTypeId !== ServiceNowConnectorConfiguration.id || + (action.actionTypeId === ServiceNowConnectorConfiguration.id && + !action.config.isCaseOwned) + ) + ); } catch (e) { toastNotifications.addDanger({ title: i18n.translate( From 2ed44d7d9260595a11e0a9f1c685dabe5e8e845f Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 16:55:43 -0700 Subject: [PATCH 27/38] fixed jest tests --- .../cases/components/configure_cases/index.test.tsx | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.test.tsx b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.test.tsx index f070431a34f21..91a5aa5c88beb 100644 --- a/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.test.tsx +++ b/x-pack/plugins/security_solution/public/cases/components/configure_cases/index.test.tsx @@ -125,7 +125,7 @@ describe('ConfigureCases', () => { jest.resetAllMocks(); useCaseConfigureMock.mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[0].config.casesConfiguration.mapping, + mapping: connectors[0].config.incidentConfiguration.mapping, closureType: 'close-by-user', connectorId: 'servicenow-1', connectorName: 'unchanged', @@ -213,7 +213,7 @@ describe('ConfigureCases', () => { jest.clearAllMocks(); useCaseConfigureMock.mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, + mapping: connectors[1].config.incidentConfiguration.mapping, closureType: 'close-by-user', connectorId: 'servicenow-2', connectorName: 'unchanged', @@ -332,7 +332,7 @@ describe('ConfigureCases', () => { jest.resetAllMocks(); useCaseConfigureMock.mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[0].config.casesConfiguration.mapping, + mapping: connectors[0].config.incidentConfiguration.mapping, closureType: 'close-by-user', connectorId: 'servicenow-1', connectorName: 'My connector', @@ -399,7 +399,7 @@ describe('closure options', () => { jest.resetAllMocks(); useCaseConfigureMock.mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[0].config.casesConfiguration.mapping, + mapping: connectors[0].config.incidentConfiguration.mapping, closureType: 'close-by-user', connectorId: 'servicenow-1', connectorName: 'My connector', @@ -435,7 +435,7 @@ describe('user interactions', () => { jest.resetAllMocks(); useCaseConfigureMock.mockImplementation(() => ({ ...useCaseConfigureResponse, - mapping: connectors[1].config.casesConfiguration.mapping, + mapping: connectors[1].config.incidentConfiguration.mapping, closureType: 'close-by-user', connectorId: 'servicenow-2', connectorName: 'unchanged', From 0ee86045bd3f1f688e9338083d15f23563aa3f92 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 17:33:24 -0700 Subject: [PATCH 28/38] Fixed URL validation --- .../builtin_action_types/servicenow/servicenow.tsx | 5 ++--- .../public/application/lib/value_validators.test.ts | 8 ++++---- .../public/application/lib/value_validators.ts | 12 ++++++------ 3 files changed, 12 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index c7ed5522372bd..df02b4ad8e410 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -10,7 +10,7 @@ import { connectorConfiguration } from './config'; import logo from './logo.svg'; import { ServiceNowActionConnector, ServiceNowActionParams } from './types'; import * as i18n from './translations'; -import { isUrlInvalid } from '../../../lib/value_validators'; +import { isValidUrl } from '../../../lib/value_validators'; const validateConnector = (action: ServiceNowActionConnector): ValidationResult => { const validationResult = { errors: {} }; @@ -25,7 +25,7 @@ const validateConnector = (action: ServiceNowActionConnector): ValidationResult errors.apiUrl = [...errors.apiUrl, i18n.API_URL_REQUIRED]; } - if (isUrlInvalid(action.config.apiUrl)) { + if (isValidUrl(action.config.apiUrl)) { errors.apiUrl = [...errors.apiUrl, i18n.API_URL_INVALID]; } @@ -49,7 +49,6 @@ export function getActionType(): ActionTypeModel< iconClass: logo, selectMessage: i18n.SERVICENOW_DESC, actionTypeTitle: connectorConfiguration.name, - // minimumLicenseRequired: 'platinum', validateConnector, actionConnectorFields: lazy(() => import('./servicenow_connectors')), validateParams: (actionParams: ServiceNowActionParams): ValidationResult => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts index eba22eae0c06b..5d14e520aae30 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts @@ -3,7 +3,7 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { throwIfAbsent, throwIfIsntContained, isUrlInvalid } from './value_validators'; +import { throwIfAbsent, throwIfIsntContained, isValidUrl } from './value_validators'; import uuid from 'uuid'; describe('throwIfAbsent', () => { @@ -80,12 +80,12 @@ describe('throwIfIsntContained', () => { }); }); -describe('isUrlInvalid', () => { +describe('isValidUrl', () => { test('verifies invalid url', () => { - expect(isUrlInvalid('this is not a url')).toBeTruthy(); + expect(isValidUrl('this is not a url')).toBeFalsy(); }); test('verifies valid url', () => { - expect(isUrlInvalid('https://www.elastic.co/')).toBeFalsy(); + expect(isValidUrl('https://www.elastic.co/')).toBeTruthy(); }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts index ff3ffae233faa..65f968597e303 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts @@ -32,11 +32,11 @@ export function throwIfIsntContained( }; } -const urlExpression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi; - -export const isUrlInvalid = (url: string | null | undefined) => { - if (!isEmpty(url) && url != null && url.match(urlExpression) == null) { - return true; +export const isValidUrl = (urlString: string, protocol?: string) => { + try { + const urlObject = new URL(urlString); + return !!protocol || urlObject.protocol === protocol; + } catch (err) { + return false; } - return false; }; From c0bec8da1de21fcefbcc65a44aa86cf4ee03a0ea Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 18:04:47 -0700 Subject: [PATCH 29/38] fixed due to comments --- .../builtin_action_types/lib/axios_utils.ts | 4 +++- .../server/builtin_action_types/servicenow/api.ts | 6 ++---- .../builtin_action_types/servicenow/index.ts | 4 ++-- .../builtin_action_types/servicenow/service.ts | 15 +++++---------- .../builtin_action_types/servicenow/types.ts | 4 +--- 5 files changed, 13 insertions(+), 20 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts index 8b21a0d711a1c..d527cf632bace 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/lib/axios_utils.ts @@ -21,13 +21,15 @@ export const request = async ({ url, method = 'get', data, + params, }: { axios: AxiosInstance; url: string; method?: Method; data?: T; + params?: unknown; }): Promise => { - const res = await axios(url, { method, data: data ?? {} }); + const res = await axios(url, { method, data: data ?? {}, params }); throwIfNotAlive(res.status, res.headers['content-type']); return res; }; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index a6f97726e4dcf..e33bfa671bc4f 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -128,13 +128,11 @@ export const transformFields = ({ date: params.updatedAt ?? params.createdAt, user: (params.updatedBy != null - ? params.updatedBy.fullName - ? params.updatedBy.fullName - : params.updatedBy.username + ? params.updatedBy.fullName || params.updatedBy.username : params.createdBy.fullName ? params.createdBy.fullName : params.createdBy.username) ?? '', - previousValue: currentIncident ? currentIncident[cur.key] : '', + previousValue: currentIncident ? (currentIncident[cur.key] as string) : '', }).value, }; }, {}); diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index c0b0d92dc8b99..dd1208616f39a 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -67,13 +67,13 @@ async function executor( }); if (!api[subAction]) { - const errorMessage = '[Action][ExternalService] Unsupported subAction type.'; + const errorMessage = `[Action][ExternalService] Unsupported subAction type ${subAction}.`; logger.error(errorMessage); throw new Error(errorMessage); } if (subAction !== 'pushToService') { - const errorMessage = '[Action][ExternalService] subAction not implemented.'; + const errorMessage = `[Action][ExternalService] subAction ${subAction} not implemented.`; logger.error(errorMessage); throw new Error(errorMessage); } diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts index 152243b978d34..2b5204af2eb7d 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/service.ts @@ -54,22 +54,17 @@ export const createExternalService = ({ }; const findIncidents = async (params?: Record) => { - const query = params - ? Object.keys(params).reduce((res, pkey) => `${res}${pkey}=${params[pkey]}&`, '?') - : ''; try { const res = await request({ axios: axiosInstance, - url: `${incidentUrl}${query}`, + url: incidentUrl, + params, }); return res.data.result.length > 0 ? { ...res.data.result } : undefined; } catch (error) { throw new Error( - getErrorMessage( - i18n.NAME, - `Unable to find incidents by query ${query}. Error: ${error.message}` - ) + getErrorMessage(i18n.NAME, `Unable to find incidents by query. Error: ${error.message}`) ); } }; @@ -80,7 +75,7 @@ export const createExternalService = ({ axios: axiosInstance, url: `${incidentUrl}`, method: 'post', - data: { ...incident }, + data: { ...(incident as Record) }, }); return { @@ -101,7 +96,7 @@ export const createExternalService = ({ const res = await patch({ axios: axiosInstance, url: `${incidentUrl}/${incidentId}`, - data: { ...incident }, + data: { ...(incident as Record) }, }); return { diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts index c265bef42d127..0db9b6642ea5c 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/types.ts @@ -53,9 +53,7 @@ export interface ExternalServiceIncidentResponse { pushedDate: string; } -export interface ExternalServiceParams { - [index: string]: any; -} +export type ExternalServiceParams = Record; export interface ExternalService { getIncident: (id: string) => Promise; From 8757548a622a4d4841e7bc7b07a752287391f793 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 20:11:59 -0700 Subject: [PATCH 30/38] fixed tests --- .../builtin_action_types/servicenow/servicenow.test.tsx | 4 +--- .../builtin_action_types/servicenow/servicenow.tsx | 2 +- .../public/application/lib/value_validators.test.ts | 6 +++++- .../public/application/lib/value_validators.ts | 7 +++++-- .../sections/action_connector_form/action_form.test.tsx | 2 +- 5 files changed, 13 insertions(+), 8 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx index 28178d4da6486..e0378ca23e10c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -59,9 +59,7 @@ describe('servicenow connector validation', () => { id: 'test', actionTypeId: '.servicenow', name: 'servicenow', - config: { - apiUrl: '', - }, + config: {}, } as unknown) as ServiceNowActionConnector; expect(actionTypeModel.validateConnector(actionConnector)).toEqual({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index df02b4ad8e410..f20b1b8b9666d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -25,7 +25,7 @@ const validateConnector = (action: ServiceNowActionConnector): ValidationResult errors.apiUrl = [...errors.apiUrl, i18n.API_URL_REQUIRED]; } - if (isValidUrl(action.config.apiUrl)) { + if (!isValidUrl(action.config.apiUrl, 'https:')) { errors.apiUrl = [...errors.apiUrl, i18n.API_URL_INVALID]; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts index 5d14e520aae30..e954fb5c7617b 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.test.ts @@ -85,7 +85,11 @@ describe('isValidUrl', () => { expect(isValidUrl('this is not a url')).toBeFalsy(); }); - test('verifies valid url', () => { + test('verifies valid url any protocol', () => { expect(isValidUrl('https://www.elastic.co/')).toBeTruthy(); }); + + test('verifies valid url with specific protocol', () => { + expect(isValidUrl('https://www.elastic.co/', 'https:')).toBeTruthy(); + }); }); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts index 65f968597e303..4942e6328097d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/lib/value_validators.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { constant, isEmpty } from 'lodash'; +import { constant } from 'lodash'; export function throwIfAbsent(message: string) { return (value: T | undefined): T => { @@ -35,7 +35,10 @@ export function throwIfIsntContained( export const isValidUrl = (urlString: string, protocol?: string) => { try { const urlObject = new URL(urlString); - return !!protocol || urlObject.protocol === protocol; + if (protocol === undefined || urlObject.protocol === protocol) { + return true; + } + return false; } catch (err) { return false; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 9f59d15a9341a..29c577400dbe8 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -151,7 +151,7 @@ describe('action_form', () => { }, { secrets: {}, - id: 'test5', + id: '.servicenow', actionTypeId: actionType.id, name: 'Non consumer connector', config: { From a3d29e447f43cda7cc310dd1b271ffa4980fc319 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 29 Jun 2020 21:00:33 -0700 Subject: [PATCH 31/38] fixed jest tests --- .../builtin_action_types/servicenow/servicenow.test.tsx | 2 +- .../components/builtin_action_types/servicenow/servicenow.tsx | 2 +- .../sections/action_connector_form/action_form.test.tsx | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx index e0378ca23e10c..5e70bc20f5c51 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.test.tsx @@ -56,7 +56,7 @@ describe('servicenow connector validation', () => { secrets: { username: 'user', }, - id: 'test', + id: '.servicenow', actionTypeId: '.servicenow', name: 'servicenow', config: {}, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx index f20b1b8b9666d..0f7b83ed84fb4 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow.tsx @@ -25,7 +25,7 @@ const validateConnector = (action: ServiceNowActionConnector): ValidationResult errors.apiUrl = [...errors.apiUrl, i18n.API_URL_REQUIRED]; } - if (!isValidUrl(action.config.apiUrl, 'https:')) { + if (action.config.apiUrl && !isValidUrl(action.config.apiUrl, 'https:')) { errors.apiUrl = [...errors.apiUrl, i18n.API_URL_INVALID]; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx index 29c577400dbe8..c21cce4cc4b62 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.test.tsx @@ -152,7 +152,7 @@ describe('action_form', () => { { secrets: {}, id: '.servicenow', - actionTypeId: actionType.id, + actionTypeId: '.servicenow', name: 'Non consumer connector', config: { isCaseOwned: true, From 2eafff53b340b3faa38b419bd0f062e961183e5d Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 30 Jun 2020 08:30:10 -0700 Subject: [PATCH 32/38] Fixed due to comments. Moved ServiceNow filtering in case plugin to server side --- .../routes/api/cases/configure/get_connectors.ts | 11 +++++++++-- .../cases/containers/configure/use_connectors.tsx | 12 +----------- 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts index d86e1777e920d..39fb5c1e82bc4 100644 --- a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts +++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts @@ -5,6 +5,8 @@ */ import Boom from 'boom'; +// eslint-disable-next-line @kbn/eslint/no-restricted-paths +import { ServiceNowConnectorConfiguration } from '../../../../../../triggers_actions_ui/public/common/constants'; import { RouteDeps } from '../../types'; import { wrapError } from '../../utils'; @@ -31,8 +33,13 @@ export function initCaseConfigureGetActionConnector({ caseService, router }: Rou throw Boom.notFound('Action client have not been found'); } - const results = (await actionsClient.getAll()).filter((action) => - SUPPORTED_CONNECTORS.includes(action.actionTypeId) + const results = (await actionsClient.getAll()).filter( + (action) => + SUPPORTED_CONNECTORS.includes(action.actionTypeId) && + // Need this filtering temporary to display only Case owned ServiceNow connectors + (action.actionTypeId !== ServiceNowConnectorConfiguration.id || + (action.actionTypeId === ServiceNowConnectorConfiguration.id && + action.config!.isCaseOwned)) ); return response.ok({ body: results }); } catch (error) { diff --git a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx index e59610562433d..812e580ad653f 100644 --- a/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx +++ b/x-pack/plugins/security_solution/public/cases/containers/configure/use_connectors.tsx @@ -6,8 +6,6 @@ import { useState, useEffect, useCallback } from 'react'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceNowConnectorConfiguration } from '../../../../../triggers_actions_ui/public/common/constants'; import { useStateToaster, errorToToaster } from '../../../common/components/toasters'; import * as i18n from '../translations'; import { fetchConnectors } from './api'; @@ -33,15 +31,7 @@ export const useConnectors = (): ReturnConnectors => { const res = await fetchConnectors({ signal: abortCtrl.signal }); if (!didCancel) { setLoading(false); - setConnectors( - res.filter( - (connector) => - // Need this filtering temporary to display only Case owned ServiceNow connectors - connector.actionTypeId !== ServiceNowConnectorConfiguration.id || - (connector.actionTypeId === ServiceNowConnectorConfiguration.id && - connector.config.isCaseOwned) - ) - ); + setConnectors(res); } } catch (error) { if (!didCancel) { From e83f57f6f27a487b74855da126845f33b5f64370 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Tue, 30 Jun 2020 12:06:08 -0700 Subject: [PATCH 33/38] fixed mock for ServiceNow --- .../case/server/routes/api/__mocks__/request_responses.ts | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts index 4aa6725159043..b02f53bcd174a 100644 --- a/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts +++ b/x-pack/plugins/case/server/routes/api/__mocks__/request_responses.ts @@ -31,7 +31,7 @@ export const getActions = (): FindActionResult[] => [ actionTypeId: '.servicenow', name: 'ServiceNow', config: { - casesConfiguration: { + incidentConfiguration: { mapping: [ { source: 'title', @@ -51,6 +51,7 @@ export const getActions = (): FindActionResult[] => [ ], }, apiUrl: 'https://dev102283.service-now.com', + isCaseOwned: true, }, isPreconfigured: false, referencedByCount: 0, From f76947887a9dbe3df74144370000dd91a819caa7 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Thu, 2 Jul 2020 17:13:47 -0700 Subject: [PATCH 34/38] fixed consumer config --- .../actions/server/builtin_action_types/servicenow/api.test.ts | 2 +- .../actions/server/builtin_action_types/servicenow/index.ts | 1 - x-pack/plugins/actions/server/config.ts | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts index 8e18f03e02b20..7daf14e99f254 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.test.ts @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { Logger } from 'src/core/server'; +import { Logger } from '../../../../../../src/core/server'; import { externalServiceMock, mapping, apiParams } from './mocks'; import { ExternalService } from './types'; import { api } from './api'; diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts index dd1208616f39a..e62ca465f30f8 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/index.ts @@ -7,7 +7,6 @@ import { curry } from 'lodash'; import { schema } from '@kbn/config-schema'; -// import { config } from './config'; import { validate } from './validators'; import { ExternalIncidentServiceConfiguration, diff --git a/x-pack/plugins/actions/server/config.ts b/x-pack/plugins/actions/server/config.ts index 8c006ec474053..b2f3fa2680a9c 100644 --- a/x-pack/plugins/actions/server/config.ts +++ b/x-pack/plugins/actions/server/config.ts @@ -12,7 +12,6 @@ const preconfiguredActionSchema = schema.object({ actionTypeId: schema.string({ minLength: 1 }), config: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), secrets: schema.recordOf(schema.string(), schema.any(), { defaultValue: {} }), - consumer: schema.maybe(schema.string()), }); export const configSchema = schema.object({ From 31a991b0a913ae77c470db9bf2638f78c23d987d Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Sun, 5 Jul 2020 16:15:23 -0700 Subject: [PATCH 35/38] fixed test --- .../case_mappings/field_mapping.tsx | 20 ++++------- .../case_mappings/field_mapping_row.tsx | 16 ++++----- .../servicenow/case_mappings/types.ts | 35 +++---------------- .../servicenow/case_mappings/utils.ts | 10 +++--- .../servicenow/servicenow_connectors.test.tsx | 2 -- .../servicenow/servicenow_connectors.tsx | 11 +----- .../builtin_action_types/servicenow/types.ts | 9 ++--- .../action_connector_form.tsx | 1 - .../sections/alert_form/alert_reducer.ts | 1 - .../triggers_actions_ui/public/types.ts | 2 -- 10 files changed, 27 insertions(+), 80 deletions(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx index 04a30af5e3b2b..52b881a1eb75f 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping.tsx @@ -8,15 +8,11 @@ import React, { useCallback, useMemo } from 'react'; import { EuiFormRow, EuiFlexItem, EuiFlexGroup, EuiSuperSelectOption } from '@elastic/eui'; import styled from 'styled-components'; -import { CaseField, ActionType, ThirdPartyField } from '../../../../../../../case/common/api'; import { FieldMappingRow } from './field_mapping_row'; import * as i18n from './translations'; import { setActionTypeToMapping, setThirdPartyToMapping } from './utils'; -import { - ThirdPartyField as ConnectorConfigurationThirdPartyField, - AllThirdPartyFields, -} from './types'; +import { ThirdPartyField as ConnectorConfigurationThirdPartyField } from './types'; import { CasesConfigurationMapping } from '../types'; import { connectorConfiguration } from '../config'; import { createDefaultMapping } from '../servicenow_connectors'; @@ -26,7 +22,7 @@ const FieldRowWrapper = styled.div` font-size: 14px; `; -const actionTypeOptions: Array> = [ +const actionTypeOptions: Array> = [ { value: 'nothing', inputDisplay: <>{i18n.FIELD_MAPPING_EDIT_NOTHING}, @@ -45,12 +41,10 @@ const actionTypeOptions: Array> = [ ]; const getThirdPartyOptions = ( - caseField: CaseField, + caseField: string, thirdPartyFields: Record -): Array> => - (Object.keys(thirdPartyFields) as AllThirdPartyFields[]).reduce< - Array> - >( +): Array> => + (Object.keys(thirdPartyFields) as string[]).reduce>>( (acc, key) => { if (thirdPartyFields[key].validSourceFields.includes(caseField)) { return [ @@ -87,7 +81,7 @@ const FieldMappingComponent: React.FC = ({ connectorActionTypeId, }) => { const onChangeActionType = useCallback( - (caseField: CaseField, newActionType: ActionType) => { + (caseField: string, newActionType: string) => { const myMapping = mapping ?? defaultMapping; onChangeMapping(setActionTypeToMapping(caseField, newActionType, myMapping)); }, @@ -96,7 +90,7 @@ const FieldMappingComponent: React.FC = ({ ); const onChangeThirdParty = useCallback( - (caseField: CaseField, newThirdPartyField: ThirdPartyField) => { + (caseField: string, newThirdPartyField: string) => { const myMapping = mapping ?? defaultMapping; onChangeMapping(setThirdPartyToMapping(caseField, newThirdPartyField, myMapping)); }, diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx index 495b47410d2f9..beca8f1fbbc77 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/field_mapping_row.tsx @@ -14,19 +14,17 @@ import { } from '@elastic/eui'; import { capitalize } from 'lodash'; -import { CaseField, ActionType, ThirdPartyField } from '../../../../../../../case/common/api/cases'; -import { AllThirdPartyFields } from './types'; export interface RowProps { id: string; disabled: boolean; - securitySolutionField: CaseField; - thirdPartyOptions: Array>; - actionTypeOptions: Array>; - onChangeActionType: (caseField: CaseField, newActionType: ActionType) => void; - onChangeThirdParty: (caseField: CaseField, newThirdPartyField: ThirdPartyField) => void; - selectedActionType: ActionType; - selectedThirdParty: ThirdPartyField; + securitySolutionField: string; + thirdPartyOptions: Array>; + actionTypeOptions: Array>; + onChangeActionType: (caseField: string, newActionType: string) => void; + onChangeThirdParty: (caseField: string, newThirdPartyField: string) => void; + selectedActionType: string; + selectedThirdParty: string; } const FieldMappingRowComponent: React.FC = ({ diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts index 4c30932077a61..6cd2200e1dc74 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/types.ts @@ -4,38 +4,13 @@ * you may not use this file except in compliance with the Elastic License. */ -import { IErrorObject, ActionType } from '../../../../../types'; +import { ActionType } from '../../../../../types'; -import { - ActionType as ThirdPartySupportedActions, - CaseField, -} from '../../../../../../../case/common/api'; - -export { ThirdPartyField as AllThirdPartyFields } from '../../../../../../../case/common/api'; - -export { ActionType, CaseField }; +export { ActionType }; export interface ThirdPartyField { label: string; - validSourceFields: CaseField[]; - defaultSourceField: CaseField; - defaultActionType: ThirdPartySupportedActions; -} - -export type Optional = Omit & Partial; - -export interface ConnectorFlyoutFormProps { - errors: IErrorObject; - action: T; - onChangeSecret: (key: string, value: string) => void; - onBlurSecret: (key: string) => void; - onChangeConfig: (key: string, value: string) => void; - onBlurConfig: (key: string) => void; -} - -export interface ConnectorFlyoutHOCProps { - ConnectorFormComponent: React.FC>; - connectorActionTypeId: string; - configKeys?: string[]; - secretKeys?: string[]; + validSourceFields: string[]; + defaultSourceField: string; + defaultActionType: string; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts index d3139e80ae3b1..a173d90515302 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/case_mappings/utils.ts @@ -3,13 +3,11 @@ * or more contributor license agreements. Licensed under the Elastic License; * you may not use this file except in compliance with the Elastic License. */ -import { ActionType, ThirdPartyField } from '../../../../../../../case/common/api'; -import { CaseField } from './types'; import { CasesConfigurationMapping } from '../types'; export const setActionTypeToMapping = ( - caseField: CaseField, - newActionType: ActionType, + caseField: string, + newActionType: string, mapping: CasesConfigurationMapping[] ): CasesConfigurationMapping[] => { const findItemIndex = mapping.findIndex((item) => item.source === caseField); @@ -26,8 +24,8 @@ export const setActionTypeToMapping = ( }; export const setThirdPartyToMapping = ( - caseField: CaseField, - newThirdPartyField: ThirdPartyField, + caseField: string, + newThirdPartyField: string, mapping: CasesConfigurationMapping[] ): CasesConfigurationMapping[] => mapping.map((item) => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx index 2eaa31a111a47..452d9c288926e 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.test.tsx @@ -33,7 +33,6 @@ describe('ServiceNowActionConnectorFields renders', () => { errors={{ apiUrl: [], username: [], password: [] }} editActionConfig={() => {}} editActionSecrets={() => {}} - editActionProperty={() => {}} docLinks={deps!.docLinks} /> ); @@ -72,7 +71,6 @@ describe('ServiceNowActionConnectorFields renders', () => { errors={{ apiUrl: [], username: [], password: [] }} editActionConfig={() => {}} editActionSecrets={() => {}} - editActionProperty={() => {}} docLinks={deps!.docLinks} /> ); diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx index 66e4bf7d38443..a5c4849cb63d9 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/servicenow_connectors.tsx @@ -15,21 +15,12 @@ import { } from '@elastic/eui'; import { isEmpty } from 'lodash'; -import { IErrorObject, ActionConnectorFieldsProps } from '../../../../types'; +import { ActionConnectorFieldsProps } from '../../../../types'; import * as i18n from './translations'; import { ServiceNowActionConnector, CasesConfigurationMapping } from './types'; import { connectorConfiguration } from './config'; import { FieldMapping } from './case_mappings/field_mapping'; -export interface ConnectorFlyoutFormProps { - errors: IErrorObject; - action: T; - onChangeSecret: (key: string, value: string) => void; - onBlurSecret: (key: string) => void; - onChangeConfig: (key: string, value: string) => void; - onBlurConfig: (key: string) => void; -} - const ServiceNowConnectorFields: React.FC> = ({ action, editActionSecrets, editActionConfig, errors, consumer }) => { diff --git a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts index 7be249440b743..92252efc3a41c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/components/builtin_action_types/servicenow/types.ts @@ -4,9 +4,6 @@ * you may not use this file except in compliance with the Elastic License. */ -// to remove -import { CaseField, ThirdPartyField, ActionType } from '../../../../../../case/common/api'; - export interface ServiceNowActionConnector { config: ServiceNowConfig; secrets: ServiceNowSecrets; @@ -43,7 +40,7 @@ interface ServiceNowSecrets { // to remove export interface CasesConfigurationMapping { - source: CaseField; - target: ThirdPartyField; - actionType: ActionType; + source: string; + target: string; + actionType: string; } diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx index cf39b072c222a..813f3598a748d 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_connector_form.tsx @@ -170,7 +170,6 @@ export const ActionConnectorForm = ({ errors={errors} editActionConfig={setActionConfigProperty} editActionSecrets={setActionSecretsProperty} - editActionProperty={setActionProperty} http={http} docLinks={docLinks} consumer={consumer} diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts index 7bc148c2dc31a..2e56f4b026b4a 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/alert_form/alert_reducer.ts @@ -25,7 +25,6 @@ export interface AlertReducerAction { key: string; value: {}; index?: number; - subKey?: string; }; } diff --git a/x-pack/plugins/triggers_actions_ui/public/types.ts b/x-pack/plugins/triggers_actions_ui/public/types.ts index 37ba9f5cc7c48..a4a13d7ec849c 100644 --- a/x-pack/plugins/triggers_actions_ui/public/types.ts +++ b/x-pack/plugins/triggers_actions_ui/public/types.ts @@ -29,7 +29,6 @@ export interface ActionConnectorFieldsProps { action: TActionConnector; editActionConfig: (property: string, value: any) => void; editActionSecrets: (property: string, value: any) => void; - editActionProperty?: (property: string, value: any) => void; errors: IErrorObject; docLinks: DocLinksStart; http?: HttpSetup; @@ -77,7 +76,6 @@ export interface ActionConnector { referencedByCount?: number; config: Record; isPreconfigured: boolean; - consumer?: string | null; } export type ActionConnectorWithoutId = Omit; From f333f4291eb278c99bce3a1d7c6fc6b32b8722bf Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Sun, 5 Jul 2020 17:18:47 -0700 Subject: [PATCH 36/38] fixed type check --- .../server/builtin_action_types/servicenow/api.ts | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts index e33bfa671bc4f..bd6f88f5efaa9 100644 --- a/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts +++ b/x-pack/plugins/actions/server/builtin_action_types/servicenow/api.ts @@ -13,7 +13,7 @@ import { } from './types'; // TODO: to remove, need to support Case -import { transformers, Transformer } from '../case/transformers'; +import { transformers } from '../case/transformers'; import { PushToServiceResponse, TransformFieldsArgs } from './case_types'; import { prepareFieldsForTransformation } from '../case/utils'; @@ -120,7 +120,7 @@ export const transformFields = ({ currentIncident, }: TransformFieldsArgs): Record => { return fields.reduce((prev, cur) => { - const transform = flow(...cur.pipes.map((p) => transformers[p])); + const transform = flow(...cur.pipes.map((p) => transformers[p])); return { ...prev, [cur.key]: transform({ @@ -128,11 +128,13 @@ export const transformFields = ({ date: params.updatedAt ?? params.createdAt, user: (params.updatedBy != null - ? params.updatedBy.fullName || params.updatedBy.username + ? params.updatedBy.fullName + ? params.updatedBy.fullName + : params.updatedBy.username : params.createdBy.fullName ? params.createdBy.fullName : params.createdBy.username) ?? '', - previousValue: currentIncident ? (currentIncident[cur.key] as string) : '', + previousValue: currentIncident ? currentIncident[cur.key] : '', }).value, }; }, {}); From eddbd87f2ad5e6ef64814b1108b7b4c81681ef58 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 6 Jul 2020 08:47:37 -0700 Subject: [PATCH 37/38] Fixed jest test --- x-pack/plugins/case/common/constants.ts | 1 + .../server/routes/api/cases/configure/get_connectors.ts | 8 +++----- .../public/common/lib/connectors/config.ts | 2 +- .../sections/action_connector_form/action_form.tsx | 6 ++---- .../components/actions_connectors_list.tsx | 2 +- .../triggers_actions_ui/public/common/constants/index.ts | 1 - x-pack/plugins/triggers_actions_ui/public/common/index.ts | 2 ++ 7 files changed, 10 insertions(+), 12 deletions(-) diff --git a/x-pack/plugins/case/common/constants.ts b/x-pack/plugins/case/common/constants.ts index 819d4110e168d..e912c661439b2 100644 --- a/x-pack/plugins/case/common/constants.ts +++ b/x-pack/plugins/case/common/constants.ts @@ -27,5 +27,6 @@ export const CASE_USER_ACTIONS_URL = `${CASE_DETAILS_URL}/user_actions`; export const ACTION_URL = '/api/actions'; export const ACTION_TYPES_URL = '/api/actions/list_action_types'; +export const SERVICENOW_ACTION_TYPE_ID = '.servicenow'; export const SUPPORTED_CONNECTORS = ['.servicenow', '.jira']; diff --git a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts index 39fb5c1e82bc4..28e75dd2f8c32 100644 --- a/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts +++ b/x-pack/plugins/case/server/routes/api/cases/configure/get_connectors.ts @@ -5,14 +5,13 @@ */ import Boom from 'boom'; -// eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceNowConnectorConfiguration } from '../../../../../../triggers_actions_ui/public/common/constants'; import { RouteDeps } from '../../types'; import { wrapError } from '../../utils'; import { CASE_CONFIGURE_CONNECTORS_URL, SUPPORTED_CONNECTORS, + SERVICENOW_ACTION_TYPE_ID, } from '../../../../../common/constants'; /* @@ -37,9 +36,8 @@ export function initCaseConfigureGetActionConnector({ caseService, router }: Rou (action) => SUPPORTED_CONNECTORS.includes(action.actionTypeId) && // Need this filtering temporary to display only Case owned ServiceNow connectors - (action.actionTypeId !== ServiceNowConnectorConfiguration.id || - (action.actionTypeId === ServiceNowConnectorConfiguration.id && - action.config!.isCaseOwned)) + (action.actionTypeId !== SERVICENOW_ACTION_TYPE_ID || + (action.actionTypeId === SERVICENOW_ACTION_TYPE_ID && action.config!.isCaseOwned)) ); return response.ok({ body: results }); } catch (error) { diff --git a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts index 386c63aca4d78..0b19e4177f5c2 100644 --- a/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts +++ b/x-pack/plugins/security_solution/public/common/lib/connectors/config.ts @@ -5,7 +5,7 @@ */ // eslint-disable-next-line @kbn/eslint/no-restricted-paths -import { ServiceNowConnectorConfiguration } from '../../../../../triggers_actions_ui/public/common/constants'; +import { ServiceNowConnectorConfiguration } from '../../../../../triggers_actions_ui/public/common'; import { connector as jiraConnectorConfig } from './jira/config'; import { ConnectorConfiguration } from './types'; diff --git a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx index e72866e2dafba..7f400ee9a5db1 100644 --- a/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx +++ b/x-pack/plugins/triggers_actions_ui/public/application/sections/action_connector_form/action_form.tsx @@ -44,10 +44,8 @@ import { ConnectorAddModal } from './connector_add_modal'; import { TypeRegistry } from '../../type_registry'; import { actionTypeCompare } from '../../lib/action_type_compare'; import { checkActionFormActionTypeEnabled } from '../../lib/check_action_type_enabled'; -import { - VIEW_LICENSE_OPTIONS_LINK, - ServiceNowConnectorConfiguration, -} from '../../../common/constants'; +import { VIEW_LICENSE_OPTIONS_LINK } from '../../../common/constants'; +import { ServiceNowConnectorConfiguration } from '../../../common'; interface ActionAccordionFormProps { actions: AlertAction[]; 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 0382cd46e0588..0e0691960729d 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 @@ -20,7 +20,7 @@ import { } from '@elastic/eui'; import { i18n } from '@kbn/i18n'; import { FormattedMessage } from '@kbn/i18n/react'; -import { ServiceNowConnectorConfiguration } from '../../../../common/constants'; +import { ServiceNowConnectorConfiguration } from '../../../../common'; import { useAppDependencies } from '../../../app_context'; import { loadAllActions, loadActionTypes, deleteActions } from '../../../lib/action_connector_api'; import ConnectorAddFlyout from '../../action_connector_form/connector_add_flyout'; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts index 1b5ecf2513a04..a2a1657a1f4cc 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/constants/index.ts @@ -7,6 +7,5 @@ export { COMPARATORS, builtInComparators } from './comparators'; export { AGGREGATION_TYPES, builtInAggregationTypes } from './aggregation_types'; export { builtInGroupByTypes } from './group_by_types'; -export { connectorConfiguration as ServiceNowConnectorConfiguration } from '../../application/components/builtin_action_types/servicenow/config'; export const VIEW_LICENSE_OPTIONS_LINK = 'https://www.elastic.co/subscriptions'; diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index.ts index 94089a274e79d..46a92d086dc37 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/index.ts @@ -5,3 +5,5 @@ */ export * from './expression_items'; + +export { ServiceNowConnectorConfiguration } from '../application/components/builtin_action_types/servicenow/config'; From 591b9b6e512269b22e9cfa8797116ea73db861c0 Mon Sep 17 00:00:00 2001 From: Yuliia Naumenko Date: Mon, 6 Jul 2020 10:16:41 -0700 Subject: [PATCH 38/38] fixed type check --- x-pack/plugins/triggers_actions_ui/public/common/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x-pack/plugins/triggers_actions_ui/public/common/index.ts b/x-pack/plugins/triggers_actions_ui/public/common/index.ts index 46a92d086dc37..9dd3fd787f860 100644 --- a/x-pack/plugins/triggers_actions_ui/public/common/index.ts +++ b/x-pack/plugins/triggers_actions_ui/public/common/index.ts @@ -6,4 +6,4 @@ export * from './expression_items'; -export { ServiceNowConnectorConfiguration } from '../application/components/builtin_action_types/servicenow/config'; +export { connectorConfiguration as ServiceNowConnectorConfiguration } from '../application/components/builtin_action_types/servicenow/config';