From bd30c415722b5fe11e9f5ec594f0cda47807f4fc Mon Sep 17 00:00:00 2001 From: anjmao Date: Thu, 23 Nov 2023 12:28:05 +0200 Subject: [PATCH] Skip linting managed jobs --- cmd/agent/main.go | 5 +--- config/config.go | 10 ++++++-- e2e/e2e.go | 3 +++ linters/kubelinter/controller.go | 37 ++++++++++++++++----------- linters/kubelinter/controller_test.go | 6 ++--- 5 files changed, 36 insertions(+), 25 deletions(-) diff --git a/cmd/agent/main.go b/cmd/agent/main.go index 8266a49f..5c9e917c 100644 --- a/cmd/agent/main.go +++ b/cmd/agent/main.go @@ -191,10 +191,7 @@ func run(ctx context.Context, logger logrus.FieldLogger, castaiClient castai.Cli if cfg.Linter.Enabled { log.Info("linter enabled") - linterCtrl, err := kubelinter.NewController(log, castaiClient, linter) - if err != nil { - return err - } + linterCtrl := kubelinter.NewController(log, cfg.Linter, castaiClient, linter) kubeCtrl.AddSubscribers(linterCtrl) } if cfg.KubeBench.Enabled { diff --git a/config/config.go b/config/config.go index 29295806..f29dba2d 100644 --- a/config/config.go +++ b/config/config.go @@ -90,7 +90,8 @@ type ImageScanImage struct { } type Linter struct { - Enabled bool `envconfig:"LINTER_ENABLED" yaml:"enabled"` + Enabled bool `envconfig:"LINTER_ENABLED" yaml:"enabled"` + ScanInterval time.Duration `envconfig:"LINTER_SCAN_INTERVAL" yaml:"scanInterval"` } type KubeBench struct { @@ -207,7 +208,12 @@ func Load(configPath string) (Config, error) { } if cfg.KubeBench.Enabled { if cfg.KubeBench.ScanInterval == 0 { - cfg.KubeBench.ScanInterval = 15 * time.Second + cfg.KubeBench.ScanInterval = 30 * time.Second + } + } + if cfg.Linter.Enabled { + if cfg.Linter.ScanInterval == 0 { + cfg.Linter.ScanInterval = 30 * time.Second } } diff --git a/e2e/e2e.go b/e2e/e2e.go index d56bf770..9b2ab724 100644 --- a/e2e/e2e.go +++ b/e2e/e2e.go @@ -186,6 +186,9 @@ func installChart(ns, imageTag string) ([]byte, error) { --set structuredConfig.imageScan.image.name=%s \ --set structuredConfig.imageScan.mode=hostfs \ --set structuredConfig.imageScan.initDelay=10s \ + --set structuredConfig.linter.scanInterval=5s \ + --set structuredConfig.deltaSyncInterval=5s \ + --set structuredConfig.kubeBench.scanInterval=5s \ --set structuredConfig.kubeBench.enabled=true \ --set structuredConfig.kubeClient.useProtobuf=true \ --set castai.apiURL=%s \ diff --git a/linters/kubelinter/controller.go b/linters/kubelinter/controller.go index c155095f..a013d70f 100644 --- a/linters/kubelinter/controller.go +++ b/linters/kubelinter/controller.go @@ -8,6 +8,7 @@ import ( "strings" "time" + "github.com/castai/kvisor/config" batchv1 "k8s.io/api/batch/v1" "github.com/samber/lo" @@ -23,25 +24,22 @@ import ( "github.com/castai/kvisor/metrics" ) -func NewController(log logrus.FieldLogger, client castai.Client, linter *Linter) (*Controller, error) { - ctx, cancel := context.WithCancel(context.Background()) +func NewController(log logrus.FieldLogger, cfg config.Linter, client castai.Client, linter *Linter) *Controller { return &Controller{ - ctx: ctx, - cancel: cancel, + log: log, + cfg: cfg, client: client, linter: linter, delta: newDeltaState(), - log: log, - }, nil + } } type Controller struct { - ctx context.Context - cancel context.CancelFunc + log logrus.FieldLogger + cfg config.Linter client castai.Client linter *Linter delta *deltaState - log logrus.FieldLogger } func (s *Controller) RequiredInformers() []reflect.Type { @@ -68,10 +66,10 @@ func (s *Controller) Run(ctx context.Context) error { select { case <-ctx.Done(): return nil - case <-time.After(15 * time.Second): + case <-time.After(s.cfg.ScanInterval): objects := s.delta.flush() if len(objects) > 0 { - if err := s.lintObjects(objects); err != nil && !errors.Is(err, context.Canceled) { + if err := s.lintObjects(ctx, objects); err != nil && !errors.Is(err, context.Canceled) { s.log.Error(err) // put unprocessed objects back to delta queue @@ -101,6 +99,11 @@ func (s *Controller) modifyDelta(event kube.Event, o kube.Object) { if !isStandalonePod(o) { return } + case *batchv1.Job: + // Skip jobs which belongs to cronjobs etc. + if !isStandaloneJob(o) { + return + } } switch event { @@ -113,7 +116,7 @@ func (s *Controller) modifyDelta(event kube.Event, o kube.Object) { } } -func (s *Controller) lintObjects(objects []kube.Object) (rerr error) { +func (s *Controller) lintObjects(ctx context.Context, objects []kube.Object) (rerr error) { start := time.Now() defer func() { metrics.IncScansTotal(metrics.ScanTypeLinter, rerr) @@ -127,7 +130,7 @@ func (s *Controller) lintObjects(objects []kube.Object) (rerr error) { return fmt.Errorf("kubelinter failed: %w", err) } - ctx, cancel := context.WithTimeout(s.ctx, time.Second*5) + ctx, cancel := context.WithTimeout(ctx, time.Second*5) defer cancel() if err := s.client.SendLinterChecks(ctx, checks); err != nil { @@ -143,11 +146,15 @@ func isStandalonePod(pod *corev1.Pod) bool { return false } - // pod created without parent + // Pod created without parent. if len(pod.OwnerReferences) == 0 { return true } - // static pod + // Static pod. return strings.HasSuffix(pod.ObjectMeta.Name, pod.Spec.NodeName) } + +func isStandaloneJob(job *batchv1.Job) bool { + return len(job.OwnerReferences) == 0 +} diff --git a/linters/kubelinter/controller_test.go b/linters/kubelinter/controller_test.go index f6091aa2..4ccabc80 100644 --- a/linters/kubelinter/controller_test.go +++ b/linters/kubelinter/controller_test.go @@ -22,7 +22,6 @@ func TestSubscriber(t *testing.T) { t.Run("sends linter checks", func(t *testing.T) { r := require.New(t) - ctx, cancel := context.WithCancel(context.Background()) mockctrl := gomock.NewController(t) defer mockctrl.Finish() castaiClient := mock_castai.NewMockClient(mockctrl) @@ -31,8 +30,6 @@ func TestSubscriber(t *testing.T) { r.NoError(err) ctrl := &Controller{ - ctx: ctx, - cancel: cancel, client: castaiClient, linter: linter, delta: newDeltaState(), @@ -52,6 +49,7 @@ func TestSubscriber(t *testing.T) { }, }, } - r.NoError(ctrl.lintObjects(objects)) + ctx := context.Background() + r.NoError(ctrl.lintObjects(ctx, objects)) }) }