diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml index af6fa4d..82897a5 100644 --- a/.github/workflows/lint.yml +++ b/.github/workflows/lint.yml @@ -36,9 +36,9 @@ jobs: make build - name: golangci-lint - uses: golangci/golangci-lint-action@v7 + uses: golangci/golangci-lint-action@4afd733a84b1f43292c63897423277bb7f4313a9 # v8.0.0 with: - version: v2.0 + version: v2.5 args: --issues-exit-code=1 --timeout 10m only-new-issues: false diff --git a/.golangci.yml b/.golangci.yml index 17e2c03..2e869d0 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -24,6 +24,10 @@ linters: - whitespace - wrapcheck - wsl + - embeddedstructfieldcheck + - noinlineerr + - wsl_v5 + settings: depguard: @@ -32,6 +36,13 @@ linters: deny: - pkg: github.com/pkg/errors desc: errors.Wrap() is deprecated in favor of fmt.Errorf() + + gocritic: + enable-all: true + disabled-checks: + - importShadow + - sloppyReassign + govet: disable: - fieldalignment diff --git a/cmd/root.go b/cmd/root.go index a3e4111..d01ef50 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -57,14 +57,14 @@ func HandleSignals(ctx context.Context) error { return nil } -func deleteDecisions(custom *custom.CustomBouncer, decisions []*models.Decision) { +func deleteDecisions(ctx context.Context, custom *custom.CustomBouncer, decisions []*models.Decision) { if len(decisions) == 1 { - log.Infof("deleting 1 decision") + log.Info("deleting 1 decision") } else { log.Infof("deleting %d decisions", len(decisions)) } for _, d := range decisions { - if err := custom.Delete(d); err != nil { + if err := custom.Delete(ctx, d); err != nil { log.Errorf("unable to delete decision for '%s': %s", *d.Value, err) continue } @@ -72,14 +72,14 @@ func deleteDecisions(custom *custom.CustomBouncer, decisions []*models.Decision) } } -func addDecisions(custom *custom.CustomBouncer, decisions []*models.Decision) { +func addDecisions(ctx context.Context, custom *custom.CustomBouncer, decisions []*models.Decision) { if len(decisions) == 1 { log.Info("adding 1 decision") } else { log.Infof("adding %d decisions", len(decisions)) } for _, d := range decisions { - if err := custom.Add(d); err != nil { + if err := custom.Add(ctx, d); err != nil { log.Errorf("unable to insert decision for '%s': %s", *d.Value, err) continue } @@ -236,13 +236,13 @@ func Execute() error { } g.Go(func() error { - log.Infof("Processing new and deleted decisions . . .") + log.Info("Processing new and deleted decisions . . .") for { select { case <-ctx.Done(): - log.Infoln("terminating bouncer process") + log.Info("terminating bouncer process") if config.PrometheusConfig.Enabled { - log.Infoln("terminating prometheus server") + log.Info("terminating prometheus server") if err := promServer.Shutdown(context.Background()); err != nil { log.Errorf("unable to shutdown prometheus server: %s", err) } @@ -252,8 +252,8 @@ func Execute() error { if decisions == nil { continue } - deleteDecisions(custom, decisions.Deleted) - addDecisions(custom, decisions.New) + deleteDecisions(ctx, custom, decisions.Deleted) + addDecisions(ctx, custom, decisions.New) case <-cacheResetTicker.C: custom.ResetCache() } diff --git a/pkg/cfg/config.go b/pkg/cfg/config.go index 0b031e5..9bc1100 100644 --- a/pkg/cfg/config.go +++ b/pkg/cfg/config.go @@ -52,29 +52,29 @@ func NewConfig(reader io.Reader) (*BouncerConfig, error) { fcontent, err := io.ReadAll(reader) if err != nil { - return &BouncerConfig{}, err + return nil, err } err = yaml.Unmarshal(fcontent, &config) if err != nil { - return &BouncerConfig{}, fmt.Errorf("failed to unmarshal: %w", err) + return nil, fmt.Errorf("failed to unmarshal: %w", err) } if err = config.Logging.setup("crowdsec-custom-bouncer.log"); err != nil { - return &BouncerConfig{}, err + return nil, err } if config.BinPath == "" { - return &BouncerConfig{}, errors.New("bin_path is not set") + return nil, errors.New("bin_path is not set") } _, err = os.Stat(config.BinPath) if os.IsNotExist(err) { - return &BouncerConfig{}, fmt.Errorf("binary '%s' doesn't exist", config.BinPath) + return nil, fmt.Errorf("binary '%s' doesn't exist", config.BinPath) } if config.CacheRetentionDuration == 0 { - log.Infof("cache_retention_duration defaults to 10 seconds") + log.Info("cache_retention_duration defaults to 10 seconds") config.CacheRetentionDuration = 10 * time.Second } diff --git a/pkg/custom/custom.go b/pkg/custom/custom.go index 6ea7c31..55e1b83 100644 --- a/pkg/custom/custom.go +++ b/pkg/custom/custom.go @@ -1,6 +1,7 @@ package custom import ( + "context" "encoding/json" "fmt" "io" @@ -56,7 +57,7 @@ func (c *CustomBouncer) Init() error { return nil } -func (c *CustomBouncer) Add(decision *models.Decision) error { +func (c *CustomBouncer) Add(ctx context.Context, decision *models.Decision) error { if _, exists := c.newDecisionValueSet[decisionToDecisionKey(decision)]; exists { return nil } @@ -79,7 +80,7 @@ func (c *CustomBouncer) Add(decision *models.Decision) error { c.newDecisionValueSet[decisionToDecisionKey(decision)] = struct{}{} return nil } - cmd := exec.Command(c.Path, "add", *decision.Value, strconv.Itoa(int(banDuration.Seconds())), *decision.Scenario, str) + cmd := exec.CommandContext(ctx, c.Path, "add", *decision.Value, strconv.Itoa(int(banDuration.Seconds())), *decision.Scenario, str) if out, err := cmd.CombinedOutput(); err != nil { log.Errorf("Error in 'add' command (%s): %v --> %s", cmd.String(), err, string(out)) } @@ -87,7 +88,7 @@ func (c *CustomBouncer) Add(decision *models.Decision) error { return nil } -func (c *CustomBouncer) Delete(decision *models.Decision) error { +func (c *CustomBouncer) Delete(ctx context.Context, decision *models.Decision) error { if _, exists := c.expiredDecisionValueSet[decisionToDecisionKey(decision)]; exists { return nil } @@ -110,7 +111,7 @@ func (c *CustomBouncer) Delete(decision *models.Decision) error { log.Warningf("serialize: %s", err) } log.Debugf("custom [%s] : del ban on %s for %s sec (%s)", c.Path, *decision.Value, strconv.Itoa(int(banDuration.Seconds())), *decision.Scenario) - cmd := exec.Command(c.Path, "del", *decision.Value, strconv.Itoa(int(banDuration.Seconds())), *decision.Scenario, str) + cmd := exec.CommandContext(ctx, c.Path, "del", *decision.Value, strconv.Itoa(int(banDuration.Seconds())), *decision.Scenario, str) if out, err := cmd.CombinedOutput(); err != nil { log.Errorf("Error in 'del' command (%s): %v --> %s", cmd.String(), err, string(out)) } diff --git a/pkg/custom/custom_test.go b/pkg/custom/custom_test.go index 96ad840..4b26959 100644 --- a/pkg/custom/custom_test.go +++ b/pkg/custom/custom_test.go @@ -40,7 +40,7 @@ func parseFile(path string) []parsedLine { panic(err) } for _, line := range strings.Split(string(dat), "\n") { - if len(line) == 0 { + if line == "" { continue } @@ -68,6 +68,8 @@ func cleanup() { } func Test_CustomBouncer_Add(t *testing.T) { + ctx := t.Context() + type args struct { Decisions []*models.Decision } @@ -166,7 +168,7 @@ func Test_CustomBouncer_Add(t *testing.T) { } c.ResetCache() for _, decision := range tt.args.Decisions { - err := c.Add(decision) + err := c.Add(ctx, decision) if err != nil { t.Error(err) } @@ -180,6 +182,8 @@ func Test_CustomBouncer_Add(t *testing.T) { } func Test_CustomBouncer_Delete(t *testing.T) { + ctx := t.Context() + type args struct { Decisions []*models.Decision } @@ -278,7 +282,7 @@ func Test_CustomBouncer_Delete(t *testing.T) { } c.ResetCache() for _, decision := range tt.args.Decisions { - err := c.Delete(decision) + err := c.Delete(ctx, decision) if err != nil { t.Error(err) }