Skip to content

Commit

Permalink
[Actions] fixes error in UI in the Edit Flyout for PreConfigured Conn…
Browse files Browse the repository at this point in the history
…ectors (#78994)

Ensures only User Configured Connectors can be validated and edited by the UI to avoid these kinds of errors in the future.
  • Loading branch information
gmmorris authored Oct 1, 2020
1 parent 9e5bf0f commit 727d626
Show file tree
Hide file tree
Showing 23 changed files with 171 additions and 101 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import { lazy } from 'react';
import { i18n } from '@kbn/i18n';
import { ActionTypeModel, ValidationResult } from '../../../../types';
import { EmailActionParams, EmailActionConnector } from '../types';
import { EmailActionParams, EmailConfig, EmailSecrets, EmailActionConnector } from '../types';

export function getActionType(): ActionTypeModel<EmailActionConnector, EmailActionParams> {
export function getActionType(): ActionTypeModel<EmailConfig, EmailSecrets, EmailActionParams> {
const mailformat = /^[^@\s]+@[^@\s]+$/;
return {
id: '.email',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import { lazy } from 'react';
import { i18n } from '@kbn/i18n';
import { ActionTypeModel, ValidationResult } from '../../../../types';
import { EsIndexActionConnector, IndexActionParams } from '../types';
import { EsIndexActionConnector, EsIndexConfig, IndexActionParams } from '../types';

export function getActionType(): ActionTypeModel<EsIndexActionConnector, IndexActionParams> {
export function getActionType(): ActionTypeModel<EsIndexConfig, unknown, IndexActionParams> {
return {
id: '.index',
iconClass: 'indexOpen',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,19 +8,20 @@ import { lazy } from 'react';
import { ValidationResult, ActionTypeModel } from '../../../../types';
import { connectorConfiguration } from './config';
import logo from './logo.svg';
import { JiraActionConnector, JiraActionParams } from './types';
import { JiraActionConnector, JiraConfig, JiraSecrets, JiraActionParams } from './types';
import * as i18n from './translations';
import { isValidUrl } from '../../../lib/value_validators';

const validateConnector = (action: JiraActionConnector): ValidationResult => {
const validationResult = { errors: {} };
const errors = {
apiUrl: new Array<string>(),
projectKey: new Array<string>(),
email: new Array<string>(),
apiToken: new Array<string>(),
const validationResult = {
errors: {
apiUrl: new Array<string>(),
projectKey: new Array<string>(),
email: new Array<string>(),
apiToken: new Array<string>(),
},
};
validationResult.errors = errors;
const { errors } = validationResult;

if (!action.config.apiUrl) {
errors.apiUrl = [...errors.apiUrl, i18n.API_URL_REQUIRED];
Expand All @@ -45,7 +46,7 @@ const validateConnector = (action: JiraActionConnector): ValidationResult => {
return validationResult;
};

export function getActionType(): ActionTypeModel<JiraActionConnector, JiraActionParams> {
export function getActionType(): ActionTypeModel<JiraConfig, JiraSecrets, JiraActionParams> {
return {
id: connectorConfiguration.id,
iconClass: logo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { coreMock } from 'src/core/public/mocks';

import { useGetIssueTypes } from './use_get_issue_types';
import { useGetFieldsByIssueType } from './use_get_fields_by_issue_type';
import { ActionConnector } from '../../../../types';

jest.mock('./use_get_issue_types');
jest.mock('./use_get_fields_by_issue_type');
Expand All @@ -35,7 +36,7 @@ const actionParams = {
},
};

const connector = {
const connector: ActionConnector = {
secrets: {},
config: {},
id: 'test',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,9 @@
*/

import { CasesConfigurationMapping } from '../case_mappings';
import { UserConfiguredActionConnector } from '../../../../types';

export interface JiraActionConnector {
config: JiraConfig;
secrets: JiraSecrets;
}
export type JiraActionConnector = UserConfiguredActionConnector<JiraConfig, JiraSecrets>;

export interface JiraActionParams {
subAction: string;
Expand All @@ -30,14 +28,14 @@ interface IncidentConfiguration {
mapping: CasesConfigurationMapping[];
}

interface JiraConfig {
export interface JiraConfig {
apiUrl: string;
projectKey: string;
incidentConfiguration?: IncidentConfiguration;
isCaseOwned?: boolean;
}

interface JiraSecrets {
export interface JiraSecrets {
email: string;
apiToken: string;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,20 @@ import { lazy } from 'react';
import { i18n } from '@kbn/i18n';
import moment from 'moment';
import { ActionTypeModel, ValidationResult } from '../../../../types';
import { PagerDutyActionParams, PagerDutyActionConnector } from '.././types';
import {
PagerDutyActionConnector,
PagerDutyConfig,
PagerDutySecrets,
PagerDutyActionParams,
} from '.././types';
import pagerDutySvg from './pagerduty.svg';
import { hasMustacheTokens } from '../../../lib/has_mustache_tokens';

export function getActionType(): ActionTypeModel {
export function getActionType(): ActionTypeModel<
PagerDutyConfig,
PagerDutySecrets,
PagerDutyActionParams
> {
return {
id: '.pagerduty',
iconClass: pagerDutySvg,
Expand All @@ -33,6 +42,7 @@ export function getActionType(): ActionTypeModel {
routingKey: new Array<string>(),
};
validationResult.errors = errors;

if (!action.secrets.routingKey) {
errors.routingKey.push(
i18n.translate(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { lazy } from 'react';
import { ValidationResult, ActionTypeModel } from '../../../../types';
import { connectorConfiguration } from './config';
import logo from './logo.svg';
import { ResilientActionConnector, ResilientActionParams } from './types';
import {
ResilientActionConnector,
ResilientConfig,
ResilientSecrets,
ResilientActionParams,
} from './types';
import * as i18n from './translations';
import { isValidUrl } from '../../../lib/value_validators';

Expand Down Expand Up @@ -45,7 +50,11 @@ const validateConnector = (action: ResilientActionConnector): ValidationResult =
return validationResult;
};

export function getActionType(): ActionTypeModel<ResilientActionConnector, ResilientActionParams> {
export function getActionType(): ActionTypeModel<
ResilientConfig,
ResilientSecrets,
ResilientActionParams
> {
return {
id: connectorConfiguration.id,
iconClass: logo,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
*/

import { CasesConfigurationMapping } from '../case_mappings';
import { UserConfiguredActionConnector } from '../../../../types';

export interface ResilientActionConnector {
config: ResilientConfig;
secrets: ResilientSecrets;
}
export type ResilientActionConnector = UserConfiguredActionConnector<
ResilientConfig,
ResilientSecrets
>;

export interface ResilientActionParams {
subAction: string;
Expand All @@ -28,14 +29,14 @@ interface IncidentConfiguration {
mapping: CasesConfigurationMapping[];
}

interface ResilientConfig {
export interface ResilientConfig {
apiUrl: string;
orgId: string;
incidentConfiguration?: IncidentConfiguration;
isCaseOwned?: boolean;
}

interface ResilientSecrets {
export interface ResilientSecrets {
apiKeyId: string;
apiKeySecret: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
*/
import { TypeRegistry } from '../../../type_registry';
import { registerBuiltInActionTypes } from '.././index';
import { ActionTypeModel, ActionConnector } from '../../../../types';
import { ActionTypeModel, UserConfiguredActionConnector } from '../../../../types';

const ACTION_TYPE_ID = '.server-log';
let actionTypeModel: ActionTypeModel;
Expand All @@ -28,13 +28,14 @@ describe('actionTypeRegistry.get() works', () => {

describe('server-log connector validation', () => {
test('connector validation succeeds when connector config is valid', () => {
const actionConnector = {
const actionConnector: UserConfiguredActionConnector<{}, {}> = {
secrets: {},
id: 'test',
actionTypeId: '.server-log',
name: 'server-log',
config: {},
} as ActionConnector;
isPreconfigured: false,
};

expect(actionTypeModel.validateConnector(actionConnector)).toEqual({
errors: {},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { i18n } from '@kbn/i18n';
import { ActionTypeModel, ValidationResult } from '../../../../types';
import { ServerLogActionParams } from '../types';

export function getActionType(): ActionTypeModel<unknown, ServerLogActionParams> {
export function getActionType(): ActionTypeModel<unknown, unknown, ServerLogActionParams> {
return {
id: '.server-log',
iconClass: 'logsApp',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,12 @@ import { lazy } from 'react';
import { ValidationResult, ActionTypeModel } from '../../../../types';
import { connectorConfiguration } from './config';
import logo from './logo.svg';
import { ServiceNowActionConnector, ServiceNowActionParams } from './types';
import {
ServiceNowActionConnector,
ServiceNowConfig,
ServiceNowSecrets,
ServiceNowActionParams,
} from './types';
import * as i18n from './translations';
import { isValidUrl } from '../../../lib/value_validators';

Expand Down Expand Up @@ -41,7 +46,8 @@ const validateConnector = (action: ServiceNowActionConnector): ValidationResult
};

export function getActionType(): ActionTypeModel<
ServiceNowActionConnector,
ServiceNowConfig,
ServiceNowSecrets,
ServiceNowActionParams
> {
return {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,12 @@
*/

import { CasesConfigurationMapping } from '../case_mappings';
import { UserConfiguredActionConnector } from '../../../../types';

export interface ServiceNowActionConnector {
config: ServiceNowConfig;
secrets: ServiceNowSecrets;
}
export type ServiceNowActionConnector = UserConfiguredActionConnector<
ServiceNowConfig,
ServiceNowSecrets
>;

export interface ServiceNowActionParams {
subAction: string;
Expand All @@ -29,13 +30,13 @@ interface IncidentConfiguration {
mapping: CasesConfigurationMapping[];
}

interface ServiceNowConfig {
export interface ServiceNowConfig {
apiUrl: string;
incidentConfiguration?: IncidentConfiguration;
isCaseOwned?: boolean;
}

interface ServiceNowSecrets {
export interface ServiceNowSecrets {
username: string;
password: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
import { lazy } from 'react';
import { i18n } from '@kbn/i18n';
import { ActionTypeModel, ValidationResult } from '../../../../types';
import { SlackActionParams, SlackActionConnector } from '../types';
import { SlackActionParams, SlackSecrets, SlackActionConnector } from '../types';

export function getActionType(): ActionTypeModel<SlackActionConnector, SlackActionParams> {
export function getActionType(): ActionTypeModel<unknown, SlackSecrets, SlackActionParams> {
return {
id: '.slack',
iconClass: 'logoSlack',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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 { ActionConnector } from '../../../types';
import { UserConfiguredActionConnector } from '../../../types';

export interface EmailActionParams {
to: string[];
Expand Down Expand Up @@ -64,66 +64,56 @@ export interface WebhookActionParams {
body?: string;
}

interface EmailConfig {
export interface EmailConfig {
from: string;
host: string;
port: number;
secure?: boolean;
}

interface EmailSecrets {
export interface EmailSecrets {
user: string | null;
password: string | null;
}

export interface EmailActionConnector extends ActionConnector {
config: EmailConfig;
secrets: EmailSecrets;
}
export type EmailActionConnector = UserConfiguredActionConnector<EmailConfig, EmailSecrets>;

interface EsIndexConfig {
export interface EsIndexConfig {
index: string;
executionTimeField?: string | null;
refresh?: boolean;
}

export interface EsIndexActionConnector extends ActionConnector {
config: EsIndexConfig;
}
export type EsIndexActionConnector = UserConfiguredActionConnector<EsIndexConfig, unknown>;

interface PagerDutyConfig {
export interface PagerDutyConfig {
apiUrl?: string;
}

interface PagerDutySecrets {
export interface PagerDutySecrets {
routingKey: string;
}

export interface PagerDutyActionConnector extends ActionConnector {
config: PagerDutyConfig;
secrets: PagerDutySecrets;
}
export type PagerDutyActionConnector = UserConfiguredActionConnector<
PagerDutyConfig,
PagerDutySecrets
>;

interface SlackSecrets {
export interface SlackSecrets {
webhookUrl: string;
}

export interface SlackActionConnector extends ActionConnector {
secrets: SlackSecrets;
}
export type SlackActionConnector = UserConfiguredActionConnector<unknown, SlackSecrets>;

interface WebhookConfig {
export interface WebhookConfig {
method: string;
url: string;
headers: Record<string, string>;
}

interface WebhookSecrets {
export interface WebhookSecrets {
user: string;
password: string;
}

export interface WebhookActionConnector extends ActionConnector {
config: WebhookConfig;
secrets: WebhookSecrets;
}
export type WebhookActionConnector = UserConfiguredActionConnector<WebhookConfig, WebhookSecrets>;
Loading

0 comments on commit 727d626

Please sign in to comment.