feat: opsgenie integration (#3429)

This commit is contained in:
Srikanth Chekuri 2023-08-31 20:50:55 +05:30 committed by GitHub
parent e596dd77bd
commit 218eb5379e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 499 additions and 68 deletions

View File

@ -81,6 +81,13 @@ var BasicPlan = basemodel.FeatureSet{
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.AlertChannelOpsgenie,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.AlertChannelMsTeams,
Active: false,
@ -161,6 +168,13 @@ var ProPlan = basemodel.FeatureSet{
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.AlertChannelOpsgenie,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.AlertChannelMsTeams,
Active: true,
@ -241,6 +255,13 @@ var EnterprisePlan = basemodel.FeatureSet{
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.AlertChannelOpsgenie,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
basemodel.Feature{
Name: basemodel.AlertChannelMsTeams,
Active: true,

View File

@ -20,6 +20,9 @@
"field_slack_recipient": "Recipient",
"field_slack_title": "Title",
"field_slack_description": "Description",
"field_opsgenie_api_key": "API Key",
"field_opsgenie_description": "Description",
"placeholder_opsgenie_description": "Description",
"field_webhook_username": "User Name (optional)",
"field_webhook_password": "Password (optional)",
"field_pager_routing_key": "Routing Key",
@ -31,8 +34,12 @@
"field_pager_class": "Class",
"field_pager_client": "Client",
"field_pager_client_url": "Client URL",
"field_opsgenie_message": "Message",
"field_opsgenie_priority": "Priority",
"placeholder_slack_description": "Description",
"placeholder_pager_description": "Description",
"placeholder_opsgenie_message": "Message",
"placeholder_opsgenie_priority": "Priority",
"help_pager_client": "Shows up as event source in Pagerduty",
"help_pager_client_url": "Shows up as event source link in Pagerduty",
"help_pager_class": "The class/type of the event",
@ -43,6 +50,9 @@
"help_webhook_username": "Leave empty for bearer auth or when authentication is not necessary.",
"help_webhook_password": "Specify a password or bearer token",
"help_pager_description": "Shows up as description in pagerduty",
"help_opsgenie_message": "Shows up as message in opsgenie",
"help_opsgenie_priority": "Priority of the incident",
"help_opsgenie_description": "Shows up as description in opsgenie",
"channel_creation_done": "Successfully created the channel",
"channel_creation_failed": "An unexpected error occurred while creating this channel",
"channel_edit_done": "Channels Edited Successfully",

View File

@ -0,0 +1,37 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createOpsgenie';
const create = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.post('/channels', {
name: props.name,
opsgenie_configs: [
{
api_key: props.api_key,
description: props.description,
priority: props.priority,
message: props.message,
details: {
...props.detailsArray,
},
},
],
});
return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default create;

View File

@ -0,0 +1,38 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/editOpsgenie';
const editOpsgenie = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.put(`/channels/${props.id}`, {
name: props.name,
opsgenie_configs: [
{
send_resolved: true,
api_key: props.api_key,
description: props.description,
priority: props.priority,
message: props.message,
details: {
...props.detailsArray,
},
},
],
});
return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default editOpsgenie;

View File

@ -0,0 +1,37 @@
import axios from 'api';
import { ErrorResponseHandler } from 'api/ErrorResponseHandler';
import { AxiosError } from 'axios';
import { ErrorResponse, SuccessResponse } from 'types/api';
import { PayloadProps, Props } from 'types/api/channels/createOpsgenie';
const testOpsgenie = async (
props: Props,
): Promise<SuccessResponse<PayloadProps> | ErrorResponse> => {
try {
const response = await axios.post('/testChannel', {
name: props.name,
opsgenie_configs: [
{
api_key: props.api_key,
description: props.description,
priority: props.priority,
message: props.message,
details: {
...props.detailsArray,
},
},
],
});
return {
statusCode: 200,
error: null,
message: 'Success',
payload: response.data.data,
};
} catch (error) {
return ErrorResponseHandler(error as AxiosError);
}
};
export default testOpsgenie;

View File

@ -6,6 +6,7 @@ export enum FeatureKeys {
ALERT_CHANNEL_SLACK = 'ALERT_CHANNEL_SLACK',
ALERT_CHANNEL_WEBHOOK = 'ALERT_CHANNEL_WEBHOOK',
ALERT_CHANNEL_PAGERDUTY = 'ALERT_CHANNEL_PAGERDUTY',
ALERT_CHANNEL_OPSGENIE = 'ALERT_CHANNEL_OPSGENIE',
ALERT_CHANNEL_MSTEAMS = 'ALERT_CHANNEL_MSTEAMS',
DurationSort = 'DurationSort',
TimestampSort = 'TimestampSort',

View File

@ -40,6 +40,30 @@ export interface PagerChannel extends Channel {
details?: string;
detailsArray?: Record<string, string>;
}
// OpsgenieChannel configures alert manager to send
// events to opsgenie
export interface OpsgenieChannel extends Channel {
// ref: https://prometheus.io/docs/alerting/latest/configuration/#opsgenie_config
api_key: string;
message?: string;
// A description of the incident
description?: string;
// A backlink to the sender of the notification.
source?: string;
// A set of arbitrary key/value pairs that provide further detail
// about the alert.
details?: string;
detailsArray?: Record<string, string>;
// Priority level of alert. Possible values are P1, P2, P3, P4, and P5.
priority?: string;
}
export const ValidatePagerChannel = (p: PagerChannel): string => {
if (!p) {
return 'Received unexpected input for this channel, please contact your administrator ';
@ -63,16 +87,14 @@ export const ValidatePagerChannel = (p: PagerChannel): string => {
return '';
};
export type ChannelType =
| 'slack'
| 'email'
| 'webhook'
| 'pagerduty'
| 'msteams';
export const SlackType: ChannelType = 'slack';
export const WebhookType: ChannelType = 'webhook';
export const PagerType: ChannelType = 'pagerduty';
export const MsTeamsType: ChannelType = 'msteams';
export enum ChannelType {
Slack = 'slack',
Email = 'email',
Webhook = 'webhook',
Pagerduty = 'pagerduty',
Opsgenie = 'opsgenie',
MsTeams = 'msteams',
}
// LabelFilterStatement will be used for preparing filter conditions / matchers
export interface LabelFilterStatement {

View File

@ -1,4 +1,4 @@
import { PagerChannel } from './config';
import { OpsgenieChannel, PagerChannel } from './config';
export const PagerInitialConfig: Partial<PagerChannel> = {
description: `[{{ .Status | toUpper }}{{ if eq .Status "firing" }}:{{ .Alerts.Firing | len }}{{ end }}] {{ .CommonLabels.alertname }} for {{ .CommonLabels.job }}
@ -22,3 +22,31 @@ export const PagerInitialConfig: Partial<PagerChannel> = {
num_resolved: '{{ .Alerts.Resolved | len }}',
}),
};
export const OpsgenieInitialConfig: Partial<OpsgenieChannel> = {
message: '{{ .CommonLabels.alertname }}',
description: `{{ if gt (len .Alerts.Firing) 0 -}}
Alerts Firing:
{{ range .Alerts.Firing }}
- Message: {{ .Annotations.description }}
Labels:
{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
{{ end }} Annotations:
{{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }}
{{ end }} Source: {{ .GeneratorURL }}
{{ end }}
{{- end }}
{{ if gt (len .Alerts.Resolved) 0 -}}
Alerts Resolved:
{{ range .Alerts.Resolved }}
- Message: {{ .Annotations.description }}
Labels:
{{ range .Labels.SortedPairs }} - {{ .Name }} = {{ .Value }}
{{ end }} Annotations:
{{ range .Annotations.SortedPairs }} - {{ .Name }} = {{ .Value }}
{{ end }} Source: {{ .GeneratorURL }}
{{ end }}
{{- end }}`,
priority:
'{{ if eq (index .Alerts 0).Labels.severity "critical" }}P1{{ else if eq (index .Alerts 0).Labels.severity "warning" }}P2{{ else if eq (index .Alerts 0).Labels.severity "info" }}P3{{ else }}P4{{ end }}',
};

View File

@ -1,9 +1,11 @@
import { Form } from 'antd';
import createMsTeamsApi from 'api/channels/createMsTeams';
import createOpsgenie from 'api/channels/createOpsgenie';
import createPagerApi from 'api/channels/createPager';
import createSlackApi from 'api/channels/createSlack';
import createWebhookApi from 'api/channels/createWebhook';
import testMsTeamsApi from 'api/channels/testMsTeams';
import testOpsGenie from 'api/channels/testOpsgenie';
import testPagerApi from 'api/channels/testPager';
import testSlackApi from 'api/channels/testSlack';
import testWebhookApi from 'api/channels/testWebhook';
@ -17,19 +19,17 @@ import { useTranslation } from 'react-i18next';
import {
ChannelType,
MsTeamsChannel,
MsTeamsType,
OpsgenieChannel,
PagerChannel,
PagerType,
SlackChannel,
SlackType,
ValidatePagerChannel,
WebhookChannel,
WebhookType,
} from './config';
import { PagerInitialConfig } from './defaults';
import { OpsgenieInitialConfig, PagerInitialConfig } from './defaults';
import { isChannelType } from './utils';
function CreateAlertChannels({
preType = 'slack',
preType = ChannelType.Slack,
}: CreateAlertChannelsProps): JSX.Element {
// init namespace for translations
const { t } = useTranslation('channels');
@ -37,7 +37,13 @@ function CreateAlertChannels({
const [formInstance] = Form.useForm();
const [selectedConfig, setSelectedConfig] = useState<
Partial<SlackChannel & WebhookChannel & PagerChannel & MsTeamsChannel>
Partial<
SlackChannel &
WebhookChannel &
PagerChannel &
MsTeamsChannel &
OpsgenieChannel
>
>({
text: `{{ range .Alerts -}}
*Alert:* {{ .Labels.alertname }}{{ if .Labels.severity }} - {{ .Labels.severity }}{{ end }}
@ -71,7 +77,7 @@ function CreateAlertChannels({
const currentType = type;
setType(value as ChannelType);
if (value === PagerType && currentType !== value) {
if (value === ChannelType.Pagerduty && currentType !== value) {
// reset config to pager defaults
setSelectedConfig({
name: selectedConfig?.name,
@ -79,6 +85,13 @@ function CreateAlertChannels({
...PagerInitialConfig,
});
}
if (value === ChannelType.Opsgenie && currentType !== value) {
setSelectedConfig((selectedConfig) => ({
...selectedConfig,
...OpsgenieInitialConfig,
}));
}
},
[type, selectedConfig],
);
@ -239,6 +252,45 @@ function CreateAlertChannels({
setSavingState(false);
}, [t, notifications, preparePagerRequest]);
const prepareOpsgenieRequest = useCallback(
() => ({
api_key: selectedConfig?.api_key || '',
name: selectedConfig?.name || '',
send_resolved: true,
description: selectedConfig?.description || '',
message: selectedConfig?.message || '',
priority: selectedConfig?.priority || '',
}),
[selectedConfig],
);
const onOpsgenieHandler = useCallback(async () => {
setSavingState(true);
try {
const response = await createOpsgenie(prepareOpsgenieRequest());
if (response.statusCode === 200) {
notifications.success({
message: 'Success',
description: t('channel_creation_done'),
});
history.replace(ROUTES.ALL_CHANNELS);
} else {
notifications.error({
message: 'Error',
description: response.error || t('channel_creation_failed'),
});
}
} catch (error) {
notifications.error({
message: 'Error',
description: t('channel_creation_failed'),
});
}
setSavingState(false);
}, [prepareOpsgenieRequest, t, notifications]);
const prepareMsTeamsRequest = useCallback(
() => ({
webhook_url: selectedConfig?.webhook_url || '',
@ -280,12 +332,15 @@ function CreateAlertChannels({
const onSaveHandler = useCallback(
async (value: ChannelType) => {
const functionMapper = {
[SlackType]: onSlackHandler,
[WebhookType]: onWebhookHandler,
[PagerType]: onPagerHandler,
[MsTeamsType]: onMsTeamsHandler,
[ChannelType.Slack]: onSlackHandler,
[ChannelType.Webhook]: onWebhookHandler,
[ChannelType.Pagerduty]: onPagerHandler,
[ChannelType.Opsgenie]: onOpsgenieHandler,
[ChannelType.MsTeams]: onMsTeamsHandler,
};
const functionToCall = functionMapper[value];
if (isChannelType(value)) {
const functionToCall = functionMapper[value as keyof typeof functionMapper];
if (functionToCall) {
functionToCall();
@ -295,11 +350,13 @@ function CreateAlertChannels({
description: t('selected_channel_invalid'),
});
}
}
},
[
onSlackHandler,
onWebhookHandler,
onPagerHandler,
onOpsgenieHandler,
onMsTeamsHandler,
notifications,
t,
@ -313,22 +370,26 @@ function CreateAlertChannels({
let request;
let response;
switch (channelType) {
case WebhookType:
case ChannelType.Webhook:
request = prepareWebhookRequest();
response = await testWebhookApi(request);
break;
case SlackType:
case ChannelType.Slack:
request = prepareSlackRequest();
response = await testSlackApi(request);
break;
case PagerType:
case ChannelType.Pagerduty:
request = preparePagerRequest();
if (request) response = await testPagerApi(request);
break;
case MsTeamsType:
case ChannelType.MsTeams:
request = prepareMsTeamsRequest();
response = await testMsTeamsApi(request);
break;
case ChannelType.Opsgenie:
request = prepareOpsgenieRequest();
response = await testOpsGenie(request);
break;
default:
notifications.error({
message: 'Error',
@ -361,6 +422,7 @@ function CreateAlertChannels({
prepareWebhookRequest,
t,
preparePagerRequest,
prepareOpsgenieRequest,
prepareSlackRequest,
prepareMsTeamsRequest,
notifications,
@ -390,6 +452,7 @@ function CreateAlertChannels({
type,
...selectedConfig,
...PagerInitialConfig,
...OpsgenieInitialConfig,
},
}}
/>

View File

@ -0,0 +1,4 @@
import { ChannelType } from './config';
export const isChannelType = (type: string): type is ChannelType =>
Object.values(ChannelType).includes(type as ChannelType);

View File

@ -1,9 +1,11 @@
import { Form } from 'antd';
import editMsTeamsApi from 'api/channels/editMsTeams';
import editOpsgenie from 'api/channels/editOpsgenie';
import editPagerApi from 'api/channels/editPager';
import editSlackApi from 'api/channels/editSlack';
import editWebhookApi from 'api/channels/editWebhook';
import testMsTeamsApi from 'api/channels/testMsTeams';
import testOpsgenie from 'api/channels/testOpsgenie';
import testPagerApi from 'api/channels/testPager';
import testSlackApi from 'api/channels/testSlack';
import testWebhookApi from 'api/channels/testWebhook';
@ -11,14 +13,11 @@ import ROUTES from 'constants/routes';
import {
ChannelType,
MsTeamsChannel,
MsTeamsType,
OpsgenieChannel,
PagerChannel,
PagerType,
SlackChannel,
SlackType,
ValidatePagerChannel,
WebhookChannel,
WebhookType,
} from 'container/CreateAlertChannels/config';
import FormAlertChannels from 'container/FormAlertChannels';
import { useNotifications } from 'hooks/useNotifications';
@ -35,7 +34,13 @@ function EditAlertChannels({
const [formInstance] = Form.useForm();
const [selectedConfig, setSelectedConfig] = useState<
Partial<SlackChannel & WebhookChannel & PagerChannel & MsTeamsChannel>
Partial<
SlackChannel &
WebhookChannel &
PagerChannel &
MsTeamsChannel &
OpsgenieChannel
>
>({
...initialValue,
});
@ -45,7 +50,7 @@ function EditAlertChannels({
const { id } = useParams<{ id: string }>();
const [type, setType] = useState<ChannelType>(
initialValue?.type ? (initialValue.type as ChannelType) : SlackType,
initialValue?.type ? (initialValue.type as ChannelType) : ChannelType.Slack,
);
const onTypeChangeHandler = useCallback((value: string) => {
@ -193,6 +198,48 @@ function EditAlertChannels({
setSavingState(false);
}, [preparePagerRequest, notifications, selectedConfig, t]);
const prepareOpsgenieRequest = useCallback(
() => ({
name: selectedConfig.name || '',
api_key: selectedConfig.api_key || '',
message: selectedConfig.message || '',
description: selectedConfig.description || '',
priority: selectedConfig.priority || '',
id,
}),
[id, selectedConfig],
);
const onOpsgenieEditHandler = useCallback(async () => {
setSavingState(true);
if (selectedConfig?.api_key === '') {
notifications.error({
message: 'Error',
description: t('api_key_required'),
});
setSavingState(false);
return;
}
const response = await editOpsgenie(prepareOpsgenieRequest());
if (response.statusCode === 200) {
notifications.success({
message: 'Success',
description: t('channel_edit_done'),
});
history.replace(ROUTES.ALL_CHANNELS);
} else {
notifications.error({
message: 'Error',
description: response.error || t('channel_edit_failed'),
});
}
setSavingState(false);
}, [prepareOpsgenieRequest, t, notifications, selectedConfig]);
const prepareMsTeamsRequest = useCallback(
() => ({
webhook_url: selectedConfig?.webhook_url || '',
@ -237,14 +284,16 @@ function EditAlertChannels({
const onSaveHandler = useCallback(
(value: ChannelType) => {
if (value === SlackType) {
if (value === ChannelType.Slack) {
onSlackEditHandler();
} else if (value === WebhookType) {
} else if (value === ChannelType.Webhook) {
onWebhookEditHandler();
} else if (value === PagerType) {
} else if (value === ChannelType.Pagerduty) {
onPagerEditHandler();
} else if (value === MsTeamsType) {
} else if (value === ChannelType.MsTeams) {
onMsTeamsEditHandler();
} else if (value === ChannelType.Opsgenie) {
onOpsgenieEditHandler();
}
},
[
@ -252,6 +301,7 @@ function EditAlertChannels({
onWebhookEditHandler,
onPagerEditHandler,
onMsTeamsEditHandler,
onOpsgenieEditHandler,
],
);
@ -262,22 +312,26 @@ function EditAlertChannels({
let request;
let response;
switch (channelType) {
case WebhookType:
case ChannelType.Webhook:
request = prepareWebhookRequest();
response = await testWebhookApi(request);
break;
case SlackType:
case ChannelType.Slack:
request = prepareSlackRequest();
response = await testSlackApi(request);
break;
case PagerType:
case ChannelType.Pagerduty:
request = preparePagerRequest();
if (request) response = await testPagerApi(request);
break;
case MsTeamsType:
case ChannelType.MsTeams:
request = prepareMsTeamsRequest();
if (request) response = await testMsTeamsApi(request);
break;
case ChannelType.Opsgenie:
request = prepareOpsgenieRequest();
if (request) response = await testOpsgenie(request);
break;
default:
notifications.error({
message: 'Error',
@ -312,6 +366,7 @@ function EditAlertChannels({
preparePagerRequest,
prepareSlackRequest,
prepareMsTeamsRequest,
prepareOpsgenieRequest,
notifications,
],
);

View File

@ -0,0 +1,74 @@
import { Form, Input } from 'antd';
import { useTranslation } from 'react-i18next';
import { OpsgenieChannel } from '../../CreateAlertChannels/config';
const { TextArea } = Input;
function OpsgenieForm({ setSelectedConfig }: OpsgenieFormProps): JSX.Element {
const { t } = useTranslation('channels');
const handleInputChange = (field: string) => (
event: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
): void => {
setSelectedConfig((value) => ({
...value,
[field]: event.target.value,
}));
};
return (
<>
<Form.Item name="api_key" label={t('field_opsgenie_api_key')} required>
<Input onChange={handleInputChange('api_key')} />
</Form.Item>
<Form.Item
name="message"
help={t('help_opsgenie_message')}
label={t('field_opsgenie_message')}
required
>
<TextArea
rows={4}
onChange={handleInputChange('message')}
placeholder={t('placeholder_opsgenie_message')}
/>
</Form.Item>
<Form.Item
name="description"
help={t('help_opsgenie_description')}
label={t('field_opsgenie_description')}
required
>
<TextArea
rows={4}
onChange={handleInputChange('description')}
placeholder={t('placeholder_opsgenie_description')}
/>
</Form.Item>
<Form.Item
name="priority"
help={t('help_opsgenie_priority')}
label={t('field_opsgenie_priority')}
required
>
<TextArea
rows={4}
onChange={handleInputChange('priority')}
placeholder={t('placeholder_opsgenie_priority')}
/>
</Form.Item>
</>
);
}
interface OpsgenieFormProps {
setSelectedConfig: React.Dispatch<
React.SetStateAction<Partial<OpsgenieChannel>>
>;
}
export default OpsgenieForm;

View File

@ -5,13 +5,10 @@ import { FeatureKeys } from 'constants/features';
import ROUTES from 'constants/routes';
import {
ChannelType,
MsTeamsType,
OpsgenieChannel,
PagerChannel,
PagerType,
SlackChannel,
SlackType,
WebhookChannel,
WebhookType,
} from 'container/CreateAlertChannels/config';
import useFeatureFlags from 'hooks/useFeatureFlag';
import { isFeatureKeys } from 'hooks/useFeatureFlag/utils';
@ -20,6 +17,7 @@ import { Dispatch, ReactElement, SetStateAction } from 'react';
import { useTranslation } from 'react-i18next';
import MsTeamsSettings from './Settings/MsTeams';
import OpsgenieSettings from './Settings/Opsgenie';
import PagerSettings from './Settings/Pager';
import SlackSettings from './Settings/Slack';
import WebhookSettings from './Settings/Webhook';
@ -61,14 +59,16 @@ function FormAlertChannels({
}
switch (type) {
case SlackType:
case ChannelType.Slack:
return <SlackSettings setSelectedConfig={setSelectedConfig} />;
case WebhookType:
case ChannelType.Webhook:
return <WebhookSettings setSelectedConfig={setSelectedConfig} />;
case PagerType:
case ChannelType.Pagerduty:
return <PagerSettings setSelectedConfig={setSelectedConfig} />;
case MsTeamsType:
case ChannelType.MsTeams:
return <MsTeamsSettings setSelectedConfig={setSelectedConfig} />;
case ChannelType.Opsgenie:
return <OpsgenieSettings setSelectedConfig={setSelectedConfig} />;
default:
return null;
}
@ -102,6 +102,9 @@ function FormAlertChannels({
<Select.Option value="pagerduty" key="pagerduty">
Pagerduty
</Select.Option>
<Select.Option value="opsgenie" key="opsgenie">
Opsgenie
</Select.Option>
{!isOssFeature?.active && (
<Select.Option value="msteams" key="msteams">
<div>
@ -147,7 +150,9 @@ interface FormAlertChannelsProps {
formInstance: FormInstance;
type: ChannelType;
setSelectedConfig: Dispatch<
SetStateAction<Partial<SlackChannel & WebhookChannel & PagerChannel>>
SetStateAction<
Partial<SlackChannel & WebhookChannel & PagerChannel & OpsgenieChannel>
>
>;
onTypeChangeHandler: (value: ChannelType) => void;
onSaveHandler: (props: ChannelType) => void;

View File

@ -1,5 +1,6 @@
import ROUTES from 'constants/routes';
import CreateAlertChannels from 'container/CreateAlertChannels';
import { ChannelType } from 'container/CreateAlertChannels/config';
import GeneralSettings from 'container/GeneralSettings';
import { t } from 'i18next';
@ -11,7 +12,9 @@ export const alertsRoutesConfig = [
key: ROUTES.SETTINGS,
},
{
Component: (): JSX.Element => <CreateAlertChannels preType="slack" />,
Component: (): JSX.Element => (
<CreateAlertChannels preType={ChannelType.Slack} />
),
name: t('routes.alert_channels'),
route: ROUTES.CHANNELS_NEW,
key: ROUTES.CHANNELS_NEW,

View File

@ -1,15 +1,13 @@
/* eslint-disable sonarjs/cognitive-complexity */
import { Typography } from 'antd';
import get from 'api/channels/get';
import Spinner from 'components/Spinner';
import {
ChannelType,
MsTeamsChannel,
MsTeamsType,
PagerChannel,
PagerType,
SlackChannel,
SlackType,
WebhookChannel,
WebhookType,
} from 'container/CreateAlertChannels/config';
import EditAlertChannels from 'container/EditAlertChannels';
import { useTranslation } from 'react-i18next';
@ -50,7 +48,7 @@ function ChannelsEdit(): JSX.Element {
const slackConfig = value.slack_configs[0];
channel = slackConfig;
return {
type: SlackType,
type: ChannelType.Slack,
channel,
};
}
@ -59,7 +57,7 @@ function ChannelsEdit(): JSX.Element {
const msteamsConfig = value.msteams_configs[0];
channel = msteamsConfig;
return {
type: MsTeamsType,
type: ChannelType.MsTeams,
channel,
};
}
@ -69,7 +67,16 @@ function ChannelsEdit(): JSX.Element {
channel.details = JSON.stringify(pagerConfig.details);
channel.detailsArray = { ...pagerConfig.details };
return {
type: PagerType,
type: ChannelType.Pagerduty,
channel,
};
}
if (value && 'opsgenie_configs' in value) {
const opsgenieConfig = value.opsgenie_configs[0];
channel = opsgenieConfig;
return {
type: ChannelType.Opsgenie,
channel,
};
}
@ -89,12 +96,12 @@ function ChannelsEdit(): JSX.Element {
}
}
return {
type: WebhookType,
type: ChannelType.Webhook,
channel,
};
}
return {
type: SlackType,
type: ChannelType.Slack,
channel,
};
};

View File

@ -0,0 +1,8 @@
import { OpsgenieChannel } from 'container/CreateAlertChannels/config';
export type Props = OpsgenieChannel;
export interface PayloadProps {
data: string;
status: string;
}

View File

@ -0,0 +1,10 @@
import { OpsgenieChannel } from 'container/CreateAlertChannels/config';
export interface Props extends OpsgenieChannel {
id: string;
}
export interface PayloadProps {
data: string;
status: string;
}

View File

@ -20,6 +20,7 @@ const AlertChannelSlack = "ALERT_CHANNEL_SLACK"
const AlertChannelWebhook = "ALERT_CHANNEL_WEBHOOK"
const AlertChannelPagerduty = "ALERT_CHANNEL_PAGERDUTY"
const AlertChannelMsTeams = "ALERT_CHANNEL_MSTEAMS"
const AlertChannelOpsgenie = "ALERT_CHANNEL_OPSGENIE"
var BasicPlan = FeatureSet{
Feature{
@ -92,6 +93,13 @@ var BasicPlan = FeatureSet{
UsageLimit: -1,
Route: "",
},
Feature{
Name: AlertChannelOpsgenie,
Active: true,
Usage: 0,
UsageLimit: -1,
Route: "",
},
Feature{
Name: AlertChannelMsTeams,
Active: false,