Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Actions][Jira] Set parent issue for Sub-task issue type #78772

Merged
merged 5 commits into from
Oct 1, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions docs/user/alerting/action-types/jira.asciidoc
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ Priority:: The priority of the incident.
Labels:: The labels of the incident.
Title:: A title for the issue, used for searching the contents of the knowledge base.
Description:: The details about the incident.
Parent:: The parent issue id or key. Only for `Sub-task` issue types.
Priority:: The priority of the incident.
Additional comments:: Additional information for the client, such as how to troubleshoot the issue.

[[configuring-jira]]
Expand Down
25 changes: 13 additions & 12 deletions x-pack/plugins/actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -274,12 +274,12 @@ Running the action by scheduling a task means that we will no longer have a user

The following table describes the properties of the `options` object.

| Property | Description | Type |
| -------- | ------------------------------------------------------------------------------------------------------ | ------ |
| id | The id of the action you want to execute. | string |
| params | The `params` value to give the action type executor. | object |
| spaceId | The space id the action is within. | string |
| apiKey | The Elasticsearch API key to use for context. (Note: only required and used when security is enabled). | string |
| Property | Description | Type |
| -------- | ------------------------------------------------------------------------------------------------------ | ---------------- |
| id | The id of the action you want to execute. | string |
| params | The `params` value to give the action type executor. | object |
| spaceId | The space id the action is within. | string |
| apiKey | The Elasticsearch API key to use for context. (Note: only required and used when security is enabled). | string |
| source | The source of the execution, either an HTTP request or a reference to a Saved Object. | object, optional |

## Example
Expand Down Expand Up @@ -308,11 +308,11 @@ This api runs the action and asynchronously returns the result of running the ac

The following table describes the properties of the `options` object.

| Property | Description | Type |
| -------- | ------------------------------------------------------------------------------------ | ------ |
| id | The id of the action you want to execute. | string |
| params | The `params` value to give the action type executor. | object |
| source | The source of the execution, either an HTTP request or a reference to a Saved Object.| object, optional |
| Property | Description | Type |
| -------- | ------------------------------------------------------------------------------------- | ---------------- |
| id | The id of the action you want to execute. | string |
| params | The `params` value to give the action type executor. | object |
| source | The source of the execution, either an HTTP request or a reference to a Saved Object. | object, optional |

## Example

Expand All @@ -330,7 +330,7 @@ const result = await actionsClient.execute({
},
source: asSavedObjectExecutionSource({
id: '573891ae-8c48-49cb-a197-0cd5ec34a88b',
type: 'alert'
type: 'alert',
}),
});
```
Expand Down Expand Up @@ -620,6 +620,7 @@ The Jira action uses the [V2 API](https://developer.atlassian.com/cloud/jira/pla
| issueType | The id of the issue type in Jira. | string _(optional)_ |
| priority | The name of the priority in Jira. Example: `Medium`. | string _(optional)_ |
| labels | An array of labels. | string[] _(optional)_ |
| parent | The parent issue id or key. Only for `Sub-task` issue types. | string _(optional)_ |
| comments | The comments of the case. A comment is of the form `{ commentId: string, version: string, comment: string }` | object[] _(optional)_ |

#### `subActionParams (issueTypes)`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ describe('api', () => {
issueType: '10006',
labels: ['kibana', 'elastic'],
priority: 'High',
parent: null,
},
});
expect(externalService.updateIncident).not.toHaveBeenCalled();
Expand Down Expand Up @@ -252,6 +253,7 @@ describe('api', () => {
issueType: '10006',
labels: ['kibana', 'elastic'],
priority: 'High',
parent: null,
},
});
expect(externalService.createIncident).not.toHaveBeenCalled();
Expand Down Expand Up @@ -380,6 +382,36 @@ describe('api', () => {
});
});

describe('getIssues', () => {
test('it returns the issues correctly', async () => {
const res = await api.issues({
externalService,
params: { title: 'Title test' },
});
expect(res).toEqual([
{
id: '10267',
key: 'RJ-107',
title: 'Test title',
},
]);
});
});

describe('getIssue', () => {
test('it returns the issue correctly', async () => {
const res = await api.issue({
externalService,
params: { id: 'RJ-107' },
});
expect(res).toEqual({
id: '10267',
key: 'RJ-107',
title: 'Test title',
});
});
});

describe('mapping variations', () => {
test('overwrite & append', async () => {
mapping.set('title', {
Expand Down
20 changes: 18 additions & 2 deletions x-pack/plugins/actions/server/builtin_action_types/jira/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,10 @@ import {
Incident,
GetFieldsByIssueTypeHandlerArgs,
GetIssueTypesHandlerArgs,
GetIssuesHandlerArgs,
PushToServiceApiParams,
PushToServiceResponse,
GetIssueHandlerArgs,
} from './types';

// TODO: to remove, need to support Case
Expand Down Expand Up @@ -46,6 +48,18 @@ const getFieldsByIssueTypeHandler = async ({
return res;
};

const getIssuesHandler = async ({ externalService, params }: GetIssuesHandlerArgs) => {
const { title } = params;
const res = await externalService.getIssues(title);
return res;
};

const getIssueHandler = async ({ externalService, params }: GetIssueHandlerArgs) => {
const { id } = params;
const res = await externalService.getIssue(id);
return res;
};

const pushToServiceHandler = async ({
externalService,
mapping,
Expand Down Expand Up @@ -83,8 +97,8 @@ const pushToServiceHandler = async ({
currentIncident,
});
} else {
const { title, description, priority, labels, issueType } = params;
incident = { summary: title, description, priority, labels, issueType };
const { title, description, priority, labels, issueType, parent } = params;
incident = { summary: title, description, priority, labels, issueType, parent };
}

if (externalId != null) {
Expand Down Expand Up @@ -134,4 +148,6 @@ export const api: ExternalServiceApi = {
getIncident: getIncidentHandler,
issueTypes: getIssueTypesHandler,
fieldsByIssueType: getFieldsByIssueTypeHandler,
issues: getIssuesHandler,
issue: getIssueHandler,
};
26 changes: 25 additions & 1 deletion x-pack/plugins/actions/server/builtin_action_types/jira/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ import {
JiraExecutorResultData,
ExecutorSubActionGetFieldsByIssueTypeParams,
ExecutorSubActionGetIssueTypesParams,
ExecutorSubActionGetIssuesParams,
ExecutorSubActionGetIssueParams,
} from './types';
import * as i18n from './translations';
import { Logger } from '../../../../../../src/core/server';
Expand All @@ -37,7 +39,13 @@ interface GetActionTypeParams {
configurationUtilities: ActionsConfigurationUtilities;
}

const supportedSubActions: string[] = ['pushToService', 'issueTypes', 'fieldsByIssueType'];
const supportedSubActions: string[] = [
'pushToService',
'issueTypes',
'fieldsByIssueType',
'issues',
'issue',
];

// action type definition
export function getActionType(
Expand Down Expand Up @@ -137,5 +145,21 @@ async function executor(
});
}

if (subAction === 'issues') {
const getIssuesParams = subActionParams as ExecutorSubActionGetIssuesParams;
data = await api.issues({
externalService,
params: getIssuesParams,
});
}

if (subAction === 'issue') {
const getIssueParams = subActionParams as ExecutorSubActionGetIssueParams;
data = await api.issue({
externalService,
params: getIssueParams,
});
}

return { status: 'ok', data: data ?? {}, actionId };
}
13 changes: 13 additions & 0 deletions x-pack/plugins/actions/server/builtin_action_types/jira/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,18 @@ const createMock = (): jest.Mocked<ExternalService> => {
defaultValue: { name: 'Medium', id: '3' },
},
})),
getIssues: jest.fn().mockImplementation(() => [
{
id: '10267',
key: 'RJ-107',
title: 'Test title',
},
]),
getIssue: jest.fn().mockImplementation(() => ({
id: '10267',
key: 'RJ-107',
title: 'Test title',
})),
};

service.createComment.mockImplementationOnce(() =>
Expand Down Expand Up @@ -120,6 +132,7 @@ const executorParams: ExecutorSubActionPushParams = {
labels: ['kibana', 'elastic'],
priority: 'High',
issueType: '10006',
parent: null,
comments: [
{
commentId: 'case-comment-1',
Expand Down
11 changes: 11 additions & 0 deletions x-pack/plugins/actions/server/builtin_action_types/jira/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const ExecutorSubActionPushParamsSchema = schema.object({
issueType: schema.nullable(schema.string()),
priority: schema.nullable(schema.string()),
labels: schema.nullable(schema.arrayOf(schema.string())),
parent: schema.nullable(schema.string()),
// TODO: modify later to string[] - need for support Case schema
comments: schema.nullable(schema.arrayOf(CommentSchema)),
...EntityInformation,
Expand All @@ -60,6 +61,8 @@ export const ExecutorSubActionGetIssueTypesParamsSchema = schema.object({});
export const ExecutorSubActionGetFieldsByIssueTypeParamsSchema = schema.object({
id: schema.string(),
});
export const ExecutorSubActionGetIssuesParamsSchema = schema.object({ title: schema.string() });
export const ExecutorSubActionGetIssueParamsSchema = schema.object({ id: schema.string() });

export const ExecutorParamsSchema = schema.oneOf([
schema.object({
Expand All @@ -82,4 +85,12 @@ export const ExecutorParamsSchema = schema.oneOf([
subAction: schema.literal('fieldsByIssueType'),
subActionParams: ExecutorSubActionGetFieldsByIssueTypeParamsSchema,
}),
schema.object({
subAction: schema.literal('issues'),
subActionParams: ExecutorSubActionGetIssuesParamsSchema,
}),
schema.object({
subAction: schema.literal('issue'),
subActionParams: ExecutorSubActionGetIssueParamsSchema,
}),
]);
Loading