mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 03:28:59 +02:00
✨️ Do not block middleware startup due to stream intialization (#281)
* 🍱 not block on stream startup * 🍱 fix * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 update readme * 📚 clarify StreamStartupBlock warning in README Make the fail-open implication of StreamStartupBlock=false explicit: banned IPs are allowed through until the first stream sync completes. * 🐛 clear isCrowdsecStreamStartup on alreadyUpdated path When cacheTimeoutKey is already set (another instance/process has populated the stream cache within the update window), the early return in handleStreamCache used to leave isCrowdsecStreamStartup at true, causing this instance to keep sending startup=true on subsequent ticks. Flip the flag in the early-return path so startup is correctly tracked across multi-instance deployments sharing a cache. --------- Co-authored-by: mhx <mathieu@hanotaux.fr>
This commit is contained in:
+11
-6
@@ -64,7 +64,7 @@ const (
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
isStartup = true
|
||||
isCrowdsecStreamStartup = true
|
||||
isCrowdsecStreamHealthy = true
|
||||
updateFailure int64
|
||||
streamTicker chan bool
|
||||
@@ -123,7 +123,7 @@ type Bouncer struct {
|
||||
|
||||
// New creates the crowdsec bouncer plugin.
|
||||
//
|
||||
//nolint:gocyclo
|
||||
//nolint:nestif,gocyclo,gocognit
|
||||
func New(_ context.Context, next http.Handler, config *configuration.Config, name string) (http.Handler, error) {
|
||||
config.LogLevel = strings.ToUpper(config.LogLevel)
|
||||
log := logger.NewWithFormat(config.LogLevel, config.LogFilePath, config.LogFormat)
|
||||
@@ -291,8 +291,11 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
handleStreamTicker(bouncer)
|
||||
isStartup = false
|
||||
if config.StreamStartupBlock {
|
||||
handleStreamTicker(bouncer)
|
||||
} else {
|
||||
go handleStreamTicker(bouncer)
|
||||
}
|
||||
streamTicker = startTicker("stream", config.UpdateIntervalSeconds, log, func() {
|
||||
handleStreamTicker(bouncer)
|
||||
})
|
||||
@@ -301,7 +304,7 @@ func New(_ context.Context, next http.Handler, config *configuration.Config, nam
|
||||
// Start metrics ticker if not already running
|
||||
if metricsTicker == nil && config.MetricsUpdateIntervalSeconds > 0 {
|
||||
lastMetricsPush = time.Now() // Initialize lastMetricsPush when starting the metrics ticker
|
||||
handleMetricsTicker(bouncer)
|
||||
go handleMetricsTicker(bouncer)
|
||||
metricsTicker = startTicker("metrics", config.MetricsUpdateIntervalSeconds, log, func() {
|
||||
handleMetricsTicker(bouncer)
|
||||
})
|
||||
@@ -624,6 +627,7 @@ func handleStreamCache(bouncer *Bouncer) error {
|
||||
_, err := bouncer.cacheClient.Get(cacheTimeoutKey)
|
||||
if err == nil {
|
||||
bouncer.log.Debug("handleStreamCache:alreadyUpdated")
|
||||
isCrowdsecStreamStartup = false
|
||||
return nil
|
||||
}
|
||||
if err.Error() != cache.CacheMiss {
|
||||
@@ -634,7 +638,7 @@ func handleStreamCache(bouncer *Bouncer) error {
|
||||
Scheme: bouncer.crowdsecScheme,
|
||||
Host: bouncer.crowdsecHost,
|
||||
Path: bouncer.crowdsecPath + bouncer.crowdsecStreamRoute,
|
||||
RawQuery: fmt.Sprintf("startup=%t", !isCrowdsecStreamHealthy || isStartup),
|
||||
RawQuery: fmt.Sprintf("startup=%t", !isCrowdsecStreamHealthy || isCrowdsecStreamStartup),
|
||||
}
|
||||
body, err := crowdsecQuery(bouncer, streamRouteURL.String(), nil)
|
||||
if err != nil {
|
||||
@@ -664,6 +668,7 @@ func handleStreamCache(bouncer *Bouncer) error {
|
||||
bouncer.cacheClient.Delete(decision.Value)
|
||||
}
|
||||
bouncer.log.Debug("handleStreamCache:updated")
|
||||
isCrowdsecStreamStartup = false
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user