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>
90 lines
2.5 KiB
JavaScript
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,
|
|
};
|
|
},
|
|
};
|