collabSupport/services/voiceDiag/checks/wan/wanAlarms.js
jmcqueen b802383441 Add Prisma SD-WAN voice-quality enrichment for /phonestatus + /voicediag
Introduces a full Palo Alto Prisma SD-WAN integration (dual-mode SASE
OAuth 2.0 / legacy CloudGenix auth, pagination, 429 backoff, session
priming) that surfaces per-path latency/jitter/loss/MOS, site
healthscore, link state, and alarm data for a store. Wired into the
/phonestatus WAN follow-up and eight new /voicediag WAN checks graded
against ITU-T G.114 / RFC 3550 defaults (env-overridable via
WAN_STANDARD_*).

Also adds a shape-aware detail renderer for /voicediag (per-link
tables with verdict icons instead of a stringified JSON dump) and a
--window flag (15m / 1h / 6h / 24h / 1d, env default via
WAN_STANDARD_WINDOW_MINUTES) so operators can widen the look-back
without redeploying. scripts/prismaProbe.js is bundled as a CLI for
schema iteration against a live tenant.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-09 09:45:29 -04:00

90 lines
2.5 KiB
JavaScript

// src/services/voiceDiag/checks/wan/wanAlarms.js
//
// Recent Prisma alarms surface. Not a threshold check — the
// severity is a direct pass-through of what Prisma raised:
//
// - critical → error
// - major → warn
// - minor → info-only (stays 'ok', but details show the count)
//
// Window defaults to the composer's 1-hour lookback. An "active
// incident" that Prisma sees is materially more urgent than a
// snapshot LQM anomaly, so this deliberately runs even when the
// per-metric checks are all green — a critical alarm from 45 min
// ago is still the operator's problem.
import { maybeSkippedByKillSwitch } from './_helpers.js';
export const WAN_ALARMS_STANDARDS = Object.freeze({
criticalAllowed: 0,
majorAllowed: 0,
});
export const wanAlarmsCheck = {
id: 'wanAlarms',
label: 'SD-WAN Alarms (last 1h)',
requires: ['sdwanSite'],
scope: null,
standards: WAN_ALARMS_STANDARDS,
async run(ctx) {
const skip = maybeSkippedByKillSwitch(wanAlarmsCheck);
if (skip) return skip;
const alarms = ctx.sdwanData?.alarms;
if (!alarms) {
return {
status: 'skipped',
message: 'Alarms feed not available from Prisma (partial fetch).',
details: null,
remediation: null,
};
}
const { critical = 0, major = 0, minor = 0 } = alarms.last1h || {};
const samples = Array.isArray(alarms.samples) ? alarms.samples : [];
const details = {
critical, major, minor,
recentSamples: samples.slice(0, 3),
};
if (critical > 0) {
return {
status: 'error',
message:
`${critical} critical alarm${critical === 1 ? '' : 's'} raised in the last hour` +
(samples[0]?.message ? ` — most recent: ${samples[0].code}: ${samples[0].message}` : '.'),
details,
remediation: null,
};
}
if (major > 0) {
return {
status: 'warn',
message:
`${major} major alarm${major === 1 ? '' : 's'} raised in the last hour` +
(samples[0]?.message ? ` — most recent: ${samples[0].code}: ${samples[0].message}` : '.'),
details,
remediation: null,
};
}
if (minor > 0) {
return {
status: 'ok',
message: `${minor} minor alarm${minor === 1 ? '' : 's'} in the last hour, no critical or major.`,
details,
remediation: null,
};
}
return {
status: 'ok',
message: 'No alarms raised in the last hour.',
details,
remediation: null,
};
},
};