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 滚动与长命令换行,修复内容溢出
This commit is contained in:
1 parent
2d73661dd1
commit
9f7c522157
50 files changed
+1346
-149
No files matched your search
@@ -38,6 +38,49 @@ const DEFAULTS: RuleForm = {
|
||||
windowMin: '15', threshold: '0', cooldownMin: '60', enabled: true,
|
||||
}
|
||||
|
||||
interface AlertTemplate {
|
||||
label: string
|
||||
desc: string
|
||||
query: string
|
||||
windowMin: number
|
||||
threshold: number
|
||||
cooldownMin: number
|
||||
}
|
||||
|
||||
/** 常用告警模板 — 只做预填,应用后可改 namespace / 阈值 / 窗口 */
|
||||
const TEMPLATES: AlertTemplate[] = [
|
||||
{
|
||||
label: '业务 NS error',
|
||||
desc: '指定命名空间(默认 astralx)内 error 日志',
|
||||
query: '{namespace="astralx"} |~ "(?i)error"',
|
||||
windowMin: 5, threshold: 10, cooldownMin: 30,
|
||||
},
|
||||
{
|
||||
label: '全 NS error > 1000',
|
||||
desc: '所有命名空间 error 日志总量超过 1000 条',
|
||||
query: '{namespace=~".+"} |~ "(?i)error"',
|
||||
windowMin: 15, threshold: 1000, cooldownMin: 60,
|
||||
},
|
||||
{
|
||||
label: 'Ingress 5xx',
|
||||
desc: 'ingress-nginx 5xx(需 JSON access log,平台可一键标准化)',
|
||||
query: '{namespace="ingress-nginx"} | json | status >= 500',
|
||||
windowMin: 5, threshold: 5, cooldownMin: 15,
|
||||
},
|
||||
{
|
||||
label: 'Ingress 4xx',
|
||||
desc: 'ingress-nginx 4xx(需 JSON access log)',
|
||||
query: '{namespace="ingress-nginx"} | json | status >= 400 | status < 500',
|
||||
windowMin: 5, threshold: 50, cooldownMin: 30,
|
||||
},
|
||||
{
|
||||
label: 'FATAL',
|
||||
desc: '所有命名空间出现 FATAL 即告警',
|
||||
query: '{namespace=~".+"} |= "FATAL"',
|
||||
windowMin: 5, threshold: 0, cooldownMin: 15,
|
||||
},
|
||||
]
|
||||
|
||||
/** 告警规则页:规则 CRUD + 立即检查 + 发送历史 */
|
||||
const AlertsPage = memo(function AlertsPage() {
|
||||
const [rules, setRules] = useState<AlertRule[]>([])
|
||||
@@ -87,6 +130,14 @@ const AlertsPage = memo(function AlertsPage() {
|
||||
setOpen(true)
|
||||
}
|
||||
|
||||
const applyTemplate = (t: AlertTemplate) => {
|
||||
form.setValue('name', t.label)
|
||||
form.setValue('query', t.query)
|
||||
form.setValue('windowMin', String(t.windowMin))
|
||||
form.setValue('threshold', String(t.threshold))
|
||||
form.setValue('cooldownMin', String(t.cooldownMin))
|
||||
}
|
||||
|
||||
const onSubmit = form.handleSubmit(async (v) => {
|
||||
setSubmitting(true)
|
||||
try {
|
||||
@@ -244,6 +295,26 @@ const AlertsPage = memo(function AlertsPage() {
|
||||
</DialogHeader>
|
||||
<Form {...form}>
|
||||
<form onSubmit={onSubmit} className="space-y-4">
|
||||
{!editing && (
|
||||
<div className="space-y-2">
|
||||
<p className="text-xs font-medium text-muted-foreground">快捷模板(点击预填,可再修改)</p>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{TEMPLATES.map((t) => (
|
||||
<Button
|
||||
key={t.label}
|
||||
type="button"
|
||||
variant="outline"
|
||||
size="sm"
|
||||
className="h-8 text-xs"
|
||||
title={`${t.desc}\n${t.query}`}
|
||||
onClick={() => applyTemplate(t)}
|
||||
>
|
||||
{t.label}
|
||||
</Button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<FormField control={form.control} name="name" render={({ field }) => (
|
||||
<FormItem>
|
||||
|
||||
Reference in new issue
Block a user