mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 11:38:59 +02:00
✨ Standalone mode come back (#74)
* ✨ Standalone mode come back * 🍱 fix lint * 🐛 fix tests cache * 🐛 fix tests * 🐛 fix tests * 🚨 fix lint * 🚨 fix lint * 🍱 add logging * :rotating-light: fix lint * 🍱 fix comments * 🐛 fix tests * 🚨 Fix lint Co-authored-by: Mathieu HANOTAUX <mathieu@hanotaux.fr>
This commit is contained in:
co-authored by
Mathieu HANOTAUX
parent
87a839f22d
commit
1b310b2c15
Vendored
+40
-38
@@ -18,14 +18,13 @@ const (
|
||||
|
||||
//nolint:gochecknoglobals
|
||||
var (
|
||||
cache = ttl_map.New()
|
||||
redis simpleredis.SimpleRedis
|
||||
redisEnabled = false
|
||||
redis simpleredis.SimpleRedis
|
||||
cache = ttl_map.New()
|
||||
)
|
||||
|
||||
// FileSystem Cache
|
||||
type localCache struct{}
|
||||
|
||||
func getDecisionLocalCache(clientIP string) (bool, error) {
|
||||
func (localCache) getDecision(clientIP string) (bool, error) {
|
||||
banned, isCached := cache.Get(clientIP)
|
||||
bannedString, isValid := banned.(string)
|
||||
if isCached && isValid && len(bannedString) > 0 {
|
||||
@@ -34,17 +33,17 @@ func getDecisionLocalCache(clientIP string) (bool, error) {
|
||||
return false, fmt.Errorf("cache:miss")
|
||||
}
|
||||
|
||||
func setDecisionLocalCache(clientIP string, value string, duration int64) {
|
||||
func (localCache) setDecision(clientIP string, value string, duration int64) {
|
||||
cache.Set(clientIP, value, duration)
|
||||
}
|
||||
|
||||
func deleteDecisionLocalCache(clientIP string) {
|
||||
func (localCache) deleteDecision(clientIP string) {
|
||||
cache.Del(clientIP)
|
||||
}
|
||||
|
||||
// Redis Cache
|
||||
type redisCache struct{}
|
||||
|
||||
func getDecisionRedisCache(clientIP string) (bool, error) {
|
||||
func (redisCache) getDecision(clientIP string) (bool, error) {
|
||||
banned, err := redis.Get(clientIP)
|
||||
bannedString := string(banned)
|
||||
if err == nil && len(bannedString) > 0 {
|
||||
@@ -53,58 +52,61 @@ func getDecisionRedisCache(clientIP string) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
func setDecisionRedisCache(clientIP string, value string, duration int64) {
|
||||
func (redisCache) setDecision(clientIP string, value string, duration int64) {
|
||||
if err := redis.Set(clientIP, []byte(value), duration); err != nil {
|
||||
logger.Error(fmt.Sprintf("cache:setDecisionRedisCache %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func deleteDecisionRedisCache(clientIP string) {
|
||||
func (redisCache) deleteDecision(clientIP string) {
|
||||
if err := redis.Del(clientIP); err != nil {
|
||||
logger.Error(fmt.Sprintf("cache:deleteDecisionRedisCache %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
// DeleteDecision delete decision in cache.
|
||||
func DeleteDecision(clientIP string) {
|
||||
logger.Debug("cache:DeleteDecision")
|
||||
if redisEnabled {
|
||||
deleteDecisionRedisCache(clientIP)
|
||||
type cacheInterface interface {
|
||||
setDecision(clientIP string, value string, duration int64)
|
||||
getDecision(clientIP string) (bool, error)
|
||||
deleteDecision(clientIP string)
|
||||
}
|
||||
|
||||
// Client Cache client.
|
||||
type Client struct {
|
||||
cache cacheInterface
|
||||
}
|
||||
|
||||
// New Initialize cache client.
|
||||
func (client *Client) New(isRedis bool, host string) {
|
||||
if isRedis {
|
||||
redis.Init(host)
|
||||
client.cache = &redisCache{}
|
||||
} else {
|
||||
deleteDecisionLocalCache(clientIP)
|
||||
client.cache = &localCache{}
|
||||
}
|
||||
logger.Debug(fmt.Sprintf("cache:New initialized isRedis:%v", isRedis))
|
||||
}
|
||||
|
||||
// DeleteDecision delete decision in cache.
|
||||
func (client *Client) DeleteDecision(clientIP string) {
|
||||
logger.Debug(fmt.Sprintf("cache:DeleteDecision ip:%v", clientIP))
|
||||
client.cache.deleteDecision(clientIP)
|
||||
}
|
||||
|
||||
// GetDecision check in the cache if the IP has the banned / not banned value.
|
||||
// Otherwise return with an error to add the IP in cache if we are on.
|
||||
func GetDecision(clientIP string) (bool, error) {
|
||||
logger.Debug("cache:GetDecision")
|
||||
if redisEnabled {
|
||||
return getDecisionRedisCache(clientIP)
|
||||
}
|
||||
return getDecisionLocalCache(clientIP)
|
||||
func (client *Client) GetDecision(clientIP string) (bool, error) {
|
||||
logger.Debug(fmt.Sprintf("cache:GetDecision ip:%v", clientIP))
|
||||
return client.cache.getDecision(clientIP)
|
||||
}
|
||||
|
||||
// SetDecision update the cache with the IP as key and the value banned / not banned.
|
||||
func SetDecision(clientIP string, isBanned bool, duration int64) {
|
||||
func (client *Client) SetDecision(clientIP string, isBanned bool, duration int64) {
|
||||
logger.Debug(fmt.Sprintf("cache:SetDecision ip:%v isBanned:%v", clientIP, isBanned))
|
||||
var value string
|
||||
if isBanned {
|
||||
logger.Debug(fmt.Sprintf("cache:SetDecision ip:%v banned", clientIP))
|
||||
value = cacheBannedValue
|
||||
} else {
|
||||
value = cacheNoBannedValue
|
||||
}
|
||||
logger.Debug("cache:SetDecision")
|
||||
if redisEnabled {
|
||||
setDecisionRedisCache(clientIP, value, duration)
|
||||
} else {
|
||||
setDecisionLocalCache(clientIP, value, duration)
|
||||
}
|
||||
}
|
||||
|
||||
// InitRedisClient loads variables.
|
||||
func InitRedisClient(host string) {
|
||||
redisEnabled = true
|
||||
redis.Init(host)
|
||||
logger.Debug("cache:InitRedisClient redis:initialized")
|
||||
client.cache.setDecision(clientIP, value, duration)
|
||||
}
|
||||
|
||||
Vendored
+38
-162
@@ -6,10 +6,11 @@ import (
|
||||
"testing"
|
||||
)
|
||||
|
||||
func Test_getDecisionLocalCache(t *testing.T) {
|
||||
func Test_GetDecision(t *testing.T) {
|
||||
IPInCache := "10.0.0.10"
|
||||
IPNotInCache := "10.0.0.20"
|
||||
setDecisionLocalCache(IPInCache, "t", 10)
|
||||
client := &Client{cache: &localCache{}}
|
||||
client.SetDecision(IPInCache, true, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
}
|
||||
@@ -22,205 +23,80 @@ func Test_getDecisionLocalCache(t *testing.T) {
|
||||
}{
|
||||
{name: "Fetch Known valid IP", args: args{clientIP: IPInCache}, want: true, wantErr: false, valueErr: ""},
|
||||
{name: "Fetch Unknown valid IP", args: args{clientIP: IPNotInCache}, want: false, wantErr: true, valueErr: "cache:miss"},
|
||||
{name: "Fetch invalid value", args: args{clientIP: "zaeaea"}, want: false, wantErr: true, valueErr: "cache:miss"},
|
||||
{name: "Fetch invalid value", args: args{clientIP: "test"}, want: false, wantErr: true, valueErr: "cache:miss"},
|
||||
{name: "Fetch empty value", args: args{clientIP: ""}, want: false, wantErr: true, valueErr: "cache:miss"},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := getDecisionLocalCache(tt.args.clientIP)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getDecisionLocalCache() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("getDecisionLocalCache() = %v, want %v", got, tt.want)
|
||||
return
|
||||
}
|
||||
if tt.valueErr != "" && tt.valueErr != err.Error() {
|
||||
t.Errorf("getDecisionLocalCache() err = %v, want %v", err.Error(), tt.valueErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_setDecisionLocalCache(t *testing.T) {
|
||||
IPInCache := "10.0.0.10"
|
||||
type args struct {
|
||||
clientIP string
|
||||
value string
|
||||
duration int64
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
{name: "Set valid IP in local cache as t", args: args{clientIP: IPInCache, value: "t", duration: 0}},
|
||||
{name: "Set valid IP in local cache as f", args: args{clientIP: IPInCache, value: "f", duration: 0}},
|
||||
{name: "Set valid IP in local cache as empty str", args: args{clientIP: IPInCache, value: "", duration: 0}},
|
||||
{name: "Set valid IP in local cache as f for -1 sec", args: args{clientIP: IPInCache, value: "f", duration: -1}},
|
||||
{name: "Set valid IP in local cache as f for 10 sec", args: args{clientIP: IPInCache, value: "f", duration: 10}},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
setDecisionLocalCache(tt.args.clientIP, tt.args.value, tt.args.duration)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deleteDecisionLocalCache(t *testing.T) {
|
||||
type args struct {
|
||||
clientIP string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
deleteDecisionLocalCache(tt.args.clientIP)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_getDecisionRedisCache(t *testing.T) {
|
||||
type args struct {
|
||||
clientIP string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := getDecisionRedisCache(tt.args.clientIP)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getDecisionRedisCache() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("getDecisionRedisCache() = %v, want %v", got, tt.want)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_setDecisionRedisCache(t *testing.T) {
|
||||
type args struct {
|
||||
clientIP string
|
||||
value string
|
||||
duration int64
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
setDecisionRedisCache(tt.args.clientIP, tt.args.value, tt.args.duration)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func Test_deleteDecisionRedisCache(t *testing.T) {
|
||||
type args struct {
|
||||
clientIP string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
deleteDecisionRedisCache(tt.args.clientIP)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestDeleteDecision(t *testing.T) {
|
||||
type args struct {
|
||||
clientIP string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
DeleteDecision(tt.args.clientIP)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestGetDecision(t *testing.T) {
|
||||
type args struct {
|
||||
clientIP string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
wantErr bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetDecision(tt.args.clientIP)
|
||||
got, err := client.GetDecision(tt.args.clientIP)
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("GetDecision() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
}
|
||||
if got != tt.want {
|
||||
t.Errorf("GetDecision() = %v, want %v", got, tt.want)
|
||||
return
|
||||
}
|
||||
if tt.valueErr != "" && tt.valueErr != err.Error() {
|
||||
t.Errorf("GetDecision() err = %v, want %v", err.Error(), tt.valueErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSetDecision(t *testing.T) {
|
||||
func Test_SetDecision(t *testing.T) {
|
||||
client := &Client{cache: &localCache{}}
|
||||
IPInCache := "10.0.0.11"
|
||||
type args struct {
|
||||
clientIP string
|
||||
isBanned bool
|
||||
value bool
|
||||
duration int64
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{name: "Set valid IP in local cache for 0 sec", args: args{clientIP: IPInCache, value: true, duration: 0}, want: false},
|
||||
{name: "Set valid IP in local cache for 10 sec", args: args{clientIP: IPInCache, value: true, duration: 10}, want: true},
|
||||
{name: "Set valid IP in local cache for 10 sec", args: args{clientIP: IPInCache, value: false, duration: 10}, want: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
SetDecision(tt.args.clientIP, tt.args.isBanned, tt.args.duration)
|
||||
client.SetDecision(tt.args.clientIP, tt.args.value, tt.args.duration)
|
||||
got, _ := client.GetDecision(tt.args.clientIP)
|
||||
if got != tt.want {
|
||||
t.Errorf("SetDecision() = %v, want %v", got, tt.want)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestInitRedisClient(t *testing.T) {
|
||||
func Test_DeleteDecision(t *testing.T) {
|
||||
IPInCache := "10.0.0.12"
|
||||
IPNotInCache := "10.0.0.22"
|
||||
client := &Client{cache: &localCache{}}
|
||||
client.SetDecision(IPInCache, true, 10)
|
||||
type args struct {
|
||||
host string
|
||||
clientIP string
|
||||
}
|
||||
tests := []struct {
|
||||
name string
|
||||
args args
|
||||
want bool
|
||||
}{
|
||||
// TODO: Add test cases.
|
||||
{name: "Delete Known valid IP", args: args{clientIP: IPInCache}, want: false},
|
||||
{name: "Delete Unknown valid IP", args: args{clientIP: IPNotInCache}, want: false},
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
InitRedisClient(tt.args.host)
|
||||
client.DeleteDecision(tt.args.clientIP)
|
||||
got, _ := client.GetDecision(tt.args.clientIP)
|
||||
if got != tt.want {
|
||||
t.Errorf("DeleteDecision() = %v, want %v", got, tt.want)
|
||||
return
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user