// src/services/voiceDiag/checks/port/portPoe.js // // Store phone standard: PoE enabled on every wired-phone switchport. // Store desk phones + DECT basestations are all PoE-powered; PoE // off on the port is either a mis-provisioned port or a phone that // won't come up after the next power cycle. // // Skip rules: // - Wireless: skipped. // - Trunk uplink: skipped (portType check owns that warning; PoE // policy for a downstream Cisco switch isn't ours to evaluate). // - No poeEnabled field at all (Meraki didn't return it or the // switch model doesn't do PoE): reported as unknown. import { collectPortDevices, isWireless, portLabelFor, maybeSkippedByKillSwitch } from './_helpers.js'; export const PORT_POE_STANDARDS = Object.freeze({ poeEnabled: true, }); export const portPoeCheck = { id: 'portPoe', label: 'Switchport PoE', requires: ['phoneStatus'], scope: null, standards: PORT_POE_STANDARDS, async run(ctx) { const skip = maybeSkippedByKillSwitch(portPoeCheck); if (skip) return skip; const devices = collectPortDevices(ctx.phoneStatus); if (devices.length === 0) { return { status: 'skipped', message: 'No wired devices with Meraki port data to inspect.', details: null, remediation: null, }; } const perDevice = devices.map((d) => { if (isWireless(d)) { return { ...portLabelFor(d), poeEnabled: null, verdict: 'wireless' }; } const portType = d.meraki?.portType; if (portType && String(portType).toLowerCase() === 'trunk') { return { ...portLabelFor(d), poeEnabled: null, verdict: 'trunk-skip' }; } const poe = d.meraki?.poeEnabled; if (poe === undefined || poe === null) { return { ...portLabelFor(d), poeEnabled: null, verdict: 'unknown' }; } return { ...portLabelFor(d), poeEnabled: !!poe, verdict: poe ? 'compliant' : 'off' }; }); const off = perDevice.filter((r) => r.verdict === 'off'); const unknown = perDevice.filter((r) => r.verdict === 'unknown'); const details = { total: perDevice.length, compliant: perDevice.filter((r) => r.verdict === 'compliant').length, off: off.length, unknown: unknown.length, wireless: perDevice.filter((r) => r.verdict === 'wireless').length, trunkSkipped: perDevice.filter((r) => r.verdict === 'trunk-skip').length, offenders: off, }; if (off.length > 0) { return { status: 'warn', message: `${off.length} device(s) on switchports with PoE DISABLED: ` + off.map((r) => `${r.deviceLabel}@${r.portLabel}`).join(', '), details, remediation: null, }; } if (unknown.length > 0) { return { status: 'warn', message: `${unknown.length} device(s) have no PoE info from Meraki.`, details, remediation: null, }; } return { status: 'ok', message: `All ${details.compliant} wired device(s) on PoE-enabled ports.`, details, remediation: null, }; }, };