logo
0
1
WeChat Login

AIOps 智能运维平台

一套面向运维场景的全栈平台:SvelteKit 5 前端 + TypeScript 后端(Fastify)

你可以把它理解为一条清晰的数据链路:

用户(Web)→ 鉴权(JWT + Refresh)→ RBAC 权限校验 → 聊天(可选 SSH 执行)→ 审计落库。


🚀 快速开始(开发)

环境要求

  • Node.js 16+

说明:仓库已迁移为 TypeScript 后端,不再需要 Python/FastAPI。

1) 安装依赖

在仓库根目录执行一次:

npm install

2) 启动前端(SvelteKit)

npm run dev

前端开发地址:

3) 启动后端(TypeScript / Fastify)

建议直接同时启动前后端(开发体验最好):

npm run dev:all

也可以只启动后端:

npm run dev:server

服务启动后访问:

Windows / PowerShell 说明:

  • PowerShell 里 curl 通常是 Invoke-WebRequest 的别名,建议使用:Invoke-RestMethod http://127.0.0.1:8000/health
  • 如需把后端以“后台进程 + 自动健康检查”的方式启动,可使用:scripts/dev_server_bg.ps1(可配端口)

说明:TypeScript 后端暂不提供 Swagger(后续可按需补充 OpenAPI)。


🧾 更新记录(性能优化)

(更新时间:2025-12-14)

  • Dev 同源代理:Vite proxy /api/*http://localhost:8000,减少/消除跨域 OPTIONS
  • /api/auth/me:前端 auth.loadMe() TTL 缓存(300s)+ in-flight 合并;后端增加 Cache-Control: private, max-age=300
  • 角色/权限/用户列表:全局 store 缓存 + in-flight 合并(roles / permissions / users)
  • 管理员主机/模型:首屏只拉列表;弹窗懒加载 users/roles;access 内存缓存(保存后失效)
  • /api/admin/users:后端分页性能优化(只查询“本页用户”的角色关联,避免全表扫描)
  • 首页 /api/dashboard/summary:前端 in-flight 合并;后端短缓存 max-age=8
  • 智能运维:sessions/messages 请求 in-flight 合并与 messages 按会话缓存(不涉及 send)
  • Dev 环境:修复动态 import 404(Vite server.fs.allow)并补齐 @types/node

(更新时间:2025-12-23)

  • 智能运维聊天:新增 SSE 流式执行POST /api/chat/stream),支持逐步推送命令与输出
  • 智能运维聊天:支持 消息级主机识别(不再强制“会话绑定主机”)
  • 智能运维聊天:增加 可选命令审批/api/chat/approval/approve|reject,由环境变量控制)
  • 隐私收敛:模型侧不下发完整主机列表/IP,仅提供必要的主机元信息用于命令选择

(更新时间:2025-12-24)

  • 聊天 UI:修复“用户刚发的消息气泡不出现/被覆盖”的并发问题(乐观插入 + 防覆盖兜底)
  • 聊天 UI:assistant 处于 loading 时,若已收到流式内容则立即渲染(不再只显示转圈)
  • 聊天 UI:输入框上方“跳到底部”按钮可正常点击(输入区 ↔ 按钮移动不再瞬间消失)
  • 命令安全:新增关机/断电类命令 硬拒绝poweroff/halt/shutdown -h/systemctl poweroff),不进入确认流程

(更新时间:2025-12-31)

  • kubectl-qyai 远程 Agent:一键安装/重装流程简化(curl | bash + nohup ... &
  • kubectl-qyai 远程 Agent:新增“查看 Agent 日志”能力(包含安装日志与运行日志)
  • QYAI_AGENT_BASE_URL 可留空,默认按目标主机 IP 自动拼接 http://{ip}:{QYAI_AGENT_PORT}(支持 {ip} 占位符)
  • 修复 listen_port NOT NULL 相关的落库失败与 UPSERT 字段覆盖问题

待办:

  • 为更多只读接口补充 ETag/Last-Modified(可选)
  • /api/admin/users 等列表接口补充 Cache-Control(可选,注意按登录态 Vary: Authorization

✅ 功能概览

  • 主机资产管理:增删改查、SSH 测试、状态轮询
  • 模型管理:OpenAI-Compatible 接口配置与测试
  • 聊天:会话/消息持久化;会话可绑定模型;主机按每条消息识别(无需绑定会话主机)
  • 远程执行:支持通过聊天触发 SSH 执行并审计落库;支持 SSE 流式输出
  • 智能运维聊天:请求会转发到被管主机上的 kubectl-qyai agent-serve,由对端 Agent 负责工具调用与执行
  • 防误操作:高风险命令可进入“待确认”审批;部分命令(如关机/断电)为硬拒绝
  • 安全:注册/登录、JWT + Refresh(可吊销/轮换)、RBAC(角色/权限)、安全审计

🧭 项目导航(常用入口)

前端(SvelteKit)

  • Chat 页:src/routes/chat/+page.svelte
  • Hosts 页:src/routes/hosts/+page.svelte
  • Settings:src/routes/settings/
  • Stores:src/lib/stores/
  • HTTP client:src/lib/api/client.ts

后端(TypeScript / Fastify)

  • 入口:server/src/index.ts
  • DB:server/src/db.ts
  • 路由模块:server/src/routes_*.ts
  • SSH:server/src/ssh.ts
  • LLM Client:server/src/llm_client.ts

🔐 默认账号与密码规则

默认账号

  • 管理员账号:admin
  • 管理员密码:123456

当你使用 MySQL 初始化脚本 mysql_init.sql 时,会自动写入该管理员与 RBAC 初始化数据。

提示:生产环境务必修改密码,并更新根目录 .env 中的 SECRET_KEY / JWT_SECRET 等安全配置。

密码规则(当前实现)

  • 注册(/register):强密码校验(至少 8 位、必须同时包含字母与数字、仅允许 A-Z a-z 0-9 _)。
  • 管理端创建用户 / 重置密码:目前只做“非空 + 长度限制”的弱校验(主要为了兼容演示环境默认密码 123456 与历史数据)。

如果你希望“管理端创建/重置”也强制使用同样的强密码规则,请在后端统一改为调用强校验函数(见 server/src/routes_admin.ts 中相关注释与校验函数),并同步前端提示文案。


🗄️ 数据库与环境变量

MySQL(唯一支持)

当前 TypeScript 后端仅支持 MySQL(不再提供 SQLite 模式)。

  1. 在根目录 .env 中填写:
  • MYSQL_HOST / MYSQL_PORT / MYSQL_USER / MYSQL_PASSWORD / MYSQL_DATABASE

建议:仓库提供 .env.example,请复制一份为 .env 再启动(避免把本地环境变量提交到仓库)。

  1. 初始化方式:
  • 项目不会在代码里自动建表,也不会自动执行 mysql_init.sql
  • 当后端/前端检测到 MySQL 数据库或核心表缺失时,会通过 GET /api/system/status 返回 needs_init=true,前端会弹窗提示你导入项目根目录的 mysql_init.sql
  1. 常见坑(root 用户“为什么不行”):
  • MySQL 用户是按 user@host 区分的。很多环境只有 root@localhost,你如果配置 MYSQL_HOST=127.0.0.1,可能会被视为 root@127.0.0.1 从而拒绝登录。
    • 优先尝试把 MYSQL_HOST 改为 localhost
    • 或在 MySQL 里显式创建/授权 root@127.0.0.1 / root@%(不建议生产这么做)
  • 更推荐创建专用账号(例如 aiops)并仅授予目标库权限。

排查建议:直接访问 GET /api/system/status?force=true 查看 db.error / db.hint.reason


智能运维聊天:对端 Agent 转发(重要)

当前聊天能力不在 AIOps 内部执行 SSH 命令。

  • AIOps 只负责:RBAC 鉴权 + 选择目标主机(can_manage=1)+ 转发请求 到被管主机上的 kubectl-qyai agent-serve
  • 审批/策略/审计等能力应由对端 Agent 或外围系统负责。

📚 常用 API 概览(按模块)

说明:TypeScript 后端目前不提供 Swagger;字段定义以本文档与前端调用(src/lib/api/client.ts + stores)为准。

Auth(/api/auth)

方法端点描述
POST/api/auth/register注册
POST/api/auth/login登录
POST/api/auth/refresh刷新 Access Token
POST/api/auth/logout登出(刷新令牌可吊销/轮换)
GET/api/auth/me获取当前用户信息

Hosts(/api/hosts)

方法端点描述
GET/api/hosts获取主机列表
GET/api/hosts/status获取主机状态(轮询)
GET/api/hosts/{host_id}获取主机详情
POST/api/hosts创建新主机
PUT/api/hosts/{host_id}更新主机信息
DELETE/api/hosts/{host_id}删除主机
POST/api/hosts/{host_id}/test测试 SSH 连接

Models(/api/models)

方法端点描述
GET/api/models获取模型列表
POST/api/models创建模型配置(OpenAI-Compatible)
PUT/api/models/{model_id}更新模型配置
DELETE/api/models/{model_id}删除模型配置
POST/api/models/{model_id}/test测试连通性与鉴权

Chat(/api/chat)

方法端点描述
GET/api/chat/sessions获取会话列表
POST/api/chat/sessions创建会话
GET/api/chat/sessions/{session_id}获取会话详情
PUT/api/chat/sessions/{session_id}更新会话
DELETE/api/chat/sessions/{session_id}删除会话
GET/api/chat/sessions/{session_id}/messages获取会话消息
POST/api/chat/send发送消息(会话 + 模型路由 + 写库)
POST/api/chat/stream流式发送(SSE):逐步推送命令/输出并写库
POST/api/chat/approval/approve审批:确认继续执行(可选功能)
POST/api/chat/approval/reject审批:拒绝执行(可选功能)
GET/api/chat/admin/other-sessions?username=管理员:按用户名搜索“其他用户会话元数据”(仅定位,不返回消息内容)

Send API(推荐)示例:

POST /api/chat/send { "session_id": 2, "message": "ping" }

成功响应示例(字段可能因前端兼容而略有差异):

{ "session_id": 2, "user_message_id": 123, "assistant_message_id": 124, "assistant_content": "..." }

Stream API(SSE)说明:

  • POST /api/chat/stream
  • Header:Accept: text/event-stream
  • 返回为 text/event-stream,每帧为:data: {"type":...}\n\n
  • 典型事件序列:thinkingcommandoutputdone(中间会穿插 ping

Agent(/api/agent)

方法端点描述
POST/api/agent/install通过 SSH 在目标机安装/重装 kubectl-qyai 并启动 agent-serve(支持 force 重装)
POST/api/agent/apply-model下发模型环境变量(export)到目标机,并重启 agent-serve(可 auto/指定 model)
POST/api/agent/apply-path下发 KUBEQY_PATH(linux/kubernetes)并重启 agent-serve
GET/api/agent/status查询目标机 agent-serve 健康状态与存储状态(安装/健康/模型)
GET/api/agent/logs通过 SSH 拉取目标机 install.log / agent-serve.log 等诊断信息

Admin(/api/admin)

方法端点描述
GET/api/admin/permissions获取权限列表
GET/api/admin/roles获取角色列表
POST/api/admin/roles创建角色
PUT/api/admin/roles/{role_id}更新角色
GET/api/admin/roles/{role}/permissions获取角色权限
PUT/api/admin/roles/{role}/permissions设置角色权限
POST/api/admin/roles/bulk-delete批量删除角色
GET/api/admin/users获取用户列表(分页)
POST/api/admin/users创建用户
PUT/api/admin/users/{user_id}更新用户
PUT/api/admin/users/{user_id}/roles设置用户角色
POST/api/admin/users/bulk-delete批量删除用户
POST/api/admin/users/{user_id}/reset-password重置密码
GET/api/admin/hosts管理员:获取主机列表(分页)
GET/api/admin/hosts/{host_id}/access获取主机访问权限(users/roles)
POST/api/admin/hosts/{host_id}/access/sync同步主机访问权限(users/roles)
POST/api/admin/hosts/bulk-delete批量删除主机
GET/api/admin/models管理员:获取模型列表(分页)
GET/api/admin/models/{model_id}/access获取模型访问权限(users/roles)
POST/api/admin/models/{model_id}/access/sync同步模型访问权限(users/roles)
POST/api/admin/models/bulk-delete批量删除模型

🧪 使用指引(从 0 到可聊天)

  1. 登录(默认 admin/123456)
  2. 进入 Chat 页,配置模型(base_url / api_key / model_name)并测试
  3. 进入 Hosts 页,新增主机并测试 SSH
  4. 回到 Chat 页,新建会话并发送消息(建议消息中包含主机名/IP,或直接用 !<主机名|IP> <命令>

🛡️ 安全说明

本项目已移除“在 AIOps 内部通过 SSH 执行命令/命令审批/本地 allow/deny 策略”。

聊天能力仅负责:选择主机、鉴权、把请求转发到被管主机上的 kubectl-qyai agent-serve。 安全策略(如命令白名单/审批/审计)应由对端 Agent 或外围系统负责。

核心规则:

  • 校验顺序:deny_commandsdeny_patternsallow_*
  • 匹配方式:
    • allow_* / deny_commands:按 token 前缀匹配(例如 systemctl status 可匹配 systemctl status nginx --no-pager
    • deny_patterns:正则(对完整命令字符串匹配,忽略大小写)
  • 分层允许:
    • allow_commands:所有有该主机可见权限的用户可用(建议仅只读/探测)
    • allow_manage_commands:仅当用户对该主机具备 can_manage 或为 owner(或管理员)时允许
    • allow_admin_commands:仅管理员允许

提示:当 CHAT_EXEC_UNRESTRICTED=false 时,才会启用该 YAML 校验;修改后重启后端即可生效。

如果你在开发环境将 CHAT_EXEC_UNRESTRICTED=true,则会跳过策略校验(相当于直接给聊天开启远程 Shell,风险很高)。

YAML 注意事项(避免解析失败):

  • deny_patterns 使用的是 YAML 字符串 + 正则。
  • 建议优先使用 单引号 包裹正则(例如:'\\btail\\s+-n'),可以减少反斜杠转义的坑。
  • 如果使用 双引号,像 \s 这类反斜杠序列需要额外转义成 \\s,否则可能触发 YAML 解析错误。

🔒 聊天数据隔离

  • 会话(ChatSession)按 user_id 归属:任意用户(包括管理员)只能查看/删除自己创建的会话与消息。
  • 管理员仅有“定位能力”:可使用 /api/chat/admin/other-sessions?username= 搜索其他用户会话元数据(不返回消息内容,也不提供删除)。

✅ 运维指令示例(走真实执行 + 审计)

在 Chat 页面发送以下内容会触发真实 SSH 执行并写入审计(前提:开启 CHAT_EXEC_ENABLED=true 且你对目标主机有 can_manage 权限):

  • 直接执行(推荐,最稳定):

    • !主机A whoami
    • !<目标IP> uptime
    • 在 主机A 执行 !df -h(消息里包含主机名即可识别)
  • 自然语言 → 命令(需要会话绑定可用模型,或请求带 model_id):

    • 在 主机A 查看 /tmp 下有什么文件
    • 在 <目标IP> 查看 nginx 进程

当消息中无法识别目标主机时:系统会返回“需要你指定目标主机”,并给出你账号可执行主机的脱敏提示列表。

补充:简单问候(例如“你好/hi/hello”)不会触发“请选择主机”,而是作为普通对话处理。


🧯 安全护栏(强制规则)

以下规则用于防止误操作造成事故:

  • 关机/断电类命令硬拒绝poweroff / halt / shutdown -h ... / shutdown --poweroff / systemctl poweroff 等。
    • 说明:该类命令默认不允许执行(不进入审批确认),避免一句话导致主机直接下线。
  • 清空根目录/破坏系统的删除命令硬拒绝:例如 rm -rf /rm -rf /* 等(会直接拒绝)。
  • (已移除)本地“高风险命令二次确认”。

🌐 UI 文案与权限说明

权限代码与中文描述

权限代码中文描述
admin:manage_users用户与角色管理(创建 / 编辑 / 禁用用户与角色)
chat:use使用智能运维对话(命令执行 / 问答)
hosts:read查看主机信息
hosts:write新增 / 编辑主机信息
hosts:delete删除主机
models:read查看大模型配置
models:write新增 / 编辑大模型
models:delete删除大模型

页面访问说明

  • 首页:对所有用户开放,展示当前账号可访问资源的运行状态与统计信息
  • 智能运维页面:对所有用户开放,可基于当前账号已授权的资源进行操作
  • 当用户无任何可用资源时:显示「当前账号暂无可用主机或模型资源」

登录页面提示

  • 登录失败(用户名或密码错误):「用户名或密码错误,请重新输入」
  • 账号未启用:「该账号尚未启用,请联系管理员」
  • 登录成功但页面仍停留:「登录成功,正在进入系统…」
  • 密码框支持显示/隐藏切换,hover 提示:「显示 / 隐藏密码」

授权相关提示

  • 授权成功说明:「授权后,该角色 / 用户将拥有此资源的操作权限」
  • 权限不足时:「当前账号未被授予该资源的操作权限」
  • 退出登录确认:「确认退出登录?」

主机管理(管理员)

  • 编辑主机弹窗仅用于编辑基础信息,权限分配请使用「分配权限」按钮
  • 编辑弹窗提示:「主机访问权限已在『分配权限』中统一管理,此处仅用于查看和编辑基础信息」

搜索选择框

  • placeholder 统一为:「输入名称搜索并添加」
  • 搜索无结果:「未找到匹配的结果」
  • 选中后悬浮框自动隐藏

About

No description, topics, or website provided.
Language
TypeScript50.9%
Svelte46.3%
JavaScript1.5%
CSS0.4%
Others0.9%