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>
77 lines
2.5 KiB
JavaScript
77 lines
2.5 KiB
JavaScript
// src/services/voiceDiag/checks/wan/wanHealthscore.js
|
|
//
|
|
// Prisma AIOps site healthscore (0-100, higher is better). This is
|
|
// Prisma's own composite score that rolls up per-path LQM, link
|
|
// availability, application health, and device health — so it's a
|
|
// good broad-brush signal for "is anything wrong on this site"
|
|
// before drilling into the individual per-path checks below.
|
|
//
|
|
// Thresholds default to 80 (warn) / 60 (error), reflecting the
|
|
// bands Prisma's own UI uses in its site-health dashboard. Both
|
|
// are overridable via WAN_STANDARD_HEALTHSCORE_WARN / _ERROR.
|
|
//
|
|
// Skipped when no site was matched OR when the healthscore fetch
|
|
// failed (composer preserves that in ctx.sdwanData.errors[]).
|
|
|
|
import {
|
|
maybeSkippedByKillSwitch,
|
|
getHealthscoreWarn,
|
|
getHealthscoreError,
|
|
} from './_helpers.js';
|
|
|
|
export const WAN_HEALTHSCORE_STANDARDS = Object.freeze({
|
|
minWarn: 80,
|
|
minError: 60,
|
|
});
|
|
|
|
export const wanHealthscoreCheck = {
|
|
id: 'wanHealthscore',
|
|
label: 'SD-WAN Site Healthscore',
|
|
requires: ['sdwanSite'],
|
|
scope: null,
|
|
standards: WAN_HEALTHSCORE_STANDARDS,
|
|
|
|
async run(ctx) {
|
|
const skip = maybeSkippedByKillSwitch(wanHealthscoreCheck);
|
|
if (skip) return skip;
|
|
|
|
const hs = ctx.sdwanData?.healthscore;
|
|
if (!hs || hs.value === null || hs.value === undefined) {
|
|
return {
|
|
status: 'skipped',
|
|
message: 'Healthscore not available from Prisma (likely a partial fetch — see other checks).',
|
|
details: null,
|
|
remediation: null,
|
|
};
|
|
}
|
|
|
|
const value = Number(hs.value);
|
|
const warnThresh = getHealthscoreWarn();
|
|
const errorThresh = getHealthscoreError();
|
|
|
|
if (value < errorThresh) {
|
|
return {
|
|
status: 'error',
|
|
message: `Healthscore ${value}/100 is below the error floor (${errorThresh}). The site is in a degraded state per Prisma AIOps.`,
|
|
details: { value, warnThresh, errorThresh, breakdown: hs.breakdown || {} },
|
|
remediation: null,
|
|
};
|
|
}
|
|
|
|
if (value < warnThresh) {
|
|
return {
|
|
status: 'warn',
|
|
message: `Healthscore ${value}/100 is below the warning threshold (${warnThresh}). Investigate before it becomes user-visible.`,
|
|
details: { value, warnThresh, errorThresh, breakdown: hs.breakdown || {} },
|
|
remediation: null,
|
|
};
|
|
}
|
|
|
|
return {
|
|
status: 'ok',
|
|
message: `Healthscore ${value}/100 (>=${warnThresh}). Site is healthy per Prisma AIOps.`,
|
|
details: { value, warnThresh, errorThresh, breakdown: hs.breakdown || {} },
|
|
remediation: null,
|
|
};
|
|
},
|
|
};
|