feat: 路由改名/kubectl预装/导出YAML精简/Service标签页优化/Alpine镜像源换清华

- 路由 /deploy/credentials → /deploy/configureTools
- kubectl 改为预装(Dockerfile) + 种子数据 preinstall
- 导出YAML精简: Service/Ingress/Deployment 全面清理运行时字段
- DeploymentEditService 只显示匹配 selector 的关联 Service
- Alpine 镜像源 mirrors.aliyun.com → mirrors.tuna.tsinghua.edu.cn
This commit is contained in:
attacker committed 2026-06-23 02:22:52 +00:00
1 parent dd7cb6895e
commit 451f65f9c8
9 files changed
+109 -29

No files matched your search

+66 -5
View File
@@ -269,6 +269,10 @@ func cleanResourceYAML(obj map[string]interface{}) {
delete(meta, "annotations")
}
}
// 移除空的 labels
if labels, ok := meta["labels"].(map[string]interface{}); ok && len(labels) == 0 {
delete(meta, "labels")
}
}
// 删除 status
@@ -276,11 +280,21 @@ func cleanResourceYAML(obj map[string]interface{}) {
// 清理 spec 中的运行时字段
if spec, ok := obj["spec"].(map[string]interface{}); ok {
// Service: 移除动态分配的 clusterIP 和 nodePorts
if obj["kind"] == "Service" {
kind, _ := obj["kind"].(string)
// Service: 移除动态分配字段和默认值
if kind == "Service" {
delete(spec, "clusterIP")
delete(spec, "clusterIPs")
// nodePorts 在 ports 数组内 — 仅移除 NodePort 类型的 nodePort 字段
delete(spec, "internalTrafficPolicy")
delete(spec, "ipFamilies")
delete(spec, "ipFamilyPolicy")
// sessionAffinity 默认 "None" → 移除
if sa, ok := spec["sessionAffinity"].(string); ok && sa == "None" {
delete(spec, "sessionAffinity")
}
delete(spec, "allocateLoadBalancerNodePorts")
// 移除 ports 内的 nodePort(仅 NodePort/LoadBalancer 类型)
if ports, ok := spec["ports"].([]interface{}); ok {
for _, p := range ports {
if pm, ok := p.(map[string]interface{}); ok {
@@ -290,8 +304,9 @@ func cleanResourceYAML(obj map[string]interface{}) {
}
}
// Deployment: 清理 template.metadata 和 template.spec 中的运行时字段
if obj["kind"] == "Deployment" {
// Deployment / StatefulSet / DaemonSet: 清理运行时和默认值
if kind == "Deployment" || kind == "StatefulSet" || kind == "DaemonSet" {
// 清理 template
if template, ok := spec["template"].(map[string]interface{}); ok {
if tMeta, ok := template["metadata"].(map[string]interface{}); ok {
delete(tMeta, "creationTimestamp")
@@ -304,8 +319,54 @@ func cleanResourceYAML(obj map[string]interface{}) {
}
if tSpec, ok := template["spec"].(map[string]interface{}); ok {
delete(tSpec, "nodeName")
delete(tSpec, "serviceAccountName") // 移除 default 值
// 清理容器内的 terminationMessagePath/Policy 默认值
if containers, ok := tSpec["containers"].([]interface{}); ok {
for _, c := range containers {
if cm, ok := c.(map[string]interface{}); ok {
if tmp, ok := cm["terminationMessagePath"].(string); ok && tmp == "/dev/termination-log" {
delete(cm, "terminationMessagePath")
}
if tmp, ok := cm["terminationMessagePolicy"].(string); ok && tmp == "File" {
delete(cm, "terminationMessagePolicy")
}
// 清理默认 imagePullPolicy
if ip, ok := cm["imagePullPolicy"].(string); ok && ip == "Always" {
delete(cm, "imagePullPolicy")
}
// 清理空 resources
if res, ok := cm["resources"].(map[string]interface{}); ok && len(res) == 0 {
delete(cm, "resources")
}
}
}
}
// 清理 dnsPolicy 默认值
if dp, ok := tSpec["dnsPolicy"].(string); ok && dp == "ClusterFirst" {
delete(tSpec, "dnsPolicy")
}
if rp, ok := tSpec["restartPolicy"].(string); ok && rp == "Always" {
delete(tSpec, "restartPolicy")
}
if tp, ok := tSpec["terminationGracePeriodSeconds"].(float64); ok && tp == 30 {
delete(tSpec, "terminationGracePeriodSeconds")
}
}
}
// 清理默认值
if rhl, ok := spec["revisionHistoryLimit"].(float64); ok && rhl == 10 {
delete(spec, "revisionHistoryLimit")
}
if pds, ok := spec["progressDeadlineSeconds"].(float64); ok && pds == 600 {
delete(spec, "progressDeadlineSeconds")
}
}
// Ingress: 清理默认值
if kind == "Ingress" {
if ic, ok := spec["ingressClassName"].(string); ok && ic == "" {
delete(spec, "ingressClassName")
}
}
}
}
+9 -7
View File
@@ -1605,13 +1605,14 @@ func (h *KubernetesHandler) listDeploymentsWithNS(c *gin.Context, ns string) {
deps, err := client.ListDeployments()
if err != nil { c.JSON(500, models.Response{Code: 500, Message: "K8s API error: " + err.Error()}); return }
type DepSummary struct {
Namespace string `json:"namespace"`
Name string `json:"name"`
Replicas int `json:"replicas"`
AvailableReplicas int `json:"available_replicas"`
ReadyReplicas int `json:"ready_replicas"`
Image string `json:"image"`
Paused bool `json:"paused"`
Namespace string `json:"namespace"`
Name string `json:"name"`
Replicas int `json:"replicas"`
AvailableReplicas int `json:"available_replicas"`
ReadyReplicas int `json:"ready_replicas"`
Image string `json:"image"`
Paused bool `json:"paused"`
Selector map[string]string `json:"selector,omitempty"` // matchLabels — 前端 Service Tab 关联用
}
result := []DepSummary{}
for _, d := range deps.Items {
@@ -1625,6 +1626,7 @@ func (h *KubernetesHandler) listDeploymentsWithNS(c *gin.Context, ns string) {
ReadyReplicas: d.Status.ReadyReplicas,
Image: image,
Paused: d.Spec.Paused,
Selector: func() map[string]string { if d.Spec.Selector != nil { return d.Spec.Selector.MatchLabels }; return nil }(),
})
}
c.JSON(200, models.Response{Code: 200, Data: result})