models

package
v0.0.151 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 20, 2025 License: MIT Imports: 11 Imported by: 0

Documentation

Index

Constants

View Source
const BuiltinLuaScriptsVersion = "v1"

BuiltinLuaScriptsVersion 统一管理所有内置脚本的版本号

Variables

View Source
var BuiltinLuaScripts = []InspectionLuaScript{
	{
		Name:        "Service Selector 检查",
		Description: "检查每个 Service 的 selector 是否有对应 Pod",
		Group:       "",
		Version:     "v1",
		Kind:        "Service",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Service_001",
		Script: `
		    -- 获取Selector 定义文档
			local doc, err = kubectl:GVK("", "v1", "Service"):Cache(10):Doc("spec.selector")
			if err then
				print( "获取 Service Doc 失败".. tostring(err))
				return
			end
			-- 检查每个 Service 的 selector 是否有对应 Pod,Pod 查询限定在 Service 所在的 namespace
			local svcs, err = kubectl:GVK("", "v1", "Service"):AllNamespace(""):List()
			if not err and svcs then
				for _, svc in ipairs(svcs) do
					if svc.spec and svc.spec.selector then
						local selector = svc.spec.selector
						local labelSelector = ""
						for k, v in pairs(selector) do
							if labelSelector ~= "" then
								labelSelector = labelSelector .. ","
							end
							labelSelector = labelSelector .. k .. "=" .. v
						end
						-- 这里使用 Namespace(svc.metadata.namespace) 保证只查找与 Service 相同命名空间下的 Pod
						local pods, err = kubectl:GVK("", "v1", "Pod"):Namespace(svc.metadata.namespace):Cache(10):WithLabelSelector(labelSelector):List()
						local count = 0
						if not err and pods then
							for _, _ in pairs(pods) do count = count + 1 end
						end
						if count = 0 then
							check_event("失败", "Service " .. svc.metadata.name .. " selector " .. labelSelector .. " 应该至少一个pod, 但是现在没有。" .. "spec.selector定义" .. doc, {name=svc.metadata.name, selector=labelSelector, namespace=svc.metadata.namespace})
						end
					end
				end
			else
				print("Service 列表获取失败: " .. tostring(err))
			end
		`,
	},

	{
		Name:        "ConfigMap 未被使用检测",
		Description: "检测所有未被 Pod 使用的 ConfigMap",
		Group:       "",
		Version:     "v1",
		Kind:        "ConfigMap",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_ConfigMap_002",
		Script: `
			local configmaps, err = kubectl:GVK("", "v1", "ConfigMap"):AllNamespace(""):List()
			if err then
				print("获取 ConfigMap 失败".. tostring(err))
				return
			end
			local pods, err = kubectl:GVK("", "v1", "Pod"):Cache(10):AllNamespace(""):List()
			if err then
				print("获取 Pod 失败".. tostring(err))
				return
			end
			local usedConfigMaps = {}
			for _, pod in ipairs(pods) do
				if pod.spec and pod.spec.volumes then
					for _, volume in ipairs(pod.spec.volumes) do
						if volume.configMap and volume.configMap.name then
							local key = pod.metadata.namespace .. "/" .. volume.configMap.name
							usedConfigMaps[key] = true
						end
					end
				end
				if pod.spec and pod.spec.containers then
					for _, container in ipairs(pod.spec.containers) do
						if container.env then
							for _, env in ipairs(container.env) do
								if env.valueFrom and env.valueFrom.configMapKeyRef and env.valueFrom.configMapKeyRef.name then
									local key = pod.metadata.namespace .. "/" .. env.valueFrom.configMapKeyRef.name
									usedConfigMaps[key] = true
								end
							end
						end
						if container.envFrom then
							for _, envFrom in ipairs(container.envFrom) do
								if envFrom.configMapRef and envFrom.configMapRef.name then
									local key = pod.metadata.namespace .. "/" .. envFrom.configMapRef.name
									usedConfigMaps[key] = true
								end
							end
						end
					end
				end
			end
			for _, cm in ipairs(configmaps) do
				local cmKey = cm.metadata.namespace .. "/" .. cm.metadata.name
				local cmName = cm.metadata.name
				local cmNamespace = cm.metadata.namespace
				if not usedConfigMaps[cmKey] then
					check_event("失败", "[未使用] ConfigMap " .. cmNamespace .. "/" .. cmName .. " 没有被任何 Pod 使用", {namespace=cmNamespace, name=cmName})
				end
			end
			print("ConfigMap 未被使用检测完成")
		`,
	},
	{
		Name:        "ConfigMap 空数据检测",
		Description: "检测所有 data 和 binaryData 字段都为空的 ConfigMap",
		Group:       "",
		Version:     "v1",
		Kind:        "ConfigMap",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_ConfigMap_003",
		Script: `
			local configmaps, err = kubectl:GVK("", "v1", "ConfigMap"):AllNamespace(""):List()
			if err then
				print("获取 ConfigMap 失败".. tostring(err))
				return
			end
			for _, cm in ipairs(configmaps) do
				local cmName = cm.metadata.name
				local cmNamespace = cm.metadata.namespace
				local isEmpty = true
				if cm.data then
					for k, v in pairs(cm.data) do
						isEmpty = false
						break
					end
				end
				if isEmpty and cm.binaryData then
					for k, v in pairs(cm.binaryData) do
						isEmpty = false
						break
					end
				end
				if isEmpty then
					check_event("失败", "[空数据] ConfigMap " .. cmNamespace .. "/" .. cmName .. " 的 data 和 binaryData 字段都为空", {namespace=cmNamespace, name=cmName})
				end
			end
			print("ConfigMap 空数据检测完成")
		`,
	},
	{
		Name:        "ConfigMap 超大检测",
		Description: "检测所有超过 1MB 的 ConfigMap",
		Group:       "",
		Version:     "v1",
		Kind:        "ConfigMap",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_ConfigMap_004",
		Script: `
			local configmaps, err = kubectl:GVK("", "v1", "ConfigMap"):AllNamespace(""):List()
			if err then
				print( "获取 ConfigMap 失败".. tostring(err))
				return
			end
			for _, cm in ipairs(configmaps) do
				local cmName = cm.metadata.name
				local cmNamespace = cm.metadata.namespace
				local totalSize = 0
				if cm.data then
					for k, v in pairs(cm.data) do
						if type(v) == "string" then
							totalSize = totalSize + string.len(v)
						end
					end
				end
				if cm.binaryData then
					for k, v in pairs(cm.binaryData) do
						if type(v) == "string" then
							totalSize = totalSize + string.len(v)
						end
					end
				end
				local maxSize = 1024 * 1024
				if totalSize > maxSize then
					local sizeMB = string.format("%.2f", totalSize / (1024 * 1024))
					check_event("失败", "[超大] ConfigMap " .. cmNamespace .. "/" .. cmName .. " 大小为 " .. sizeMB .. "MB,超过 1MB 限制", {namespace=cmNamespace, name=cmName, size=sizeMB})
				end
			end
			print("ConfigMap 超大检测完成")
		`,
	},

	{
		Name:        "Deployment 配置检查",
		Description: "分析 Deployment 配置问题",
		Group:       "apps",
		Version:     "v1",
		Kind:        "Deployment",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Deployment_005",
		Script: `
			local doc, err = kubectl:GVK("apps", "v1", "Deployment"):Cache(10):Doc("spec.replicas")
			if err then
				print( "获取 Deployment Doc 失败".. tostring(err))
				return
			end
			print("Deployment Doc 获取成功: " .. doc)
			local deployments, err = kubectl:GVK("apps", "v1", "Deployment"):Cache(10):AllNamespace(""):List()
			if err then
				print( "获取 Deployment 失败".. tostring(err))
				return
			end
			local problemCount = 0
			for _, deployment in ipairs(deployments) do
				local deploymentName = deployment.metadata.name
				local deploymentNamespace = deployment.metadata.namespace
				local specReplicas = 0
				local statusReplicas = 0
				local readyReplicas = 0
				if deployment.spec and deployment.spec.replicas ~= nil then
					specReplicas = tonumber(deployment.spec.replicas) or 0
				end
				if deployment.status then
					if deployment.status.replicas ~= nil then
						statusReplicas = tonumber(deployment.status.replicas) or 0
					end
					if deployment.status.readyReplicas ~= nil then
						readyReplicas = tonumber(deployment.status.readyReplicas) or 0
					end
				end
				if specReplicas ~= readyReplicas then
					problemCount = problemCount + 1
					if statusReplicas > specReplicas then
						check_event("失败", "[副本数不匹配] Deployment " .. deploymentNamespace .. "/" .. deploymentName ..
							" 期望副本数: " .. specReplicas ..
							", 状态副本数: " .. statusReplicas ..
							", 就绪副本数: " .. readyReplicas ..
							" (状态字段尚未更新,缩容进行中)", {namespace=deploymentNamespace, name=deploymentName, specReplicas=specReplicas, statusReplicas=statusReplicas, readyReplicas=readyReplicas})
					else
						check_event("失败", "[副本数不足] Deployment " .. deploymentNamespace .. "/" .. deploymentName ..
							" 期望副本数: " .. specReplicas ..
							", 就绪副本数: " .. readyReplicas ..
							" (可能存在 Pod 启动失败或资源不足)", {namespace=deploymentNamespace, name=deploymentName, specReplicas=specReplicas, readyReplicas=readyReplicas})
					end
					if readyReplicas == 0 and specReplicas > 0 then
						check_event("失败", "没有就绪的副本,可能存在严重问题", {namespace=deploymentNamespace, name=deploymentName})
					elseif readyReplicas < specReplicas then
						local missingReplicas = specReplicas - readyReplicas
						check_event("失败", "缺少 " .. missingReplicas .. " 个副本,建议检查 Pod 状态和资源限制", {namespace=deploymentNamespace, name=deploymentName, missingReplicas=missingReplicas})
					end
				end
				if deployment.status and deployment.status.conditions then
					for _, condition in ipairs(deployment.status.conditions) do
						if condition.type == "Progressing" and condition.status == "False" then
							check_event("失败", "进度停滞: " .. (condition.reason or "未知原因") ..
								" - " .. (condition.message or "无详细信息"), {namespace=deploymentNamespace, name=deploymentName, reason=condition.reason, message=condition.message})
						elseif condition.type == "Available" and condition.status == "False" then
							check_event("失败", "不可用状态: " .. (condition.reason or "未知原因") ..
								" - " .. (condition.message or "无详细信息"), {namespace=deploymentNamespace, name=deploymentName, reason=condition.reason, message=condition.message})
						end
					end
				end
			end
		`,
	},
	{
		Name:        "CronJob 合规性检查",
		Description: "检查 CronJob 是否被挂起、调度表达式是否合法、startingDeadlineSeconds 是否为负数",
		Group:       "",
		Version:     "v1",
		Kind:        "CronJob",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_CronJob_006",
		Script: `
			local cron = require("cron")
			local cronjobs, err = kubectl:GVK("batch", "v1", "CronJob"):AllNamespace(""):List()
			if err then
				print("获取 CronJob 失败: " .. tostring(err))
				return
			end
			local doc_suspend, _ = kubectl:GVK("batch", "v1", "CronJob"):Doc("spec.suspend")
			local doc_schedule, _ = kubectl:GVK("batch", "v1", "CronJob"):Doc("spec.schedule")
			local doc_deadline, _ = kubectl:GVK("batch", "v1", "CronJob"):Doc("spec.startingDeadlineSeconds")
			for _, cj in ipairs(cronjobs) do
				local ns = cj.metadata and cj.metadata.namespace or "default"
				local name = cj.metadata and cj.metadata.name or ""
				-- 检查挂起
				if cj.spec and cj.spec.suspend == true then
					check_event("失败", "CronJob " .. name .. " 已被挂起", {namespace=ns, name=name, doc=doc_suspend})
				end
				-- 检查 startingDeadlineSeconds
				if cj.spec and cj.spec.startingDeadlineSeconds ~= nil then
					if tonumber(cj.spec.startingDeadlineSeconds) < 0 then
						check_event("失败", "CronJob " .. name .. " 的 startingDeadlineSeconds 为负数", {namespace=ns, name=name, value=cj.spec.startingDeadlineSeconds, doc=doc_deadline})
					end
				end
			end
			print("CronJob 合规性检查完成")
		`,
	},
	{
		Name:        "Gateway 合规性检查",
		Description: "检查 Gateway 关联的 GatewayClass 是否存在,以及 Gateway 状态是否被接受",
		Group:       "gateway.networking.k8s.io",
		Version:     "v1",
		Kind:        "Gateway",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Gateway_007",
		Script: `
			local gateways, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "Gateway"):AllNamespace(""):List()
			if err then
				print("获取 Gateway 失败: " .. tostring(err))
				return
			end
			for _, gtw in ipairs(gateways) do
				local ns = gtw.metadata and gtw.metadata.namespace or "default"
				local name = gtw.metadata and gtw.metadata.name or ""
				local className = gtw.spec and gtw.spec.gatewayClassName or nil
				local classExists = false
				if className then
					local gtwclass, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "GatewayClass"):Name(className):Get()
					if not err and gtwclass then
						classExists = true
					end
				end
				if not classExists then
					check_event("失败", "Gateway 使用的 GatewayClass " .. tostring(className) .. " 不存在", {namespace=ns, name=name, gatewayClassName=className})
				end
				-- 检查第一个 Condition 状态
				if gtw.status and gtw.status.conditions and #gtw.status.conditions > 0 then
					local cond = gtw.status.conditions[1]
					if cond.status ~= "True" then
						check_event("失败", "Gateway '" .. ns .. "/" .. name .. "' 未被接受, Message: '" .. (cond.message or "") .. "'", {namespace=ns, name=name, message=cond.message})
					end
				end
			end
			print("Gateway 合规性检查完成")
		`,
	},
	{
		Name:        "GatewayClass 合规性检查",
		Description: "检查 GatewayClass 的第一个 Condition 状态是否为 True,否则报告未被接受及 message。",
		Group:       "gateway.networking.k8s.io",
		Version:     "v1",
		Kind:        "GatewayClass",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_GatewayClass_008",
		Script: `
			local gatewayclasses, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "GatewayClass"):AllNamespace(""):List()
			if err then
				print("获取 GatewayClass 失败: " .. tostring(err))
				return
			end
			for _, gc in ipairs(gatewayclasses) do
				local name = gc.metadata and gc.metadata.name or ""
				if gc.status and gc.status.conditions and #gc.status.conditions > 0 then
					local cond = gc.status.conditions[1]
					if cond.status ~= "True" then
						check_event("失败", "GatewayClass '" .. name .. "' 未被接受, Message: '" .. (cond.message or "") .. "'", {name=name, message=cond.message})
					end
				end
			end
			print("GatewayClass 合规性检查完成")
		`,
	},
	{
		Name:        "HPA Condition 检查",
		Description: "检查 HorizontalPodAutoscaler 的 Condition 状态,ScalingLimited 为 True 或其他 Condition 为 False 时报警。",
		Group:       "autoscaling",
		Version:     "v2",
		Kind:        "HorizontalPodAutoscaler",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_HPA_Condition_009",
		Script: `
			local hpas, err = kubectl:GVK("autoscaling", "v2", "HorizontalPodAutoscaler"):AllNamespace(""):List()
			if err then print("获取 HPA 失败: " .. tostring(err)) return end
			for _, hpa in ipairs(hpas) do
				if hpa.status and hpa.status.conditions then
					for _, cond in ipairs(hpa.status.conditions) do
						if cond.type == "ScalingLimited" and cond.status == "True" then
							check_event("失败", cond.message or "ScalingLimited condition True", {namespace=hpa.metadata.namespace, name=hpa.metadata.name, type=cond.type})
						elseif cond.status == "False" then
							check_event("失败", cond.message or (cond.type .. " condition False"), {namespace=hpa.metadata.namespace, name=hpa.metadata.name, type=cond.type})
						end
					end
				end
			end
			print("HPA Condition 检查完成")
		`,
	},
	{
		Name:        "HPA ScaleTargetRef 存在性检查",
		Description: "检查 HorizontalPodAutoscaler 的 ScaleTargetRef 指向的对象是否存在。",
		Group:       "autoscaling",
		Version:     "v2",
		Kind:        "HorizontalPodAutoscaler",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_HPA_ScaleTargetRef_010",
		Script: `
			local hpas, err = kubectl:GVK("autoscaling", "v2", "HorizontalPodAutoscaler"):AllNamespace(""):List()
			if err then print("获取 HPA 失败: " .. tostring(err)) return end
			for _, hpa in ipairs(hpas) do
				if hpa.spec and hpa.spec.scaleTargetRef then
					local ref = hpa.spec.scaleTargetRef
					local exists = false
					if ref.kind == "Deployment" then
						exists = kubectl:GVK("apps", "v1", "Deployment"):Namespace(hpa.metadata.namespace):Name(ref.name):Exists()
					elseif ref.kind == "ReplicaSet" then
						exists = kubectl:GVK("apps", "v1", "ReplicaSet"):Namespace(hpa.metadata.namespace):Name(ref.name):Exists()
					elseif ref.kind == "StatefulSet" then
						exists = kubectl:GVK("apps", "v1", "StatefulSet"):Namespace(hpa.metadata.namespace):Name(ref.name):Exists()
					elseif ref.kind == "ReplicationController" then
						exists = kubectl:GVK("", "v1", "ReplicationController"):Namespace(hpa.metadata.namespace):Name(ref.name):Exists()
					else
						check_event("失败", "HorizontalPodAutoscaler 使用了不支持的 ScaleTargetRef Kind: " .. tostring(ref.kind), {namespace=hpa.metadata.namespace, name=hpa.metadata.name, kind=ref.kind})
					end
					if not exists then
						check_event("失败", "HorizontalPodAutoscaler 的 ScaleTargetRef " .. ref.kind .. "/" .. ref.name .. " 不存在", {namespace=hpa.metadata.namespace, name=hpa.metadata.name, kind=ref.kind, refname=ref.name})
					end
				end
			end
			print("HPA ScaleTargetRef 存在性检查完成")
		`,
	},
	{
		Name:        "HPA 资源配置检查",
		Description: "检查 HPA 关联对象的 Pod 模板中所有容器是否配置了 requests 和 limits。",
		Group:       "autoscaling",
		Version:     "v2",
		Kind:        "HorizontalPodAutoscaler",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_HPA_Resource_011",
		Script: `
			local hpas, err = kubectl:GVK("autoscaling", "v2", "HorizontalPodAutoscaler"):AllNamespace(""):List()
			if err then print("获取 HPA 失败: " .. tostring(err)) return end
			for _, hpa in ipairs(hpas) do
				if hpa.spec and hpa.spec.scaleTargetRef then
					local ref = hpa.spec.scaleTargetRef
					local gvk_map = {
						Deployment = {group="apps", version="v1", kind="Deployment"},
						ReplicaSet = {group="apps", version="v1", kind="ReplicaSet"},
						StatefulSet = {group="apps", version="v1", kind="StatefulSet"},
						ReplicationController = {group="", version="v1", kind="ReplicationController"},
					}
					local gvk = gvk_map[ref.kind]
					if gvk then
						local target, err = kubectl:GVK(gvk.group, gvk.version, gvk.kind):Namespace(hpa.metadata.namespace):Name(ref.name):Get()
						if not err and target and target.spec and target.spec.template and target.spec.template.spec and target.spec.template.spec.containers then
							local containers = target.spec.template.spec.containers
							local all_ok = true
							for _, c in ipairs(containers) do
								if not c.resources or not c.resources.requests or not c.resources.limits then
									all_ok = false
									check_event("失败", ref.kind .. " " .. hpa.metadata.namespace .. "/" .. ref.name .. " 的容器未配置 requests 或 limits", {namespace=hpa.metadata.namespace, name=hpa.metadata.name, kind=ref.kind, refname=ref.name, container=c.name})
								end
							end
						end
					end
				end
			end
			print("HPA 资源配置检查完成")
		`,
	}, {
		Name:        "HTTPRoute Backend Service 存在性与端口检查",
		Description: "检查 HTTPRoute 所引用的后端 Service 是否存在,以及端口是否匹配 Service 的端口。",
		Group:       "gateway.networking.k8s.io",
		Version:     "v1",
		Kind:        "HTTPRoute",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_HTTPRoute_Backend_012",
		Script: `
			local httproutes, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "HTTPRoute"):AllNamespace(""):List()
			if err then print("获取 HTTPRoute 失败: " .. tostring(err)) return end
			for _, route in ipairs(httproutes) do
				if route.spec and route.spec.rules then
					for _, rule in ipairs(route.spec.rules) do
						if rule.backendRefs then
							for _, backend in ipairs(rule.backendRefs) do
								local svc, err = kubectl:GVK("", "v1", "Service"):Namespace(route.metadata.namespace):Name(backend.name):Get()
								if err or not svc then
									check_event("失败", "HTTPRoute 使用的 Service '" .. route.metadata.namespace .. "/" .. backend.name .. "' 不存在", {namespace=route.metadata.namespace, name=backend.name})
								else
									local portMatch = false
									if svc.spec and svc.spec.ports and backend.port then
										for _, svcPort in ipairs(svc.spec.ports) do
											if svcPort.port == backend.port then portMatch = true end
										end
									end
									if not portMatch then
										check_event("失败", "HTTPRoute 的后端 Service '" .. backend.name .. "' 使用端口 '" .. tostring(backend.port) .. "',但 Service 未配置该端口", {namespace=route.metadata.namespace, name=backend.name, port=backend.port})
									end
								end
							end
						end
					end
				end
			end
			print("HTTPRoute Backend Service 检查完成")
		`,
	}, {
		Name:        "HTTPRoute Backend Service 存在性与端口检查",
		Description: "检查 HTTPRoute 所引用的后端 Service 是否存在,以及端口是否匹配 Service 的端口。",
		Group:       "gateway.networking.k8s.io",
		Version:     "v1",
		Kind:        "HTTPRoute",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_HTTPRoute_Backend_013",
		Script: `
			local httproutes, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "HTTPRoute"):AllNamespace(""):List()
			if err then print("获取 HTTPRoute 失败: " .. tostring(err)) return end
			for _, route in ipairs(httproutes) do
				if route.spec and route.spec.rules then
					for _, rule in ipairs(route.spec.rules) do
						if rule.backendRefs then
							for _, backend in ipairs(rule.backendRefs) do
								local svc, err = kubectl:GVK("", "v1", "Service"):Namespace(route.metadata.namespace):Name(backend.name):Get()
								if err or not svc then
									check_event("失败", "HTTPRoute 使用的 Service '" .. route.metadata.namespace .. "/" .. backend.name .. "' 不存在", {namespace=route.metadata.namespace, name=backend.name})
								else
									local portMatch = false
									if svc.spec and svc.spec.ports and backend.port then
										for _, svcPort in ipairs(svc.spec.ports) do
											if svcPort.port == backend.port then portMatch = true end
										end
									end
									if not portMatch then
										check_event("失败", "HTTPRoute 的后端 Service '" .. backend.name .. "' 使用端口 '" .. tostring(backend.port) .. "',但 Service 未配置该端口", {namespace=route.metadata.namespace, name=backend.name, port=backend.port})
									end
								end
							end
						end
					end
				end
			end
			print("HTTPRoute Backend Service 检查完成")
		`,
	}, {
		Name:        "HTTPRoute Gateway 存在性与命名空间策略检查",
		Description: "检查 HTTPRoute 所引用的 Gateway 是否存在,以及 Gateway 的 AllowedRoutes 策略是否允许该 HTTPRoute。",
		Group:       "gateway.networking.k8s.io",
		Version:     "v1",
		Kind:        "HTTPRoute",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_HTTPRoute_Gateway_014",
		Script: `
			local httproutes, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "HTTPRoute"):AllNamespace(""):List()
			if err then print("获取 HTTPRoute 失败: " .. tostring(err)) return end
			for _, route in ipairs(httproutes) do
				if route.spec and route.spec.parentRefs then
					for _, gtwref in ipairs(route.spec.parentRefs) do
						local ns = route.metadata.namespace
						if gtwref.namespace then ns = gtwref.namespace end
						local gtw, err = kubectl:GVK("gateway.networking.k8s.io", "v1", "Gateway"):Namespace(ns):Name(gtwref.name):Get()
						if err or not gtw then
							check_event("失败", "HTTPRoute 使用的 Gateway '" .. ns .. "/" .. gtwref.name .. "' 不存在", {namespace=ns, name=gtwref.name})
						else
							if gtw.spec and gtw.spec.listeners then
								for _, listener in ipairs(gtw.spec.listeners) do
									if listener.allowedRoutes and listener.allowedRoutes.namespaces and listener.allowedRoutes.namespaces.from then
										local allow = listener.allowedRoutes.namespaces.from
										if allow == "Same" and route.metadata.namespace ~= gtw.metadata.namespace then
											check_event("失败", "HTTPRoute '" .. route.metadata.namespace .. "/" .. route.metadata.name .. "' 与 Gateway '" .. gtw.metadata.namespace .. "/" .. gtw.metadata.name .. "' 不在同一命名空间,且 Gateway 只允许同命名空间 HTTPRoute", {route_ns=route.metadata.namespace, route_name=route.metadata.name, gtw_ns=gtw.metadata.namespace, gtw_name=gtw.metadata.name})
										elseif allow == "Selector" and listener.allowedRoutes.namespaces.selector and listener.allowedRoutes.namespaces.selector.matchLabels then
											local match = false
											for k, v in pairs(listener.allowedRoutes.namespaces.selector.matchLabels) do
												if route.metadata.labels and route.metadata.labels[k] == v then match = true end
											end
											if not match then
												check_event("失败", "HTTPRoute '" .. route.metadata.namespace .. "/" .. route.metadata.name .. "' 的标签与 Gateway '" .. gtw.metadata.namespace .. "/" .. gtw.metadata.name .. "' 的 Selector 不匹配", {route_ns=route.metadata.namespace, route_name=route.metadata.name, gtw_ns=gtw.metadata.namespace, gtw_name=gtw.metadata.name})
											end
										end
									end
								end
							end
						end
					end
				end
			end
			print("HTTPRoute Gateway 检查完成")
		`,
	},
	{
		Name:        "Ingress 合规性检查",
		Description: "检查 Ingress 是否指定 IngressClass,引用的 IngressClass/Service/Secret 是否存在。",
		Group:       "networking",
		Version:     "v1",
		Kind:        "Ingress",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Ingress_015",
		Script: `
			local ingresses, err = kubectl:GVK("networking.k8s.io", "v1", "Ingress"):AllNamespace(""):List()
			if err then print("获取 Ingress 失败: " .. tostring(err)) return end
			for _, ing in ipairs(ingresses) do
				local ingressClassName = ing.spec and ing.spec.ingressClassName or nil
				if not ingressClassName and ing.metadata and ing.metadata.annotations then
					ingressClassName = ing.metadata.annotations["kubernetes.io/ingress.class"]
				end
				if not ingressClassName or ingressClassName == "" then
					check_event("失败", "Ingress " .. ing.metadata.namespace .. "/" .. ing.metadata.name .. " 未指定 IngressClass", {namespace=ing.metadata.namespace, name=ing.metadata.name})
				else
					local ic, err = kubectl:GVK("networking.k8s.io", "v1", "IngressClass"):Name(ingressClassName):Get()
					if err or not ic then
						check_event("失败", "Ingress 使用的 IngressClass '" .. ingressClassName .. "' 不存在", {namespace=ing.metadata.namespace, name=ing.metadata.name, ingressClass=ingressClassName})
					end
				end
				if ing.spec and ing.spec.rules then
					for _, rule in ipairs(ing.spec.rules) do
						if rule.http and rule.http.paths then
							for _, path in ipairs(rule.http.paths) do
								if path.backend and path.backend.service and path.backend.service.name then
									local svc, err = kubectl:GVK("", "v1", "Service"):Namespace(ing.metadata.namespace):Name(path.backend.service.name):Get()
									if err or not svc then
										check_event("失败", "Ingress 使用的 Service '" .. ing.metadata.namespace .. "/" .. path.backend.service.name .. "' 不存在", {namespace=ing.metadata.namespace, name=path.backend.service.name})
									end
								end
							end
						end
					end
				end
				if ing.spec and ing.spec.tls then
					for _, tls in ipairs(ing.spec.tls) do
						if tls.secretName then
							local sec, err = kubectl:GVK("", "v1", "Secret"):Namespace(ing.metadata.namespace):Name(tls.secretName):Get()
							if err or not sec then
								check_event("失败", "Ingress 使用的 TLS Secret '" .. ing.metadata.namespace .. "/" .. tls.secretName .. "' 不存在", {namespace=ing.metadata.namespace, name=tls.secretName})
							end
						end
					end
				end
			end
			print("Ingress 合规性检查完成")
		`,
	},
	{
		Name:        "Job 合规性检查",
		Description: "检查 Job 是否被挂起(suspend)以及是否有失败(status.failed > 0)",
		Group:       "batch",
		Version:     "v1",
		Kind:        "Job",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Job_016",
		Script: `
			local jobs, err = kubectl:GVK("batch", "v1", "Job"):AllNamespace(""):List()
			if err then print("获取 Job 失败: " .. tostring(err)) return end
			for _, job in ipairs(jobs) do
				if job.spec and job.spec.suspend == true then
					check_event("失败", "Job " .. job.metadata.name .. " 已被挂起", {namespace=job.metadata.namespace, name=job.metadata.name})
				end
				if job.status and job.status.failed and job.status.failed > 0 then
					check_event("失败", "Job " .. job.metadata.name .. " 有失败记录 (failed=" .. tostring(job.status.failed) .. ")", {namespace=job.metadata.namespace, name=job.metadata.name, failed=job.status.failed})
				end
			end
			print("Job 合规性检查完成")
		`,
	},
	{
		Name:        "MutatingWebhookConfiguration 合规性检查",
		Description: "检查 MutatingWebhookConfiguration 的 webhook 指向的 Service 是否存在、是否有活跃 Pod、Pod 状态。",
		Group:       "admissionregistration.k8s.io",
		Version:     "v1",
		Kind:        "MutatingWebhookConfiguration",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_MutatingWebhook_017",
		Script: `
			local mwcs, err = kubectl:GVK("admissionregistration.k8s.io", "v1", "MutatingWebhookConfiguration"):AllNamespace(""):List()
			if err then print("获取 MutatingWebhookConfiguration 失败: " .. tostring(err)) return end
			for _, mwc in ipairs(mwcs) do
				if mwc.webhooks then
					for _, webhook in ipairs(mwc.webhooks) do
						if webhook.clientConfig and webhook.clientConfig.service then
							local svc = webhook.clientConfig.service
							local service, err = kubectl:GVK("", "v1", "Service"):Namespace(svc.namespace):Name(svc.name):Get()
							if err or not service then
								check_event("失败", "MutatingWebhook " .. webhook.name .. " 指向的 Service '" .. svc.namespace .. "/" .. svc.name .. "' 不存在", {namespace=svc.namespace, name=svc.name, webhook=webhook.name})
							else
								if service.spec and service.spec.selector and next(service.spec.selector) ~= nil then
									local selector = ""
									for k, v in pairs(service.spec.selector) do
										if selector ~= "" then selector = selector .. "," end
										selector = selector .. k .. "=" .. v
									end
									local pods, err = kubectl:GVK("", "v1", "Pod"):Namespace(svc.namespace):WithLabelSelector(selector):List()
									if not err and pods and #pods.items == 0 then
										check_event("失败", "MutatingWebhook " .. webhook.name .. " 指向的 Service '" .. svc.namespace .. "/" .. svc.name .. "' 没有活跃 Pod", {namespace=svc.namespace, name=svc.name, webhook=webhook.name})
									end
									if pods and pods.items then
										for _, pod in ipairs(pods.items) do
											if pod.status and pod.status.phase ~= "Running" then
												check_event("失败", "MutatingWebhook " .. webhook.name .. " 指向的 Pod '" .. pod.metadata.name .. "' 状态为 " .. (pod.status.phase or "未知") , {namespace=svc.namespace, name=svc.name, webhook=webhook.name, pod=pod.metadata.name, phase=pod.status.phase})
											end
										end
									end
								end
							end
						end
					end
				end
			end
			print("MutatingWebhookConfiguration 合规性检查完成")
		`,
	},
	{
		Name:        "NetworkPolicy 合规性检查",
		Description: "检查 NetworkPolicy 是否允许所有 Pod,或未作用于任何 Pod。",
		Group:       "networking",
		Version:     "v1",
		Kind:        "NetworkPolicy",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_NetworkPolicy_018",
		Script: `
			local nps, err = kubectl:GVK("networking.k8s.io", "v1", "NetworkPolicy"):AllNamespace(""):List()
			if err then print("获取 NetworkPolicy 失败: " .. tostring(err)) return end
			for _, np in ipairs(nps) do
				if np.spec and np.spec.podSelector and (not np.spec.podSelector.matchLabels or next(np.spec.podSelector.matchLabels) == nil) then
					check_event("失败", "NetworkPolicy '" .. np.metadata.name .. "' 允许所有 Pod", {namespace=np.metadata.namespace, name=np.metadata.name})
				else
					local selector = ""
					if np.spec and np.spec.podSelector and np.spec.podSelector.matchLabels then
						for k, v in pairs(np.spec.podSelector.matchLabels) do
							if selector ~= "" then selector = selector .. "," end
							selector = selector .. k .. "=" .. v
						end
					end
					if selector ~= "" then
						local pods, err = kubectl:GVK("", "v1", "Pod"):Namespace(np.metadata.namespace):WithLabelSelector(selector):List()
						if not err and pods and #pods.items == 0 then
							check_event("失败", "NetworkPolicy '" .. np.metadata.name .. "' 未作用于任何 Pod", {namespace=np.metadata.namespace, name=np.metadata.name})
						end
					end
				end
			end
			print("NetworkPolicy 合规性检查完成")
		`,
	},
	{
		Name:        "Node 合规性检查",
		Description: "检查 Node 的 Condition 状态,非 Ready/EtcdIsVoter 且状态异常时报警。",
		Group:       "",
		Version:     "v1",
		Kind:        "Node",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Node_019",
		Script: `
			local nodes, err = kubectl:GVK("", "v1", "Node"):AllNamespace(""):List()
			if err then print("获取 Node 失败: " .. tostring(err)) return end
			for _, node in ipairs(nodes) do
				if node.status and node.status.conditions then
					for _, cond in ipairs(node.status.conditions) do
						if cond.type == "Ready" then
							if cond.status ~= "True" then
								check_event("失败", node.metadata.name .. " Ready 状态异常: " .. (cond.reason or "") .. " - " .. (cond.message or ""), {name=node.metadata.name, type=cond.type, reason=cond.reason, message=cond.message})
							end
						elseif cond.type == "EtcdIsVoter" then
							-- 跳过 k3s 特有的 EtcdIsVoter
						else
							if cond.status ~= "False" then
								check_event("失败", node.metadata.name .. " " .. cond.type .. " 状态异常: " .. (cond.reason or "") .. " - " .. (cond.message or ""), {name=node.metadata.name, type=cond.type, reason=cond.reason, message=cond.message})
							end
						end
					end
				end
			end
			print("Node 合规性检查完成")
		`,
	},
	{
		Name:        "Pod 合规性检查",
		Description: "检查 Pod 的 Pending、调度失败、CrashLoopBackOff、终止异常、ReadinessProbe 失败等状态。",
		Group:       "",
		Version:     "v1",
		Kind:        "Pod",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Pod_020",
		Script: `
			local pods, err = kubectl:GVK("", "v1", "Pod"):AllNamespace(""):List()
			if err then print("获取 Pod 失败: " .. tostring(err)) return end
			for _, pod in ipairs(pods) do
				if pod.status and pod.status.phase == "Pending" and pod.status.conditions then
					for _, cond in ipairs(pod.status.conditions) do
						if cond.type == "PodScheduled" and cond.reason == "Unschedulable" and cond.message and cond.message ~= "" then
							check_event("失败", cond.message, {namespace=pod.metadata.namespace, name=pod.metadata.name})
						end
					end
				end
				local function check_container_statuses(statuses, phase)
					if not statuses then return end
					for _, cs in ipairs(statuses) do
						if cs.state and cs.state.waiting then
							if cs.state.waiting.reason == "CrashLoopBackOff" and cs.lastState and cs.lastState.terminated then
								check_event("失败", "CrashLoopBackOff: 上次终止原因 " .. (cs.lastState.terminated.reason or "") .. " 容器=" .. cs.name .. " pod=" .. pod.metadata.name, {namespace=pod.metadata.namespace, name=pod.metadata.name, container=cs.name})
							elseif cs.state.waiting.reason and (cs.state.waiting.reason == "ImagePullBackOff" or cs.state.waiting.reason == "ErrImagePull" or cs.state.waiting.reason == "CreateContainerConfigError" or cs.state.waiting.reason == "CreateContainerError" or cs.state.waiting.reason == "RunContainerError" or cs.state.waiting.reason == "InvalidImageName") then
								check_event("失败", cs.state.waiting.message or (cs.state.waiting.reason .. " 容器=" .. cs.name .. " pod=" .. pod.metadata.name), {namespace=pod.metadata.namespace, name=pod.metadata.name, container=cs.name})
							end
						elseif cs.state and cs.state.terminated and cs.state.terminated.exitCode and cs.state.terminated.exitCode ~= 0 then
							check_event("失败", "终止异常: " .. (cs.state.terminated.reason or "Unknown") .. " exitCode=" .. tostring(cs.state.terminated.exitCode) .. " 容器=" .. cs.name .. " pod=" .. pod.metadata.name, {namespace=pod.metadata.namespace, name=pod.metadata.name, container=cs.name, exitCode=cs.state.terminated.exitCode})
						elseif cs.ready == false and phase == "Running" then
							check_event("失败", "容器未就绪: " .. cs.name .. " pod=" .. pod.metadata.name, {namespace=pod.metadata.namespace, name=pod.metadata.name, container=cs.name})
						end
					end
				end
				if pod.status then
					check_container_statuses(pod.status.initContainerStatuses, pod.status.phase)
					check_container_statuses(pod.status.containerStatuses, pod.status.phase)
				end
			end
			print("Pod 合规性检查完成")
		`,
	},
	{
		Name:        "PVC 合规性检查",
		Description: "检查 PVC Pending 状态下的 ProvisioningFailed 事件。",
		Group:       "",
		Version:     "v1",
		Kind:        "PersistentVolumeClaim",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_PVC_021",
		Script: `
			local pvcs, err = kubectl:GVK("", "v1", "PersistentVolumeClaim"):AllNamespace(""):List()
			if err then print("获取 PVC 失败: " .. tostring(err)) return end
			for _, pvc in ipairs(pvcs) do
				if pvc.status and pvc.status.phase == "Pending" then
					local events, err = kubectl:GVK("", "v1", "Event"):Namespace(pvc.metadata.namespace):WithFieldSelector("involvedObject.name=" .. pvc.metadata.name):List()
					if not err and events and events.items then
						for _, evt in ipairs(events.items) do
							if evt.reason == "ProvisioningFailed" and evt.message and evt.message ~= "" then
								check_event("失败", evt.message, {namespace=pvc.metadata.namespace, name=pvc.metadata.name})
							end
						end
					end
				end
			end
			print("PVC 合规性检查完成")
		`,
	},
	{
		Name:        "ReplicaSet 合规性检查",
		Description: "检测副本数为0且有 FailedCreate 的 ReplicaFailure。",
		Group:       "apps",
		Version:     "v1",
		Kind:        "ReplicaSet",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_ReplicaSet_022",
		Script: `
			local rss, err = kubectl:GVK("apps", "v1", "ReplicaSet"):AllNamespace(""):List()
			if err then print("获取 ReplicaSet 失败: " .. tostring(err)) return end
			for _, rs in ipairs(rss) do
				if rs.status and rs.status.replicas == 0 and rs.status.conditions then
					for _, cond in ipairs(rs.status.conditions) do
						if cond.type == "ReplicaFailure" and cond.reason == "FailedCreate" then
							check_event("失败", cond.message or "ReplicaSet 副本创建失败", {namespace=rs.metadata.namespace, name=rs.metadata.name})
						end
					end
				end
			end
			print("ReplicaSet 合规性检查完成")
		`,
	},
	{
		Name:        "Security ServiceAccount 默认账户使用检测",
		Description: "检测 default ServiceAccount 是否被 Pod 使用。",
		Group:       "core",
		Version:     "v1",
		Kind:        "ServiceAccount",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Security_SA_023",
		Script: `
			local sas, err = kubectl:GVK("", "v1", "ServiceAccount"):AllNamespace(""):List()
			if err then print("获取 ServiceAccount 失败: " .. tostring(err)) return end
			for _, sa in ipairs(sas) do
				if sa.metadata and sa.metadata.name == "default" then
					local pods, err = kubectl:GVK("", "v1", "Pod"):Namespace(sa.metadata.namespace):List()
					if not err and pods then
						local defaultSAUsers = {}
						for _, pod in ipairs(pods) do
							if pod.spec and pod.spec.serviceAccountName == "default" then
								table.insert(defaultSAUsers, pod.metadata.name)
							end
						end
						if #defaultSAUsers > 0 then
							check_event("失败", "Default service account 被以下 Pod 使用: " .. table.concat(defaultSAUsers, ", "), {namespace=sa.metadata.namespace, name=sa.metadata.name})
						end
					end
				end
			end
			print("Security ServiceAccount 检查完成")
		`,
	},
	{
		Name:        "Security RoleBinding 通配符检测",
		Description: "检测 RoleBinding 关联的 Role 是否包含通配符权限。",
		Group:       "rbac.authorization.k8s.io",
		Version:     "v1",
		Kind:        "RoleBinding",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Security_RoleBinding_024",
		Script: `
			local rbs, err = kubectl:GVK("rbac.authorization.k8s.io", "v1", "RoleBinding"):AllNamespace(""):List()
			if err then print("获取 RoleBinding 失败: " .. tostring(err)) return end
			for _, rb in ipairs(rbs) do
				if rb.roleRef and rb.roleRef.kind == "Role" and rb.roleRef.name then
					local role, err = kubectl:GVK("rbac.authorization.k8s.io", "v1", "Role"):Namespace(rb.metadata.namespace):Name(rb.roleRef.name):Get()
					if not err and role and role.rules then
						for _, rule in ipairs(role.rules) do
							local function containsWildcard(arr)
								if not arr then return false end
								for _, v in ipairs(arr) do if v == "*" then return true end end
								return false
							end
							if containsWildcard(rule.verbs) or containsWildcard(rule.resources) then
								check_event("失败", "RoleBinding '" .. rb.metadata.name .. "' 关联的 Role '" .. role.metadata.name .. "' 存在通配符权限", {namespace=rb.metadata.namespace, name=rb.metadata.name, role=role.metadata.name})
							end
						end
					end
				end
			end
			print("Security RoleBinding 检查完成")
		`,
	},
	{
		Name:        "Security Pod 安全上下文检测",
		Description: "检测 Pod 是否存在特权容器或缺少安全上下文。",
		Group:       "core",
		Version:     "v1",
		Kind:        "Pod",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_Security_Pod_025",
		Script: `
			local pods, err = kubectl:GVK("", "v1", "Pod"):AllNamespace(""):List()
			if err then print("获取 Pod 失败: " .. tostring(err)) return end
			for _, pod in ipairs(pods) do
				local hasPrivileged = false
				if pod.spec and pod.spec.containers then
					for _, c in ipairs(pod.spec.containers) do
						if c.securityContext and c.securityContext.privileged == true then
							hasPrivileged = true
							check_event("失败", "容器 " .. c.name .. " 以特权模式运行,存在安全风险", {namespace=pod.metadata.namespace, name=pod.metadata.name, container=c.name})
							break
						end
					end
				end
				if not hasPrivileged and (not pod.spec or not pod.spec.securityContext) then
					check_event("失败", "Pod " .. pod.metadata.name .. " 未定义安全上下文,存在安全风险", {namespace=pod.metadata.namespace, name=pod.metadata.name})
				end
			end
			print("Security Pod 安全上下文检查完成")
		`,
	},
	{
		Name:        "StatefulSet 合规性检查",
		Description: "检测 StatefulSet 关联的 Service、StorageClass 是否存在及 Pod 状态。",
		Group:       "apps",
		Version:     "v1",
		Kind:        "StatefulSet",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_StatefulSet_026",
		Script: `
			local stss, err = kubectl:GVK("apps", "v1", "StatefulSet"):AllNamespace(""):List()
			if err then print("获取 StatefulSet 失败: " .. tostring(err)) return end
			for _, sts in ipairs(stss) do
				if sts.spec and sts.spec.serviceName then
					local svc, err = kubectl:GVK("", "v1", "Service"):Namespace(sts.metadata.namespace):Name(sts.spec.serviceName):Get()
					if err or not svc then
						check_event("失败", "StatefulSet 使用的 Service '" .. sts.metadata.namespace .. "/" .. sts.spec.serviceName .. "' 不存在", {namespace=sts.metadata.namespace, name=sts.metadata.name, service=sts.spec.serviceName})
					end
				end
				if sts.spec and sts.spec.volumeClaimTemplates then
					for _, vct in ipairs(sts.spec.volumeClaimTemplates) do
						if vct.spec and vct.spec.storageClassName then
							local sc, err = kubectl:GVK("storage.k8s.io", "v1", "StorageClass"):Name(vct.spec.storageClassName):Get()
							if err or not sc then
								check_event("失败", "StatefulSet 使用的 StorageClass '" .. vct.spec.storageClassName .. "' 不存在", {namespace=sts.metadata.namespace, name=sts.metadata.name, storageClass=vct.spec.storageClassName})
							end
						end
					end
				end
				if sts.spec and sts.spec.replicas and sts.status and sts.status.availableReplicas and sts.spec.replicas ~= sts.status.availableReplicas then
					for i = 0, sts.spec.replicas - 1 do
						local podName = sts.metadata.name .. "-" .. tostring(i)
						local pod, err = kubectl:GVK("", "v1", "Pod"):Namespace(sts.metadata.namespace):Name(podName):Get()
						if err or not pod then
							if i == 0 then
								local events, err = kubectl:GVK("", "v1", "Event"):Namespace(sts.metadata.namespace):WithFieldSelector("involvedObject.name=" .. sts.metadata.name):List()
								if not err and events and events.items then
									for _, evt in ipairs(events.items) do
										if evt.type ~= "Normal" and evt.message and evt.message ~= "" then
											check_event("失败", evt.message, {namespace=sts.metadata.namespace, name=sts.metadata.name})
										end
									end
								end
							end
							break
						end
						if pod.status and pod.status.phase ~= "Running" then
							check_event("失败", "StatefulSet 的 Pod '" .. pod.metadata.name .. "' 不在 Running 状态", {namespace=sts.metadata.namespace, name=sts.metadata.name, pod=pod.metadata.name, phase=pod.status.phase})
							break
						end
					end
				end
			end
			print("StatefulSet 合规性检查完成")
		`,
	},
	{
		Name:        "StorageClass 合规性检查",
		Description: "检测 StorageClass 是否使用了已废弃的 provisioner,及是否存在多个默认 StorageClass。",
		Group:       "storage.k8s.io",
		Version:     "v1",
		Kind:        "StorageClass",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_StorageClass_027",
		Script: `
			local scs, err = kubectl:GVK("storage.k8s.io", "v1", "StorageClass"):AllNamespace(""):List()
			if err then print("获取 StorageClass 失败: " .. tostring(err)) return end
			local defaultCount = 0
			for _, sc in ipairs(scs) do
				if sc.provisioner == "kubernetes.io/no-provisioner" then
					check_event("失败", "StorageClass '" .. sc.metadata.name .. "' 使用了已废弃的 provisioner 'kubernetes.io/no-provisioner'", {name=sc.metadata.name})
				end
				if sc.metadata.annotations and sc.metadata.annotations["storageclass.kubernetes.io/is-default-class"] == "true" then
					defaultCount = defaultCount + 1
				end
			end
			if defaultCount > 1 then
				check_event("失败", "存在多个默认 StorageClass (" .. tostring(defaultCount) .. "),可能导致混淆", {})
			end
			print("StorageClass 合规性检查完成")
		`,
	},
	{
		Name:        "PersistentVolume 合规性检查",
		Description: "检测 PV 是否为 Released/Failed 状态,及容量小于 1Gi。",
		Group:       "core",
		Version:     "v1",
		Kind:        "PersistentVolume",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_PV_028",
		Script: `
			local pvs, err = kubectl:GVK("", "v1", "PersistentVolume"):AllNamespace(""):List()
			if err then print("获取 PersistentVolume 失败: " .. tostring(err)) return end
			for _, pv in ipairs(pvs) do
				if pv.status and pv.status.phase == "Released" then
					check_event("失败", "PersistentVolume '" .. pv.metadata.name .. "' 处于 Released 状态,应及时清理", {name=pv.metadata.name})
				end
				if pv.status and pv.status.phase == "Failed" then
					check_event("失败", "PersistentVolume '" .. pv.metadata.name .. "' 处于 Failed 状态", {name=pv.metadata.name})
				end
				if pv.spec and pv.spec.capacity and pv.spec.capacity.storage then
					local function parseGi(val)
						local n = tonumber(val:match("%d+"))
						if val:find("Gi") then return n end
						if val:find("Mi") then return n and n/1024 or 0 end
						return 0
					end
					if parseGi(pv.spec.capacity.storage) < 1 then
						check_event("失败", "PersistentVolume '" .. pv.metadata.name .. "' 容量过小 (" .. pv.spec.capacity.storage .. ")", {name=pv.metadata.name, capacity=pv.spec.capacity.storage})
					end
				end
			end
			print("PersistentVolume 合规性检查完成")
		`,
	},
	{
		Name:        "PersistentVolumeClaim 合规性检查",
		Description: "检测 PVC Pending/Lost 状态、容量小于 1Gi、无 StorageClass。",
		Group:       "core",
		Version:     "v1",
		Kind:        "PersistentVolumeClaim",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_PVC_029",
		Script: `
			local pvcs, err = kubectl:GVK("", "v1", "PersistentVolumeClaim"):AllNamespace(""):List()
			if err then print("获取 PVC 失败: " .. tostring(err)) return end
			for _, pvc in ipairs(pvcs) do
				if pvc.status and pvc.status.phase == "Pending" then
					check_event("失败", "PersistentVolumeClaim '" .. pvc.metadata.name .. "' 处于 Pending 状态", {namespace=pvc.metadata.namespace, name=pvc.metadata.name})
				elseif pvc.status and pvc.status.phase == "Lost" then
					check_event("失败", "PersistentVolumeClaim '" .. pvc.metadata.name .. "' 处于 Lost 状态", {namespace=pvc.metadata.namespace, name=pvc.metadata.name})
				else
					if pvc.spec and pvc.spec.resources and pvc.spec.resources.requests and pvc.spec.resources.requests.storage then
						local function parseGi(val)
							local n = tonumber(val:match("%d+"))
							if val:find("Gi") then return n end
							if val:find("Mi") then return n and n/1024 or 0 end
							return 0
						end
						if parseGi(pvc.spec.resources.requests.storage) < 1 then
							check_event("失败", "PersistentVolumeClaim '" .. pvc.metadata.name .. "' 容量过小 (" .. pvc.spec.resources.requests.storage .. ")", {namespace=pvc.metadata.namespace, name=pvc.metadata.name, capacity=pvc.spec.resources.requests.storage})
						end
					end
					if (not pvc.spec or not pvc.spec.storageClassName) and (not pvc.spec or not pvc.spec.volumeName or pvc.spec.volumeName == "") then
						check_event("失败", "PersistentVolumeClaim '" .. pvc.metadata.name .. "' 未指定 StorageClass", {namespace=pvc.metadata.namespace, name=pvc.metadata.name})
					end
				end
			end
			print("PersistentVolumeClaim 合规性检查完成")
		`,
	},
	{
		Name:        "ValidatingWebhookConfiguration 合规性检查",
		Description: "检查 ValidatingWebhookConfiguration 的 webhook 指向的 Service 是否存在、是否有活跃 Pod、Pod 状态。",
		Group:       "admissionregistration.k8s.io",
		Version:     "v1",
		Kind:        "ValidatingWebhookConfiguration",
		ScriptType:  constants.LuaScriptTypeBuiltin,
		ScriptCode:  "Builtin_ValidatingWebhook_030",
		Script: `
			local vwcs, err = kubectl:GVK("admissionregistration.k8s.io", "v1", "ValidatingWebhookConfiguration"):AllNamespace(""):List()
			if err then print("获取 ValidatingWebhookConfiguration 失败: " .. tostring(err)) return end
			for _, vwc in ipairs(vwcs) do
				if vwc.webhooks then
					for _, webhook in ipairs(vwc.webhooks) do
						if webhook.clientConfig and webhook.clientConfig.service then
							local svc = webhook.clientConfig.service
							local service, err = kubectl:GVK("", "v1", "Service"):Namespace(svc.namespace):Name(svc.name):Get()
							if err or not service then
								check_event("失败", "ValidatingWebhook " .. webhook.name .. " 指向的 Service '" .. svc.namespace .. "/" .. svc.name .. "' 不存在", {namespace=svc.namespace, name=svc.name, webhook=webhook.name})
							else
								if service.spec and service.spec.selector and next(service.spec.selector) ~= nil then
									local selector = ""
									for k, v in pairs(service.spec.selector) do
										if selector ~= "" then selector = selector .. "," end
										selector = selector .. k .. "=" .. v
									end
									local pods, err = kubectl:GVK("", "v1", "Pod"):Namespace(svc.namespace):WithLabelSelector(selector):List()
									if not err and pods and #pods.items == 0 then
										check_event("失败", "ValidatingWebhook " .. webhook.name .. " 指向的 Service '" .. svc.namespace .. "/" .. svc.name .. "' 没有活跃 Pod", {namespace=svc.namespace, name=svc.name, webhook=webhook.name})
									end
									if pods and pods.items then
										for _, pod in ipairs(pods.items) do
											if pod.status and pod.status.phase ~= "Running" then
												check_event("失败", "ValidatingWebhook " .. webhook.name .. " 指向的 Pod '" .. pod.metadata.name .. "' 状态为 " .. (pod.status.phase or "未知") , {namespace=svc.namespace, name=svc.name, webhook=webhook.name, pod=pod.metadata.name, phase=pod.status.phase})
											end
										end
									end
								end
							end
						end
					end
				end
			end
			print("ValidatingWebhookConfiguration 合规性检查完成")
		`,
	},
}

BuiltinLuaScripts 内置检查脚本列表

Functions

func AddBuiltinLuaScripts added in v0.0.129

func AddBuiltinLuaScripts() error

func AddInnerAdminUser added in v0.0.97

func AddInnerAdminUser() error

AddInnerAdminUser 添加内置管理员账户

func AddInnerAdminUserGroup added in v0.0.97

func AddInnerAdminUserGroup() error

AddInnerAdminUserGroup 添加内置管理员账户组

func AddInnerMCPServer added in v0.0.66

func AddInnerMCPServer() error

AddInnerMCPServer 检查并初始化名为 "k8m" 的内部 MCP 服务器配置,不存在则创建,已存在则更新其 URL。

func AutoMigrate

func AutoMigrate() error

func DeleteHelmReleaseByNsAndReleaseName added in v0.0.137

func DeleteHelmReleaseByNsAndReleaseName(namespace, releaseName, cluster string) error

DeleteHelmReleaseByNsAndReleaseName 删除指定namespace和releaseName的HelmRelease记录

func FixClusterAuthorizationTypeName added in v0.0.87

func FixClusterAuthorizationTypeName() error

func FixClusterName added in v0.0.48

func FixClusterName() error

func FixRoleName added in v0.0.69

func FixRoleName() error

func GetBuiltinLuaScriptsVersion added in v0.0.129

func GetBuiltinLuaScriptsVersion(db *gorm.DB) (string, error)

GetBuiltinLuaScriptsVersion 获取数据库中记录的内置脚本版本

func InitConditionTable added in v0.0.86

func InitConditionTable() error

func InitConfigTable added in v0.0.74

func InitConfigTable() error

func MigrateAIModel added in v0.0.124

func MigrateAIModel() error

func SetBuiltinLuaScriptsVersion added in v0.0.129

func SetBuiltinLuaScriptsVersion(db *gorm.DB, version string) error

SetBuiltinLuaScriptsVersion 设置数据库中内置脚本的版本号

Types

type AIModelConfig added in v0.0.124

type AIModelConfig struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id"`
	ApiKey      string    `json:"api_key"`
	ApiURL      string    `json:"api_url"`
	ApiModel    string    `json:"api_model"`
	Temperature float32   `json:"temperature"`
	TopP        float32   `json:"top_p"`
	Think       bool      `json:"think"` // 是否关闭思考模式
	Description string    `json:"description,omitempty"`
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"`
}

func (*AIModelConfig) Delete added in v0.0.124

func (c *AIModelConfig) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*AIModelConfig) GetOne added in v0.0.124

func (c *AIModelConfig) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*AIModelConfig, error)

func (*AIModelConfig) List added in v0.0.124

func (c *AIModelConfig) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*AIModelConfig, int64, error)

func (*AIModelConfig) Save added in v0.0.124

func (c *AIModelConfig) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type ApiKey added in v0.0.80

type ApiKey struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Username    string    `gorm:"index;not null" json:"username,omitempty"` // 所属用户
	Key         string    `gorm:"type:text" json:"key,omitempty"`           // API密钥值
	Description string    `json:"description,omitempty"`                    // 描述信息
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"`   // Automatically managed by GORM for update time
	CreatedBy   string    `json:"created_by,omitempty"`   // 创建者
	LastUsedAt  time.Time `json:"last_used_at,omitempty"` // 最后使用时间
}

ApiKey 用户API密钥

func (*ApiKey) Delete added in v0.0.80

func (c *ApiKey) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*ApiKey) GetOne added in v0.0.80

func (c *ApiKey) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*ApiKey, error)

func (*ApiKey) List added in v0.0.80

func (c *ApiKey) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*ApiKey, int64, error)

func (*ApiKey) Save added in v0.0.80

func (c *ApiKey) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type ClusterUserRole added in v0.0.69

type ClusterUserRole struct {
	ID                  uint                               `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Cluster             string                             `gorm:"index" json:"cluster,omitempty"`  // 集群名称
	Username            string                             `gorm:"index" json:"username,omitempty"` // 用户名
	Role                string                             `gorm:"index" json:"role,omitempty"`     // 角色类型:只读、读写、Exec
	Namespaces          string                             `json:"namespaces,omitempty"`            // Namespaces列表,逗号分割 ,该用户可以访问的Ns
	BlacklistNamespaces string                             `json:"blacklist_namespaces,omitempty"`  // 黑名单Namespaces列表,逗号分割,禁止访问的Ns
	AuthorizationType   constants.ClusterAuthorizationType `json:"authorization_type,omitempty"`    // 用户类型。User\Group两种,默认为User,空为User。Group指用户组
	CreatedAt           time.Time                          `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt           time.Time                          `json:"updated_at,omitempty"`
}

ClusterUserRole 集群用户权限表 AuthorizationType有两种类型(user、user_group),如果是用户,那么代表这个人有哪些权限 如果是Group,那么代表这个组有哪些权限,这个组可能会有多个用户,那么这多个用户都有相关的权限

func (*ClusterUserRole) Delete added in v0.0.69

func (c *ClusterUserRole) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*ClusterUserRole) GetOne added in v0.0.69

func (c *ClusterUserRole) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*ClusterUserRole, error)

func (*ClusterUserRole) List added in v0.0.69

func (c *ClusterUserRole) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*ClusterUserRole, int64, error)

func (*ClusterUserRole) Save added in v0.0.69

func (c *ClusterUserRole) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type ConditionReverse added in v0.0.86

type ConditionReverse struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Name        string    `gorm:"type:text" json:"name,omitempty"`        // 指标名称,使用包含方式查找。如Pressure、Unavailable等
	Enabled     bool      `json:"enabled,omitempty"`                      // 指标描述
	Description string    `gorm:"type:text" json:"description,omitempty"` // 指标描述
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"` // 更新时间
}

ConditionReverse 用于记录需要反转解释的K8s状态指标

func (*ConditionReverse) Delete added in v0.0.86

func (c *ConditionReverse) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 删除记录

func (*ConditionReverse) GetOne added in v0.0.86

func (c *ConditionReverse) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*ConditionReverse, error)

GetOne 获取单条记录

func (*ConditionReverse) List added in v0.0.86

func (c *ConditionReverse) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*ConditionReverse, int64, error)

List 列出所有记录

func (*ConditionReverse) Save added in v0.0.86

func (c *ConditionReverse) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存记录

type Config added in v0.0.74

type Config struct {
	ID                   uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	ProductName          string    `json:"product_name,omitempty"` // 产品名称
	LoginType            string    `json:"login_type,omitempty"`
	JwtTokenSecret       string    `json:"jwt_token_secret,omitempty"`
	NodeShellImage       string    `json:"node_shell_image,omitempty"`
	KubectlShellImage    string    `json:"kubectl_shell_image,omitempty"`
	ImagePullTimeout     int       `gorm:"default:30" json:"image_pull_timeout,omitempty"` // 镜像拉取超时时间(秒)
	AnySelect            bool      `gorm:"default:true" json:"any_select"`
	PrintConfig          bool      `json:"print_config"`
	EnableAI             bool      `gorm:"default:true" json:"enable_ai"` // 是否启用AI功能,默认开启
	UseBuiltInModel      bool      `gorm:"default:true" json:"use_built_in_model"`
	MaxIterations        int32     `json:"max_iterations"`                                     //  模型自动对话的最大轮数
	MaxHistory           int32     `json:"max_history"`                                        //  模型对话上下文历史记录数
	ResourceCacheTimeout int       `gorm:"default:60" json:"resource_cache_timeout,omitempty"` // 资源缓存时间(秒)
	ModelID              uint      `json:"model_id"`
	CreatedAt            time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt            time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
}

func (*Config) Delete added in v0.0.124

func (c *Config) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*Config) GetOne added in v0.0.124

func (c *Config) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*Config, error)

func (*Config) List added in v0.0.124

func (c *Config) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*Config, int64, error)

func (*Config) Save added in v0.0.124

func (c *Config) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type CustomTemplate

type CustomTemplate struct {
	ID        uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"` // 模板 ID,主键,自增
	Name      string    `gorm:"index" json:"name,omitempty"`                  // 模板名称,非空,最大长度 255
	Content   string    `gorm:"type:text" json:"content,omitempty"`           // 模板内容,支持大文本存储
	Kind      string    `gorm:"index" json:"kind,omitempty"`                  // 模板类型,最大长度 100
	Cluster   string    `gorm:"index" json:"cluster,omitempty"`               // 模板类型,最大长度 100
	IsGlobal  bool      `gorm:"index" json:"is_global,omitempty"`             // 模板类型,最大长度 100
	CreatedBy string    `gorm:"index" json:"created_by,omitempty"`            // 创建者
	CreatedAt time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
}

CustomTemplate 表示用户自定义模板表的结构体

func (*CustomTemplate) Delete

func (c *CustomTemplate) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*CustomTemplate) GetOne

func (c *CustomTemplate) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*CustomTemplate, error)

func (*CustomTemplate) List

func (c *CustomTemplate) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*CustomTemplate, int64, error)

func (*CustomTemplate) Save

func (c *CustomTemplate) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type HelmChart added in v0.0.51

type HelmChart struct {
	ID             uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	RepositoryID   uint      `gorm:"index;not null" json:"repository_id,omitempty"` // 关联仓库ID
	RepositoryName string    `json:"repository_name,omitempty"`                     // 关联仓库ID
	Name           string    `gorm:"index;not null" json:"name,omitempty"`          // Chart名称
	LatestVersion  string    `json:"latest_version,omitempty"`                      // 最新版本(冗余字段,优化查询)
	Description    string    `json:"description,omitempty"`                         // Chart描述
	Home           string    `json:"home,omitempty"`                                // 项目主页URL
	Icon           string    `json:"icon,omitempty"`                                // Chart图标链接
	Keywords       string    `json:"keywords,omitempty"`                            // 关键词(PostgreSQL数组类型)
	KubeVersion    string    `json:"kubeVersion,omitempty"`                         // 最低k8s版本要求
	AppVersion     string    `json:"appVersion,omitempty"`                          // app应用版本
	Deprecated     bool      `json:"deprecated,omitempty"`                          // Whether or not this chart is deprecated
	CreatedAt      time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt      time.Time `json:"updated_at"`
	Sources        string    `json:"sources,omitempty"` // 源码主页
}

func (*HelmChart) BatchSave added in v0.0.137

func (c *HelmChart) BatchSave(params *dao.Params, events []*HelmChart, batchSize int, queryFuncs ...func(*gorm.DB) *gorm.DB) error

BatchSave 批量保存 InspectionCheckEvent 实例

func (*HelmChart) Delete added in v0.0.51

func (c *HelmChart) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*HelmChart) GetOne added in v0.0.51

func (c *HelmChart) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*HelmChart, error)

func (*HelmChart) List added in v0.0.51

func (c *HelmChart) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*HelmChart, int64, error)

func (*HelmChart) Save added in v0.0.51

func (c *HelmChart) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type HelmRelease added in v0.0.137

type HelmRelease struct {
	ID           uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	ReleaseName  string    `gorm:"index" json:"release_name,omitempty"`       // Release 名称
	RepoName     string    `json:"repo_name,omitempty"`                       // 仓库名称
	Namespace    string    `gorm:"not null;index" json:"namespace,omitempty"` // 命名空间
	ChartName    string    `gorm:"not null" json:"chart_name,omitempty"`      // Chart 名称
	ChartVersion string    `json:"chart_version,omitempty"`                   // Chart 版本
	Values       string    `json:"values,omitempty"`                          // values.yaml 内容
	Status       string    `json:"status,omitempty"`                          // 安装状态
	Cluster      string    `json:"cluster,omitempty"`
	Result       string    `json:"result,omitempty"` // 描述
	CreatedAt    time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt    time.Time `json:"updated_at,omitempty"`
}

func GetHelmReleaseByNsAndReleaseName added in v0.0.137

func GetHelmReleaseByNsAndReleaseName(namespace, releaseName, cluster string) (*HelmRelease, error)

GetHelmReleaseByNsAndReleaseName 通过namespace和releaseName获取repo名称

func (*HelmRelease) Delete added in v0.0.137

func (r *HelmRelease) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*HelmRelease) GetOne added in v0.0.137

func (r *HelmRelease) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*HelmRelease, error)

func (*HelmRelease) List added in v0.0.137

func (r *HelmRelease) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*HelmRelease, int64, error)

func (*HelmRelease) Save added in v0.0.137

func (r *HelmRelease) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type HelmRepository added in v0.0.51

type HelmRepository struct {
	ID                    uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Name                  string    `gorm:"not null" json:"name,omitempty"` // 仓库名称(唯一)
	URL                   string    `gorm:"not null" json:"url,omitempty"`  // 仓库地址(如 https://charts.example.com
	Type                  string    `gorm:"comment:仓库类型(OCI/HTTP)" json:"type,omitempty"`
	Description           string    `json:"description,omitempty"` // 仓库描述
	AuthType              string    `gorm:"comment:认证类型(Basic/AuthToken/OAuth)" json:"auth_type,omitempty"`
	Username              string    `json:"username,omitempty"` // 认证用户名(加密存储)
	Password              string    `gorm:"-;comment:密码(临时字段,存储时需加密)" json:"password,omitempty"`
	EncryptedSecret       string    `gorm:"comment:加密后的凭据" json:"encrypted_secret,omitempty"`
	IsActive              bool      `gorm:"default:true" json:"is_active,omitempty"` // 是否启用
	Generated             string    `json:"generated,omitempty"`                     // repo 索引文件创建时间
	CertFile              string    `json:"certFile,omitempty"`
	KeyFile               string    `json:"keyFile,omitempty"`
	CAFile                string    `json:"caFile,omitempty"`
	InsecureSkipTLSverify bool      `json:"insecure_skip_tls_verify,omitempty"`
	PassCredentialsAll    bool      `json:"pass_credentials_all,omitempty"`
	CreatedAt             time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt             time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
}

func (*HelmRepository) Delete added in v0.0.51

func (c *HelmRepository) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*HelmRepository) GetIDByNameAndURL added in v0.0.51

func (c *HelmRepository) GetIDByNameAndURL(params *dao.Params) (uint, error)

func (*HelmRepository) GetOne added in v0.0.51

func (c *HelmRepository) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*HelmRepository, error)

func (*HelmRepository) List added in v0.0.51

func (c *HelmRepository) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*HelmRepository, int64, error)

func (*HelmRepository) Save added in v0.0.51

func (c *HelmRepository) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type InspectionCheckEvent added in v0.0.129

type InspectionCheckEvent struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	RecordID    uint      `json:"record_id"`                        // 关联的巡检执行记录ID
	EventStatus string    `json:"event_status"`                     // 事件状态(如“正常”、“失败”)
	EventMsg    string    `json:"event_msg"`                        // 事件消息
	Extra       string    `gorm:"type:text" json:"extra,omitempty"` // 额外上下文
	ScriptName  string    `json:"script_name"`                      // 检测脚本名称
	Kind        string    `json:"kind"`                             // 检查的资源类型
	CheckDesc   string    `json:"check_desc"`                       // 检查脚本内容描述
	Cluster     string    `json:"cluster"`                          // 检查集群
	Namespace   string    `json:"namespace"`                        // 资源命名空间
	Name        string    `json:"name"`                             // 资源名称
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"`  // Automatically managed by GORM for update time
	ScheduleID  *uint     `json:"schedule_id,omitempty"` // 关联的定时任务ID
}

InspectionCheckEvent 用于记录每次检测的详细信息,包括检测状态、消息、额外上下文、脚本名称、资源类型、描述、命名空间和资源名。

func (*InspectionCheckEvent) BatchSave added in v0.0.129

func (c *InspectionCheckEvent) BatchSave(params *dao.Params, events []*InspectionCheckEvent, batchSize int, queryFuncs ...func(*gorm.DB) *gorm.DB) error

BatchSave 批量保存 InspectionCheckEvent 实例

func (*InspectionCheckEvent) Delete added in v0.0.129

func (c *InspectionCheckEvent) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 根据指定 ID 删除 InspectionCheckEvent 实例

func (*InspectionCheckEvent) GetOne added in v0.0.129

func (c *InspectionCheckEvent) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*InspectionCheckEvent, error)

GetOne 获取单个 InspectionCheckEvent 实例

func (*InspectionCheckEvent) List added in v0.0.129

func (c *InspectionCheckEvent) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*InspectionCheckEvent, int64, error)

List 返回符合条件的 InspectionCheckEvent 列表及总数

func (*InspectionCheckEvent) Save added in v0.0.129

func (c *InspectionCheckEvent) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存或更新 InspectionCheckEvent 实例

type InspectionLuaScript added in v0.0.129

type InspectionLuaScript struct {
	ID          uint                    `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Name        string                  `json:"name"`                                   // 脚本名称,主键
	Description string                  `json:"description"`                            // 脚本描述
	Group       string                  `json:"group"`                                  // 分组
	Version     string                  `json:"version"`                                // 版本
	Kind        string                  `json:"kind"`                                   // 类型
	ScriptType  constants.LuaScriptType `json:"script_type"`                            // 脚本类型 内置/自定义
	Script      string                  `gorm:"type:text" json:"script"`                // 脚本内容
	ScriptCode  string                  `gorm:"uniqueIndex;size:64" json:"script_code"` // 脚本唯一标识码,每个脚本唯一
	CreatedAt   time.Time               `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time               `json:"updated_at,omitempty"` // Automatically managed by GORM for update time

}

InspectionLuaScript 表示一条 Lua 脚本的元数据及内容 包含脚本名称、描述、分组、版本、类型和脚本内容等信息 用于存储和管理自定义 Lua 脚本

func (*InspectionLuaScript) Delete added in v0.0.129

func (c *InspectionLuaScript) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 根据指定 ID 删除 InspectionLuaScript 实例

func (*InspectionLuaScript) GetOne added in v0.0.129

func (c *InspectionLuaScript) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*InspectionLuaScript, error)

GetOne 获取单个 InspectionLuaScript 实例

func (*InspectionLuaScript) List added in v0.0.129

func (c *InspectionLuaScript) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*InspectionLuaScript, int64, error)

List 返回符合条件的 InspectionLuaScript 列表及总数

func (*InspectionLuaScript) Save added in v0.0.129

func (c *InspectionLuaScript) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存或更新 InspectionLuaScript 实例

type InspectionLuaScriptBuiltinVersion added in v0.0.129

type InspectionLuaScriptBuiltinVersion struct {
	Key       string    `gorm:"primaryKey;size:64" json:"key"` // 固定为 builtin_lua_scripts
	Version   string    `json:"version"`                       // 版本号
	UpdatedAt time.Time `json:"updated_at"`
}

InspectionLuaScriptBuiltinVersion 用于记录内置脚本的版本号 只会有一条记录,key 固定为 builtin_lua_scripts 用于判断是否需要更新内置脚本

type InspectionRecord added in v0.0.129

type InspectionRecord struct {
	ID           uint       `gorm:"primaryKey;autoIncrement" json:"id,omitempty"` // 主键
	ScheduleID   *uint      `json:"schedule_id,omitempty"`                        // 关联的定时任务ID,可为空(手动触发时为空)
	ScheduleName string     `json:"schedule_name,omitempty"`                      // 巡检任务名称快照
	Cluster      string     `json:"cluster"`                                      // 巡检目标集群
	TriggerType  string     `json:"trigger_type"`                                 // 触发类型(manual/cron)
	Status       string     `json:"status"`                                       // 执行状态(pending/running/success/failed)
	StartTime    time.Time  `json:"start_time"`
	EndTime      *time.Time `json:"end_time,omitempty"`
	CreatedAt    time.Time  `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt    time.Time  `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
	ErrorCount   int        `json:"error_count"`
	AISummary    string     `json:"ai_summary,omitempty"` // AI生成的巡检总结
}

func (*InspectionRecord) Delete added in v0.0.129

func (c *InspectionRecord) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 删除指定ID的 InspectionRecord

func (*InspectionRecord) GetAISummaryById added in v0.0.132

func (c *InspectionRecord) GetAISummaryById(recordID uint) (string, error)

GetAISummaryById 获取 InspectionRecord 的AISummary

func (*InspectionRecord) GetOne added in v0.0.129

func (c *InspectionRecord) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*InspectionRecord, error)

GetOne 获取单个 InspectionRecord

func (*InspectionRecord) List added in v0.0.129

func (c *InspectionRecord) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*InspectionRecord, int64, error)

List 返回符合条件的 InspectionRecord 列表及总数

func (*InspectionRecord) Save added in v0.0.129

func (c *InspectionRecord) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存或更新 InspectionRecord 实例

type InspectionSchedule added in v0.0.129

type InspectionSchedule struct {
	ID           uint         `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Name         string       `json:"name"`                          // 巡检任务名称
	Description  string       `json:"description"`                   // 巡检任务描述
	Clusters     string       `json:"clusters"`                      // 目标集群列表
	Webhooks     string       `json:"webhooks"`                      // webhook列表
	WebhookNames string       `json:"webhook_names"`                 // webhook 名称列表
	Cron         string       `json:"cron"`                          // cron表达式,定时周期
	ScriptCodes  string       `gorm:"type:text" json:"script_codes"` // 每个脚本唯一标识码
	Enabled      bool         `json:"enabled"`                       // 是否启用该任务
	CreatedAt    time.Time    `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt    time.Time    `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
	CronRunID    cron.EntryID `json:"cron_run_id"`          // cron 运行ID,可用于删除
	LastRunTime  *time.Time   `json:"last_run_time"`        // 上次运行时间
	ErrorCount   int          `json:"error_count"`          // 错误次数
}

InspectionSchedule 用于描述定时巡检任务的元数据,包括任务名称、描述、目标集群、cron表达式等 该结构体可用于存储和管理定时巡检任务的相关信息 字段涵盖任务名称、描述、目标集群、cron表达式、启用状态、创建人和创建时间 可结合数据库或配置管理进行持久化

func (*InspectionSchedule) Delete added in v0.0.129

func (c *InspectionSchedule) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 根据指定 ID 删除 InspectionSchedule 实例

func (*InspectionSchedule) GetOne added in v0.0.129

func (c *InspectionSchedule) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*InspectionSchedule, error)

GetOne 获取单个 InspectionSchedule 实例

func (*InspectionSchedule) List added in v0.0.129

func (c *InspectionSchedule) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*InspectionSchedule, int64, error)

List 返回符合条件的 InspectionSchedule 列表及总数

func (*InspectionSchedule) Save added in v0.0.129

func (c *InspectionSchedule) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存或更新 InspectionSchedule 实例

type InspectionScriptResult added in v0.0.129

type InspectionScriptResult struct {
	ID         uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	RecordID   uint      `json:"record_id"`   // 关联的巡检执行记录ID
	ScriptName string    `json:"script_name"` // 脚本名称
	ScriptKind string    `json:"script_kind"` // 脚本资源类型
	ScriptDesc string    `json:"script_desc"` // 脚本描述
	StartTime  time.Time `json:"start_time"`
	EndTime    time.Time `json:"end_time"`
	StdOutput  string    `json:"std_output"`          // 脚本标准输出
	ErrorMsg   string    `json:"error_msg,omitempty"` // 错误信息
	CreatedAt  time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt  time.Time `json:"updated_at,omitempty"`  // Automatically managed by GORM for update time
	Cluster    string    `json:"cluster"`               // 目标集群
	ScheduleID *uint     `json:"schedule_id,omitempty"` // 巡检计划ID
}

func (*InspectionScriptResult) BatchSave added in v0.0.129

func (c *InspectionScriptResult) BatchSave(params *dao.Params, events []*InspectionScriptResult, batchSize int, queryFuncs ...func(*gorm.DB) *gorm.DB) error

BatchSave 批量保存 InspectionCheckEvent 实例

func (*InspectionScriptResult) Delete added in v0.0.129

func (c *InspectionScriptResult) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 删除指定ID的 InspectionScriptResult

func (*InspectionScriptResult) GetOne added in v0.0.129

func (c *InspectionScriptResult) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*InspectionScriptResult, error)

GetOne 获取单个 InspectionScriptResult

func (*InspectionScriptResult) List added in v0.0.129

func (c *InspectionScriptResult) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*InspectionScriptResult, int64, error)

List 返回符合条件的 InspectionScriptResult 列表及总数

func (*InspectionScriptResult) Save added in v0.0.129

func (c *InspectionScriptResult) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存或更新 InspectionScriptResult 实例

type KubeConfig

type KubeConfig struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"` // 模板 ID,主键,自增
	Content     string    `gorm:"type:text" json:"content,omitempty"`           // 模板内容,支持大文本存储
	Server      string    `gorm:"index" json:"server,omitempty"`
	User        string    `gorm:"index" json:"user,omitempty"`
	Cluster     string    `gorm:"index" json:"cluster,omitempty"` // 模板类型,最大长度 100
	Namespace   string    `gorm:"index" json:"namespace,omitempty"`
	DisplayName string    `gorm:"index" json:"display_name,omitempty"`
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
}

KubeConfig 用户导入kubeconfig

func (*KubeConfig) Delete

func (c *KubeConfig) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*KubeConfig) GetOne

func (c *KubeConfig) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*KubeConfig, error)

func (*KubeConfig) List

func (c *KubeConfig) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*KubeConfig, int64, error)

func (*KubeConfig) Save

func (c *KubeConfig) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type LDAPConfig added in v0.0.148

type LDAPConfig struct {
	ID              uint      `gorm:"primaryKey" json:"id"`
	Name            string    `gorm:"size:50;not null" json:"name"`            // 配置名称
	Host            string    `gorm:"size:100;not null" json:"host"`           // 服务器地址
	Port            int       `gorm:"not null" json:"port"`                    // 端口
	BindDN          string    `gorm:"size:100;not null" json:"bind_dn"`        // 管理员DN
	BindPassword    string    `gorm:"not null" json:"bind_password,omitempty"` // 管理员密码(加密存储)
	BaseDN          string    `gorm:"size:100;not null" json:"base_dn"`        // 基础DN
	UserFilter      string    `gorm:"size:255" json:"user_filter"`             // 用户过滤器
	LOGIN2AUTHCLOSE bool      `gorm:"default:true" json:"login2_auth_close"`   // 登录后开启认证
	DefaultGroup    string    `gorm:"size:50" json:"default_group"`            // 默认用户组
	Enabled         bool      `gorm:"default:true" json:"enabled"`             // 启用状态
	CreatedAt       time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt       time.Time `json:"updated_at"`
}

func (*LDAPConfig) Delete added in v0.0.148

func (l *LDAPConfig) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 删除记录

func (*LDAPConfig) GetOne added in v0.0.148

func (l *LDAPConfig) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*LDAPConfig, error)

GetOne 获取单条记录

func (*LDAPConfig) List added in v0.0.148

func (l *LDAPConfig) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*LDAPConfig, int64, error)

List 列出所有记录

func (*LDAPConfig) Save added in v0.0.148

func (l *LDAPConfig) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存记录

type MCPServerConfig added in v0.0.64

type MCPServerConfig struct {
	ID        uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	URL       string    `gorm:"not null" json:"url,omitempty"`
	Name      string    `gorm:"uniqueIndex;not null;type:varchar(255)" json:"name,omitempty"`
	Enabled   bool      `gorm:"default:false" json:"enabled,omitempty"`
	CreatedAt time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt time.Time `json:"updated_at,omitempty"`
}

MCPServerConfig MCP服务器配置

func (*MCPServerConfig) Delete added in v0.0.64

func (c *MCPServerConfig) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*MCPServerConfig) GetOne added in v0.0.64

func (c *MCPServerConfig) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*MCPServerConfig, error)

func (*MCPServerConfig) List added in v0.0.64

func (c *MCPServerConfig) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*MCPServerConfig, int64, error)

func (*MCPServerConfig) Save added in v0.0.64

func (c *MCPServerConfig) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type MCPTool added in v0.0.85

type MCPTool struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	ServerName  string    `json:"server_name,omitempty"`                                        // mcp server id,唯一
	Name        string    `gorm:"uniqueIndex;not null;type:varchar(255)" json:"name,omitempty"` // 工具名称,唯一
	Description string    `gorm:"type:text" json:"description,omitempty"`                       // 工具描述
	InputSchema string    `gorm:"type:text" json:"input_schema,omitempty"`                      // 输入模式,JSON格式
	Enabled     bool      `gorm:"default:true" json:"enabled,omitempty"`                        // 是否启用
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`                        // 创建时间
	UpdatedAt   time.Time `json:"updated_at,omitempty"`                                         // 更新时间
}

MCPTool MCP工具配置

func (*MCPTool) BatchSave added in v0.0.85

func (c *MCPTool) BatchSave(params *dao.Params, tools []*MCPTool, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*MCPTool) Delete added in v0.0.85

func (c *MCPTool) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*MCPTool) GetOne added in v0.0.85

func (c *MCPTool) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*MCPTool, error)

func (*MCPTool) List added in v0.0.85

func (c *MCPTool) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*MCPTool, int64, error)

func (*MCPTool) Save added in v0.0.85

func (c *MCPTool) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type MCPToolCallResult added in v0.0.107

type MCPToolCallResult struct {
	ToolName   string `json:"tool_name"`
	Parameters any    `json:"parameters"`
	Result     string `json:"result"`
	Error      string `json:"error,omitempty"`
}

MCPToolCallResult 存储工具调用的结果

type MCPToolLog added in v0.0.88

type MCPToolLog struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	ToolName    string    `gorm:"index" json:"tool_name,omitempty"`      // 工具名称
	ServerName  string    `gorm:"index" json:"server_name,omitempty"`    // 服务器名称
	Parameters  string    `gorm:"type:text" json:"parameters,omitempty"` // 执行参数
	Prompt      string    `gorm:"type:text" json:"prompt,omitempty"`
	Result      string    `gorm:"type:text" json:"result,omitempty"` // 执行结果
	Error       string    `gorm:"type:text" json:"error,omitempty"`  // 错误信息
	ExecuteTime int64     `json:"execute_time,omitempty"`            // 执行时间(毫秒)
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	CreatedBy   string    `gorm:"index" json:"created_by,omitempty"`
}

MCPToolLog MCP工具执行日志

func (*MCPToolLog) Delete added in v0.0.88

func (c *MCPToolLog) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*MCPToolLog) GetOne added in v0.0.88

func (c *MCPToolLog) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*MCPToolLog, error)

func (*MCPToolLog) List added in v0.0.88

func (c *MCPToolLog) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*MCPToolLog, int64, error)

func (*MCPToolLog) Save added in v0.0.88

func (c *MCPToolLog) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type McpKey added in v0.0.89

type McpKey struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Username    string    `gorm:"index;not null" json:"username,omitempty"` // 所属用户
	McpKey      string    `gorm:"type:text" json:"mcp_key,omitempty"`       // MCP密钥值
	Description string    `json:"description,omitempty"`                    // 描述信息
	Enabled     bool      `gorm:"default:true" json:"enabled,omitempty"`    // 是否启用
	Jwt         string    `gorm:"type:text" json:"jwt"`                     //  JWT
	LastUsedAt  time.Time `json:"last_used_at,omitempty"`                   // 最后使用时间
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
	CreatedBy   string    `json:"created_by,omitempty"` // 创建者
}

McpKey MCP访问密钥

func (*McpKey) Delete added in v0.0.89

func (c *McpKey) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*McpKey) GetOne added in v0.0.89

func (c *McpKey) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*McpKey, error)

func (*McpKey) List added in v0.0.89

func (c *McpKey) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*McpKey, int64, error)

func (*McpKey) Save added in v0.0.89

func (c *McpKey) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error
type Menu struct {
	ID        uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	MenuData  string    `gorm:"type:text" json:"-"`
	CreatedAt time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt time.Time `json:"updated_at,omitempty"`
}

Menu represents a versioned menu structure. Each save operation creates a new record with an incremented version.

func (m *Menu) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete removes menu records by their IDs.

func (m *Menu) DeleteByID(id int) error

DeleteByID removes a single menu record by its ID.

func (m *Menu) GetLatest(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*Menu, error)

GetLatest retrieves the latest version of the menu.

func (m *Menu) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*Menu, error)

GetOne retrieves a single menu record by its ID.

func (m *Menu) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*Menu, int64, error)

List retrieves a list of menu versions based on parameters.

func (m *Menu) MarshalJSON() ([]byte, error)

MarshalJSON 自定义JSON序列化方法 将存储在数据库中的字符串转换为JSON对象

func (c *Menu) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error
func (m *Menu) UnmarshalJSON(data []byte) error

UnmarshalJSON 自定义JSON反序列化方法 将接收到的JSON数据转换为字符串存储

type MenuDataJSON struct {
	ID        uint        `json:"id,omitempty"`
	MenuData  interface{} `json:"menu_data,omitempty"`
	CreatedAt time.Time   `json:"created_at,omitempty"`
	UpdatedAt time.Time   `json:"updated_at,omitempty"`
}

MenuDataJSON 用于处理JSON序列化和反序列化

type OperationLog

type OperationLog struct {
	ID           uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"` // 模板 ID,主键,自增
	UserName     string    `json:"username,omitempty"`
	Role         string    `json:"role,omitempty"`
	Cluster      string    `gorm:"index" json:"cluster,omitempty"`
	Namespace    string    `json:"namespace,omitempty"`
	Name         string    `json:"name,omitempty"`
	Group        string    `json:"group,omitempty"`                       // 资源group
	Kind         string    `json:"kind,omitempty"`                        // 资源kind
	Action       string    `json:"action,omitempty"`                      // 操作类型
	Params       string    `gorm:"type:text" json:"params,omitempty"`     // 操作参数
	ActionResult string    `json:"action_result,omitempty"`               // 操作结果
	CreatedAt    time.Time `json:"created_at,omitempty" gorm:"<-:create"` // Automatically managed by GORM for creation time
	UpdatedAt    time.Time `json:"updated_at,omitempty"`                  // Automatically managed by GORM for update time

}

OperationLog 用户导入OperationLog

func (*OperationLog) Delete

func (c *OperationLog) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*OperationLog) GetOne

func (c *OperationLog) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*OperationLog, error)

func (*OperationLog) List

func (c *OperationLog) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*OperationLog, int64, error)

func (*OperationLog) Save

func (c *OperationLog) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type Release added in v0.0.137

type Release struct {
	Name        string `json:"name"`
	Namespace   string `json:"namespace"`
	Revision    string `json:"revision"`
	Updated     string `json:"updated"`
	Status      string `json:"status"`
	Chart       string `json:"chart"`
	AppVersion  string `json:"app_version"`
	Description string `json:"description"`
}

type ReleaseHistory added in v0.0.137

type ReleaseHistory struct {
	Revision   int    `json:"revision"`
	Updated    string `json:"updated"`
	Status     string `json:"status"`
	Chart      string `json:"chart"`
	AppVersion string `json:"app_version"`
}

type SSOConfig added in v0.0.92

type SSOConfig struct {
	ID                 uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Name               string    `json:"name,omitempty"`                                    // 配置名称
	Type               string    `gorm:"default:oidc" json:"type,omitempty"`                // 配置类型
	ClientID           string    `gorm:"type:text;" json:"client_id,omitempty"`             // OAuth2客户端ID
	ClientSecret       string    `gorm:"type:text;" json:"client_secret,omitempty"`         // OAuth2客户端密钥
	Issuer             string    `gorm:"type:text;" json:"issuer,omitempty"`                // 认证服务器地址
	Enabled            bool      `gorm:"default:false" json:"enabled,omitempty"`            // 是否启用SSO
	PreferUserNameKeys string    `gorm:"type:text;" json:"prefer_user_name_keys,omitempty"` // 用户自定义获取用户名的字段顺序,适用于如果用户名字段不在默认字段中情况
	Scopes             string    `gorm:"type:text;" json:"scopes,omitempty"`                // 授权范围
	CreatedAt          time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt          time.Time `json:"updated_at,omitempty"` // 更新时间
}

SSOConfig SSO配置表

func (*SSOConfig) Delete added in v0.0.92

func (s *SSOConfig) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Delete 删除记录

func (*SSOConfig) GetOne added in v0.0.92

func (s *SSOConfig) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*SSOConfig, error)

GetOne 获取单条记录

func (*SSOConfig) List added in v0.0.92

func (s *SSOConfig) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*SSOConfig, int64, error)

List 列出所有记录

func (*SSOConfig) Save added in v0.0.92

func (s *SSOConfig) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Save 保存记录

type ShellLog

type ShellLog struct {
	ID            uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"` // 模板 ID,主键,自增
	UserName      string    `json:"username,omitempty"`
	Cluster       string    `json:"cluster,omitempty"`
	Namespace     string    `json:"namespace,omitempty"`
	PodName       string    `json:"pod_name,omitempty"`
	ContainerName string    `json:"container_name,omitempty"`
	Command       string    `json:"command,omitempty"` // shell 执行命令
	Role          string    `json:"role,omitempty"`
	CreatedAt     time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt     time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
}

ShellLog 用户导入ShellLog

func (*ShellLog) Delete

func (c *ShellLog) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*ShellLog) GetOne

func (c *ShellLog) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*ShellLog, error)

func (*ShellLog) List

func (c *ShellLog) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*ShellLog, int64, error)

func (*ShellLog) Save

func (c *ShellLog) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type User

type User struct {
	ID               uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Username         string    `gorm:"type:varchar(255);uniqueIndex;not null" json:"username,omitempty"`
	Salt             string    `gorm:"not null" json:"salt,omitempty"`
	Password         string    `gorm:"not null" json:"password,omitempty"`
	GroupNames       string    `json:"group_names,omitempty"`
	Source           string    `json:"source,omitempty"` // 来源,如:db, ldap_config.json, oauth
	CreatedAt        time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt        time.Time `json:"updated_at,omitempty"`                          // Automatically managed by GORM for update time
	TwoFAEnabled     bool      `gorm:"default:false" json:"two_fa_enabled,omitempty"` // 是否启用2FA
	TwoFAType        string    `gorm:"size:20" json:"two_fa_type,omitempty"`          // 2FA类型:如 'totp', 'sms', 'email'
	TwoFASecret      string    `gorm:"size:100" json:"two_fa_secret,omitempty"`       // 2FA密钥
	TwoFABackupCodes string    `gorm:"size:500" json:"two_fa_backup_codes,omitempty"` // 备用恢复码,逗号分隔
	TwoFAAppName     string    `gorm:"size:100" json:"two_fa_app_name,omitempty"`     // 2FA应用名称,用于提醒用户使用的是哪个软件
	Disabled         bool      `gorm:"default:false" json:"disabled,omitempty"`       // 是否启用
}

User 用户导入User

func (*User) Delete

func (c *User) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*User) GetOne

func (c *User) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*User, error)

func (*User) IsDisabled added in v0.0.132

func (c *User) IsDisabled(username string) (bool, error)

func (*User) List

func (c *User) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*User, int64, error)

func (*User) Save

func (c *User) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*User) UpdateColumn added in v0.0.139

func (c *User) UpdateColumn(columnName string, value any) error

type UserGroup added in v0.0.55

type UserGroup struct {
	ID          uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	GroupName   string    `gorm:"index" json:"group_name,omitempty"`
	Description string    `json:"description,omitempty"`
	Role        string    `gorm:"index" json:"role,omitempty"` // 管理员/只读
	MenuData    string    `gorm:"type:text" json:"menu_data"`
	CreatedAt   time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt   time.Time `json:"updated_at,omitempty"`
}

func (*UserGroup) Delete added in v0.0.55

func (c *UserGroup) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*UserGroup) GetOne added in v0.0.55

func (c *UserGroup) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*UserGroup, error)

func (*UserGroup) List added in v0.0.55

func (c *UserGroup) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*UserGroup, int64, error)

func (*UserGroup) Save added in v0.0.55

func (c *UserGroup) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

type WebhookReceiver added in v0.0.130

type WebhookReceiver struct {
	ID            uint      `gorm:"primaryKey;autoIncrement" json:"id,omitempty"`
	Name          string    `json:"name,omitempty"`     // webhook名称
	Platform      string    `json:"platform,omitempty"` // feishu,dingtalk
	TargetURL     string    `json:"target_url,omitempty"`
	Method        string    `json:"method,omitempty"`
	Template      string    `gorm:"type:text" json:"template,omitempty"`
	SignSecret    string    `json:"sign_secret,omitempty"`
	SignAlgo      string    `json:"sign_algo,omitempty"`       // e.g. "hmac-sha256", "feishu"
	SignHeaderKey string    `json:"sign_header_key,omitempty"` // e.g. "X-Signature" or unused
	CreatedAt     time.Time `json:"created_at,omitempty" gorm:"<-:create"`
	UpdatedAt     time.Time `json:"updated_at,omitempty"` // Automatically managed by GORM for update time
}

func (*WebhookReceiver) Delete added in v0.0.130

func (c *WebhookReceiver) Delete(params *dao.Params, ids string, queryFuncs ...func(*gorm.DB) *gorm.DB) error

func (*WebhookReceiver) GetNamesByIds added in v0.0.132

func (c *WebhookReceiver) GetNamesByIds(ids string) ([]string, error)

func (*WebhookReceiver) GetOne added in v0.0.130

func (c *WebhookReceiver) GetOne(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) (*WebhookReceiver, error)

func (*WebhookReceiver) List added in v0.0.130

func (c *WebhookReceiver) List(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) ([]*WebhookReceiver, int64, error)

func (*WebhookReceiver) ListByRecordID added in v0.0.132

func (c *WebhookReceiver) ListByRecordID(recordID uint) ([]*WebhookReceiver, error)

func (*WebhookReceiver) Save added in v0.0.130

func (c *WebhookReceiver) Save(params *dao.Params, queryFuncs ...func(*gorm.DB) *gorm.DB) error

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL