Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add ns include/exclude config for scans #323

Merged
merged 1 commit into from
Jul 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion build/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM --platform=$BUILDPLATFORM golang:1.22-bullseye as builder
FROM --platform=$BUILDPLATFORM golang:1.22-bullseye AS builder

ENV GO111MODULE=on CGO_ENABLED=0
WORKDIR /work
Expand Down
2 changes: 1 addition & 1 deletion main.go
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,7 @@ func main() {

nodeName := os.Getenv(config.NodeNameEnvVar)
// Create watchers
dWatcher := dynamicwatcher.NewWatchHandler(k8sClient)
dWatcher := dynamicwatcher.NewWatchHandler(k8sClient, cfg)
// create k8sObject cache
k8sObjectCache, err := k8scache.NewK8sObjectCache(nodeName, k8sClient)
if err != nil {
Expand Down
18 changes: 18 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package config

import (
"slices"
"time"

"github.com/kubescape/node-agent/pkg/exporters"
Expand All @@ -26,6 +27,8 @@ type Config struct {
EnableNodeProfile bool `mapstructure:"nodeProfileServiceEnabled"`
NodeProfileInterval time.Duration `mapstructure:"nodeProfileInterval"`
EnableSeccomp bool `mapstructure:"seccompServiceEnabled"`
ExcludeNamespaces []string `mapstructure:"excludeNamespaces"`
IncludeNamespaces []string `mapstructure:"includeNamespaces"`
}

// LoadConfig reads configuration from file or environment variables.
Expand All @@ -49,3 +52,18 @@ func LoadConfig(path string) (Config, error) {
err = viper.Unmarshal(&config)
return config, err
}

func (c *Config) SkipNamespace(ns string) bool {
if includeNamespaces := c.IncludeNamespaces; len(includeNamespaces) > 0 {
if !slices.Contains(includeNamespaces, ns) {
// skip ns not in IncludeNamespaces
return true
}
} else if excludeNamespaces := c.ExcludeNamespaces; len(excludeNamespaces) > 0 {
if slices.Contains(excludeNamespaces, ns) {
// skip ns in ExcludeNamespaces
return true
}
}
return false
}
9 changes: 7 additions & 2 deletions pkg/containerwatcher/v1/container_watcher_private.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ const (

func (ch *IGContainerWatcher) containerCallback(notif containercollection.PubSubEvent) {

// do not trace the node-agent pod
// check if the container should be ignored
if ch.ignoreContainer(notif.Container.K8s.Namespace, notif.Container.K8s.PodName) {
// avoid loops when the container is being removed
if notif.Type == containercollection.EventTypeAddContainer {
Expand Down Expand Up @@ -363,5 +363,10 @@ func (ch *IGContainerWatcher) unregisterContainer(container *containercollection
}

func (ch *IGContainerWatcher) ignoreContainer(namespace, name string) bool {
return name == ch.podName && namespace == ch.namespace
// do not trace the node-agent pod
if name == ch.podName && namespace == ch.namespace {
return true
}
// check if config excludes the namespace
return ch.cfg.SkipNamespace(namespace)
}
16 changes: 0 additions & 16 deletions pkg/objectcache/applicationactivitiescache_interface.go

This file was deleted.

1 change: 0 additions & 1 deletion pkg/storage/storage_interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (

type StorageClient interface {
CreateApplicationActivity(activity *v1beta1.ApplicationActivity, namespace string) error
GetApplicationActivity(namespace, name string) (*v1beta1.ApplicationActivity, error)
CreateApplicationProfile(profile *v1beta1.ApplicationProfile, namespace string) error
PatchApplicationProfile(name, namespace string, patch []byte, channel chan error) error
GetApplicationProfile(namespace, name string) (*v1beta1.ApplicationProfile, error)
Expand Down
8 changes: 0 additions & 8 deletions pkg/storage/storage_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,6 @@ type StorageHttpClientMock struct {
failedOnce bool
}

func (sc *StorageHttpClientMock) GetApplicationActivity(_, _ string) (*spdxv1beta1.ApplicationActivity, error) {
return &spdxv1beta1.ApplicationActivity{
Spec: spdxv1beta1.ApplicationActivitySpec{
Syscalls: []string{"open"},
},
}, nil
}

var _ StorageClient = (*StorageHttpClientMock)(nil)

func CreateSyftSBOMStorageHttpClientMock(sbom spdxv1beta1.SBOMSyft) *StorageHttpClientMock {
Expand Down
4 changes: 0 additions & 4 deletions pkg/storage/v1/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,6 @@ func (sc Storage) CreateApplicationActivity(activity *v1beta1.ApplicationActivit
return nil
}

func (sc Storage) GetApplicationActivity(namespace, name string) (*v1beta1.ApplicationActivity, error) {
return sc.StorageClient.ApplicationActivities(namespace).Get(context.Background(), name, metav1.GetOptions{})
}

func (sc Storage) CreateFilteredSBOM(SBOM *v1beta1.SBOMSyftFiltered) error {
_, err := sc.StorageClient.SBOMSyftFiltereds(sc.namespace).Create(context.Background(), SBOM, metav1.CreateOptions{})
if err != nil {
Expand Down
37 changes: 25 additions & 12 deletions pkg/watcher/dynamicwatcher/watch.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,12 @@ import (
"os"
"time"

"github.com/kubescape/node-agent/pkg/config"
"github.com/kubescape/node-agent/pkg/k8sclient"
"github.com/kubescape/node-agent/pkg/watcher"
"github.com/kubescape/node-agent/pkg/watcher/cooldownqueue"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/tools/pager"

"github.com/cenkalti/backoff/v4"

Expand All @@ -36,15 +39,17 @@ type WatchHandler struct {
resources map[string]watcher.WatchResource
eventQueues map[string]*cooldownqueue.CooldownQueue
handlers []watcher.Watcher
cfg config.Config
}

var errWatchClosed = errors.New("watch channel closed")

func NewWatchHandler(k8sClient k8sclient.K8sClientInterface) *WatchHandler {
func NewWatchHandler(k8sClient k8sclient.K8sClientInterface, cfg config.Config) *WatchHandler {
return &WatchHandler{
k8sClient: k8sClient,
resources: make(map[string]watcher.WatchResource),
eventQueues: make(map[string]*cooldownqueue.CooldownQueue),
cfg: cfg,
}
}

Expand Down Expand Up @@ -152,7 +157,10 @@ func (wh *WatchHandler) watchRetry(ctx context.Context, res schema.GroupVersionR
if event.Type == watch.Error {
return fmt.Errorf("watch error: %s", event.Object)
}

pod := event.Object.(*unstructured.Unstructured)
if wh.cfg.SkipNamespace(pod.GetNamespace()) {
continue
}
eventQueue.Enqueue(event)
}
}, newBackOff(), func(err error, d time.Duration) {
Expand All @@ -172,20 +180,25 @@ func (wh *WatchHandler) watchRetry(ctx context.Context, res schema.GroupVersionR

func (wh *WatchHandler) getExistingStorageObjects(ctx context.Context, res schema.GroupVersionResource, watchOpts metav1.ListOptions) (string, error) {
logger.L().Debug("WatchHandler - getting existing objects from storage", helpers.String("resource", res.Resource))
list, err := wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").List(context.Background(), watchOpts)
if err != nil {
return "", fmt.Errorf("list resources: %w", err)
}
logger.L().Debug("WatchHandler - got existing objects from storage", helpers.String("resource", res.Resource), helpers.Int("count", len(list.Items)))
for i := range list.Items {
list := pager.New(func(ctx context.Context, opts metav1.ListOptions) (runtime.Object, error) {
return wh.k8sClient.GetDynamicClient().Resource(res).Namespace("").List(ctx, opts)
})
var resourceVersion string
if err := list.EachListItem(context.Background(), watchOpts, func(obj runtime.Object) error {
pod := obj.(*unstructured.Unstructured)
resourceVersion = pod.GetResourceVersion()
if wh.cfg.SkipNamespace(pod.GetNamespace()) {
return nil
}
for _, handler := range wh.handlers {
var l unstructured.Unstructured
l = list.Items[i]
handler.AddHandler(ctx, &l)
handler.AddHandler(ctx, pod)
}
return nil
}); err != nil {
return "", fmt.Errorf("list resources: %w", err)
}
// set resource version to watch from
return list.GetResourceVersion(), nil
return resourceVersion, nil
}

func newBackOff() backoff.BackOff {
Expand Down
3 changes: 2 additions & 1 deletion pkg/watcher/dynamicwatcher/watch_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"time"

"github.com/kubescape/node-agent/mocks"
"github.com/kubescape/node-agent/pkg/config"
"github.com/kubescape/node-agent/pkg/watcher"

"github.com/kubescape/storage/pkg/apis/softwarecomposition/v1beta1"
Expand Down Expand Up @@ -74,7 +75,7 @@ func startTest(t *testing.T, tc testObj) {
k8sClient := k8sinterface.NewKubernetesApiMock()
k8sClient.DynamicClient = dynamicfake.NewSimpleDynamicClient(scheme.Scheme, tc.preCreatedObjects...)

wh := NewWatchHandler(k8sClient)
wh := NewWatchHandler(k8sClient, config.Config{})

wh.AddAdaptor(a)

Expand Down
Loading