mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-10-17 23:19:37 +02:00
Disable request blocking when CrowdSec is unavailable in live mode. (#373)
* Disable request blocking when CrowdSec is unavailable in live mode. * 📝 document the live-mode behaviour and cover it with tests The README said UpdateMaxFailure is "used only in stream and alone mode", which this branch makes untrue, so the feature was undiscoverable from the docs. It now also records that -1 is the only value with any effect in live and none mode, since that path has no failure counter. Test_handleNoStreamCache had a TODO and no cases, so this path had no coverage in either direction. Adds four: live blocks at the default and at any positive value, live lets the request through at -1, and none does the same. The last two fail without the three-line change in this branch. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: mhx <mathieu@hanotaux.fr> Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
3 files changed
+59
-9
No files matched your search
@@ -473,7 +473,8 @@ make run
|
||||
- UpdateMaxFailure
|
||||
- int64
|
||||
- default: 0
|
||||
- Used only in `stream` and `alone` mode, the maximum number of time we can not reach Crowdsec before blocking traffic (set -1 to never block)
|
||||
- In `stream` and `alone` mode, the maximum number of time we can not reach Crowdsec before blocking traffic (set -1 to never block)
|
||||
- In `live` and `none` mode, only `-1` has an effect: a request is let through instead of blocked when Crowdsec cannot be reached. Any other value blocks on the first failure, there is no failure counter on that path.
|
||||
- StreamStartupBlock
|
||||
- bool
|
||||
- default: true
|
||||
|
||||
@@ -546,6 +546,9 @@ func handleNoStreamCache(bouncer *Bouncer, remoteIP string) (string, error) {
|
||||
}
|
||||
body, err := crowdsecQuery(bouncer, routeURL.String(), nil)
|
||||
if err != nil {
|
||||
if bouncer.updateMaxFailure == -1 {
|
||||
return cache.NoBannedValue, err
|
||||
}
|
||||
return cache.BannedValue, err
|
||||
}
|
||||
|
||||
|
||||
+54
-8
@@ -123,22 +123,68 @@ func TestBouncer_ServeHTTP(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_handleNoStreamCache(t *testing.T) {
|
||||
type args struct {
|
||||
bouncer *Bouncer
|
||||
remoteIP string
|
||||
newBouncer := func(mode string, updateMaxFailure int64) *Bouncer {
|
||||
log := logger.New("ERROR", "")
|
||||
cacheClient := &cache.Client{}
|
||||
cacheClient.New(log, false, "", nil, "", "")
|
||||
return &Bouncer{
|
||||
crowdsecScheme: "http",
|
||||
crowdsecHost: "127.0.0.1:1",
|
||||
crowdsecPath: "/",
|
||||
crowdsecMode: mode,
|
||||
updateMaxFailure: updateMaxFailure,
|
||||
defaultDecisionTimeout: 60,
|
||||
httpClient: &http.Client{Timeout: time.Second},
|
||||
cacheClient: cacheClient,
|
||||
log: log,
|
||||
}
|
||||
}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
wantErr bool
|
||||
name string
|
||||
mode string
|
||||
updateMaxFailure int64
|
||||
want string
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{
|
||||
name: "live mode blocks by default when crowdsec is unreachable",
|
||||
mode: configuration.LiveMode,
|
||||
updateMaxFailure: 0,
|
||||
want: cache.BannedValue,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "live mode blocks for any positive updateMaxFailure",
|
||||
mode: configuration.LiveMode,
|
||||
updateMaxFailure: 3,
|
||||
want: cache.BannedValue,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "live mode lets the request through when updateMaxFailure is -1",
|
||||
mode: configuration.LiveMode,
|
||||
updateMaxFailure: -1,
|
||||
want: cache.NoBannedValue,
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "none mode lets the request through when updateMaxFailure is -1",
|
||||
mode: configuration.NoneMode,
|
||||
updateMaxFailure: -1,
|
||||
want: cache.NoBannedValue,
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
if _, err := handleNoStreamCache(tt.args.bouncer, tt.args.remoteIP); (err != nil) != tt.wantErr {
|
||||
got, err := handleNoStreamCache(newBouncer(tt.mode, tt.updateMaxFailure), "1.2.3.4")
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("handleNoStreamCache() error = %v, wantErr %v", err, tt.wantErr)
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("handleNoStreamCache() = %q, want %q", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user