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 加密前缀保留(已加密凭证不受影响)。
This commit is contained in:
1 parent
327e282356
commit
f9c6c1d826
204 files changed
+14107
-9103
No files matched your search
@@ -5,7 +5,7 @@
|
||||
|
||||
## 项目概览
|
||||
|
||||
LokiDeploy 是一个基于 **Gin (Go) + React/TypeScript + JSON 文件存储** 的平台,用于把 Grafana
|
||||
opsx-loki 是一个基于 **Gin (Go) + React/TypeScript + JSON 文件存储** 的平台,用于把 Grafana
|
||||
Loki 日志聚合系统部署到 Kubernetes 集群(通过 `kubectl`/`helm`)或裸金属 Linux 主机(通过 SSH)。
|
||||
Go 二进制同时提供 REST API 服务和已构建的前端(SPA)静态资源。
|
||||
|
||||
@@ -57,7 +57,7 @@ docker compose -f docker-compose.prod.yml up -d # 生产环境(读取 ./secret
|
||||
|
||||
## 架构
|
||||
|
||||
### 后端分层(`backend/`,模块路径 `lokideploy`,Go 1.24)
|
||||
### 后端分层(`backend/`,模块路径 `opsxloki`,Go 1.24)
|
||||
请求流转:**router → middleware(JWT)→ controller → service → repository(JsonDB)**。
|
||||
|
||||
- `config/` — `GetConfig()` 单例。读取环境变量;密钥缺失或长度不足时直接 `log.Fatal`。
|
||||
@@ -71,12 +71,16 @@ docker compose -f docker-compose.prod.yml up -d # 生产环境(读取 ./secret
|
||||
(`k8s-helm` / `k8s-yaml` / `host-binary`)分发,实际通过 shell 调用 `kubectl`/`helm` 或 SSH。
|
||||
其它 service:`K8sClient`、`ssh`(+ `ssh_errors`)、`storage`、`cluster_info`,
|
||||
以及较新的 **collector(日志采集器)** 模块(`collector*.go` — 部署客户端日志采集器)。
|
||||
- `middleware/jwt.go` — `JWTAuth()`(`/authorized` 路由组必用)、`AdminAuth()`。
|
||||
- `middleware/jwt.go` — `JWTAuth()`(解析后对照 JsonDB 校验 `TokenVersion`,并以数据库最新
|
||||
role 为准)、`AdminAuth()`;`ratelimit.go` — 登录接口 IP 滑动窗口限流(20 次/分钟)。
|
||||
- 用户管理(简单两级,无 RBAC):`GET/POST /users`、`DELETE /users/:id`、
|
||||
`POST /users/:id/reset-password`,全部仅 admin。改密/重置密码会递增用户 `TokenVersion`,
|
||||
旧 access+refresh token 立即失效(会话吊销)。
|
||||
- `utils/` — `response.go`(响应封装助手)、`crypto.go`(Argon2 + AES-GCM)、`jwt.go`。
|
||||
- `seed/` — 数据库为空时写入默认 admin 用户。
|
||||
|
||||
### 数据层 — JSON 文件数据库(唯一数据源)
|
||||
持久化是 **单个 JSON 文件**,位于 `$DATA_DIR/lokideploy.json`(默认 `./data/`)。
|
||||
持久化是 **单个 JSON 文件**,位于 `$DATA_DIR/opsxloki.json(兼容加载旧 lokideploy.json)`(默认 `./data/`)。
|
||||
**没有 SQL 数据库**。`repository.JsonDB` 是一个与文件对应的内存结构:
|
||||
|
||||
- **并发模型**(重要):写操作由 `Lock()/RLock()` 保护,随后 `RequestSave()` 会通过一个
|
||||
@@ -109,14 +113,42 @@ docker compose -f docker-compose.prod.yml up -d # 生产环境(读取 ./secret
|
||||
|
||||
## 前端(`frontend/`,React 19 + Vite 7 + TypeScript)
|
||||
|
||||
- 技术栈:Tailwind、**shadcn/ui**(Radix 基础组件在 `src/components/ui/`)、react-router 7、
|
||||
react-hook-form + zod、recharts、sonner(通知)。
|
||||
- `src/api/` 是 **当前在用** 的 API 客户端(取代了已删除的 `src/srv/api/`)。`http.ts` 是
|
||||
fetch 封装:注入 `Authorization: Bearer`、30s 超时、401 → 清除 token 并跳转 `/login`、可选重试。
|
||||
每个资源一个模块(`auth`、`cluster` ……)。
|
||||
- `src/App.tsx` — 路由通过 `React.lazy` 懒加载,`RequireAuth` 守卫在 localStorage 无 `token`
|
||||
时重定向到 `/login`。`@` → `src/` 别名(tsconfig + vite)。
|
||||
- 开发服务器跑在 `:3000`,把 `/api` 代理到 `:8080`;生产环境下由 Go 二进制直接提供 `dist/` 静态服务。
|
||||
> 前端开发标准:`docs/web-ui-guide/`(9 章,含分章 AI 检查清单)。编码、Review、重构
|
||||
> 时以该标准为基准;与标准冲突的既有代码即为待改进项。
|
||||
|
||||
- 技术栈:Tailwind、**shadcn/ui**(Radix 基础组件在 `src/components/ui/`,只保留实际
|
||||
使用的,需要新组件 `npx shadcn add <name>`)、react-router 7、react-hook-form + zod、
|
||||
sonner(通知)、next-themes(暗色)。
|
||||
- **页面按域组织**(`src/pages/<domain>/`):`index.tsx` 编排(≤400 行)+
|
||||
`components/`(表单弹窗/卡片/详情)+ `hooks/`(私有数据逻辑)。跨页复用第三次才晋升
|
||||
到 `src/components/`。
|
||||
- `src/api/` — API 客户端,一域一模块。`http.ts` 提供:结构化 `ApiError`(status/code)、
|
||||
30s 超时、`silent` 请求选项、**401 单飞刷新 + 队列重放**(refreshToken 走裸 fetch,
|
||||
登录/轮询接口静默)、`buildQuery` 编码 query。组件**禁止**绕过 api 层直接 fetch。
|
||||
- 凭证存取统一走 `src/lib/auth-storage.ts`,key 带命名空间(`lokideploy.auth.*`);
|
||||
redirect 回跳校验在 `src/lib/redirect.ts`(防开放重定向)。
|
||||
- 路由单源:`src/router/routes.tsx`(meta: title/icon/order)驱动菜单、顶栏标题与
|
||||
`document.title`;守卫 `RequireAuth` 带来源路径回跳;404 走 `pages/not-found`。
|
||||
- 部署向导(`/wizard`):状态推导式步骤地图(preflight 端点聚合各资源状态),四步:环境与
|
||||
目标 → 存储 → Loki(+Grafana)→ 采集;k8s 资源统一默认 `log` 命名空间(可改)。
|
||||
Grafana 为**可选**(默认关闭):k8s 用 NodePort(自动分配)+数据源 ConfigMap,主机用 tarball+systemd;平台已内置日志查询,通常无需 Grafana。
|
||||
- **LDAP 接入**(参照 opsx-web-lite):设置页配置(SystemSetting 表 JSON,Bind 密码 AES 加密、
|
||||
对外只回 `hasPassword`);启用后 ①登录支持 LDAP 用户验证并自动建号(authSource=ldap)②用户页
|
||||
出现「从 LDAP 导入」(已导入置灰;本地同名转 LDAP);`/settings/ldap/{test,users}` 端点。
|
||||
- **日志查询**(`/logs`):数据源 `LogSources`(cluster-svc=经 kubectl --raw service proxy 查集群内
|
||||
Loki,不依赖 ClusterIP/DNS;url=直连;部署成功自动注册);`/logs/{query,labels,label/*/values,histogram}`
|
||||
代理端点(cursor 翻页);前端 LogQL 高亮补全 + 直方图 + 标签点击过滤 + Live Tail(3s 轮询)。
|
||||
- 用户管理页(`/users`,meta `adminOnly: true` — 菜单按角色过滤,后端 AdminAuth 兜底);
|
||||
部署表单的 Loki 版本下拉来自 `GET /deployments/versions`(失败回退兜底列表)。
|
||||
- 列表数据一律 `useListQuery`(AbortController 取消 + 版本号防错序 + 分页);反馈分级:
|
||||
成功静默(禁 toast.success)、失败 toast.error、危险操作 ConfirmDialog、加载失败渲染
|
||||
ErrorState + 重试(与空态严格区分)。
|
||||
- 主题:语义 Token 单源(`src/index.css`,品牌色 = `--primary`,状态色 =
|
||||
success/warning/destructive/info);暗色 `.dark` class 由 next-themes 驱动
|
||||
(key `lokideploy.theme.mode`),禁止硬编码调色板类(如 `bg-emerald-600`)。
|
||||
- 开发服务器跑在 `:3000`(strictPort),把 `/api` 代理到 `:8080`;生产环境下由 Go
|
||||
二进制直接提供 `dist/` 静态服务。构建指纹(`__APP_VERSION__`/`__COMMIT_HASH__`)
|
||||
在 Settings「关于」展示。
|
||||
|
||||
## Loki 部署相关细节
|
||||
- 合法的部署模式:`k8s-helm`、`k8s-yaml`、`host-binary`。K8s 模式需要一个 Cluster(kubeconfig);
|
||||
|
||||
Reference in new issue
Block a user