Skip to content

Commit

Permalink
Refactor case connectors to support mappings
Browse files Browse the repository at this point in the history
  • Loading branch information
cnasikas committed Jun 7, 2021
1 parent b6c982c commit 18ab35c
Show file tree
Hide file tree
Showing 32 changed files with 330 additions and 186 deletions.
2 changes: 2 additions & 0 deletions x-pack/plugins/cases/common/api/connectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ export enum ConnectorTypes {
none = '.none',
}

export const connectorTypes = Object.values(ConnectorTypes);

const ConnectorJiraTypeFieldsRt = rt.type({
type: rt.literal(ConnectorTypes.jira),
fields: rt.union([JiraFieldsRT, rt.null]),
Expand Down
8 changes: 5 additions & 3 deletions x-pack/plugins/cases/server/client/cases/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import { createCaseError, flattenCaseSavedObject, getAlertInfoFromComments } fro
import { ENABLE_CASE_CONNECTOR } from '../../../common/constants';
import { CasesClient, CasesClientArgs, CasesClientInternal } from '..';
import { Operations } from '../../authorization';
import { CaseConnectors } from '../../connectors';

/**
* Returns true if the case should be closed based on the configuration settings and whether the case
Expand Down Expand Up @@ -65,7 +66,8 @@ export const push = async (
{ connectorId, caseId }: PushParams,
clientArgs: CasesClientArgs,
casesClient: CasesClient,
casesClientInternal: CasesClientInternal
casesClientInternal: CasesClientInternal,
casesConnectors: CaseConnectors
): Promise<CaseResponse> => {
const {
unsecuredSavedObjectsClient,
Expand Down Expand Up @@ -110,8 +112,7 @@ export const push = async (
});

const connectorMappings = await casesClientInternal.configuration.getMappings({
connectorId: connector.id,
connectorType: connector.actionTypeId,
connector,
});

if (connectorMappings.length === 0) {
Expand All @@ -125,6 +126,7 @@ export const push = async (
connector: connector as ActionConnector,
mappings: connectorMappings[0].attributes.mappings,
alerts,
casesConnectors,
});

const pushRes = await actionsClient.execute({
Expand Down
16 changes: 8 additions & 8 deletions x-pack/plugins/cases/server/client/cases/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import {
CommentType,
ConnectorMappingsAttributes,
ConnectorTypes,
CommentAttributes,
CommentRequestUserType,
CommentRequestAlertType,
} from '../../../common';
import { ActionsClient } from '../../../../actions/server';
import { externalServiceFormatters, FormatterConnectorTypes } from '../../connectors';
import { CasesClientGetAlertsResponse } from '../../client/alerts/types';
import {
BasicParams,
Expand All @@ -39,6 +41,8 @@ import {
TransformFieldsArgs,
} from './types';
import { getAlertIds } from '../utils';
import { isConnectorSupported } from '../utils';
import { CaseConnectors } from '../../connectors';

interface CreateIncidentArgs {
actionsClient: ActionsClient;
Expand All @@ -47,6 +51,7 @@ interface CreateIncidentArgs {
connector: ActionConnector;
mappings: ConnectorMappingsAttributes[];
alerts: CasesClientGetAlertsResponse;
casesConnectors: CaseConnectors;
}

export const getLatestPushInfo = (
Expand All @@ -70,9 +75,6 @@ export const getLatestPushInfo = (
return null;
};

const isConnectorSupported = (connectorId: string): connectorId is FormatterConnectorTypes =>
Object.values(ConnectorTypes).includes(connectorId as ConnectorTypes);

const getCommentContent = (comment: CommentResponse): string => {
if (comment.type === CommentType.user) {
return comment.comment;
Expand All @@ -99,6 +101,7 @@ export const createIncident = async ({
connector,
mappings,
alerts,
casesConnectors,
}: CreateIncidentArgs): Promise<MapIncident> => {
const {
comments: caseComments,
Expand All @@ -120,10 +123,7 @@ export const createIncident = async ({
const defaultPipes = externalId ? ['informationUpdated'] : ['informationCreated'];
let currentIncident: ExternalServiceParams | undefined;

const externalServiceFields = externalServiceFormatters[connector.actionTypeId].format(
theCase,
alerts
);
const externalServiceFields = casesConnectors[connector.actionTypeId].format(theCase, alerts);
let incident: Partial<PushToServiceApiParams['incident']> = { ...externalServiceFields };

if (externalId) {
Expand Down
26 changes: 6 additions & 20 deletions x-pack/plugins/cases/server/client/configure/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ import {
excess,
GetConfigureFindRequest,
GetConfigureFindRequestRt,
GetFieldsResponse,
throwErrors,
CasesConfigurationsResponse,
CaseConfigurationsResponseRt,
Expand All @@ -34,20 +33,14 @@ import {
} from '../../common';
import { CasesClientInternal } from '../client_internal';
import { CasesClientArgs } from '../types';
import { getFields } from './get_fields';
import { getMappings } from './get_mappings';

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { FindActionResult } from '../../../../actions/server/types';
import { ActionType } from '../../../../actions/common';
import { Operations } from '../../authorization';
import { combineAuthorizedAndOwnerFilter } from '../utils';
import {
ConfigurationGetFields,
MappingsArgs,
CreateMappingsArgs,
UpdateMappingsArgs,
} from './types';
import { MappingsArgs, CreateMappingsArgs, UpdateMappingsArgs } from './types';
import { createMappings } from './create_mappings';
import { updateMappings } from './update_mappings';
import {
Expand All @@ -62,7 +55,6 @@ import {
* @ignore
*/
export interface InternalConfigureSubClient {
getFields(params: ConfigurationGetFields): Promise<GetFieldsResponse>;
getMappings(
params: MappingsArgs
): Promise<SavedObjectsFindResponse<ConnectorMappings>['saved_objects']>;
Expand Down Expand Up @@ -109,7 +101,6 @@ export const createInternalConfigurationSubClient = (
casesClientInternal: CasesClientInternal
): InternalConfigureSubClient => {
const configureSubClient: InternalConfigureSubClient = {
getFields: (params: ConfigurationGetFields) => getFields(params, clientArgs),
getMappings: (params: MappingsArgs) => getMappings(params, clientArgs),
createMappings: (params: CreateMappingsArgs) =>
createMappings(params, clientArgs, casesClientInternal),
Expand Down Expand Up @@ -186,8 +177,7 @@ async function get(
if (connector != null) {
try {
mappings = await casesClientInternal.configuration.getMappings({
connectorId: connector.id,
connectorType: connector.type,
connector,
});
} catch (e) {
error = e.isBoom
Expand Down Expand Up @@ -295,22 +285,19 @@ async function update(

try {
const resMappings = await casesClientInternal.configuration.getMappings({
connectorId: connector != null ? connector.id : configuration.attributes.connector.id,
connectorType: connector != null ? connector.type : configuration.attributes.connector.type,
connector: connector != null ? connector : configuration.attributes.connector,
});
mappings = resMappings.length > 0 ? resMappings[0].attributes.mappings : [];

if (connector != null) {
if (resMappings.length !== 0) {
mappings = await casesClientInternal.configuration.updateMappings({
connectorId: connector.id,
connectorType: connector.type,
connector,
mappingId: resMappings[0].id,
});
} else {
mappings = await casesClientInternal.configuration.createMappings({
connectorId: connector.id,
connectorType: connector.type,
connector,
owner: configuration.attributes.owner,
});
}
Expand Down Expand Up @@ -419,8 +406,7 @@ async function create(

try {
mappings = await casesClientInternal.configuration.createMappings({
connectorId: configuration.connector.id,
connectorType: configuration.connector.type,
connector: configuration.connector,
owner: configuration.owner,
});
} catch (e) {
Expand Down
37 changes: 0 additions & 37 deletions x-pack/plugins/cases/server/client/configure/get_fields.ts

This file was deleted.

8 changes: 4 additions & 4 deletions x-pack/plugins/cases/server/client/configure/get_mappings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,13 +13,13 @@ import { CasesClientArgs } from '..';
import { MappingsArgs } from './types';

export const getMappings = async (
{ connectorType, connectorId }: MappingsArgs,
{ connector }: MappingsArgs,
clientArgs: CasesClientArgs
): Promise<SavedObjectsFindResponse<ConnectorMappings>['saved_objects']> => {
const { unsecuredSavedObjectsClient, connectorMappingsService, logger } = clientArgs;

try {
if (connectorType === ConnectorTypes.none) {
if (connector.actionTypeId === ConnectorTypes.none) {
return [];
}

Expand All @@ -28,15 +28,15 @@ export const getMappings = async (
options: {
hasReference: {
type: ACTION_SAVED_OBJECT_TYPE,
id: connectorId,
id: connector.id,
},
},
});

return myConnectorMappings.saved_objects;
} catch (error) {
throw createCaseError({
message: `Failed to retrieve mapping connector id: ${connectorId} type: ${connectorType}: ${error}`,
message: `Failed to retrieve mapping connector id: ${connector.id} type: ${connector.actionTypeId}: ${error}`,
error,
logger,
});
Expand Down
10 changes: 3 additions & 7 deletions x-pack/plugins/cases/server/client/configure/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@
* 2.0.
*/

import { ActionConnector } from '../../../common';

export interface MappingsArgs {
connectorType: string;
connectorId: string;
connector: ActionConnector;
}

export interface CreateMappingsArgs extends MappingsArgs {
Expand All @@ -17,8 +18,3 @@ export interface CreateMappingsArgs extends MappingsArgs {
export interface UpdateMappingsArgs extends MappingsArgs {
mappingId: string;
}

export interface ConfigurationGetFields {
connectorId: string;
connectorType: string;
}
33 changes: 0 additions & 33 deletions x-pack/plugins/cases/server/client/configure/utils.test.ts

This file was deleted.

3 changes: 3 additions & 0 deletions x-pack/plugins/cases/server/client/factory.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,15 @@ import { PluginStartContract as FeaturesPluginStart } from '../../../features/se
import { PluginStartContract as ActionsPluginStart } from '../../../actions/server';
import { AuthorizationAuditLogger } from '../authorization';
import { CasesClient, createCasesClient } from '.';
import { CaseConnectors } from '../connectors/types';

interface CasesClientFactoryArgs {
securityPluginSetup?: SecurityPluginSetup;
securityPluginStart?: SecurityPluginStart;
getSpace: GetSpaceFn;
featuresPluginStart: FeaturesPluginStart;
actionsPluginStart: ActionsPluginStart;
casesConnectors: CaseConnectors;
}

/**
Expand Down Expand Up @@ -110,6 +112,7 @@ export class CasesClientFactory {
logger: this.logger,
authorization: auth,
actionsClient: await this.options.actionsPluginStart.getActionsClientWithRequest(request),
casesConnectors: this.options.casesConnectors,
});
}
}
2 changes: 2 additions & 0 deletions x-pack/plugins/cases/server/client/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import type { PublicMethodsOf } from '@kbn/utility-types';
import { ElasticsearchClient, SavedObjectsClientContract, Logger } from 'kibana/server';
import { User } from '../../common/api';
import { Authorization } from '../authorization/authorization';
import { CaseConnectors } from '../connectors/types';
import {
AlertServiceContract,
CaseConfigureService,
Expand All @@ -35,4 +36,5 @@ export interface CasesClientArgs {
readonly logger: Logger;
readonly authorization: PublicMethodsOf<Authorization>;
readonly actionsClient: PublicMethodsOf<ActionsClient>;
readonly casesConnectors: CaseConnectors;
}
23 changes: 23 additions & 0 deletions x-pack/plugins/cases/server/connectors/factory.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import { ConnectorTypes } from '../../common/api';
import { getCaseConnector as getJiraCaseConnector } from './jira';
import { getCaseConnector as getResilientCaseConnector } from './resilient';
import { getServiceNowITSMCaseConnector, getServiceNowSIRCaseConnector } from './servicenow';
import { CaseConnectors, CreateCasesConnectorFactory } from './types';

const getCaseConnectors = (): CaseConnectors => ({
[ConnectorTypes.jira]: getJiraCaseConnector(),
[ConnectorTypes.serviceNowITSM]: getServiceNowITSMCaseConnector(),
[ConnectorTypes.serviceNowSIR]: getServiceNowSIRCaseConnector(),
[ConnectorTypes.resilient]: getResilientCaseConnector(),
});

export const createCaseConnectorFactory: CreateCasesConnectorFactory = () => ({
getCaseConnectors,
});
Loading

0 comments on commit 18ab35c

Please sign in to comment.