Some checks failed
AI automation / Route event (push) Has been cancelled
AI automation / Hand reopened issue to maintainers (push) Has been cancelled
AI automation / Clean source issue state (push) Has been cancelled
AI automation / Reconcile handoffs (push) Has been cancelled
AI automation / Classify issue (push) Has been cancelled
AI automation / Claude Code smoke (push) Has been cancelled
AI automation / Review issue follow-up (push) Has been cancelled
AI automation / Publish issue follow-up (push) Has been cancelled
AI automation / Implement with Claude Code (push) Has been cancelled
AI automation / Publish implement PR (push) Has been cancelled
AI automation / Continue queued issue comments (push) Has been cancelled
AI automation / Codex review loop (push) Has been cancelled
AI automation / Publish Codex fix (push) Has been cancelled
AI automation / Clear Codex dispatch marker (push) Has been cancelled
AI automation / Own PR re-request Codex (push) Has been cancelled
AI automation / External PR re-request Codex (push) Has been cancelled
AI automation / Poll Codex reaction / retry (push) Has been cancelled
- 8 new store modules + matcher + initialResponse + aggregation + remediation + AlertStateMonitor + planGenerator - alert chain auto-integrated after runInspection: freeze snapshot + generate response + real-time agg + auto-start monitor - AlertAIPanel component + MonitoringDetailPanel expandable alert list - PlanManagementPage: full page with list/edit/AI generate/templates/commands
160 lines
9.1 KiB
JavaScript
160 lines
9.1 KiB
JavaScript
"use strict";
|
||
|
||
/**
|
||
* 预置命令 ID 目录(D4:白名单方式为主)
|
||
*
|
||
* 结构:
|
||
* {
|
||
* id: "switch_show_cpu",
|
||
* name: "显示 CPU 使用率",
|
||
* command: "display cpu-usage",
|
||
* device_types: ["huawei_h3c_switch", "cisco_switch"],
|
||
* risk_level: "low", // low | medium | high
|
||
* execution: "auto" | "confirm" | "manual_only",
|
||
* category: "diagnostic", // diagnostic | config | security | backup | recovery
|
||
* description: "...",
|
||
* }
|
||
*/
|
||
|
||
const { STORAGE_KEY_COMMAND_CATALOG } = require("./storageKeys.cjs");
|
||
|
||
let _catalog = null;
|
||
|
||
function _ensureLoaded(readFn) {
|
||
if (_catalog === null) {
|
||
const raw = readFn(STORAGE_KEY_COMMAND_CATALOG);
|
||
_catalog = raw ? _safeParse(raw, []) : _getDefaultCatalog();
|
||
}
|
||
}
|
||
|
||
function _safeParse(text, def) {
|
||
if (text === null || text === undefined) return def;
|
||
if (typeof text === "object") return text;
|
||
try { return JSON.parse(text); }
|
||
catch { return def; }
|
||
}
|
||
|
||
function _save(writeFn) {
|
||
writeFn(STORAGE_KEY_COMMAND_CATALOG, JSON.stringify(_catalog));
|
||
}
|
||
|
||
function _getDefaultCatalog() {
|
||
const now = Date.now();
|
||
return [
|
||
// ========== 通用诊断命令(auto)==========
|
||
{ id: "linux_show_cpu", name: "查看 CPU 使用率", command: "top -bn1 | head -20", device_types: ["linux", "windows"], risk_level: "low", execution: "auto", category: "diagnostic", description: "一次性显示 CPU 负载", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "linux_show_mem", name: "查看内存使用率", command: "free -m", device_types: ["linux"], risk_level: "low", execution: "auto", category: "diagnostic", description: "查看内存使用情况", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "linux_show_disk", name: "查看磁盘使用率", command: "df -h", device_types: ["linux"], risk_level: "low", execution: "auto", category: "diagnostic", description: "查看各挂载点磁盘使用率", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "linux_show_processes", name: "查看进程列表", command: "ps aux --sort=-%cpu | head -20", device_types: ["linux"], risk_level: "low", execution: "auto", category: "diagnostic", description: "按 CPU 排序显示前 20 条进程", builtin: true, created_at: now, updated_at: now },
|
||
|
||
// ========== 华为/H3C 交换机(auto)==========
|
||
{ id: "switch_show_cpu", name: "显示 CPU 使用率", command: "display cpu-usage", device_types: ["huawei_h3c_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示 CPU 使用率明细", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_show_mem", name: "显示内存使用率", command: "display memory", device_types: ["huawei_h3c_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示内存使用情况", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_show_temp", name: "显示温度", command: "display temperature", device_types: ["huawei_h3c_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示各传感器温度", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_show_device", name: "显示设备信息", command: "display device", device_types: ["huawei_h3c_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示电源、风扇、板卡状态", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_show_version", name: "显示版本信息", command: "display version", device_types: ["huawei_h3c_switch", "cisco_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示软件版本、硬件型号", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_show_power", name: "显示电源状态", command: "display power", device_types: ["huawei_h3c_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示各电源模块状态", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_show_fan", name: "显示风扇状态", command: "display fan", device_types: ["huawei_h3c_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示各风扇模块状态", builtin: true, created_at: now, updated_at: now },
|
||
|
||
// ========== 华为/H3C 交换机(confirm)==========
|
||
{ id: "switch_collect_diagnostic", name: "采集诊断信息", command: "display diagnostic-information save", device_types: ["huawei_h3c_switch"], risk_level: "medium", execution: "confirm", category: "backup", description: "采集完整诊断信息并保存到设备存储", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_backup_config", name: "备份 running-config", command: "display current-configuration", device_types: ["huawei_h3c_switch", "cisco_switch"], risk_level: "medium", execution: "confirm", category: "backup", description: "导出当前运行配置", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "switch_adjust_cpu_threshold", name: "调整 CPU 告警阈值", command: "cpu-usage threshold 95 log", device_types: ["huawei_h3c_switch"], risk_level: "medium", execution: "confirm", category: "config", description: "调 CPU 告警阈值避免重复告警", builtin: true, created_at: now, updated_at: now },
|
||
|
||
// ========== Cisco 交换机(auto)==========
|
||
{ id: "cisco_show_cpu", name: "显示 CPU 使用率", command: "show processes cpu sorted", device_types: ["cisco_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "按 CPU 使用率排序显示进程", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "cisco_show_mem", name: "显示内存使用率", command: "show memory summary", device_types: ["cisco_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示内存使用摘要", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "cisco_show_interfaces", name: "显示接口状态", command: "show interfaces brief", device_types: ["cisco_switch"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示所有接口简要状态", builtin: true, created_at: now, updated_at: now },
|
||
|
||
// ========== 防火墙(auto)==========
|
||
{ id: "fw_show_version", name: "显示版本信息", command: "display version", device_types: ["huawei_firewall", "fortinet_firewall"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示防火墙软件版本", builtin: true, created_at: now, updated_at: now },
|
||
{ id: "fw_show_temp", name: "显示温度", command: "display temperature all", device_types: ["huawei_firewall"], risk_level: "low", execution: "auto", category: "diagnostic", description: "显示防火墙各传感器温度", builtin: true, created_at: now, updated_at: now },
|
||
];
|
||
}
|
||
|
||
// ---------- CRUD ----------
|
||
|
||
function listCommands(readFn, filters = {}) {
|
||
_ensureLoaded(readFn);
|
||
let result = [..._catalog];
|
||
if (filters.device_type) {
|
||
result = result.filter((c) => c.device_types.includes(filters.device_type));
|
||
}
|
||
if (filters.execution) {
|
||
result = result.filter((c) => c.execution === filters.execution);
|
||
}
|
||
if (filters.risk_level) {
|
||
result = result.filter((c) => c.risk_level === filters.risk_level);
|
||
}
|
||
return result;
|
||
}
|
||
|
||
function getCommand(readFn, commandId) {
|
||
_ensureLoaded(readFn);
|
||
return _catalog.find((c) => c.id === commandId) || null;
|
||
}
|
||
|
||
function createCommand(readFn, writeFn, data) {
|
||
_ensureLoaded(readFn);
|
||
const cmd = {
|
||
id: data.id || `cmd_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`,
|
||
name: data.name,
|
||
command: data.command,
|
||
device_types: data.device_types || [],
|
||
risk_level: data.risk_level || "low",
|
||
execution: data.execution || "auto",
|
||
category: data.category || "diagnostic",
|
||
description: data.description || "",
|
||
builtin: false,
|
||
created_at: Date.now(),
|
||
updated_at: Date.now(),
|
||
};
|
||
_catalog.push(cmd);
|
||
_save(writeFn);
|
||
return { ...cmd };
|
||
}
|
||
|
||
function updateCommand(readFn, writeFn, commandId, updates) {
|
||
_ensureLoaded(readFn);
|
||
const idx = _catalog.findIndex((c) => c.id === commandId);
|
||
if (idx === -1) return null;
|
||
_catalog[idx] = { ..._catalog[idx], ...updates, updated_at: Date.now() };
|
||
_save(writeFn);
|
||
return { ..._catalog[idx] };
|
||
}
|
||
|
||
function deleteCommand(readFn, writeFn, commandId) {
|
||
_ensureLoaded(readFn);
|
||
const idx = _catalog.findIndex((c) => c.id === commandId);
|
||
if (idx === -1) return false;
|
||
if (_catalog[idx].builtin) return false; // 预置命令不可删
|
||
_catalog.splice(idx, 1);
|
||
_save(writeFn);
|
||
return true;
|
||
}
|
||
|
||
/**
|
||
* 批量校验 command_id 是否在目录中(D14:AI 生成预案交叉校验)
|
||
*/
|
||
function validateCommandIds(readFn, ids) {
|
||
_ensureLoaded(readFn);
|
||
if (!Array.isArray(ids)) return { valid: true, invalid: [] };
|
||
const invalid = [];
|
||
for (const id of ids) {
|
||
if (!_catalog.find((c) => c.id === id)) invalid.push(id);
|
||
}
|
||
return { valid: invalid.length === 0, invalid };
|
||
}
|
||
|
||
function _resetForTest() { _catalog = null; }
|
||
|
||
module.exports = {
|
||
listCommands,
|
||
getCommand,
|
||
createCommand,
|
||
updateCommand,
|
||
deleteCommand,
|
||
validateCommandIds,
|
||
_resetForTest,
|
||
};
|