trigger pager alarm
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user