"use strict"; /** * 设备扩展数据存储(巡检相关配置) * * 关联 NetMesh 的主机数据,扩展巡检相关字段: * - 设备类型(catalog_id) * - 设备层级(core/aggregation/access) * - 巡检周期 * - 启用状态 * - 自定义告警阈值 * - 上次巡检信息 * * 周期优先级(从高到低): * 1. 设备独立设置 inspection_interval * 2. 设备层级的默认周期 DEVICE_TIER_DEFAULT_INTERVAL * 3. 系统默认周期 SYS_CONFIG_DEFAULTS.inspection_default_interval */ const { STORAGE_KEY_DEVICE_EXTENSION, STORAGE_KEY_SYS_CONFIG, } = require("./storageKeys.cjs"); const { DEVICE_TIERS, DEVICE_TIER_LABELS, DEVICE_TIER_DEFAULT_INTERVAL, SYS_CONFIG_DEFAULTS, } = require("./types.cjs"); const { getPresetCatalog } = require("./deviceCatalogStore.cjs"); // ---------- 内存缓存 ---------- let _extensions = null; // { [hostId]: { ... } } let _sysConfig = null; // { inspection_default_interval: 5, ... } let _catalog = null; // 设备类型列表 /** * 从存储加载数据(首次调用时加载,之后用缓存) * @param {function} readFn - 读取函数 (key) => rawString */ function _ensureLoaded(readFn) { if (_extensions === null) { const raw = readFn(STORAGE_KEY_DEVICE_EXTENSION); _extensions = raw ? _safeParse(raw, {}) : {}; } if (_sysConfig === null) { const raw = readFn(STORAGE_KEY_SYS_CONFIG); _sysConfig = raw ? _safeParse(raw, {}) : { ...SYS_CONFIG_DEFAULTS }; // 合并默认值 for (const k of Object.keys(SYS_CONFIG_DEFAULTS)) { if (_sysConfig[k] === undefined) _sysConfig[k] = SYS_CONFIG_DEFAULTS[k]; } } if (_catalog === null) { _catalog = getPresetCatalog(); } } function _safeParse(text, def) { if (text === null || text === undefined) return def; // 已经是对象/数组 → 直接返回 if (typeof text === "object") return text; if (typeof text !== "string") return def; let parsed; try { parsed = JSON.parse(text); } catch (e) { return def; } // 防御二次/三次 stringify:inspectionStorage.writeStorage 先 JSON.stringify 一次, // _save 又 JSON.stringify 一次 → 文件里值是 "\"{...}\"" 这种嵌套字符串 // 连续 parse 直到拿到真正的对象/数组(最多 3 层避免死循环) let depth = 0; while (typeof parsed === "string" && parsed.length > 0 && depth < 3) { let next; try { next = JSON.parse(parsed); } catch { break; } if (typeof next === "string" && next === parsed) break; parsed = next; depth++; } return (parsed !== null && typeof parsed === "object") ? parsed : def; } function _save(writeFn, key, data) { writeFn(key, JSON.stringify(data)); } // ---------- 系统配置 ---------- /** * 获取系统配置 */ function getSysConfig(readFn) { _ensureLoaded(readFn); return { ..._sysConfig }; } /** * 更新系统配置 */ function updateSysConfig(readFn, writeFn, updates) { _ensureLoaded(readFn); _sysConfig = { ..._sysConfig, ...updates }; _save(writeFn, STORAGE_KEY_SYS_CONFIG, _sysConfig); return { ..._sysConfig }; } // ---------- 设备扩展 ---------- /** * 获取所有设备扩展配置 */ function getAllExtensions(readFn) { _ensureLoaded(readFn); return { ..._extensions }; } /** * 获取单个设备的扩展配置 */ function getExtension(readFn, hostId) { _ensureLoaded(readFn); return _extensions[hostId] || null; } /** * 创建/更新设备扩展配置 * @param {string} hostId - NetMesh 主机 ID * @param {object} data - 扩展配置 * @param {string} data.catalog_id - 设备类型 ID * @param {string} [data.tier] - 设备层级 core/aggregation/access * @param {number} [data.inspection_interval] - 巡检周期(分钟),null 表示继承 * @param {boolean} [data.inspection_enabled] - 是否启用巡检 * @param {object} [data.custom_thresholds] - 自定义告警阈值 * @param {string[]} [data.inspection_tags] - 巡检标签 * @param {string} [data.hostname] - 主机名(IP 或域名),用于调度器关联 vault host SSH 配置 */ function upsertExtension(readFn, writeFn, hostId, data) { _ensureLoaded(readFn); const existing = _extensions[hostId] || { host_id: hostId, hostname: null, catalog_id: "", tier: null, inspection_interval: null, inspection_enabled: false, custom_thresholds: [], inspection_tags: [], last_scan_at: null, last_scan_status: null, last_scan_error: null, }; _extensions[hostId] = { ...existing, ...data, updated_at: Date.now(), }; _save(writeFn, STORAGE_KEY_DEVICE_EXTENSION, _extensions); return { ..._extensions[hostId] }; } /** * 删除设备扩展配置 */ function deleteExtension(readFn, writeFn, hostId) { _ensureLoaded(readFn); if (_extensions[hostId]) { delete _extensions[hostId]; _save(writeFn, STORAGE_KEY_DEVICE_EXTENSION, _extensions); return true; } return false; } /** * 计算设备的实际巡检周期(考虑三级继承) * @param {string} hostId * @returns {number} 周期(分钟) */ function getEffectiveInterval(readFn, hostId) { _ensureLoaded(readFn); const ext = _extensions[hostId]; if (!ext) return _sysConfig.inspection_default_interval; // 1. 设备独立设置 if (typeof ext.inspection_interval === "number" && ext.inspection_interval > 0) { return ext.inspection_interval; } // 2. 设备层级默认 if (ext.tier && DEVICE_TIER_DEFAULT_INTERVAL[ext.tier]) { return DEVICE_TIER_DEFAULT_INTERVAL[ext.tier]; } // 3. 系统默认 return _sysConfig.inspection_default_interval; } /** * 获取所有启用了巡检的设备列表(带有效周期) */ function getEnabledDevices(readFn) { _ensureLoaded(readFn); const result = []; for (const hostId of Object.keys(_extensions)) { const ext = _extensions[hostId]; if (ext.inspection_enabled) { result.push({ ...ext, effective_interval: getEffectiveInterval(readFn, hostId), }); } } return result; } /** * 更新上次巡检信息 */ function updateLastScan(readFn, writeFn, hostId, status, error = null) { _ensureLoaded(readFn); if (!_extensions[hostId]) return false; _extensions[hostId].last_scan_at = Date.now(); _extensions[hostId].last_scan_status = status; _extensions[hostId].last_scan_error = error; _save(writeFn, STORAGE_KEY_DEVICE_EXTENSION, _extensions); return true; } // ---------- 设备类型 ---------- /** * 获取设备类型列表 */ function getCatalog() { if (_catalog === null) { _catalog = getPresetCatalog(); } return [..._catalog]; } /** * 根据 ID 获取设备类型 */ function getCatalogById(catalogId) { const list = getCatalog(); return list.find((c) => c.id === catalogId) || null; } // ---------- 设备层级 ---------- /** * 获取设备层级列表(带中文名称和默认周期) */ function getTiers() { return [ { key: DEVICE_TIERS.CORE, label: DEVICE_TIER_LABELS.core, default_interval: DEVICE_TIER_DEFAULT_INTERVAL.core }, { key: DEVICE_TIERS.AGGREGATION, label: DEVICE_TIER_LABELS.aggregation, default_interval: DEVICE_TIER_DEFAULT_INTERVAL.aggregation }, { key: DEVICE_TIERS.ACCESS, label: DEVICE_TIER_LABELS.access, default_interval: DEVICE_TIER_DEFAULT_INTERVAL.access }, ]; } // ---------- 重置(测试用) ---------- function _resetForTest() { _extensions = null; _sysConfig = null; _catalog = null; } module.exports = { // 系统配置 getSysConfig, updateSysConfig, // 设备扩展 getAllExtensions, getExtension, upsertExtension, deleteExtension, getEffectiveInterval, getEnabledDevices, updateLastScan, // 设备类型 getCatalog, getCatalogById, // 设备层级 getTiers, // 内部 _resetForTest, };