2020-05-06 15:25:35 +00:00
|
|
|
import {json, Router} from 'express';
|
2020-07-05 18:19:52 +00:00
|
|
|
import {CurrentStatus, State} from './app/_data/data';
|
|
|
|
import {existsSync, readFileSync, writeFileSync} from 'fs';
|
|
|
|
import * as jp from 'jsonpath';
|
2020-05-06 15:25:35 +00:00
|
|
|
|
|
|
|
interface Cache {
|
2020-07-05 18:19:52 +00:00
|
|
|
[id: string]: State;
|
2020-05-06 15:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
interface Config {
|
|
|
|
authToken: string;
|
|
|
|
title: string;
|
|
|
|
description: string;
|
2020-07-05 18:19:52 +00:00
|
|
|
statePath: string;
|
|
|
|
stateValues: {
|
|
|
|
operational: string[];
|
|
|
|
maintenance: string[];
|
|
|
|
};
|
2020-05-06 15:25:35 +00:00
|
|
|
groups: {
|
|
|
|
id: string;
|
|
|
|
name: string;
|
|
|
|
services: {
|
|
|
|
id: string;
|
|
|
|
name: string;
|
|
|
|
url: string;
|
2020-07-05 18:19:52 +00:00
|
|
|
statePath?: string;
|
|
|
|
stateValues?: {
|
|
|
|
operational?: string[];
|
|
|
|
maintenance?: string[];
|
|
|
|
};
|
2020-05-06 15:25:35 +00:00
|
|
|
}[];
|
|
|
|
}[];
|
|
|
|
}
|
|
|
|
|
2020-07-05 18:19:52 +00:00
|
|
|
interface StateKey {
|
|
|
|
statePath: string;
|
|
|
|
stateValues: {
|
|
|
|
operational: string[];
|
|
|
|
maintenance: string[];
|
|
|
|
};
|
2020-05-06 15:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
const api = Router();
|
|
|
|
api.use(json());
|
|
|
|
|
2020-07-05 18:19:52 +00:00
|
|
|
const config = JSON.parse(readFileSync('config.json', {encoding: 'utf-8'})) as Config;
|
|
|
|
const stateKeys: { [service: string]: StateKey } = config.groups
|
|
|
|
.map(g => g.services).reduce((x, y) => x.concat(y), [])
|
|
|
|
.reduce((services, service) => {
|
|
|
|
services[service.id] = {
|
|
|
|
statePath: service.statePath || config.statePath,
|
|
|
|
stateValues: {
|
|
|
|
operational: service.stateValues ? service.stateValues.operational || config.stateValues.operational : config.stateValues.operational,
|
|
|
|
maintenance: service.stateValues ? service.stateValues.maintenance || config.stateValues.maintenance : config.stateValues.maintenance,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
return services;
|
|
|
|
}, {});
|
|
|
|
const serviceStates = existsSync('cache.json') ? JSON.parse(readFileSync('cache.json', {encoding: 'utf-8'})) : {} as Cache;
|
2020-05-06 15:25:35 +00:00
|
|
|
|
|
|
|
let cache: CurrentStatus;
|
|
|
|
updateCache();
|
|
|
|
|
|
|
|
api.post('/update/health', (req, res) => {
|
|
|
|
const token = req.query.token;
|
|
|
|
if (token !== config.authToken) {
|
|
|
|
return res.status(401).send('invalid token');
|
|
|
|
}
|
|
|
|
const serviceId = req.query.service as string;
|
2020-07-05 18:19:52 +00:00
|
|
|
const keys = stateKeys[serviceId];
|
|
|
|
const state = jp.value(req.body, keys.statePath);
|
|
|
|
|
|
|
|
if (keys.stateValues.operational.includes(state)) {
|
|
|
|
serviceStates[serviceId] = 'operational';
|
|
|
|
} else if (keys.stateValues.maintenance.includes(state)) {
|
|
|
|
serviceStates[serviceId] = 'maintenance';
|
|
|
|
} else {
|
|
|
|
serviceStates[serviceId] = 'outage';
|
2020-05-06 15:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
updateCache();
|
|
|
|
|
2020-07-05 18:19:52 +00:00
|
|
|
writeFileSync('cache.json', JSON.stringify(serviceStates), {encoding: 'utf-8'});
|
2020-05-06 15:25:35 +00:00
|
|
|
|
|
|
|
return res.send('OK');
|
|
|
|
});
|
|
|
|
|
|
|
|
api.get('/status', (req, res) => {
|
|
|
|
return res.json(cache);
|
|
|
|
});
|
|
|
|
|
|
|
|
api.get('/info', (req, res) => {
|
|
|
|
return res.json({
|
|
|
|
title: config.title,
|
|
|
|
description: config.description
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
|
|
|
function updateCache(): void {
|
|
|
|
const groups = config.groups.map(group => {
|
|
|
|
const services = group.services.map(service => {
|
|
|
|
return {
|
|
|
|
id: service.id,
|
|
|
|
name: service.name,
|
|
|
|
url: service.url,
|
2020-07-05 18:19:52 +00:00
|
|
|
state: serviceStates[service.id] || 'operational'
|
|
|
|
};
|
2020-05-06 15:25:35 +00:00
|
|
|
});
|
|
|
|
return {
|
|
|
|
id: group.id,
|
|
|
|
name: group.name,
|
|
|
|
state: calculateOverallState(services.map(s => s.state)),
|
|
|
|
services: services
|
2020-07-05 18:19:52 +00:00
|
|
|
};
|
2020-05-06 15:25:35 +00:00
|
|
|
});
|
|
|
|
cache = {
|
|
|
|
state: calculateOverallState(groups.map(g => g.state)),
|
|
|
|
groups: groups
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
function calculateOverallState(states: State[]): State {
|
2020-07-05 18:19:52 +00:00
|
|
|
return states.includes('outage') ? 'outage' : states.includes('maintenance') ? 'maintenance' : 'operational';
|
2020-05-06 15:25:35 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
export {api};
|