mirror of
https://github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin.git
synced 2026-07-21 11:38:59 +02:00
✨ Add a logger instance to bouncer instance (#134)
* ✨ Add a logger instance to bouncer instance * 🍱 fix test * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 fix lint * 🍱 fix test * 🍱 fix test * 🍱 fix lint + test * 🍱 fix test * 🍱 fix test * 🍱 fix test * 🍱 fix lint * 🍱 fix lint
This commit is contained in:
+32
-29
@@ -75,19 +75,20 @@ type Bouncer struct {
|
||||
serverPoolStrategy *ip.PoolStrategy
|
||||
httpClient *http.Client
|
||||
cacheClient *cache.Client
|
||||
log *logger.Log
|
||||
}
|
||||
|
||||
// New creates the crowdsec bouncer plugin.
|
||||
func New(ctx context.Context, next http.Handler, config *configuration.Config, name string) (http.Handler, error) {
|
||||
logger.Init(config.LogLevel)
|
||||
log := logger.New(config.LogLevel)
|
||||
err := configuration.ValidateParams(config)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("New:validateParams %s", err.Error()))
|
||||
log.Error(fmt.Sprintf("New:validateParams %s", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
|
||||
serverChecker, _ := ip.NewChecker(config.ForwardedHeadersTrustedIPs)
|
||||
clientChecker, _ := ip.NewChecker(config.ClientTrustedIPs)
|
||||
serverChecker, _ := ip.NewChecker(log, config.ForwardedHeadersTrustedIPs)
|
||||
clientChecker, _ := ip.NewChecker(log, config.ClientTrustedIPs)
|
||||
|
||||
var tlsConfig *tls.Config
|
||||
crowdsecStreamRoute := ""
|
||||
@@ -103,14 +104,14 @@ func New(ctx context.Context, next http.Handler, config *configuration.Config, n
|
||||
} else {
|
||||
crowdsecStreamRoute = crowdsecLapiStreamRoute
|
||||
crowdsecHeader = crowdsecLapiHeader
|
||||
tlsConfig, err = configuration.GetTLSConfigCrowdsec(config)
|
||||
tlsConfig, err = configuration.GetTLSConfigCrowdsec(config, log)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("New:getTLSConfigCrowdsec fail to get tlsConfig %s", err.Error()))
|
||||
log.Error(fmt.Sprintf("New:getTLSConfigCrowdsec fail to get tlsConfig %s", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
apiKey, errAPIKey := configuration.GetVariable(config, "CrowdsecLapiKey")
|
||||
if errAPIKey != nil && len(tlsConfig.Certificates) == 0 {
|
||||
logger.Error(fmt.Sprintf("New:crowdsecLapiKey fail to get CrowdsecLapiKey and no client certificate setup %s", errAPIKey.Error()))
|
||||
log.Error(fmt.Sprintf("New:crowdsecLapiKey fail to get CrowdsecLapiKey and no client certificate setup %s", errAPIKey.Error()))
|
||||
return nil, err
|
||||
}
|
||||
config.CrowdsecLapiKey = apiKey
|
||||
@@ -137,6 +138,7 @@ func New(ctx context.Context, next http.Handler, config *configuration.Config, n
|
||||
defaultDecisionTimeout: config.DefaultDecisionSeconds,
|
||||
crowdsecStreamRoute: crowdsecStreamRoute,
|
||||
crowdsecHeader: crowdsecHeader,
|
||||
log: log,
|
||||
serverPoolStrategy: &ip.PoolStrategy{
|
||||
Checker: serverChecker,
|
||||
},
|
||||
@@ -157,7 +159,8 @@ func New(ctx context.Context, next http.Handler, config *configuration.Config, n
|
||||
return bouncer, nil
|
||||
}
|
||||
config.RedisCachePassword, _ = configuration.GetVariable(config, "RedisCachePassword")
|
||||
bouncer.cacheClient.New(
|
||||
bouncer.cacheClient.Init(
|
||||
log,
|
||||
config.RedisCacheEnabled,
|
||||
config.RedisCacheHost,
|
||||
config.RedisCachePassword,
|
||||
@@ -167,17 +170,17 @@ func New(ctx context.Context, next http.Handler, config *configuration.Config, n
|
||||
if (config.CrowdsecMode == configuration.StreamMode || config.CrowdsecMode == configuration.AloneMode) && ticker == nil {
|
||||
if config.CrowdsecMode == configuration.AloneMode {
|
||||
if err := getToken(bouncer); err != nil {
|
||||
logger.Error(fmt.Sprintf("New:getToken %s", err.Error()))
|
||||
bouncer.log.Error(fmt.Sprintf("New:getToken %s", err.Error()))
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
handleStreamTicker(bouncer)
|
||||
isStartup = false
|
||||
ticker = startTicker(config, func() {
|
||||
ticker = startTicker(config, log, func() {
|
||||
handleStreamTicker(bouncer)
|
||||
})
|
||||
}
|
||||
logger.Debug(fmt.Sprintf("New initialized mode:%s", config.CrowdsecMode))
|
||||
bouncer.log.Debug(fmt.Sprintf("New initialized mode:%s", config.CrowdsecMode))
|
||||
|
||||
return bouncer, nil
|
||||
}
|
||||
@@ -194,18 +197,18 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
// Here we check for the trusted IPs in the customHeader
|
||||
remoteIP, err := ip.GetRemoteIP(req, bouncer.serverPoolStrategy, bouncer.customHeader)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("ServeHTTP:getRemoteIp ip:%s %s", remoteIP, err.Error()))
|
||||
bouncer.log.Error(fmt.Sprintf("ServeHTTP:getRemoteIp ip:%s %s", remoteIP, err.Error()))
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
isTrusted, err := bouncer.clientPoolStrategy.Checker.Contains(remoteIP)
|
||||
if err != nil {
|
||||
logger.Error(fmt.Sprintf("ServeHTTP:checkerContains ip:%s %s", remoteIP, err.Error()))
|
||||
bouncer.log.Error(fmt.Sprintf("ServeHTTP:checkerContains ip:%s %s", remoteIP, err.Error()))
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
// if our IP is in the trusted list we bypass the next checks
|
||||
logger.Debug(fmt.Sprintf("ServeHTTP ip:%s isTrusted:%v", remoteIP, isTrusted))
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP ip:%s isTrusted:%v", remoteIP, isTrusted))
|
||||
if isTrusted {
|
||||
bouncer.next.ServeHTTP(rw, req)
|
||||
return
|
||||
@@ -221,14 +224,14 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
isBanned, cacheErr := bouncer.cacheClient.GetDecision(remoteIP)
|
||||
if cacheErr != nil {
|
||||
errString := cacheErr.Error()
|
||||
logger.Debug(fmt.Sprintf("ServeHTTP:getDecision ip:%s isBanned:false %s", remoteIP, errString))
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP:getDecision ip:%s isBanned:false %s", remoteIP, errString))
|
||||
if errString != cache.CacheMiss {
|
||||
logger.Error(fmt.Sprintf("ServeHTTP:getDecision ip:%s %s", remoteIP, errString))
|
||||
bouncer.log.Error(fmt.Sprintf("ServeHTTP:getDecision ip:%s %s", remoteIP, errString))
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
logger.Debug(fmt.Sprintf("ServeHTTP ip:%s cache:hit isBanned:%v", remoteIP, isBanned))
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP ip:%s cache:hit isBanned:%v", remoteIP, isBanned))
|
||||
if isBanned {
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
} else {
|
||||
@@ -243,13 +246,13 @@ func (bouncer *Bouncer) ServeHTTP(rw http.ResponseWriter, req *http.Request) {
|
||||
if isCrowdsecStreamHealthy {
|
||||
handleNextServeHTTP(bouncer, remoteIP, rw, req)
|
||||
} else {
|
||||
logger.Debug(fmt.Sprintf("ServeHTTP isCrowdsecStreamHealthy:false ip:%s", remoteIP))
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP isCrowdsecStreamHealthy:false ip:%s", remoteIP))
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
}
|
||||
} else {
|
||||
err = handleNoStreamCache(bouncer, remoteIP)
|
||||
if err != nil {
|
||||
logger.Debug(fmt.Sprintf("ServeHTTP:handleNoStreamCache ip:%s isBanned:true %s", remoteIP, err.Error()))
|
||||
bouncer.log.Debug(fmt.Sprintf("ServeHTTP:handleNoStreamCache ip:%s isBanned:true %s", remoteIP, err.Error()))
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
} else {
|
||||
handleNextServeHTTP(bouncer, remoteIP, rw, req)
|
||||
@@ -289,7 +292,7 @@ func handleNextServeHTTP(bouncer *Bouncer, remoteIP string, rw http.ResponseWrit
|
||||
if bouncer.appsecEnabled {
|
||||
err := appsecQuery(bouncer, remoteIP, req)
|
||||
if err != nil {
|
||||
logger.Debug(fmt.Sprintf("handleNextServeHTTP ip:%s isWaf:true %s", remoteIP, err.Error()))
|
||||
bouncer.log.Debug(fmt.Sprintf("handleNextServeHTTP ip:%s isWaf:true %s", remoteIP, err.Error()))
|
||||
rw.WriteHeader(http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
@@ -300,17 +303,17 @@ func handleNextServeHTTP(bouncer *Bouncer, remoteIP string, rw http.ResponseWrit
|
||||
func handleStreamTicker(bouncer *Bouncer) {
|
||||
if err := handleStreamCache(bouncer); err != nil {
|
||||
isCrowdsecStreamHealthy = false
|
||||
logger.Error(err.Error())
|
||||
bouncer.log.Error(err.Error())
|
||||
} else {
|
||||
isCrowdsecStreamHealthy = true
|
||||
}
|
||||
}
|
||||
|
||||
func startTicker(config *configuration.Config, work func()) chan bool {
|
||||
func startTicker(config *configuration.Config, log *logger.Log, work func()) chan bool {
|
||||
ticker := time.NewTicker(time.Duration(config.UpdateIntervalSeconds) * time.Second)
|
||||
stop := make(chan bool, 1)
|
||||
go func() {
|
||||
defer logger.Debug("ticker:stopped")
|
||||
defer log.Debug("ticker:stopped")
|
||||
for {
|
||||
select {
|
||||
case <-ticker.C:
|
||||
@@ -387,7 +390,7 @@ func getToken(bouncer *Bouncer) error {
|
||||
}
|
||||
if login.Code == 200 && len(login.Token) > 0 {
|
||||
bouncer.crowdsecKey = login.Token
|
||||
logger.Debug(fmt.Sprintf("getToken statusCode:%d", login.Code))
|
||||
bouncer.log.Debug(fmt.Sprintf("getToken statusCode:%d", login.Code))
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("getToken statusCode:%d", login.Code)
|
||||
@@ -400,7 +403,7 @@ func handleStreamCache(bouncer *Bouncer) error {
|
||||
// because updated routine information is in the cache
|
||||
_, err := bouncer.cacheClient.GetDecision(cacheTimeoutKey)
|
||||
if err == nil {
|
||||
logger.Debug("handleStreamCache:alreadyUpdated")
|
||||
bouncer.log.Debug("handleStreamCache:alreadyUpdated")
|
||||
return nil
|
||||
}
|
||||
if err.Error() != cache.CacheMiss {
|
||||
@@ -431,7 +434,7 @@ func handleStreamCache(bouncer *Bouncer) error {
|
||||
for _, decision := range stream.Deleted {
|
||||
bouncer.cacheClient.DeleteDecision(decision.Value)
|
||||
}
|
||||
logger.Debug("handleStreamCache:updated")
|
||||
bouncer.log.Debug("handleStreamCache:updated")
|
||||
isCrowdsecStreamHealthy = true
|
||||
return nil
|
||||
}
|
||||
@@ -456,7 +459,7 @@ func crowdsecQuery(bouncer *Bouncer, stringURL string, isPost bool) ([]byte, err
|
||||
}
|
||||
defer func() {
|
||||
if err = res.Body.Close(); err != nil {
|
||||
logger.Error(fmt.Sprintf("crowdsecQuery:closeBody %s", err.Error()))
|
||||
bouncer.log.Error(fmt.Sprintf("crowdsecQuery:closeBody %s", err.Error()))
|
||||
}
|
||||
}()
|
||||
if res.StatusCode == http.StatusUnauthorized && bouncer.crowdsecMode == configuration.AloneMode {
|
||||
@@ -511,11 +514,11 @@ func appsecQuery(bouncer *Bouncer, ip string, httpReq *http.Request) error {
|
||||
}
|
||||
defer func() {
|
||||
if err = res.Body.Close(); err != nil {
|
||||
logger.Error(fmt.Sprintf("appsecQuery:closeBody %s", err.Error()))
|
||||
bouncer.log.Error(fmt.Sprintf("appsecQuery:closeBody %s", err.Error()))
|
||||
}
|
||||
}()
|
||||
if res.StatusCode == http.StatusInternalServerError {
|
||||
logger.Debug("crowdsecQuery statusCode:500")
|
||||
bouncer.log.Debug("crowdsecQuery statusCode:500")
|
||||
if bouncer.appsecFailureBlock {
|
||||
return fmt.Errorf("appsecQuery statusCode:%d", res.StatusCode)
|
||||
}
|
||||
|
||||
Vendored
+23
-19
@@ -44,7 +44,9 @@ func (localCache) deleteDecision(clientIP string) {
|
||||
cache.Del(clientIP)
|
||||
}
|
||||
|
||||
type redisCache struct{}
|
||||
type redisCache struct {
|
||||
log *logger.Log
|
||||
}
|
||||
|
||||
func (redisCache) getDecision(clientIP string) (bool, error) {
|
||||
banned, err := redis.Get(clientIP)
|
||||
@@ -58,15 +60,15 @@ func (redisCache) getDecision(clientIP string) (bool, error) {
|
||||
return false, err
|
||||
}
|
||||
|
||||
func (redisCache) setDecision(clientIP string, value string, duration int64) {
|
||||
func (rc 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()))
|
||||
rc.log.Error(fmt.Sprintf("cache:setDecisionRedisCache %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
func (redisCache) deleteDecision(clientIP string) {
|
||||
func (rc redisCache) deleteDecision(clientIP string) {
|
||||
if err := redis.Del(clientIP); err != nil {
|
||||
logger.Error(fmt.Sprintf("cache:deleteDecisionRedisCache %s", err.Error()))
|
||||
rc.log.Error(fmt.Sprintf("cache:deleteDecisionRedisCache %s", err.Error()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -79,40 +81,42 @@ type cacheInterface interface {
|
||||
// Client Cache client.
|
||||
type Client struct {
|
||||
cache cacheInterface
|
||||
log *logger.Log
|
||||
}
|
||||
|
||||
// New Initialize cache client.
|
||||
func (client *Client) New(isRedis bool, host, pass, database string) {
|
||||
// Init Initialize cache client.
|
||||
func (c *Client) Init(log *logger.Log, isRedis bool, host, pass, database string) {
|
||||
c.log = log
|
||||
if isRedis {
|
||||
redis.Init(host, pass, database)
|
||||
client.cache = &redisCache{}
|
||||
c.cache = &redisCache{log: log}
|
||||
} else {
|
||||
client.cache = &localCache{}
|
||||
c.cache = &localCache{}
|
||||
}
|
||||
logger.Debug(fmt.Sprintf("cache:New initialized isRedis:%v", isRedis))
|
||||
c.log.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)
|
||||
func (c *Client) DeleteDecision(clientIP string) {
|
||||
c.log.Debug(fmt.Sprintf("cache:DeleteDecision ip:%v", clientIP))
|
||||
c.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 (client *Client) GetDecision(clientIP string) (bool, error) {
|
||||
logger.Debug(fmt.Sprintf("cache:GetDecision ip:%v", clientIP))
|
||||
return client.cache.getDecision(clientIP)
|
||||
func (c *Client) GetDecision(clientIP string) (bool, error) {
|
||||
c.log.Debug(fmt.Sprintf("cache:GetDecision ip:%v", clientIP))
|
||||
return c.cache.getDecision(clientIP)
|
||||
}
|
||||
|
||||
// SetDecision update the cache with the IP as key and the value banned / not banned.
|
||||
func (client *Client) SetDecision(clientIP string, isBanned bool, duration int64) {
|
||||
logger.Debug(fmt.Sprintf("cache:SetDecision ip:%v isBanned:%v duration:%vs", clientIP, isBanned, duration))
|
||||
func (c *Client) SetDecision(clientIP string, isBanned bool, duration int64) {
|
||||
c.log.Debug(fmt.Sprintf("cache:SetDecision ip:%v isBanned:%v duration:%vs", clientIP, isBanned, duration))
|
||||
var value string
|
||||
if isBanned {
|
||||
value = cacheBannedValue
|
||||
} else {
|
||||
value = cacheNoBannedValue
|
||||
}
|
||||
client.cache.setDecision(clientIP, value, duration)
|
||||
c.cache.setDecision(clientIP, value, duration)
|
||||
}
|
||||
|
||||
Vendored
+5
-3
@@ -4,12 +4,14 @@ package cache
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
)
|
||||
|
||||
func Test_GetDecision(t *testing.T) {
|
||||
IPInCache := "10.0.0.10"
|
||||
IPNotInCache := "10.0.0.20"
|
||||
client := &Client{cache: &localCache{}}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client.SetDecision(IPInCache, true, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
@@ -45,7 +47,7 @@ func Test_GetDecision(t *testing.T) {
|
||||
}
|
||||
|
||||
func Test_SetDecision(t *testing.T) {
|
||||
client := &Client{cache: &localCache{}}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
IPInCache := "10.0.0.11"
|
||||
type args struct {
|
||||
clientIP string
|
||||
@@ -76,7 +78,7 @@ func Test_SetDecision(t *testing.T) {
|
||||
func Test_DeleteDecision(t *testing.T) {
|
||||
IPInCache := "10.0.0.12"
|
||||
IPNotInCache := "10.0.0.22"
|
||||
client := &Client{cache: &localCache{}}
|
||||
client := &Client{cache: &localCache{}, log: logger.New("INFO")}
|
||||
client.SetDecision(IPInCache, true, 10)
|
||||
type args struct {
|
||||
clientIP string
|
||||
|
||||
@@ -235,11 +235,9 @@ func validateParamsTLS(config *Config) error {
|
||||
|
||||
func validateParamsIPs(listIP []string, key string) error {
|
||||
if len(listIP) > 0 {
|
||||
if _, err := ip.NewChecker(listIP); err != nil {
|
||||
if _, err := ip.NewChecker(logger.New("INFO"), listIP); err != nil {
|
||||
return fmt.Errorf("%s must be a list of IP/CIDR :%w", key, err)
|
||||
}
|
||||
} else {
|
||||
logger.Debug(fmt.Sprintf("No IP provided for %s", key))
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -275,16 +273,18 @@ func validateParamsRequired(config *Config) error {
|
||||
}
|
||||
|
||||
// GetTLSConfigCrowdsec get TLS config from Config.
|
||||
func GetTLSConfigCrowdsec(config *Config) (*tls.Config, error) {
|
||||
//
|
||||
//nolint:nestif
|
||||
func GetTLSConfigCrowdsec(config *Config, log *logger.Log) (*tls.Config, error) {
|
||||
tlsConfig := new(tls.Config)
|
||||
tlsConfig.RootCAs = x509.NewCertPool()
|
||||
//nolint:gocritic
|
||||
if config.CrowdsecLapiScheme != HTTPS {
|
||||
logger.Debug("getTLSConfigCrowdsec:CrowdsecLapiScheme https:no")
|
||||
log.Debug("getTLSConfigCrowdsec:CrowdsecLapiScheme https:no")
|
||||
return tlsConfig, nil
|
||||
} else if config.CrowdsecLapiTLSInsecureVerify {
|
||||
logger.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSInsecureVerify tlsInsecure:true")
|
||||
tlsConfig.InsecureSkipVerify = true
|
||||
log.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSInsecureVerify tlsInsecure:true")
|
||||
// If we return here and still want to use client auth this won't work
|
||||
// return tlsConfig, nil
|
||||
} else {
|
||||
@@ -292,12 +292,13 @@ func GetTLSConfigCrowdsec(config *Config) (*tls.Config, error) {
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
cert := []byte(certAuthority)
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM(cert) {
|
||||
logger.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSCertificateAuthority read cert failed")
|
||||
// here we return because if CrowdsecLapiTLSInsecureVerify is false
|
||||
// and CA not load, we can't communicate with https
|
||||
return nil, fmt.Errorf("getTLSConfigCrowdsec:cannot load CA and verify cert is enabled")
|
||||
if len(certAuthority) > 0 {
|
||||
if !tlsConfig.RootCAs.AppendCertsFromPEM([]byte(certAuthority)) {
|
||||
// here we return because if CrowdsecLapiTLSInsecureVerify is false
|
||||
// and CA not load, we can't communicate with https
|
||||
return nil, fmt.Errorf("getTLSConfigCrowdsec:cannot load CA and verify cert is enabled")
|
||||
}
|
||||
log.Debug("getTLSConfigCrowdsec:CrowdsecLapiTLSCertificateAuthority CA added successfully")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@ import (
|
||||
"crypto/tls"
|
||||
"reflect"
|
||||
"testing"
|
||||
|
||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
)
|
||||
|
||||
func getMinimalConfig() *Config {
|
||||
@@ -147,7 +149,7 @@ func Test_validateParamsIPs(t *testing.T) {
|
||||
{name: "Not validate localhost", args: args{listIP: []string{0: "localhost"}}, wantErr: true},
|
||||
{name: "Not validate a weird ip", args: args{listIP: []string{0: "0.0.0.0/89"}}, wantErr: true},
|
||||
{name: "Not validate a weird ip 2", args: args{listIP: []string{0: "0.0.0.256/12"}}, wantErr: true},
|
||||
{name: "Validate an ip not trimed", args: args{listIP: []string{0: " 0.0.0.0/0"}}, wantErr: false},
|
||||
{name: "Validate an ip not trimmed", args: args{listIP: []string{0: " 0.0.0.0/0"}}, wantErr: false},
|
||||
{name: "Validate an ip", args: args{listIP: []string{0: "0.0.0.0/12"}}, wantErr: false},
|
||||
{name: "Validate an ip list", args: args{listIP: []string{0: "0.0.0.0/0", 1: "1.1.1.1/1"}}, wantErr: false},
|
||||
}
|
||||
@@ -231,7 +233,7 @@ func Test_GetTLSConfigCrowdsec(t *testing.T) {
|
||||
}
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
got, err := GetTLSConfigCrowdsec(tt.args.config)
|
||||
got, err := GetTLSConfigCrowdsec(tt.args.config, logger.New("INFO"))
|
||||
if (err != nil) != tt.wantErr {
|
||||
t.Errorf("getTLSConfigCrowdsec() error = %v, wantErr %v", err, tt.wantErr)
|
||||
return
|
||||
|
||||
+4
-4
@@ -8,7 +8,7 @@ import (
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
"github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
logger "github.com/maxlerebourg/crowdsec-bouncer-traefik-plugin/pkg/logger"
|
||||
)
|
||||
|
||||
// CHECKER
|
||||
@@ -20,14 +20,14 @@ type Checker struct {
|
||||
}
|
||||
|
||||
// NewChecker builds a new Checker given a list of CIDR-Strings to trusted IPs.
|
||||
func NewChecker(trustedIPs []string) (*Checker, error) {
|
||||
func NewChecker(log *logger.Log, trustedIPs []string) (*Checker, error) {
|
||||
checker := &Checker{}
|
||||
|
||||
for _, ipMaskRaw := range trustedIPs {
|
||||
ipMask := strings.TrimSpace(ipMaskRaw)
|
||||
if ipAddr := net.ParseIP(ipMask); ipAddr != nil {
|
||||
checker.authorizedIPs = append(checker.authorizedIPs, &ipAddr)
|
||||
logger.Debug(fmt.Sprintf("IP %v is trusted", ipAddr))
|
||||
log.Debug(fmt.Sprintf("IP %v is trusted", ipAddr))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ func NewChecker(trustedIPs []string) (*Checker, error) {
|
||||
return nil, fmt.Errorf("parsing CIDR trusted IPs %s: %w", ipAddr, err)
|
||||
}
|
||||
checker.authorizedIPsNet = append(checker.authorizedIPsNet, ipAddr)
|
||||
logger.Debug(fmt.Sprintf("IP network %v is trusted", ipAddr))
|
||||
log.Debug(fmt.Sprintf("IP network %v is trusted", ipAddr))
|
||||
}
|
||||
|
||||
return checker, nil
|
||||
|
||||
+25
-16
@@ -8,32 +8,41 @@ import (
|
||||
"os"
|
||||
)
|
||||
|
||||
var (
|
||||
loggerInfo = log.New(io.Discard, "INFO: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime) //nolint:gochecknoglobals
|
||||
loggerDebug = log.New(io.Discard, "DEBUG: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime) //nolint:gochecknoglobals
|
||||
loggerError = log.New(io.Discard, "ERROR: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime) //nolint:gochecknoglobals
|
||||
)
|
||||
// Log Logger struct.
|
||||
type Log struct {
|
||||
logError *log.Logger
|
||||
logInfo *log.Logger
|
||||
logDebug *log.Logger
|
||||
}
|
||||
|
||||
// Init Set Default log level to info in case log level to defined.
|
||||
func Init(logLevel string) {
|
||||
loggerError.SetOutput(os.Stderr)
|
||||
loggerInfo.SetOutput(os.Stdout)
|
||||
// New Set Default log level to info in case log level to defined.
|
||||
func New(logLevel string) *Log {
|
||||
logError := log.New(io.Discard, "ERROR: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logInfo := log.New(io.Discard, "INFO: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logDebug := log.New(io.Discard, "DEBUG: CrowdsecBouncerTraefikPlugin: ", log.Ldate|log.Ltime)
|
||||
logError.SetOutput(os.Stderr)
|
||||
logInfo.SetOutput(os.Stdout)
|
||||
if logLevel == "DEBUG" {
|
||||
loggerDebug.SetOutput(os.Stdout)
|
||||
logDebug.SetOutput(os.Stdout)
|
||||
}
|
||||
return &Log{
|
||||
logError: logError,
|
||||
logInfo: logInfo,
|
||||
logDebug: logDebug,
|
||||
}
|
||||
}
|
||||
|
||||
// Info log to Stdout.
|
||||
func Info(str string) {
|
||||
loggerInfo.Printf(str)
|
||||
func (l *Log) Info(str string) {
|
||||
l.logInfo.Printf(str)
|
||||
}
|
||||
|
||||
// Debug log to Stdout.
|
||||
func Debug(str string) {
|
||||
loggerDebug.Printf(str)
|
||||
func (l *Log) Debug(str string) {
|
||||
l.logDebug.Printf(str)
|
||||
}
|
||||
|
||||
// Error log to Stderr.
|
||||
func Error(str string) {
|
||||
loggerError.Printf(str)
|
||||
func (l *Log) Error(str string) {
|
||||
l.logError.Printf(str)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user