Implement all vendor integrations, WAN graphs, and FortiGate health panel
- Wire up 26 vendor providers: Atlassian Statuspage API, Status.io, Instatus, AWS RSS feeds, Apple/Google JSON feeds, M365 Graph API, and synthetic checks - Add 11 new providers: AWS, Cloudflare, SmartPass, School Dismissal Manager, SherpaDesk, Classkick, ClassDojo, Savvas, Study Island, Promethean, RAZ-Kids - Rename Local Infrastructure → Internet (TCP check to 8.8.8.8:53) - Add WAN throughput graph section: dual-link canvas graphs (Crown Castle + Comcast) polling FortiGate REST API every 30s with 30-min rolling history - Add FortiGate health card: uptime, CPU %, memory % from FortiOS API - Add /api/throughput and /api/fortigate-health endpoints - Add README with setup instructions Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,66 @@
|
||||
export const name = "Google Workspace";
|
||||
export const url = "https://workspace.google.com/status/";
|
||||
|
||||
const INCIDENTS_URL =
|
||||
"https://www.google.com/appsstatus/dashboard/incidents.json";
|
||||
|
||||
// status_impact → dashboard status
|
||||
const STATUS_MAP = {
|
||||
SERVICE_OUTAGE: "outage",
|
||||
SERVICE_DISRUPTION: "degraded",
|
||||
};
|
||||
|
||||
const IMPACT_LABEL = {
|
||||
SERVICE_OUTAGE: "outage",
|
||||
SERVICE_DISRUPTION: "service disruption",
|
||||
};
|
||||
|
||||
const SEVERITY_ORDER = ["operational", "degraded", "outage"];
|
||||
|
||||
function worstStatus(a, b) {
|
||||
return SEVERITY_ORDER.indexOf(a) >= SEVERITY_ORDER.indexOf(b) ? a : b;
|
||||
}
|
||||
|
||||
export async function checkStatus() {
|
||||
const res = await fetch(INCIDENTS_URL);
|
||||
|
||||
if (!res.ok) {
|
||||
throw new Error(`Google Workspace status request failed (${res.status})`);
|
||||
}
|
||||
|
||||
const incidents = await res.json();
|
||||
|
||||
// Active incidents have no end timestamp
|
||||
const active = incidents.filter((i) => !i.end);
|
||||
|
||||
if (active.length === 0) {
|
||||
return {
|
||||
name,
|
||||
status: "operational",
|
||||
message: "All services operating normally.",
|
||||
lastUpdated: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
let overall = "operational";
|
||||
const descriptions = [];
|
||||
|
||||
for (const incident of active) {
|
||||
const mapped = STATUS_MAP[incident.status_impact] ?? "degraded";
|
||||
overall = worstStatus(overall, mapped);
|
||||
|
||||
const services = (incident.affected_products ?? [])
|
||||
.map((p) => p.title)
|
||||
.join(", ");
|
||||
const label = services || incident.service_name || "Unknown service";
|
||||
const impact = IMPACT_LABEL[incident.status_impact] ?? "incident";
|
||||
descriptions.push(`${label}: ${impact}`);
|
||||
}
|
||||
|
||||
return {
|
||||
name,
|
||||
status: "operational",
|
||||
message: "All services running normally.",
|
||||
status: overall,
|
||||
message: descriptions.join(" | "),
|
||||
lastUpdated: new Date().toISOString(),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user