diff --git a/go.mod b/go.mod index ae6d275e7..c22bee7f1 100644 --- a/go.mod +++ b/go.mod @@ -34,7 +34,7 @@ require ( github.com/joncrlsn/dque v0.0.0-20241024143830-7723fd131a64 github.com/kubescape/backend v0.0.39 github.com/kubescape/go-logger v0.0.28 - github.com/kubescape/k8s-interface v0.0.206 + github.com/kubescape/k8s-interface v0.0.207 github.com/kubescape/storage v0.0.258 github.com/kubescape/workerpool v0.0.0-20250526074519-0e4a4e7f44cf github.com/moby/sys/mountinfo v0.7.2 diff --git a/go.sum b/go.sum index d18386e6c..381e31cba 100644 --- a/go.sum +++ b/go.sum @@ -885,8 +885,8 @@ github.com/kubescape/backend v0.0.39 h1:B1QRfKCSFlzuE+jWOnk/l7EpH71/Q3n14KKq0QSn github.com/kubescape/backend v0.0.39/go.mod h1:cMEGP8cXUZgY89YU4GRBGIla9HZW7grZsUtlCwvZgAE= github.com/kubescape/go-logger v0.0.28 h1:xulKTp9kOg3rD98sopFELQ6yZCHQoQXMDzteoSHDFKI= github.com/kubescape/go-logger v0.0.28/go.mod h1:YZHFjwGCDar1hP9OyBLE46oR7a0Y/Z/0FperDo8+9D0= -github.com/kubescape/k8s-interface v0.0.206 h1:qaYu4mlLmSBePanSGq+DBCssh4O785TAT0lQGNGWyGw= -github.com/kubescape/k8s-interface v0.0.206/go.mod h1:WNYUG93aZ5kDmuaRKFLtVhp18Yc6EfaHdD1gLYtVTN4= +github.com/kubescape/k8s-interface v0.0.207 h1:jX+EqZLjSArw4xa+XMvjnnoK0Q8IxdD2tvihwLa/WGg= +github.com/kubescape/k8s-interface v0.0.207/go.mod h1:WNYUG93aZ5kDmuaRKFLtVhp18Yc6EfaHdD1gLYtVTN4= github.com/kubescape/storage v0.0.258 h1:0mL0z3dAmtP1qup7VgoEgwLgbBSROu5oOusBAPeMmus= github.com/kubescape/storage v0.0.258/go.mod h1:VHs+xQzvZKE2lJDN8rR1sFmTa43N6XJAcatZ249gviU= github.com/kubescape/workerpool v0.0.0-20250526074519-0e4a4e7f44cf h1:hI0jVwrB6fT4GJWvuUjzObfci1CUknrZdRHfnRVtKM0= diff --git a/pkg/containerprofilemanager/v1/lifecycle.go b/pkg/containerprofilemanager/v1/lifecycle.go index 8e40fd870..21ff1cf3b 100644 --- a/pkg/containerprofilemanager/v1/lifecycle.go +++ b/pkg/containerprofilemanager/v1/lifecycle.go @@ -159,6 +159,7 @@ func (cpm *ContainerProfileManager) addContainer(container *containercollection. // Setup monitoring timer sniffingTime := cpm.calculateSniffingTime(container) + sharedData.LearningPeriod = sniffingTime timer := time.AfterFunc(sniffingTime, func() { cpm.handleContainerMaxTime(container) }) diff --git a/pkg/objectcache/shared_container_data.go b/pkg/objectcache/shared_container_data.go index f2773c628..49ac5d7ed 100644 --- a/pkg/objectcache/shared_container_data.go +++ b/pkg/objectcache/shared_container_data.go @@ -82,6 +82,7 @@ type WatchedContainerData struct { CurrentReportTimestamp time.Time UserDefinedProfile string LabelOverrides map[string]string // optional label overrides applied after GetLabels() + LearningPeriod time.Duration } type ContainerInfo struct { @@ -90,31 +91,19 @@ type ContainerInfo struct { ImageID string } +func formatDuration(d time.Duration) string { + s := d.String() + s = strings.Replace(s, "m0s", "m", 1) + s = strings.Replace(s, "h0m", "h", 1) + return s +} + func GetLabels(cloudMetadata *armotypes.CloudMetadata, watchedContainer *WatchedContainerData, stripContainer bool) map[string]string { labels := watchedContainer.InstanceID.GetLabels() - for i := range labels { - if labels[i] == "" || (stripContainer && i == helpersv1.ContainerNameMetadataKey) { - delete(labels, i) - continue - } - if errs := content.IsLabelValue(labels[i]); len(errs) != 0 { - logger.L().Debug("GetLabels - label is not valid", helpers.String("label", labels[i])) - for j := range errs { - logger.L().Debug("GetLabels - label err description", helpers.String("Err: ", errs[j])) - } - delete(labels, i) - } - } + labels[helpersv1.LearningPeriodMetadataKey] = formatDuration(watchedContainer.LearningPeriod) // Apply label overrides for k, v := range watchedContainer.LabelOverrides { - if v == "" { - delete(labels, k) - } else if errs := content.IsLabelValue(v); len(errs) != 0 { - logger.L().Warning("GetLabels - label override value is not valid, skipping", helpers.String("key", k), helpers.String("value", v)) - delete(labels, k) - } else { - labels[k] = v - } + labels[k] = v } if watchedContainer.ParentResourceVersion != "" { labels[helpersv1.ResourceVersionMetadataKey] = watchedContainer.ParentResourceVersion @@ -134,6 +123,20 @@ func GetLabels(cloudMetadata *armotypes.CloudMetadata, watchedContainer *Watched labels[helpersv1.RegionMetadataKey] = region } } + // Sanitize labels + for i := range labels { + if labels[i] == "" || (stripContainer && i == helpersv1.ContainerNameMetadataKey) { + delete(labels, i) + continue + } + if errs := content.IsLabelValue(labels[i]); len(errs) != 0 { + logger.L().Debug("GetLabels - label is not valid", helpers.String("label", labels[i])) + for j := range errs { + logger.L().Debug("GetLabels - label err description", helpers.String("Err: ", errs[j])) + } + delete(labels, i) + } + } return labels } diff --git a/pkg/objectcache/shared_container_data_test.go b/pkg/objectcache/shared_container_data_test.go index 63eb1983c..ff1cd4752 100644 --- a/pkg/objectcache/shared_container_data_test.go +++ b/pkg/objectcache/shared_container_data_test.go @@ -2,6 +2,7 @@ package objectcache import ( "testing" + "time" "github.com/kubescape/k8s-interface/instanceidhandler/v1" "github.com/stretchr/testify/assert" @@ -51,6 +52,7 @@ func Test_GetLabels(t *testing.T) { "kubescape.io/workload-api-version": "v1", "kubescape.io/workload-container-name": "redis", "kubescape.io/workload-kind": "Deployment", + "kubescape.io/learning-period": "0s", "kubescape.io/workload-name": "redis", "kubescape.io/workload-namespace": "aaa", }, @@ -67,6 +69,7 @@ func Test_GetLabels(t *testing.T) { want: map[string]string{ "kubescape.io/workload-api-version": "v1", "kubescape.io/workload-kind": "Deployment", + "kubescape.io/learning-period": "0s", "kubescape.io/workload-name": "redis", "kubescape.io/workload-namespace": "aaa", }, @@ -79,3 +82,36 @@ func Test_GetLabels(t *testing.T) { }) } } + +func Test_formatDuration(t *testing.T) { + tests := []struct { + d time.Duration + want string + }{ + { + d: 5 * time.Minute, + want: "5m", + }, + { + d: 1*time.Hour + 30*time.Minute, + want: "1h30m", + }, + { + d: 45 * time.Second, + want: "45s", + }, + { + d: 1*time.Hour + 30*time.Second, + want: "1h30s", + }, + { + d: 1 * time.Hour, + want: "1h", + }, + } + for _, tt := range tests { + t.Run(tt.d.String(), func(t *testing.T) { + assert.Equal(t, tt.want, formatDuration(tt.d)) + }) + } +}