refactor: split deployment configuration validation

This commit is contained in:
2026-08-22 15:57:03 +08:00
parent 54567e243c
commit a81f81e347
+34 -28
View File
@@ -325,66 +325,72 @@ func rejectUnknownKeys(table map[string]any, parent string, allowed ...string) e
// 它依次校验 daemon.environment、backend.systemctl_path 的绝对路径约束,再按 backend.type // 它依次校验 daemon.environment、backend.systemctl_path 的绝对路径约束,再按 backend.type
// 分支精确校验原生或容器槽位的 unit、jar、container_name、health_endpoint 等字段。 // 分支精确校验原生或容器槽位的 unit、jar、container_name、health_endpoint 等字段。
func (c Config) Validate() error { func (c Config) Validate() error {
switch c.Daemon.Environment { if c.Daemon.Environment != EnvironmentDev && c.Daemon.Environment != EnvironmentProd {
case EnvironmentDev, EnvironmentProd:
default:
return fmt.Errorf("daemon.environment must be %q or %q", EnvironmentDev, EnvironmentProd) return fmt.Errorf("daemon.environment must be %q or %q", EnvironmentDev, EnvironmentProd)
} }
if err := validateAbsolutePath("backend.systemctl_path", c.Backend.SystemctlPath); err != nil { if err := validateAbsolutePath("backend.systemctl_path", c.Backend.SystemctlPath); err != nil {
return err return err
} }
if c.Backend.StopGraceSeconds != nil && *c.Backend.StopGraceSeconds <= 0 { if err := validateBackend(c.Backend); err != nil {
return err
}
return validateNodeSsr(c.NodeSsr)
}
func validateBackend(backend Backend) error {
if backend.StopGraceSeconds != nil && *backend.StopGraceSeconds <= 0 {
return errors.New("backend.stop_grace_seconds must be a positive integer") return errors.New("backend.stop_grace_seconds must be a positive integer")
} }
switch c.Backend.Type { switch backend.Type {
case BackendTypeNative: case BackendTypeNative:
if c.Backend.Slot.Port8080.ContainerName != "" || c.Backend.Slot.Port8081.ContainerName != "" { if backend.Slot.Port8080.ContainerName != "" || backend.Slot.Port8081.ContainerName != "" {
return errors.New("native backend slots do not accept container_name") return errors.New("native backend slots do not accept container_name")
} }
if c.Backend.ReleaseDir != nativeReleaseDir { if backend.ReleaseDir != nativeReleaseDir {
return fmt.Errorf("backend.release_dir must be %q", nativeReleaseDir) return fmt.Errorf("backend.release_dir must be %q", nativeReleaseDir)
} }
if c.Backend.ActiveJAR != nativeActiveJAR { if backend.ActiveJAR != nativeActiveJAR {
return fmt.Errorf("backend.active_jar must be %q", nativeActiveJAR) return fmt.Errorf("backend.active_jar must be %q", nativeActiveJAR)
} }
if err := validateNativeSlot("backend.slot.8080", c.Backend.Slot.Port8080, nativeUnit8080, nativeSlotJAR8080, nativeHealthURL8080); err != nil { return validateNativeBackendSlots(backend.Slot)
return err
}
if err := validateNativeSlot("backend.slot.8081", c.Backend.Slot.Port8081, nativeUnit8081, nativeSlotJAR8081, nativeHealthURL8081); err != nil {
return err
}
case BackendTypeContainer: case BackendTypeContainer:
if c.Backend.ReleaseDir != "" || c.Backend.ActiveJAR != "" { if backend.ReleaseDir != "" || backend.ActiveJAR != "" {
return errors.New("container backend does not accept release_dir or active_jar") return errors.New("container backend does not accept release_dir or active_jar")
} }
if c.Backend.Slot.Port8080.Unit != "" || c.Backend.Slot.Port8080.JAR != "" || c.Backend.Slot.Port8081.Unit != "" || c.Backend.Slot.Port8081.JAR != "" { if backend.Slot.Port8080.Unit != "" || backend.Slot.Port8080.JAR != "" || backend.Slot.Port8081.Unit != "" || backend.Slot.Port8081.JAR != "" {
return errors.New("container backend slots do not accept unit or jar") return errors.New("container backend slots do not accept unit or jar")
} }
if err := validateContainerSlot("backend.slot.8080", c.Backend.Slot.Port8080, containerName8080, nativeHealthURL8080); err != nil { if err := validateContainerSlot("backend.slot.8080", backend.Slot.Port8080, containerName8080, nativeHealthURL8080); err != nil {
return err
}
if err := validateContainerSlot("backend.slot.8081", c.Backend.Slot.Port8081, containerName8081, nativeHealthURL8081); err != nil {
return err return err
} }
return validateContainerSlot("backend.slot.8081", backend.Slot.Port8081, containerName8081, nativeHealthURL8081)
default: default:
return fmt.Errorf("backend.type must be %q or %q", BackendTypeNative, BackendTypeContainer) return fmt.Errorf("backend.type must be %q or %q", BackendTypeNative, BackendTypeContainer)
} }
if c.NodeSsr.Type == "" {
}
func validateNativeBackendSlots(slots BackendSlots) error {
if err := validateNativeSlot("backend.slot.8080", slots.Port8080, nativeUnit8080, nativeSlotJAR8080, nativeHealthURL8080); err != nil {
return err
}
return validateNativeSlot("backend.slot.8081", slots.Port8081, nativeUnit8081, nativeSlotJAR8081, nativeHealthURL8081)
}
func validateNodeSsr(node NodeSsr) error {
if node.Type == "" {
return nil return nil
} }
if c.NodeSsr.Type != BackendTypeContainer { if node.Type != BackendTypeContainer {
return fmt.Errorf("nodeSsr.type must be %q", BackendTypeContainer) return fmt.Errorf("nodeSsr.type must be %q", BackendTypeContainer)
} }
if c.NodeSsr.StopGraceSeconds != nil && *c.NodeSsr.StopGraceSeconds <= 0 { if node.StopGraceSeconds != nil && *node.StopGraceSeconds <= 0 {
return errors.New("nodeSsr.stop_grace_seconds must be a positive integer") return errors.New("nodeSsr.stop_grace_seconds must be a positive integer")
} }
if err := validateNodeSsrSlot("nodeSsr.slot.18910", c.NodeSsr.Slot.Port18910, nodeSsrContainerName18910, nodeSsrHealthURL18910); err != nil { if err := validateNodeSsrSlot("nodeSsr.slot.18910", node.Slot.Port18910, nodeSsrContainerName18910, nodeSsrHealthURL18910); err != nil {
return err return err
} }
if err := validateNodeSsrSlot("nodeSsr.slot.28910", c.NodeSsr.Slot.Port28910, nodeSsrContainerName28910, nodeSsrHealthURL28910); err != nil { return validateNodeSsrSlot("nodeSsr.slot.28910", node.Slot.Port28910, nodeSsrContainerName28910, nodeSsrHealthURL28910)
return err
}
return nil
} }
// SlotForNodeSsrPort 返回 Node SSR 宿主端口对应的槽位配置。 // SlotForNodeSsrPort 返回 Node SSR 宿主端口对应的槽位配置。