feat(waf): complete composable rule orchestration

Add the React Flow rule editor, ordered graph APIs and runtime DAG execution.\n\nPublish rules only on OpenResty reload and reconcile checksum-driven IP group snapshots in bounded shared memory.
This commit is contained in:
ryan
2026-07-13 14:16:55 +08:00
parent d36409fbf9
commit a1a997bcda
72 changed files with 5897 additions and 3080 deletions
+16 -4
View File
@@ -66,6 +66,7 @@ func main() {
"lua_dir", cfg.LuaDir,
"runtime_config_dir", cfg.RuntimeConfigDir,
"mmdb_path", cfg.MMDBPath,
"city_mmdb_path", cfg.CityMMDBPath,
)
client := httpclient.New(cfg.ServerURL, cfg.InitialAuthToken(), cfg.RequestTimeout.Duration())
@@ -81,6 +82,8 @@ func main() {
LuaDir: cfg.LuaDir,
NginxLuaDir: cfg.OpenrestyLuaDir,
RuntimeConfigDir: cfg.RuntimeConfigDir,
MMDBPath: cfg.MMDBPath,
CityMMDBPath: cfg.CityMMDBPath,
PagesDir: cfg.PagesDir,
OpenrestyObservabilityListen: nginx.ObservabilityListenAddress(cfg.OpenrestyObservabilityPort),
OpenrestyObservabilityPort: cfg.OpenrestyObservabilityPort,
@@ -122,10 +125,9 @@ func main() {
}
ctx, stop := signal.NotifyContext(context.Background(), syscall.SIGINT, syscall.SIGTERM)
geoIPUpdater := &geoipupdate.Updater{
MMDBPath: cfg.MMDBPath,
DownloadURL: cfg.MMDBDownloadURL,
UpdateInterval: cfg.MMDBUpdateInterval.Duration(),
geoIPUpdater := newGeoIPUpdater(cfg)
if err = geoIPUpdater.EnsureInitialDatabases(ctx); err != nil {
slog.Warn("failed to prepare GeoIP databases before agent startup", "error", err)
}
go geoIPUpdater.Run(ctx)
slog.Info("agent process started")
@@ -138,3 +140,13 @@ func main() {
stop()
slog.Info("agent process stopped")
}
func newGeoIPUpdater(cfg *config.Config) *geoipupdate.Updater {
return &geoipupdate.Updater{
MMDBPath: cfg.MMDBPath,
DownloadURL: cfg.MMDBDownloadURL,
CityMMDBPath: cfg.CityMMDBPath,
CityDownloadURL: cfg.CityMMDBDownloadURL,
UpdateInterval: cfg.MMDBUpdateInterval.Duration(),
}
}
+24
View File
@@ -0,0 +1,24 @@
package main
import (
"testing"
"time"
"github.com/Rain-kl/Wavelet/internal/apps/agent/config"
)
func TestNewGeoIPUpdaterWiresCountryAndCity(t *testing.T) {
cfg := &config.Config{
MMDBPath: "/data/GeoLite2-Country.mmdb",
MMDBDownloadURL: "https://geo.example/GeoLite2-Country.mmdb",
CityMMDBPath: "/data/GeoLite2-City.mmdb",
CityMMDBDownloadURL: "https://geo.example/GeoLite2-City.mmdb",
MMDBUpdateInterval: config.MillisecondDuration(time.Hour),
}
updater := newGeoIPUpdater(cfg)
if updater.MMDBPath != cfg.MMDBPath || updater.DownloadURL != cfg.MMDBDownloadURL ||
updater.CityMMDBPath != cfg.CityMMDBPath || updater.CityDownloadURL != cfg.CityMMDBDownloadURL ||
updater.UpdateInterval != time.Hour {
t.Fatalf("GeoIP updater wiring incomplete: %#v", updater)
}
}