Commit Graph
9 Commits
Author SHA1 Message Date
opsx b49677f6a6 feat: 运维标杆化打磨 P0/P1/P2 —— 审计日志、真实指标、备份恢复、菜单收敛
审计发现 5 处硬伤(/metrics 空壳、零备份、prod 双副本数据分裂、零审计、资源偏紧),
本轮全部落地。

=== P0-1 真实 /metrics(原来是空壳)===
原实现只返回一行注释 `# LokiStack Metrics`,注释却写着"可被 Prometheus 抓取",
平台挂了/DB 写不进去/告警引擎卡死都只能靠用户反馈。
现接入 prometheus/client_golang,四层指标:
  HTTP    : lokistack_http_requests_total / _duration_seconds / _in_flight_requests
  存储    : lokistack_db_size_bytes / _db_save_duration_seconds / _db_save_total / _db_records
  业务    : lokistack_deployments{status,mode} / lokistack_collectors{status,type,run_mode}
  后台任务: lokistack_alert_evaluations_total / _duration_seconds / lokistack_loki_queries_total
  + go_* / process_*(GoCollector、ProcessCollector)

关键点:path 标签用 c.FullPath() 路由模板,不用原始 URL —— 否则 117 个 Deployment
会把 Prometheus 基数炸掉。指标定义下沉 pkg/metrics 叶子包,避开
services ↔ repository 循环依赖。

=== P0-2 备份与恢复(原来 0 处代码)===
平台全部状态在 /app/data/opsxloki.json(51KB)+ kubeconfigs/ + known_hosts/,
DB 丢了 = 失去"这些资源是谁建的"的映射,从此无法管理/卸载/升级在跑的 Loki。

  CLI : lokistack backup --output <path> / restore <pkg> / self-check / version
  API : GET /system/backup(下载)/ POST /system/restore(校验暂存)/
        POST /system/restore/apply(确认应用)/ GET /system/backups
  K8s : kubernetes/pdb-backup.yaml —— 每日 03:30 CronJob,保留最近 7 份

安全设计:
  - manifest.json 记录 ENCRYPTION_KEY 的 sha256 前 16 位**指纹**,用于恢复时
    校验"这把钥匙能不能解开这份备份",不泄露密钥本身
  - 恢复分两步(校验暂存 → 确认应用),应用前自动把当前 DB 备份为
    opsxloki.json.before-restore.<时间戳>
  - 包内不含明文密钥(kubeconfig 本就是加密态)

=== P0-3 prod compose 双副本 → 单副本 ===
lokistack-1 / lokistack-2 各挂独立数据卷 + nginx 轮询 = 数据分裂:
页面刷新两次可能看到不同结果,写操作只落一个副本。不是高可用。
已改单实例(nginx 仅做反代),文件顶部与 nginx.conf 都写明原因。

=== P0-4 操作审计日志(借鉴 /usr/local/src/aiops 的字段口径)===
aiops 是每个 controller 各写 recordXxxAudit();本平台有 60+ 写接口,
逐个埋点必然漏,漏掉的那个恰好最危险(删集群、改存储凭证)。
改为 **gin 中间件统一记录** + handler 通过 SetAudit 补充业务语义:
  models/audit.go     : 字段对齐 aiops,另加 Method/Path/Before/After
  services/audit.go   : 写入 + 90 天/2 万条自动裁剪 + 脱敏 + diff 生成
  middleware/audit.go : 自动识别 module/action/resource,跳过只读接口
  controllers/audit.go: 列表/详情/统计(仅 admin)
敏感字段(password/secretKey/privateKey/token)写入前统一替换为 ***。

=== P1 稳定性 ===
- 平台资源 1C/1Gi → 4C/4Gi 限(500m/512Mi 请求):JSON DB 全量读写 +
  每分钟告警评估 + 批量发布并发,1Gi 会 OOM
- terminationGracePeriodSeconds: 30 —— 收到 SIGTERM 要等 DB 完整落盘,
  否则 kubelet SIGKILL 会把 JSON 写一半(全库丢失)
- liveness timeoutSeconds 10s(默认 1s 写盘时会被误杀)
- PDB minAvailable: 0 —— 让 kubectl drain 正确等待重建,不卡维护
- DB schemaVersion + migrateSchema() 版本递进迁移(原先加字段全靠零值兜底)
- scripts/release.sh —— 不可变 tag <版本>-<日期>-<commit> + IfNotPresent,
  根治 latest 并发构建互相覆盖导致的静默回滚(本项目已实际踩过)
- PVC 保持 30Gi(按长期增长预留,云盘单价低,不做在线扩容)

=== P2 易用性 ===
- 一键自检 GET /system/self-check + 仪表盘自检卡:真实探活 Loki /ready、
  集群凭据解密、磁盘空间、主机状态、近 24h 失败操作
- 审计日志页 /audit:统计卡 + 用户名/模块/结果筛选 + 变更前后 diff 弹窗
- 菜单收敛 13 → 7(页内 tab 切换,URL 全部不变):
    资源接入 = 集群 + 主机 + 存储
    日志服务 = Loki 实例 + 采集器
    日志     = 查询 + 分析
    系统管理 = 用户 + 审计 + 设置
  新增 GroupTabs 组件 + meta.group/groupKey,侧栏按分组去重并正确高亮

测试:go vet 通过、go test 全绿、tsc 通过
2026-10-28 21:27:01 +00:00
opsx 7b600f7eee feat(log): Gin 结构化 JSON 访问日志 + 生产默认 release 模式(去掉启动路由 dump)
=== 一、结构化 JSON 访问日志(middleware/accesslog.go)===
gin.Default() → gin.New() + AccessLog() + gin.Recovery()
  - 一行一个 JSON:ts/level/type/method/path/status/latency_ms/bytes/ip/ua
  - 自动分级:5xx=error / 4xx=warn / 其余=info
  - jwt 中间件写入的 userId/username 一并输出,便于审计
  - 健康检查与 /assets 静音(探针每 10s 一次会淹没真实请求)
  - Recovery 显式加回(gin.Default 里包含它)

⚠️ Go map 序列化按 key 字母序,ts 会排到最后 → LogJSON 手工拼装,
   把 ts/level/type/msg 固定在最前,其余排序输出。

=== 二、生产默认 release 模式 ===
代码里此前**完全没有 gin.SetMode**,一直跑在 debug:
  - 每次启动 dump 100+ 行路由表([GIN-debug] GET /api/v1/...)
  - 每请求有额外开销,且把完整路由暴露在日志里
现在:GIN_MODE 未显式设置且 DEBUG!=true 时自动 SetMode(ReleaseMode),
需要调试仍可用 DEBUG=true 或 GIN_MODE=debug 覆盖。

=== 三、实测 ===
  GIN-debug 路由 dump 行数: 0 ✅(修复前 100+)
  JSON 访问日志:
    {"ts":"2026-10-27T14:49:28.53Z","level":"info","type":"access","bytes":828,
     "ip":"172.19.16.92","latency_ms":173.5,"method":"POST",
     "path":"/api/v1/auth/login","status":200,"ua":"curl/8.4.0"} ✅
  带用户信息: ...,"user_id":1,"username":"admin" ✅
  health 日志行数: 0 ✅
  总日志 15 行 / JSON 7 行 / 非 JSON 8 行(全部是启动日志)
  health ok、Promtail 12/12、lokistack 1/1 ✅

镜像:lghost/lokistack:latest + v0.1 = sha256:8b25b0a29efa
2026-10-27 14:49:45 +00:00
opsx f3733f0bfc feat: 品牌统一 LokiStack + 全站中英 i18n + 用户批量删除 + 主题定时切换与浅色侧栏
- 品牌: Go 模块/数据文件/二进制/构建部署资产全部 opsx→lokistack;前端 localStorage 命名空间迁移(读旧写新,含按用户 id 前缀迁移);修复 nginx upstream 与 Makefile 引用已改名服务的断裂
- i18n: react-i18next 落地,common + 11 个页面域命名空间全站中英(菜单/顶栏/登录/列表页/表单/确认弹窗/状态徽章);设置页语言即时切换;修复词典自注册导致的循环导入白屏
- 用户管理: 批量删除(POST /users/batch-delete,不删自己/最后管理员,部分失败不阻断)+ 行复选/全选/批量工具条
- 主题: 浅色侧栏(中性灰激活态)、四态模式(浅色/深色/跟随系统/定时切换,按时区判定)、顶栏太阳月亮二态、设置页紧凑分段选择器
- UI: 登录记住用户名、CardActionButton 统一五页卡片操作钮、shadcn Badge 替换手写徽章、语义色修正
- 清理: 移除主机 Web 终端(前后端)、k8s-helm/Helm 遗留代码与字段、README 重写精简
- 修复: 侧栏与日志告警 order 重复、路由标题 i18n key 未翻译、词典双逗号等
2026-10-27 17:11:38 +08:00
opsx 3c27e58a73 feat(security): 移除 admin123 硬编码默认密码 + 编译加 -trimpath
安全加固(降低二进制泄露/逆向的信息面):

1. 初始密码随机化
   - 首次启动生成 16 位随机密码(大小写+数字,排除 0/O/1/l/I 易混淆字符)
   - 写入数据卷 initial-admin-password.txt(0600)并打印到首次启动日志
   - admin 首次改密后自动删除该文件(seed.CleanupInitPassword)
   - 支持 ADMIN_INIT_PASSWORD 环境变量指定(自动化部署 / 固定密码场景)
   - 生成失败直接 Fatal 退出,不再降级到公开默认口令

2. 移除硬编码 admin123
   - main.go 不再打印 "Default login: admin / admin123"
   - 二进制内 admin123 命中:2 → 0

3. -trimpath
   - build.sh / run.sh 编译加 -trimpath
   - 二进制内 /app/backend/ 源码路径命中:66 → 0

4. 文档
   - README 新增「第 4 步:获取管理员初始密码」
     (docker compose exec / logs / docker cp / named volume 四种方式 + K8s 对应命令)
   - .env.example 补 ADMIN_INIT_PASSWORD
   - kubernetes/deployment.yaml 加 env 注释说明

验证(strings 对比加固前后二进制):
  admin123              2 → 0
  /app/backend/        66 → 0
  initial-admin-password.txt / ADMIN_INIT_PASSWORD / CleanupInitPassword 均存在
2026-10-26 17:01:09 +00:00
logan 9f7c522157 feat: K8s 部署清单、Token 接入加固与日志/设置页优化
- kubernetes/: 30Gi PVC、单副本 Recreate、Secret/Service/NodePort/Ingress 清单与部署文档
- 数据安全: kubeconfig/token 统一加密存储,启动迁移历史明文,DB 0600
- Token 接入: 命名空间级最小权限提示、长期 Token、自签证书 TLS 兼容
- 部署: 命名空间级 Token 下跳过 Namespace patch/枚举,节点信息容错
- 日志页: namespace → app → pod 选择顺序与作用域收窄
- 设置页: 拆分为通用/告警/LDAP/镜像源四个 tab
- 弹框: 统一 max-h 滚动与长命令换行,修复内容溢出
2026-10-25 23:44:07 +08:00
logan 2d73661dd1 feat: complete Loki query, insights, settings and deployment workflows
Add the Loki query UI, access policies, ingress insights, alert and registry settings, and their backend APIs. Include the related Kubernetes deployment and collector updates required by the integrated application.

Validated with go test ./..., npm run build, and npm run lint.
2026-10-25 21:28:32 +08:00
logan f9c6c1d826 feat: opsx-loki 全面升级 — 前端重构/用户与LDAP/部署向导/日志查询
基于 WEB-UI-Development-Guide 标准的整体升级,并更名 LokiDeploy → opsx-loki。

前端(Gin+React+shadcn/ui):
- 按 02/07 章重构:页面域化拆分(无超 400 行文件)、PageContainer/ListQuery、
  反馈分级(成功静默/失败 toast/危险确认)、401 单飞刷新+队列重放
- 暗色模式(next-themes)+ 语义 Token(--primary 品牌色/success/warning/info)
- 部署向导(状态推导四步:环境→存储→Loki→采集,内嵌表单闭环)
- 日志查询页:LogQL 标签构建器/拖拽直方图/日志上下文/Live Tail/查询历史
- 按用户+标签策略的查询授权(服务端强制合并策略)

后端(Go+Gin+JSON DB):
- 简单用户管理(仅 admin,无 RBAC)+ TokenVersion 会话吊销 + 登录 IP 限流
- LDAP 接入:配置(AES 加密存储/hasPassword 脱敏)/测试连接/批量导入/登录
- 存储配置测试连接(SigV4 零依赖)+ 桶不存在自动创建
- Loki 三模式部署修复:SSH 密钥认证、3.x 配置模板、ruler 对象存储嵌套块、
  凭证解密、孤儿 deploying 状态恢复、Grafana 部署(可选默认关)+面板导入
- DaemonSet 采集纯 YAML(去 helm 依赖)+ DNS 自愈回退 ClusterIP + 集群名标签
- 日志查询代理:cluster-svc 经 kube-apiserver proxy/url 直连 + cursor 翻页
- 统一 log 命名空间;部署就绪探活;Grafana 访问地址自动记录

修复:run.sh 增量编译检测、Sanitized 脱敏补全、LokiDeployment Update 白名单、
健康检查 CreatedAt 零值等 10+ 存量 bug。

数据兼容:DB 沿用旧 lokideploy.json(新名优先);localStorage 一次性迁移;
HKDF 加密前缀保留(已加密凭证不受影响)。
2026-10-24 13:20:12 +08:00
Logan.LiandClaude 327e282356 refactor: 前后端目录结构模块化 + v2 优化移植与缺陷修复
前端:
- src/srv/api → src/api,按域分文件夹(auth/cluster/host/storage/deployment/collector)
- 新增 http.ts 引擎(http.get/post/put/delete),域模块改用语义化调用
- index.html 增加 favicon(匹配应用 logo 的 emerald + Activity 脉冲)

后端分层增强(保留包名):
- 新增 repository/:从 models 拆出 JsonDB 持久化层(InitDB/GetDB/Shutdown/RequestSave)
- 新增 dto/:从 controllers 抽出各域请求契约(带 binding 校验)
- 新增 pkg/crypto、pkg/jwt:从 utils 拆出安全原语(外部 jwt 别名 jwtv5 避免冲突)
- models 只留领域实体 + sanitizer;utils 只留 gin/应用相关(response/errors)

v2 优化移植与缺陷修复:
- 移植密钥分离/SSH TOFU/并发写安全/Loki 生产级配置/Docker 加固
- 修复 deployment.go 并发丢更新、Helm values 重复键、EncryptField 哨兵、loki-gateway 端点等审计缺陷
- 实现真正的优雅关停(main.go http.Server + signal + repository.Shutdown)
- 修复登录契约:后端返回 accessToken,前端 auth.ts/Login.tsx 对齐
- 补 crypto/jwt/repository 单元测试(含并发写回归)

验证: go build/vet/test 全绿;npm run build 通过;登录→鉴权→优雅关停冒烟通过

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-30 10:46:26 +08:00
Logan.LiandClaude 2a93de600d feat: LokiDeploy 初始提交 - 轻量级 K8s Loki 部署平台
Go(Gin) + React(Vite + shadcn/ui + Tailwind) 前后端分离,全中文 UI

- 集群管理:Kubeconfig / Token 双接入,kubectl + helm 部署
- 主机管理:SSH 密钥 / 密码双认证,CPU/内存/磁盘使用率监控,SSH 错误中文友好提示
- 存储配置、部署管理、系统设置
- Docker 镜像内置 kubectl + helm,开箱即用
- run.sh 一键启停(start/stop/restart/status)

Co-Authored-By: Claude <noreply@anthropic.com>
2026-06-29 17:03:57 +08:00