feat: 添加 RuntimeRouteConfigPath 支持,优化 Nginx 配置管理

This commit is contained in:
ryan
2026-03-12 23:09:15 +08:00
parent a5da53a2fb
commit 4e19cd1565
3 changed files with 67 additions and 13 deletions
+9 -4
View File
@@ -42,11 +42,16 @@ func main() {
client := httpclient.New(cfg.ServerURL, cfg.InitialAuthToken(), cfg.RequestTimeout.Duration()) client := httpclient.New(cfg.ServerURL, cfg.InitialAuthToken(), cfg.RequestTimeout.Duration())
stateStore := state.NewStore(cfg.StatePath) stateStore := state.NewStore(cfg.StatePath)
runtimeRouteConfigPath := cfg.RouteConfigPath
if cfg.OpenrestyPath == "" {
runtimeRouteConfigPath = nginx.DockerRouteConfigPath
}
runtimeManager := &nginx.Manager{ runtimeManager := &nginx.Manager{
MainConfigPath: cfg.MainConfigPath, MainConfigPath: cfg.MainConfigPath,
RouteConfigPath: cfg.RouteConfigPath, RouteConfigPath: cfg.RouteConfigPath,
CertDir: cfg.CertDir, RuntimeRouteConfigPath: runtimeRouteConfigPath,
NginxCertDir: cfg.OpenrestyCertDir, CertDir: cfg.CertDir,
NginxCertDir: cfg.OpenrestyCertDir,
Executor: nginx.NewExecutor(nginx.ExecutorOptions{ Executor: nginx.NewExecutor(nginx.ExecutorOptions{
NginxPath: cfg.OpenrestyPath, NginxPath: cfg.OpenrestyPath,
DockerBinary: cfg.DockerBinary, DockerBinary: cfg.DockerBinary,
+19 -9
View File
@@ -20,6 +20,7 @@ import (
const CertDirPlaceholder = "__ATSF_CERT_DIR__" const CertDirPlaceholder = "__ATSF_CERT_DIR__"
const RouteConfigPlaceholder = "__ATSF_ROUTE_CONFIG__" const RouteConfigPlaceholder = "__ATSF_ROUTE_CONFIG__"
const DockerMainConfigPath = "/usr/local/openresty/nginx/conf/nginx.conf" const DockerMainConfigPath = "/usr/local/openresty/nginx/conf/nginx.conf"
const DockerRouteConfigPath = "/etc/nginx/conf.d/atsflare_routes.conf"
const dockerRuntimeCommand = "openresty" const dockerRuntimeCommand = "openresty"
@@ -191,11 +192,12 @@ func (e *DockerExecutor) runContainer(ctx context.Context) error {
} }
type Manager struct { type Manager struct {
MainConfigPath string MainConfigPath string
RouteConfigPath string RouteConfigPath string
CertDir string RuntimeRouteConfigPath string
NginxCertDir string CertDir string
Executor Executor NginxCertDir string
Executor Executor
} }
func (m *Manager) Apply(ctx context.Context, mainConfig string, routeConfig string, supportFiles []protocol.SupportFile) error { func (m *Manager) Apply(ctx context.Context, mainConfig string, routeConfig string, supportFiles []protocol.SupportFile) error {
@@ -280,8 +282,8 @@ func (m *Manager) CurrentChecksum() (string, error) {
return "", err return "", err
} }
normalizedMain := string(mainData) normalizedMain := string(mainData)
if m.RouteConfigPath != "" { if includePath := m.routeConfigIncludePath(); includePath != "" {
normalizedMain = strings.ReplaceAll(normalizedMain, m.RouteConfigPath, RouteConfigPlaceholder) normalizedMain = strings.ReplaceAll(normalizedMain, includePath, RouteConfigPlaceholder)
} }
normalizedRoute := string(data) normalizedRoute := string(data)
if m.NginxCertDir != "" { if m.NginxCertDir != "" {
@@ -579,10 +581,18 @@ func (m *Manager) renderRouteConfig(content string) string {
} }
func (m *Manager) renderMainConfig(content string) string { func (m *Manager) renderMainConfig(content string) string {
if m.RouteConfigPath == "" { includePath := m.routeConfigIncludePath()
if includePath == "" {
return content return content
} }
return strings.ReplaceAll(content, RouteConfigPlaceholder, m.RouteConfigPath) return strings.ReplaceAll(content, RouteConfigPlaceholder, includePath)
}
func (m *Manager) routeConfigIncludePath() string {
if strings.TrimSpace(m.RuntimeRouteConfigPath) != "" {
return strings.TrimSpace(m.RuntimeRouteConfigPath)
}
return strings.TrimSpace(m.RouteConfigPath)
} }
func checksum(content string) string { func checksum(content string) string {
+39
View File
@@ -371,6 +371,45 @@ func TestManagerApplyAndChecksumIncludeMainConfig(t *testing.T) {
} }
} }
func TestManagerApplyUsesRuntimeRouteConfigPath(t *testing.T) {
tempDir := t.TempDir()
mainPath := filepath.Join(tempDir, "nginx.conf")
routePath := filepath.Join(tempDir, "conf.d", "atsflare_routes.conf")
manager := &Manager{
MainConfigPath: mainPath,
RouteConfigPath: routePath,
RuntimeRouteConfigPath: DockerRouteConfigPath,
CertDir: filepath.Join(tempDir, "certs"),
NginxCertDir: "/etc/nginx/atsflare-certs",
Executor: &fakeExecutor{},
}
if err := manager.Apply(context.Background(), "include __ATSF_ROUTE_CONFIG__;\n", "server { listen 80; }\n", nil); err != nil {
t.Fatalf("Apply failed: %v", err)
}
mainData, err := os.ReadFile(mainPath)
if err != nil {
t.Fatalf("failed to read main config: %v", err)
}
if string(mainData) != "include "+DockerRouteConfigPath+";\n" {
t.Fatalf("unexpected main config include path: %s", string(mainData))
}
value, err := manager.CurrentChecksum()
if err != nil {
t.Fatalf("CurrentChecksum failed: %v", err)
}
expected := bundleChecksum(
"include __ATSF_ROUTE_CONFIG__;\n",
"server { listen 80; }\n",
nil,
)
if value != expected {
t.Fatalf("unexpected checksum: got %s want %s", value, expected)
}
}
func TestDetectVersionFromDockerImage(t *testing.T) { func TestDetectVersionFromDockerImage(t *testing.T) {
runner := &fakeRunner{ runner := &fakeRunner{
runFn: func(name string, args ...string) ([]byte, error) { runFn: func(name string, args ...string) ([]byte, error) {