feat(plan-management): implement alert-remediation-plan system v1.3
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
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
This commit is contained in:
159
electron/bridges/inspection/commandCatalogStore.cjs
Normal file
159
electron/bridges/inspection/commandCatalogStore.cjs
Normal file
@@ -0,0 +1,159 @@
|
||||
"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,
|
||||
};
|
||||
Reference in New Issue
Block a user