trigger pager alarm

This commit is contained in:
Samira Mokaram
2020-10-21 14:12:52 +02:00
parent 4dba9ea97a
commit 4e93108ba4
8 changed files with 99 additions and 38 deletions
+3 -1
View File
@@ -22,12 +22,14 @@
"dependencies": {
"@backstage/core": "^0.1.1-alpha.25",
"@backstage/theme": "^0.1.1-alpha.25",
"@backstage/catalog-model": "^0.1.1-alpha.25",
"@material-ui/core": "^4.11.0",
"@material-ui/icons": "^4.9.1",
"@material-ui/lab": "4.0.0-alpha.45",
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-use": "^15.3.3"
"react-use": "^15.3.3",
"moment": "^2.27.0"
},
"devDependencies": {
"@backstage/cli": "^0.1.1-alpha.25",
@@ -0,0 +1,73 @@
/*
* Copyright 2020 Spotify AB
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
type Options = {
method: string;
headers: {
'Content-Type': string;
Accept: string;
};
body: string;
};
const request = async (
url: string,
options: Options,
): Promise<Response | Error> => {
const response = await fetch(url, options);
if (!response.ok) {
const payload = await response.json();
const errors = payload.errors.map((error: string) => error).join(' ');
const message = `Request failed with ${response.status}, ${errors}`;
throw new Error(message);
}
return await response.json();
};
export function triggerPagerDutyAlarm(
integrationKey: string,
source: string,
description: string,
userName: string,
) {
const options = {
method: 'POST',
headers: {
'Content-Type': 'application/json; charset=UTF-8',
Accept: 'application/json, text/plain, */*',
},
body: JSON.stringify({
event_action: 'trigger',
routing_key: integrationKey,
client: 'Backstage',
client_url: source,
payload: {
summary: description,
source: source,
severity: 'error',
class: 'manual trigger',
custom_details: {
user: userName,
},
},
}),
};
return request('https://events.pagerduty.com/v2/enqueue', options);
}

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

@@ -29,7 +29,7 @@ import {
import UserIcon from '@material-ui/icons/Person';
import EmailIcon from '@material-ui/icons/Email';
import { StatusWarning } from '@backstage/core';
import Pagerduty from './pd.svg';
import Pagerduty from '../assets/pd.svg';
import { PagerDutyUserData } from './types';
const useStyles = makeStyles({
@@ -27,7 +27,7 @@ import {
ListSubheader,
} from '@material-ui/core';
import { StatusError, StatusWarning, StatusOK } from '@backstage/core';
import Pagerduty from './pd.svg';
import Pagerduty from '../assets/pd.svg';
import moment from 'moment';
const useStyles = makeStyles({
@@ -22,7 +22,7 @@ import { EscalationPolicy } from './Escalation';
import { PagerDutyData } from './types';
import { TriggerButton } from './TriggerButton';
const PAGERDUTY_INTEGRATION_KEY = 'pagerduty.com/integration-key';
export const PAGERDUTY_INTEGRATION_KEY = 'pagerduty.com/integration-key';
export const isPluginApplicableToEntity = (entity: Entity) =>
Boolean(entity.metadata.annotations?.[PAGERDUTY_INTEGRATION_KEY]);
@@ -76,7 +76,7 @@ export const PagerDutyServiceCard = ({ entity }: Props) => {
link: homepageUrl,
};
return isPluginApplicableToEntity(entity) ? (
return !isPluginApplicableToEntity(entity) ? (
<MissingAnnotationEmptyState annotation={PAGERDUTY_INTEGRATION_KEY} />
) : (
<InfoCard title="PagerDuty" deepLink={link}>
@@ -18,6 +18,7 @@ import React, { useState } from 'react';
import { Button } from '@material-ui/core';
import { TriggerDialog } from './TriggerDialog';
import { Entity } from '@backstage/catalog-model';
import { PAGERDUTY_INTEGRATION_KEY } from './PagerDutyServiceCard';
type Props = {
entity: Entity;
@@ -30,21 +31,6 @@ export const TriggerButton = ({ entity }: Props) => {
setShowDialog(!showDialog);
};
// const onTriggerAlarm = async (description: string) => {
// try {
// //TODO: call method from pagerduty client
// alertApi.post({
// message: `Alarm successfully triggered by ${userId}`,
// });
// } catch (error) {
// alertApi.post({
// message: `Failed to trigger alarm, ${error.message}`,
// severity: 'error',
// });
// throw error;
// }
// };
return (
<>
<Button
@@ -58,8 +44,9 @@ export const TriggerButton = ({ entity }: Props) => {
{showDialog && (
<TriggerDialog
name={entity.metadata.name}
integrationKey="someKey"
// onTrigger={onTriggerAlarm}
integrationKey={
entity.metadata.annotations![PAGERDUTY_INTEGRATION_KEY]
}
onClose={handleDialog}
/>
)}
@@ -23,11 +23,10 @@ import {
DialogActions,
Button,
DialogContent,
FormControl,
FormHelperText,
} from '@material-ui/core';
import { Progress, useApi, alertApiRef, identityApiRef } from '@backstage/core';
import { useAsyncFn } from 'react-use';
import { triggerPagerDutyAlarm } from '../api/pagerDutyClient';
const useStyles = makeStyles({
warningText: {
@@ -54,16 +53,16 @@ export const TriggerDialog = ({ name, integrationKey, onClose }: Props) => {
setDescription(event.target.value);
};
const promiseFunc = () =>
new Promise((resolve, reject) => {
setTimeout(() => {
reject('Inside test await');
}, 1000);
});
const [{ value, loading, error }, triggerAlarm] = useAsyncFn(async () => {
return await promiseFunc();
});
const [{ value, loading, error }, triggerAlarm] = useAsyncFn(
async (desc: string) => {
return await triggerPagerDutyAlarm(
integrationKey,
window.location.toString(),
desc,
userId,
);
},
);
useEffect(() => {
if (value) {
@@ -75,14 +74,14 @@ export const TriggerDialog = ({ name, integrationKey, onClose }: Props) => {
if (error) {
alertApi.post({
message: `Failed to trigger alarm, ${error.message}`,
message: `Failed to trigger alarm. ${error.message}`,
severity: 'error',
});
}
}, [value, error]);
}, [value, error, alertApi, onClose, userId]);
return (
<Dialog maxWidth="sm" open={true} onClose={onClose} fullWidth={true}>
<Dialog maxWidth="sm" open onClose={onClose} fullWidth>
<DialogTitle>
This action will send PagerDuty alarms and notifications to on-call
people responsible for {name}.
@@ -117,7 +116,7 @@ export const TriggerDialog = ({ name, integrationKey, onClose }: Props) => {
id="trigger"
color="secondary"
disabled={!description || loading}
onClick={triggerAlarm}
onClick={() => triggerAlarm(description)}
>
Trigger
</Button>