mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-10-30 14:49:14 +00:00
91 lines
2.3 KiB
TypeScript
91 lines
2.3 KiB
TypeScript
import ConfigStore from 'sentry/stores/configStore';
|
|
import type {SentryServiceIncident, SentryServiceStatus} from 'sentry/types';
|
|
|
|
type IncidentImpact = SentryServiceStatus['indicator'];
|
|
|
|
/**
|
|
* This is a partial typing of the statuspage API [0]
|
|
*
|
|
* [0]: https://doers.statuspage.io/api/v2/incidents/
|
|
*/
|
|
type StatuspageIncident = {
|
|
created_at: string;
|
|
id: string;
|
|
impact: IncidentImpact;
|
|
name: string;
|
|
shortlink: string;
|
|
status: string;
|
|
components?: Array<any>;
|
|
incident_updates?: Array<any>;
|
|
};
|
|
|
|
function getIncidentsFromIncidentResponse(statuspageIncidents: StatuspageIncident[]): {
|
|
incidents: SentryServiceIncident[];
|
|
indicator: IncidentImpact;
|
|
} {
|
|
if (statuspageIncidents === null || statuspageIncidents.length === 0) {
|
|
return {incidents: [], indicator: 'none'};
|
|
}
|
|
|
|
let isMajor = false;
|
|
const incidents: SentryServiceIncident[] = [];
|
|
|
|
statuspageIncidents.forEach(item => {
|
|
if (!isMajor && item.impact === 'major') {
|
|
isMajor = true;
|
|
}
|
|
incidents.push({
|
|
id: item.id,
|
|
name: item.name,
|
|
createdAt: item.created_at,
|
|
updates:
|
|
item.incident_updates?.map(update => ({
|
|
body: update.body,
|
|
status: update.status,
|
|
updatedAt: update.updated_at,
|
|
})) ?? [],
|
|
affectedComponents:
|
|
item.components?.map(componentUpdate => ({
|
|
name: componentUpdate.name,
|
|
status: componentUpdate.status,
|
|
updatedAt: componentUpdate.updated_at,
|
|
})) ?? [],
|
|
url: item.shortlink,
|
|
status: item.status,
|
|
});
|
|
});
|
|
|
|
return {incidents, indicator: isMajor ? 'major' : 'minor'};
|
|
}
|
|
|
|
export async function loadIncidents(): Promise<SentryServiceStatus | null> {
|
|
const cfg = ConfigStore.get('statuspage');
|
|
let response: Response | undefined = undefined;
|
|
if (!cfg || !cfg.id) {
|
|
return null;
|
|
}
|
|
|
|
try {
|
|
response = await fetch(
|
|
`https://${cfg.id}.${cfg.api_host}/api/v2/incidents/unresolved.json`
|
|
);
|
|
} catch (err) {
|
|
// No point in capturing this as we can't make statuspage come back.
|
|
return null;
|
|
}
|
|
|
|
if (!response.ok) {
|
|
// Sometimes statuspage responds with a 500
|
|
return null;
|
|
}
|
|
|
|
const data = await response.json();
|
|
const {incidents, indicator} = getIncidentsFromIncidentResponse(data.incidents);
|
|
|
|
return {
|
|
incidents,
|
|
indicator,
|
|
url: data.page.url,
|
|
};
|
|
}
|