diff --git a/cmd/agent/common/autodiscovery.go b/cmd/agent/common/autodiscovery.go index 989e6525d56b44..a21758b82b5eb5 100644 --- a/cmd/agent/common/autodiscovery.go +++ b/cmd/agent/common/autodiscovery.go @@ -13,6 +13,7 @@ import ( "slices" "time" + "github.com/DataDog/datadog-agent/pkg/util/flavor" "go.uber.org/atomic" utilserror "k8s.io/apimachinery/pkg/util/errors" @@ -59,6 +60,16 @@ func setupAutoDiscovery(confSearchPaths []string, wmeta workloadmeta.Component, time.Duration(pkgconfigsetup.Datadog().GetInt("autoconf_config_files_poll_interval"))*time.Second, ) + crdCheckEnabled := pkgconfigsetup.Datadog().GetBool("workload_config.enabled") + if crdCheckEnabled && flavor.GetFlavor() != flavor.ClusterAgent { + pollInterval := time.Duration(pkgconfigsetup.Datadog().GetInt("autoconf_crd_checks_poll_interval")) * time.Second + ac.AddConfigProvider( + providers.NewCRDFileConfigProvider(pkgconfigsetup.Datadog().GetString("autoconf_crd_checks_dir"), providers.DefaultCRDNameExtractor, acTelemetryStore), + true, + pollInterval, + ) + } + // Autodiscovery cannot easily use config.RegisterOverrideFunc() due to Unmarshalling extraConfigProviders, extraConfigListeners := confad.DiscoverComponentsFromConfig() diff --git a/cmd/cluster-agent/subcommands/start/command.go b/cmd/cluster-agent/subcommands/start/command.go index 4254026af4ff23..2dcedb54b722cd 100644 --- a/cmd/cluster-agent/subcommands/start/command.go +++ b/cmd/cluster-agent/subcommands/start/command.go @@ -389,6 +389,7 @@ func start(log log.Component, DynamicInformerFactory: apiCl.DynamicInformerFactory, Client: apiCl.InformerCl, IsLeaderFunc: le.IsLeader, + LeaderNotifier: le.Subscribe, EventRecorder: eventRecorder, WorkloadMeta: wmeta, StopCh: stopCh, diff --git a/comp/core/autodiscovery/listeners/service.go b/comp/core/autodiscovery/listeners/service.go index 63ffb6814f5074..6b6c7ea05f3efa 100644 --- a/comp/core/autodiscovery/listeners/service.go +++ b/comp/core/autodiscovery/listeners/service.go @@ -149,6 +149,10 @@ func (s *WorkloadService) FilterTemplates(configs map[string]integration.Config) s.filterTemplatesOverriddenChecks(configs) filterTemplatesMatched(s, configs) + // Provider precedence must run after matching so that a CRD file template + // rejected by workload filters does not suppress the file fallback. + s.filterTemplatesProviderPrecedence(configs) + // Container Collect All filtering should always be last s.filterTemplatesContainerCollectAll(configs) } @@ -187,16 +191,16 @@ func (s *WorkloadService) filterTemplatesEmptyOverrides(configs map[string]integ } } -// filterTemplatesOverriddenChecks drops file-based templates if this service's -// labels/annotations specify a check of the same name. +// filterTemplatesOverriddenChecks drops file-based and CRD-file-based templates +// if this service's labels/annotations specify a check of the same name. func (s *WorkloadService) filterTemplatesOverriddenChecks(configs map[string]integration.Config) { for digest, config := range configs { - if config.Provider != names.File { - continue // only override file configs + if config.Provider != names.File && config.Provider != names.CRDFile { + continue // only override file and CRD file configs } for _, checkName := range s.checkNames { if config.Name == checkName { - // Ignore config from file when the same check is activated on + // Ignore config from file/CRD file when the same check is activated on // the same service via other config providers (k8s annotations // or container labels) log.Debugf("Ignoring config from %s: the service %s overrides check %s", @@ -207,6 +211,30 @@ func (s *WorkloadService) filterTemplatesOverriddenChecks(configs map[string]int } } +// filterTemplatesProviderPrecedence enforces CRD-file-over-file precedence among +// the templates that survived workload matching. It must be called after +// filterTemplatesMatched so that a CRD file template rejected by workload +// filters does not incorrectly suppress the corresponding file template. +func (s *WorkloadService) filterTemplatesProviderPrecedence(configs map[string]integration.Config) { + crdFileNames := map[string]struct{}{} + for _, config := range configs { + if config.Provider == names.CRDFile { + crdFileNames[config.Name] = struct{}{} + } + } + + for digest, config := range configs { + if config.Provider != names.File { + continue + } + if _, hasCRD := crdFileNames[config.Name]; hasCRD { + log.Debugf("Ignoring file config from %s: CRD file provider overrides check %s for service %s", + config.Source, config.Name, s.GetServiceID()) + delete(configs, digest) + } + } +} + // filterTemplatesContainerCollectAll drops the container-collect-all template // added by the config provider (AddContainerCollectAllConfigs) if the service // has any other templates containing logs config. diff --git a/comp/core/autodiscovery/listeners/service_test.go b/comp/core/autodiscovery/listeners/service_test.go index 7d0f59ebebf319..6d6ea62a70c4db 100644 --- a/comp/core/autodiscovery/listeners/service_test.go +++ b/comp/core/autodiscovery/listeners/service_test.go @@ -82,6 +82,8 @@ func TestServiceFilterTemplatesOverriddenChecks(t *testing.T) { entity := &workloadmeta.Container{EntityID: workloadmeta.EntityID{Kind: "container", ID: "testy"}} fooTpl := integration.Config{Name: "foo", Provider: names.File, LogsConfig: []byte(`{"source":"foo"}`)} barTpl := integration.Config{Name: "bar", Provider: names.File, LogsConfig: []byte(`{"source":"bar"}`)} + fooCRDTpl := integration.Config{Name: "foo", Provider: names.CRDFile, Instances: []integration.Data{[]byte(`{"crd":"foo"}`)}} + barCRDTpl := integration.Config{Name: "bar", Provider: names.CRDFile, Instances: []integration.Data{[]byte(`{"crd":"bar"}`)}} fooNonFileTpl := integration.Config{Name: "foo", Provider: "xxx", LogsConfig: []byte(`{"source":"foo-nf"}`)} barNonFileTpl := integration.Config{Name: "bar", Provider: "xxx", LogsConfig: []byte(`{"source":"bar-nf"}`)} nothingDropped := []integration.Config{} @@ -105,6 +107,60 @@ func TestServiceFilterTemplatesOverriddenChecks(t *testing.T) { assert.Equal(t, []integration.Config{barTpl}, filterDrops(&WorkloadService{entity: entity, checkNames: []string{"bing", "bar"}}, fooTpl, barTpl, fooNonFileTpl, barNonFileTpl)) }) + + t.Run("CRD file template dropped by annotation checkName", func(t *testing.T) { + assert.Equal(t, []integration.Config{fooCRDTpl}, + filterDrops(&WorkloadService{entity: entity, checkNames: []string{"foo"}}, fooCRDTpl, barTpl)) + }) + + t.Run("both file and CRD file templates dropped by annotation checkNames", func(t *testing.T) { + assert.Equal(t, []integration.Config{fooTpl, fooCRDTpl, barCRDTpl}, + filterDrops(&WorkloadService{entity: entity, checkNames: []string{"foo", "bar"}}, fooTpl, fooCRDTpl, barCRDTpl, fooNonFileTpl)) + }) + + t.Run("non-file non-CRD template not dropped", func(t *testing.T) { + assert.Equal(t, nothingDropped, + filterDrops(&WorkloadService{entity: entity, checkNames: []string{"foo"}}, fooNonFileTpl)) + }) +} + +func TestServiceFilterTemplatesProviderPrecedence(t *testing.T) { + filterDrops := func(svc *WorkloadService, configs ...integration.Config) []integration.Config { + return filterConfigsDropped(svc.filterTemplatesProviderPrecedence, configs...) + } + + entity := &workloadmeta.Container{EntityID: workloadmeta.EntityID{Kind: "container", ID: "testy"}} + fooFile := integration.Config{Name: "foo", Provider: names.File, LogsConfig: []byte(`{"a":"file"}`)} + fooCRD := integration.Config{Name: "foo", Provider: names.CRDFile, Instances: []integration.Data{[]byte(`{}`)}} + barFile := integration.Config{Name: "bar", Provider: names.File, LogsConfig: []byte(`{"a":"bar"}`)} + nothingDropped := []integration.Config{} + + svc := &WorkloadService{entity: entity} + + t.Run("file only: nothing dropped", func(t *testing.T) { + assert.Equal(t, nothingDropped, + filterDrops(svc, fooFile)) + }) + + t.Run("CRD only: nothing dropped", func(t *testing.T) { + assert.Equal(t, nothingDropped, + filterDrops(svc, fooCRD)) + }) + + t.Run("CRD present: file dropped", func(t *testing.T) { + assert.Equal(t, []integration.Config{fooFile}, + filterDrops(svc, fooFile, fooCRD)) + }) + + t.Run("CRD for different name: unrelated file not dropped", func(t *testing.T) { + assert.Equal(t, nothingDropped, + filterDrops(svc, barFile, fooCRD)) + }) + + t.Run("CRD for foo, file for bar: only foo file dropped", func(t *testing.T) { + assert.Equal(t, []integration.Config{fooFile}, + filterDrops(svc, fooFile, fooCRD, barFile)) + }) } func TestServiceFilterTemplatesCCA(t *testing.T) { diff --git a/comp/core/autodiscovery/providers/crd_file.go b/comp/core/autodiscovery/providers/crd_file.go new file mode 100644 index 00000000000000..551695f1986ea1 --- /dev/null +++ b/comp/core/autodiscovery/providers/crd_file.go @@ -0,0 +1,134 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package providers + +import ( + "context" + "errors" + "fmt" + "os" + "path/filepath" + "strings" + + "github.com/DataDog/datadog-agent/comp/core/autodiscovery/integration" + "github.com/DataDog/datadog-agent/comp/core/autodiscovery/providers/names" + "github.com/DataDog/datadog-agent/comp/core/autodiscovery/providers/types" + "github.com/DataDog/datadog-agent/comp/core/autodiscovery/telemetry" + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +// NameExtractorFunc extracts an integration check name from a config filename (without extension). +// It returns the check name and an error if the filename does not conform to the expected convention. +type NameExtractorFunc func(filenameWithoutExt string) (checkName string, err error) + +// DefaultCRDNameExtractor returns the portion of the filename after the last '_'. +// e.g. "mynamespace_mypod_redis" → "redis" +func DefaultCRDNameExtractor(filenameWithoutExt string) (string, error) { + idx := strings.LastIndex(filenameWithoutExt, "_") + if idx < 0 || idx == len(filenameWithoutExt)-1 { + return "", fmt.Errorf("filename %q does not match expected convention ", filenameWithoutExt) + } + return filenameWithoutExt[idx+1:], nil +} + +// CRDFileConfigProvider collects check configurations from a directory populated +// by an external CRD controller and mounted into the agent container via a +// Kubernetes ConfigMap. +type CRDFileConfigProvider struct { + dir string + nameExtractor NameExtractorFunc + Errors map[string]string + telemetryStore *telemetry.Store +} + +// NewCRDFileConfigProvider creates a new CRDFileConfigProvider. +func NewCRDFileConfigProvider(dir string, extractor NameExtractorFunc, telemetryStore *telemetry.Store) *CRDFileConfigProvider { + return &CRDFileConfigProvider{ + dir: dir, + nameExtractor: extractor, + Errors: make(map[string]string), + telemetryStore: telemetryStore, + } +} + +// Collect returns the check configurations found in the CRD config directory. +// Configs with advanced AD identifiers (kube_services, kube_endpoints CEL selectors) are filtered out. +func (c *CRDFileConfigProvider) Collect(_ context.Context) ([]integration.Config, error) { + entries, err := os.ReadDir(c.dir) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + log.Warnf("CRDFileConfigProvider: directory %q does not exist (expected mount point from ConfigMap)", c.dir) + } else { + log.Warnf("CRDFileConfigProvider: error reading directory %q: %s", c.dir, err) + } + return []integration.Config{}, nil + } + + if len(entries) == 0 { + log.Debugf("CRDFileConfigProvider: directory %q is empty (no CRD-driven checks configured)", c.dir) + return []integration.Config{}, nil + } + + integrationErrors := make(map[string]string) + var configs []integration.Config + + for _, entry := range entries { + if entry.IsDir() { + continue + } + + fileName := entry.Name() + ext := filepath.Ext(fileName) + if ext != ".yaml" && ext != ".yml" { + continue + } + + filenameWithoutExt := strings.TrimSuffix(fileName, ext) + checkName, err := c.nameExtractor(filenameWithoutExt) + if err != nil { + log.Warnf("CRDFileConfigProvider: skipping file %q: %s", fileName, err) + integrationErrors[filenameWithoutExt] = err.Error() + continue + } + + absPath := filepath.Join(c.dir, fileName) + conf, _, err := GetIntegrationConfigFromFile(checkName, absPath) + if err != nil { + log.Warnf("CRDFileConfigProvider: %q is not a valid config file: %s", absPath, err) + integrationErrors[checkName] = err.Error() + continue + } + + if !WithoutAdvancedAD(conf) { + log.Debugf("CRDFileConfigProvider: skipping config %q with advanced AD identifiers", checkName) + continue + } + + configs = append(configs, conf) + } + + c.Errors = integrationErrors + if c.telemetryStore != nil { + c.telemetryStore.Errors.Set(float64(len(integrationErrors)), names.CRDFile) + } + + return configs, nil +} + +// IsUpToDate always returns false — polling is driven by the config poller. +func (c *CRDFileConfigProvider) IsUpToDate(_ context.Context) (bool, error) { + return false, nil +} + +// String returns a string representation of the CRDFileConfigProvider. +func (c *CRDFileConfigProvider) String() string { + return names.CRDFile +} + +// GetConfigErrors returns the errors encountered when collecting configs. +func (c *CRDFileConfigProvider) GetConfigErrors() map[string]types.ErrorMsgSet { + return make(map[string]types.ErrorMsgSet) +} diff --git a/comp/core/autodiscovery/providers/crd_file_test.go b/comp/core/autodiscovery/providers/crd_file_test.go new file mode 100644 index 00000000000000..787f888a165362 --- /dev/null +++ b/comp/core/autodiscovery/providers/crd_file_test.go @@ -0,0 +1,189 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +package providers + +import ( + "context" + "fmt" + "os" + "path/filepath" + "strings" + "testing" + + acTelemetry "github.com/DataDog/datadog-agent/comp/core/autodiscovery/telemetry" + "github.com/DataDog/datadog-agent/comp/core/telemetry/telemetryimpl" + "github.com/DataDog/datadog-agent/pkg/util/fxutil" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "github.com/DataDog/datadog-agent/comp/core/telemetry" +) + +func newCRDTelemetryStore(t *testing.T) *acTelemetry.Store { + tel := fxutil.Test[telemetry.Component](t, telemetryimpl.MockModule()) + return acTelemetry.NewStore(tel) +} + +// TestCRDCollectEmptyDirectory verifies that an empty directory returns an empty +// slice without error — this is normal startup state when no CRD checks are configured. +func TestCRDCollectEmptyDirectory(t *testing.T) { + dir := t.TempDir() + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + assert.Empty(t, configs) + assert.Empty(t, provider.Errors) +} + +// TestCRDCollectNonExistentDirectory verifies that a missing directory returns an +// empty slice. A missing directory is unexpected (the Operator/Helm always mounts +// the ConfigMap), so a warning is logged, but no error is returned to the caller. +func TestCRDCollectNonExistentDirectory(t *testing.T) { + dir := filepath.Join(t.TempDir(), "does-not-exist") + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + assert.Empty(t, configs) +} + +// TestCRDCollectValidFileWithADIdentifiers verifies that a YAML file whose name +// follows the "" convention is parsed correctly, that +// the check name comes from the filename (not the YAML), and that ADIdentifiers +// are populated, making the config a template (IsTemplate() == true). +func TestCRDCollectValidFileWithADIdentifiers(t *testing.T) { + dir := t.TempDir() + + content := `ad_identifiers: + - redis + +init_config: + +instances: + - host: localhost + port: 6379 +` + require.NoError(t, os.WriteFile(filepath.Join(dir, "mynamespace_mypod_redis.yaml"), []byte(content), os.FileMode(0644))) + + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + require.Len(t, configs, 1) + + cfg := configs[0] + assert.Equal(t, "redis", cfg.Name) + assert.Equal(t, []string{"redis"}, cfg.ADIdentifiers) + assert.True(t, cfg.IsTemplate(), "config with ad_identifiers should be a template") + assert.Empty(t, provider.Errors) +} + +// TestCRDCollectValidFileWithoutADIdentifiers verifies that a valid YAML file +// without ad_identifiers is collected and scheduled immediately (non-template). +func TestCRDCollectValidFileWithoutADIdentifiers(t *testing.T) { + dir := t.TempDir() + + content := `init_config: + +instances: + - host: localhost + port: 5432 +` + require.NoError(t, os.WriteFile(filepath.Join(dir, "default_dbpod_postgres.yaml"), []byte(content), os.FileMode(0644))) + + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + require.Len(t, configs, 1) + + cfg := configs[0] + assert.Equal(t, "postgres", cfg.Name) + assert.Empty(t, cfg.ADIdentifiers) + assert.False(t, cfg.IsTemplate(), "config without ad_identifiers should not be a template") + assert.Empty(t, provider.Errors) +} + +// TestCRDCollectFilenameNotMatchingConvention verifies that a file whose name +// does not match the extractor convention is skipped and recorded in Errors. +func TestCRDCollectFilenameNotMatchingConvention(t *testing.T) { + dir := t.TempDir() + + // Name has no '_', so DefaultCRDNameExtractor will return an error. + content := `init_config: + +instances: + - foo: bar +` + require.NoError(t, os.WriteFile(filepath.Join(dir, "badname.yaml"), []byte(content), os.FileMode(0644))) + + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + assert.Empty(t, configs) + assert.Contains(t, provider.Errors, "badname") +} + +// TestCRDCollectNonYAMLFileIgnored verifies that files with non-YAML extensions +// are silently skipped. +func TestCRDCollectNonYAMLFileIgnored(t *testing.T) { + dir := t.TempDir() + require.NoError(t, os.WriteFile(filepath.Join(dir, "redis-mypod-mynamespace.txt"), []byte("some: content"), os.FileMode(0644))) + + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + assert.Empty(t, configs) + assert.Empty(t, provider.Errors) +} + +// TestCRDCollectSubdirectoriesIgnored verifies that subdirectories are silently +// skipped (flat-only layout). +func TestCRDCollectSubdirectoriesIgnored(t *testing.T) { + dir := t.TempDir() + subdir := filepath.Join(dir, "redis-mypod-mynamespace.d") + require.NoError(t, os.MkdirAll(subdir, os.FileMode(0755))) + + content := `init_config: + +instances: + - host: localhost +` + require.NoError(t, os.WriteFile(filepath.Join(subdir, "conf.yaml"), []byte(content), os.FileMode(0644))) + + provider := NewCRDFileConfigProvider(dir, DefaultCRDNameExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + assert.Empty(t, configs) +} + +// TestCRDCollectCustomNameExtractor verifies that injecting a custom +// NameExtractorFunc overrides the default extraction logic. +func TestCRDCollectCustomNameExtractor(t *testing.T) { + dir := t.TempDir() + + content := `init_config: + +instances: + - host: localhost + port: 9200 +` + // File name uses a custom '-' convention (check name is the first segment). + require.NoError(t, os.WriteFile(filepath.Join(dir, "elasticsearch-node1-production.yaml"), []byte(content), os.FileMode(0644))) + + // Custom extractor: returns the portion before the first '-'. + customExtractor := func(filenameWithoutExt string) (string, error) { + idx := strings.Index(filenameWithoutExt, "-") + if idx <= 0 { + return "", fmt.Errorf("filename %q does not match custom convention", filenameWithoutExt) + } + return filenameWithoutExt[:idx], nil + } + + provider := NewCRDFileConfigProvider(dir, customExtractor, newCRDTelemetryStore(t)) + configs, err := provider.Collect(context.Background()) + require.NoError(t, err) + require.Len(t, configs, 1) + assert.Equal(t, "elasticsearch", configs[0].Name) +} diff --git a/comp/core/autodiscovery/providers/names/provider_names.go b/comp/core/autodiscovery/providers/names/provider_names.go index 42e1a1fb710ab0..83ccd594ceba69 100644 --- a/comp/core/autodiscovery/providers/names/provider_names.go +++ b/comp/core/autodiscovery/providers/names/provider_names.go @@ -15,6 +15,7 @@ const ( ClusterChecks = "cluster-checks" EndpointsChecks = "endpoints-checks" Etcd = "etcd" + CRDFile = "crd-file" File = "file" KubeContainer = "kubernetes-container-allinone" Kubernetes = "kubernetes" diff --git a/comp/core/autodiscovery/providers/tests/crd/default_dbpod_postgres.yaml b/comp/core/autodiscovery/providers/tests/crd/default_dbpod_postgres.yaml new file mode 100644 index 00000000000000..31031ccf6aca49 --- /dev/null +++ b/comp/core/autodiscovery/providers/tests/crd/default_dbpod_postgres.yaml @@ -0,0 +1,6 @@ +init_config: + +instances: + - host: localhost + port: 5432 + username: datadog diff --git a/comp/core/autodiscovery/providers/tests/crd/mynamespace_mypod_redis.yaml b/comp/core/autodiscovery/providers/tests/crd/mynamespace_mypod_redis.yaml new file mode 100644 index 00000000000000..8db0c55e3fe09a --- /dev/null +++ b/comp/core/autodiscovery/providers/tests/crd/mynamespace_mypod_redis.yaml @@ -0,0 +1,8 @@ +ad_identifiers: + - redis + +init_config: + +instances: + - host: localhost + port: 6379 diff --git a/comp/core/workloadfilter/def/types.go b/comp/core/workloadfilter/def/types.go index 2b0eed98e07cb7..973ab50df21378 100644 --- a/comp/core/workloadfilter/def/types.go +++ b/comp/core/workloadfilter/def/types.go @@ -84,11 +84,11 @@ func GetAllResourceTypes() []ResourceType { // Rules defines the rules for filtering different resource types. type Rules struct { - Containers []string `yaml:"containers" json:"containers"` - Processes []string `yaml:"processes" json:"processes"` - Pods []string `yaml:"pods" json:"pods"` - KubeServices []string `yaml:"kube_services" json:"kube_services"` - KubeEndpoints []string `yaml:"kube_endpoints" json:"kube_endpoints"` + Containers []string `yaml:"containers,omitempty" json:"containers"` + Processes []string `yaml:"processes,omitempty" json:"processes"` + Pods []string `yaml:"pods,omitempty" json:"pods"` + KubeServices []string `yaml:"kube_services,omitempty" json:"kube_services"` + KubeEndpoints []string `yaml:"kube_endpoints,omitempty" json:"kube_endpoints"` } // String returns a string representation of the Rules struct, only showing non-empty fields. @@ -322,13 +322,14 @@ func (p *Pod) ToBytes() ([]byte, error) { } // CreatePod creates a Filterable Pod object. -func CreatePod(id, name, namespace string, annotations map[string]string) *Pod { +func CreatePod(id, name, namespace string, annotations, labels map[string]string) *Pod { return &Pod{ FilterPod: &core.FilterPod{ Id: id, Name: name, Namespace: namespace, Annotations: annotations, + Labels: labels, }, } } diff --git a/comp/core/workloadfilter/program/cel_program_test.go b/comp/core/workloadfilter/program/cel_program_test.go index 858fbebb272a4e..7ff747d99088cb 100644 --- a/comp/core/workloadfilter/program/cel_program_test.go +++ b/comp/core/workloadfilter/program/cel_program_test.go @@ -88,6 +88,16 @@ func TestCELFieldConfigurationErrors(t *testing.T) { expr: `container.pod.namespaces == "default"`, expectError: true, }, + { + name: "Valid pod label access", + expr: `container.pod.labels["app"] == "nginx"`, + expectError: false, + }, + { + name: "Invalid pod labels field", + expr: `container.pod.labelz["app"] == "nginx"`, + expectError: true, + }, } for _, tt := range tests { diff --git a/comp/core/workloadfilter/util/workloadmeta/create.go b/comp/core/workloadfilter/util/workloadmeta/create.go index 9b9c97867d2b7c..b1411ced799b7a 100644 --- a/comp/core/workloadfilter/util/workloadmeta/create.go +++ b/comp/core/workloadfilter/util/workloadmeta/create.go @@ -42,6 +42,7 @@ func CreatePod(pod *workloadmeta.KubernetesPod) *workloadfilter.Pod { Name: pod.Name, Namespace: pod.Namespace, Annotations: pod.Annotations, + Labels: pod.Labels, }, } } diff --git a/comp/otelcol/collector-contrib/impl/go.mod b/comp/otelcol/collector-contrib/impl/go.mod index 4cdb33830d47fb..7bb747e216d1bc 100644 --- a/comp/otelcol/collector-contrib/impl/go.mod +++ b/comp/otelcol/collector-contrib/impl/go.mod @@ -200,7 +200,7 @@ require ( github.com/edsrzf/mmap-go v1.2.0 // indirect github.com/elastic/go-grok v0.3.1 // indirect github.com/elastic/lunes v0.2.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/expr-lang/expr v1.17.8 // indirect @@ -217,8 +217,8 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.24.1 // indirect github.com/go-openapi/errors v0.22.4 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/loads v0.23.2 // indirect github.com/go-openapi/spec v0.22.1 // indirect github.com/go-openapi/strfmt v0.25.0 // indirect @@ -248,7 +248,7 @@ require ( github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/protobuf v1.5.4 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-querystring v1.2.0 // indirect github.com/google/go-tpm v0.9.8 // indirect @@ -323,6 +323,8 @@ require ( github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/oklog/ulid v1.3.1 // indirect github.com/oklog/ulid/v2 v2.1.1 // indirect + github.com/onsi/ginkgo/v2 v2.27.5 // indirect + github.com/onsi/gomega v1.39.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/extension/observer v0.147.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.147.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.147.0 // indirect @@ -395,8 +397,6 @@ require ( github.com/stackitcloud/stackit-sdk-go/core v0.20.1 // indirect github.com/stretchr/objx v0.5.2 // indirect github.com/stretchr/testify v1.11.1 // indirect - github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/pretty v1.2.1 // indirect github.com/tilinna/clock v1.1.0 // indirect github.com/tinylib/msgp v1.6.3 // indirect github.com/tklauser/go-sysconf v0.3.16 // indirect @@ -531,8 +531,8 @@ require ( k8s.io/apimachinery v0.35.1 // indirect k8s.io/client-go v0.35.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect sigs.k8s.io/controller-runtime v0.23.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect diff --git a/comp/otelcol/collector-contrib/impl/go.sum b/comp/otelcol/collector-contrib/impl/go.sum index cef7cbadb3378c..8a017ff11d51ef 100644 --- a/comp/otelcol/collector-contrib/impl/go.sum +++ b/comp/otelcol/collector-contrib/impl/go.sum @@ -187,8 +187,8 @@ github.com/elastic/go-grok v0.3.1 h1:WEhUxe2KrwycMnlvMimJXvzRa7DoByJB4PVUIE1ZD/U github.com/elastic/go-grok v0.3.1/go.mod h1:n38ls8ZgOboZRgKcjMY8eFeZFMmcL9n2lP0iHhIDk64= github.com/elastic/lunes v0.2.0 h1:WI3bsdOTuaYXVe2DS1KbqA7u7FOHN4o8qJw80ZyZoQs= github.com/elastic/lunes v0.2.0/go.mod h1:u3W/BdONWTrh0JjNZ21C907dDc+cUZttZrGa625nf2k= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane/envoy v1.36.0 h1:yg/JjO5E7ubRyKX3m07GF3reDNEnfOboJ0QySbH736g= github.com/envoyproxy/go-control-plane/envoy v1.36.0/go.mod h1:ty89S1YCCVruQAm9OtKeEkQLTb+Lkz0k8v9W0Oxsv98= github.com/envoyproxy/protoc-gen-validate v1.3.0 h1:TvGH1wof4H33rezVKWSpqKz5NXWg5VPuZ0uONDT6eb4= @@ -237,10 +237,10 @@ github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rB github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84= github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM= github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4= github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY= github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k= @@ -319,8 +319,8 @@ github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -564,10 +564,10 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/open-telemetry/opentelemetry-collector-contrib/connector/routingconnector v0.147.0 h1:LBsvBOuEFrBcmvFSC8mC9pOuV70HNSW1/kVrt3vs2eA= github.com/open-telemetry/opentelemetry-collector-contrib/connector/routingconnector v0.147.0/go.mod h1:l8iHJuARluy9Cqsh4CMgXZOTTyO1oMssT9zE8Q6irO4= github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.147.0 h1:sAjARhiJxByhuUz0JTUPthqetNp6rxACW6KMEDd6K3c= @@ -846,7 +846,6 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/tinylru v1.1.0 h1:XY6IUfzVTU9rpwdhKUF6nQdChgCdGjkMfLzbWyiau6I= @@ -1336,10 +1335,10 @@ k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM= k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/controller-runtime v0.23.1 h1:TjJSM80Nf43Mg21+RCy3J70aj/W6KyvDtOlpKf+PupE= sigs.k8s.io/controller-runtime v0.23.1/go.mod h1:B6COOxKptp+YaUT5q4l6LqUJTRpizbgf9KSRNdQGns0= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= diff --git a/comp/otelcol/ddflareextension/impl/go.mod b/comp/otelcol/ddflareextension/impl/go.mod index 05d70caee68458..12888561c7e6be 100644 --- a/comp/otelcol/ddflareextension/impl/go.mod +++ b/comp/otelcol/ddflareextension/impl/go.mod @@ -47,11 +47,7 @@ require ( go.yaml.in/yaml/v2 v2.4.3 ) -require ( - github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect - github.com/tidwall/gjson v1.18.0 // indirect - github.com/tidwall/pretty v1.2.1 // indirect -) +require github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect require ( github.com/DataDog/datadog-agent/comp/core/secrets/noop-impl v0.77.0-devel.0.20260213154712-e02b9359151a // indirect @@ -90,6 +86,8 @@ require ( github.com/hashicorp/go-msgpack v1.1.5 // indirect github.com/hashicorp/go-msgpack/v2 v2.1.2 // indirect github.com/klauspost/cpuid/v2 v2.3.0 // indirect + github.com/onsi/ginkgo/v2 v2.27.5 // indirect + github.com/onsi/gomega v1.39.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/healthcheck v0.147.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/pkg/status v0.147.0 // indirect github.com/outcaste-io/ristretto v0.2.3 // indirect @@ -263,7 +261,7 @@ require ( github.com/edsrzf/mmap-go v1.2.0 // indirect github.com/elastic/go-grok v0.3.1 // indirect github.com/elastic/lunes v0.2.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect; indrc.1irect github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/facette/natsort v0.0.0-20181210072756-2cd4dd1e2dcb // indirect @@ -279,8 +277,8 @@ require ( github.com/go-ole/go-ole v1.3.0 // indirect github.com/go-openapi/analysis v0.24.1 // indirect github.com/go-openapi/errors v0.22.4 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/loads v0.23.2 // indirect github.com/go-openapi/spec v0.22.1 // indirect github.com/go-openapi/strfmt v0.25.0 // indirect @@ -297,7 +295,7 @@ require ( github.com/golang-jwt/jwt/v5 v5.3.0 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-querystring v1.2.0 // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/google/s2a-go v0.1.9 // indirect @@ -525,8 +523,8 @@ require ( k8s.io/apimachinery v0.35.1 // indirect k8s.io/client-go v0.35.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/yaml v1.6.0 // indirect ) diff --git a/comp/otelcol/ddflareextension/impl/go.sum b/comp/otelcol/ddflareextension/impl/go.sum index 575ed52215e6c2..18569dfe9a723e 100644 --- a/comp/otelcol/ddflareextension/impl/go.sum +++ b/comp/otelcol/ddflareextension/impl/go.sum @@ -186,8 +186,8 @@ github.com/elastic/go-grok v0.3.1 h1:WEhUxe2KrwycMnlvMimJXvzRa7DoByJB4PVUIE1ZD/U github.com/elastic/go-grok v0.3.1/go.mod h1:n38ls8ZgOboZRgKcjMY8eFeZFMmcL9n2lP0iHhIDk64= github.com/elastic/lunes v0.2.0 h1:WI3bsdOTuaYXVe2DS1KbqA7u7FOHN4o8qJw80ZyZoQs= github.com/elastic/lunes v0.2.0/go.mod h1:u3W/BdONWTrh0JjNZ21C907dDc+cUZttZrGa625nf2k= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -236,10 +236,10 @@ github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rB github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84= github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM= github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4= github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY= github.com/go-openapi/spec v0.22.1 h1:beZMa5AVQzRspNjvhe5aG1/XyBSMeX1eEOs7dMoXh/k= @@ -321,8 +321,8 @@ github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= @@ -557,10 +557,10 @@ github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/oklog/ulid/v2 v2.1.1 h1:suPZ4ARWLOJLegGFiZZ1dFAkqzhMjL3J1TzI+5wHz8s= github.com/oklog/ulid/v2 v2.1.1/go.mod h1:rcEKHmBBKfef9DhnvX7y1HZBYxjXb0cP5ExxNsTT1QQ= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.147.0 h1:sAjARhiJxByhuUz0JTUPthqetNp6rxACW6KMEDd6K3c= github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.147.0/go.mod h1:nAEpAXAz41JmUxHcHeXpg6tMwe9JL5RxpX+pGa9yJP0= github.com/open-telemetry/opentelemetry-collector-contrib/exporter/prometheusremotewriteexporter v0.147.0 h1:lF1zkn8hSBmZCK4UjmKuiob+w48QiJtfLaAxb/9PVOQ= @@ -748,7 +748,6 @@ github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/match v1.1.1 h1:+Ho715JplO36QYgwN9PGYNhgZvoUSc9X2c80KVTi+GA= github.com/tidwall/match v1.1.1/go.mod h1:eRSPERbgtNPcGhD8UCthc6PmLEQXEWd3PRB5JTxsfmM= -github.com/tidwall/pretty v1.2.0/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/pretty v1.2.1 h1:qjsOFOWWQl+N3RsoF5/ssm1pHmJJwhjlSbZ51I6wMl4= github.com/tidwall/pretty v1.2.1/go.mod h1:ITEVvHYasfjBbM0u2Pg8T2nJnzm8xPwvNhhsoaGGjNU= github.com/tidwall/tinylru v1.1.0 h1:XY6IUfzVTU9rpwdhKUF6nQdChgCdGjkMfLzbWyiau6I= @@ -1255,10 +1254,10 @@ k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM= k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/comp/otelcol/ddprofilingextension/impl/go.mod b/comp/otelcol/ddprofilingextension/impl/go.mod index c0a525106f390b..d12a25b161bde4 100644 --- a/comp/otelcol/ddprofilingextension/impl/go.mod +++ b/comp/otelcol/ddprofilingextension/impl/go.mod @@ -127,7 +127,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/dustin/go-humanize v1.0.1 // indirect github.com/ebitengine/purego v0.10.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/felixge/httpsnoop v1.0.4 // indirect github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f // indirect github.com/fsnotify/fsnotify v1.9.0 // indirect @@ -135,8 +135,8 @@ require ( github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect github.com/go-ole/go-ole v1.3.0 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/swag v0.25.4 // indirect github.com/go-viper/mapstructure/v2 v2.5.0 // indirect github.com/gobwas/glob v0.2.3 // indirect @@ -145,7 +145,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/mock v1.7.0-rc.1 // indirect github.com/golang/snappy v1.0.0 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/google/pprof v0.0.0-20260111202518-71be6bfdd440 // indirect @@ -171,6 +171,8 @@ require ( github.com/modern-go/reflect2 v1.0.3-0.20250322232337-35a7c28c31ee // indirect github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/onsi/ginkgo/v2 v2.27.5 // indirect + github.com/onsi/gomega v1.39.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.147.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.147.0 // indirect github.com/open-telemetry/opentelemetry-collector-contrib/internal/datadog v0.147.0 // indirect @@ -268,8 +270,8 @@ require ( k8s.io/apimachinery v0.35.1 // indirect k8s.io/client-go v0.35.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect diff --git a/comp/otelcol/ddprofilingextension/impl/go.sum b/comp/otelcol/ddprofilingextension/impl/go.sum index e14a6fef26b1ad..9f4caa8a585d5a 100644 --- a/comp/otelcol/ddprofilingextension/impl/go.sum +++ b/comp/otelcol/ddprofilingextension/impl/go.sum @@ -90,8 +90,8 @@ github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4 h1:8EXxF+tCLqaVk8 github.com/eapache/queue/v2 v2.0.0-20230407133247-75960ed334e4/go.mod h1:I5sHm0Y0T1u5YjlyqC5GVArM7aNZRUYtTjmJ8mPJFds= github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ISU= github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/foxboron/go-tpm-keyfiles v0.0.0-20251226215517-609e4778396f h1:RJ+BDPLSHQO7cSjKBqjPJSbi1qfk9WcsjQDtZiw3dZw= @@ -111,10 +111,10 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= @@ -166,8 +166,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/golang/snappy v1.0.0 h1:Oy607GVXHs7RtbggtPBnr2RmDArIsAefDwvrdWvRhGs= github.com/golang/snappy v1.0.0/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -248,10 +248,10 @@ github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826 h1:RWengNIwukTxcDr9 github.com/mohae/deepcopy v0.0.0-20170929034955-c48cc78d4826/go.mod h1:TaXosZuwdSHYgviHp1DAtfrULt5eUgsSMsZf+YrPgl8= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.147.0 h1:XReTF0gmEwxTRCg6xzAQnXpdbmbZrDaVAoIuESHQ8NY= github.com/open-telemetry/opentelemetry-collector-contrib/internal/aws/ecsutil v0.147.0/go.mod h1:tcLift8U4k1Sjl2VbESx5kCnqTCaxBnbyZnPPAVY6N8= github.com/open-telemetry/opentelemetry-collector-contrib/internal/common v0.147.0 h1:T7yBzSHaI7kKMe8skPtnqQvp4hp8sAmLZdQav2MDrW0= @@ -616,10 +616,10 @@ k8s.io/client-go v0.35.1 h1:+eSfZHwuo/I19PaSxqumjqZ9l5XiTEKbIaJ+j1wLcLM= k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/comp/otelcol/status/impl/go.mod b/comp/otelcol/status/impl/go.mod index 526fc27397017e..95aff386a401c5 100644 --- a/comp/otelcol/status/impl/go.mod +++ b/comp/otelcol/status/impl/go.mod @@ -108,7 +108,6 @@ require ( golang.org/x/time v0.14.0 // indirect google.golang.org/protobuf v1.36.11 // indirect k8s.io/apimachinery v0.35.1 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect ) // This section was automatically added by 'dda inv modules.add-all-replace' command, do not edit manually diff --git a/comp/otelcol/status/impl/go.sum b/comp/otelcol/status/impl/go.sum index 9e101ed501ccab..f1c2e6facffcba 100644 --- a/comp/otelcol/status/impl/go.sum +++ b/comp/otelcol/status/impl/go.sum @@ -283,5 +283,5 @@ k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= diff --git a/deps/go.MODULE.bazel b/deps/go.MODULE.bazel index aed4e730eef91c..9f933ed42e2c5b 100644 --- a/deps/go.MODULE.bazel +++ b/deps/go.MODULE.bazel @@ -387,6 +387,7 @@ use_repo( "com_github_yusufpapurcu_wmi", "com_gitlab_gitlab_org_api_client_go", "in_gopkg_datadog_dd_trace_go_v1", + "in_gopkg_yaml_v2", "in_gopkg_zorkian_go_datadog_api_v2", "in_yaml_go_yaml_v2", "in_yaml_go_yaml_v3", diff --git a/go.mod b/go.mod index cd0d5e3e3905c0..8b5c98fc8fe3e1 100644 --- a/go.mod +++ b/go.mod @@ -166,7 +166,7 @@ require ( github.com/DataDog/datadog-agent/pkg/util/winutil v0.77.0-devel.0.20260213154712-e02b9359151a github.com/DataDog/datadog-agent/pkg/version v0.77.0-devel.0.20260213154712-e02b9359151a github.com/DataDog/datadog-go/v5 v5.8.3 - github.com/DataDog/datadog-operator/api v0.0.0-20260218132256-6fb0dc76eec6 + github.com/DataDog/datadog-operator/api v0.0.0-20260312201613-877d28ec5510 github.com/DataDog/datadog-traceroute v1.0.13 github.com/DataDog/ebpf-manager v0.7.15 github.com/DataDog/go-sqllexer v0.1.13 @@ -407,7 +407,7 @@ require ( istio.io/api v1.27.3 istio.io/client-go v1.27.3 k8s.io/api v0.35.1 - k8s.io/apiextensions-apiserver v0.35.0 + k8s.io/apiextensions-apiserver v0.35.1 k8s.io/apimachinery v0.35.1 k8s.io/autoscaler/vertical-pod-autoscaler v1.2.2 k8s.io/cli-runtime v0.34.1 @@ -421,7 +421,7 @@ require ( k8s.io/kubectl v0.34.1 k8s.io/kubelet v0.34.1 k8s.io/metrics v0.34.1 - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 pgregory.net/rapid v1.2.0 sigs.k8s.io/custom-metrics-apiserver v1.33.0 sigs.k8s.io/gateway-api v1.3.1-0.20250527223622-54df0a899c1c @@ -565,7 +565,7 @@ require ( github.com/elastic/go-licenser v0.4.2 // indirect github.com/elastic/go-perf v0.0.0-20260224073651-af0ee0c731b7 // indirect github.com/elastic/lunes v0.2.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/envoyproxy/go-control-plane/envoy v1.36.0 // indirect github.com/envoyproxy/protoc-gen-validate v1.3.0 // indirect github.com/evanphx/json-patch/v5 v5.9.11 // indirect @@ -582,8 +582,8 @@ require ( github.com/go-logr/stdr v1.2.2 // indirect github.com/go-openapi/analysis v0.24.1 // indirect github.com/go-openapi/errors v0.22.4 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/loads v0.23.2 // indirect github.com/go-openapi/spec v0.22.1 // indirect github.com/go-openapi/strfmt v0.25.0 // indirect @@ -602,7 +602,7 @@ require ( github.com/golang-jwt/jwt/v4 v4.5.2 // indirect github.com/golang-jwt/jwt/v5 v5.3.0 github.com/golang/snappy v1.0.0 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-querystring v1.2.0 // indirect github.com/google/go-tpm v0.9.8 // indirect github.com/google/pprof v0.0.0-20260111202518-71be6bfdd440 // indirect @@ -940,7 +940,7 @@ require ( k8s.io/component-helpers v0.34.1 // indirect k8s.io/csi-translation-lib v0.34.1 // indirect k8s.io/kms v0.35.0-alpha.0 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect k8s.io/sample-controller v0.34.1 // indirect mellium.im/sasl v0.3.2 // indirect modernc.org/sqlite v1.36.2 // indirect @@ -997,6 +997,7 @@ require ( gitlab.com/gitlab-org/api/client-go v1.46.0 go.temporal.io/api v1.62.2 go.temporal.io/sdk v1.39.0 + gopkg.in/yaml.v2 v2.4.0 ) require github.com/puzpuzpuz/xsync/v4 v4.4.0 // indirect @@ -1197,7 +1198,6 @@ require ( github.com/xanzy/ssh-agent v0.3.3 // indirect gopkg.in/neurosnap/sentences.v1 v1.0.7 // indirect gopkg.in/warnings.v0 v0.1.2 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index 008a932bfc8ad4..2904201120cded 100644 --- a/go.sum +++ b/go.sum @@ -196,8 +196,8 @@ github.com/DataDog/datadog-go v3.2.0+incompatible h1:qSG2N4FghB1He/r2mFrWKCaL7dX github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3tL4fMGNddJ+vMq1mwgfaqoQ= github.com/DataDog/datadog-go/v5 v5.8.3 h1:s58CUJ9s8lezjhTNJO/SxkPBv2qZjS3ktpRSqGF5n0s= github.com/DataDog/datadog-go/v5 v5.8.3/go.mod h1:K9kcYBlxkcPP8tvvjZZKs/m1edNAUFzBbdpTUKfCsuw= -github.com/DataDog/datadog-operator/api v0.0.0-20260218132256-6fb0dc76eec6 h1:UXO2N0ElAkDMRwMSX1aurYLCRbr1rYtT2ta/f7O9Hdg= -github.com/DataDog/datadog-operator/api v0.0.0-20260218132256-6fb0dc76eec6/go.mod h1:lejC6AK61CXsAj6kfQI8/ByZly9xvsdBNODJfC+EutQ= +github.com/DataDog/datadog-operator/api v0.0.0-20260312201613-877d28ec5510 h1:cUR6Bg/C0XU+M1jVWGXsoJyePqDvW0mSm1/yLBMwHQs= +github.com/DataDog/datadog-operator/api v0.0.0-20260312201613-877d28ec5510/go.mod h1:IDXBsCFwKxGmq5ScOjs93hDpo1yB7mlXhWTmDp5bGxQ= github.com/DataDog/datadog-traceroute v1.0.13 h1:PBkmwNCRqDrjFMXi/W9yTydFOKuxr8fcP08NVKXri1U= github.com/DataDog/datadog-traceroute v1.0.13/go.mod h1:ywOVt342keSUAzy1Aa47td4+2yl8WJsYQ+m7PlEDy8o= github.com/DataDog/ddtrivy v0.0.0-20260115083325-07614fb0b8d5 h1:R6uhWnfvq23xRAoV3vK9sc6D5pDHxEEDYBgs2YbcX8s= @@ -780,8 +780,8 @@ github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= github.com/emicklei/dot v0.15.0 h1:XDBW0Xco1QNyRb33cqLe10cT04yMWL1XpCZfa98Q6Og= github.com/emicklei/dot v0.15.0/go.mod h1:DeV7GvQtIw4h2u73RKBkkFdvVAz0D9fzeJrgPW6gy/s= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/envoyproxy/gateway v1.5.7 h1:41ZerUfu/aFb1vLOWIkAQ89eChUOolZTSIp11rxNBnc= @@ -917,10 +917,10 @@ github.com/go-openapi/analysis v0.24.1 h1:Xp+7Yn/KOnVWYG8d+hPksOYnCYImE3TieBa7rB github.com/go-openapi/analysis v0.24.1/go.mod h1:dU+qxX7QGU1rl7IYhBC8bIfmWQdX4Buoea4TGtxXY84= github.com/go-openapi/errors v0.22.4 h1:oi2K9mHTOb5DPW2Zjdzs/NIvwi2N3fARKaTJLdNabaM= github.com/go-openapi/errors v0.22.4/go.mod h1:z9S8ASTUqx7+CP1Q8dD8ewGH/1JWFFLX/2PmAYNQLgk= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/loads v0.23.2 h1:rJXAcP7g1+lWyBHC7iTY+WAF0rprtM+pm8Jxv1uQJp4= github.com/go-openapi/loads v0.23.2/go.mod h1:IEVw1GfRt/P2Pplkelxzj9BYFajiWOtY2nHZNj4UnWY= github.com/go-openapi/runtime v0.29.2 h1:UmwSGWNmWQqKm1c2MGgXVpC2FTGwPDQeUsBMufc5Yj0= @@ -1089,8 +1089,8 @@ github.com/google/certificate-transparency-go v1.3.2 h1:9ahSNZF2o7SYMaKaXhAumVEz github.com/google/certificate-transparency-go v1.3.2/go.mod h1:H5FpMUaGa5Ab2+KCYsxg6sELw3Flkl7pGZzWdBoYLXs= github.com/google/flatbuffers v25.2.10+incompatible h1:F3vclr7C3HpB1k9mxCGRMXq6FdUalZ6H/pNX4FP1v0Q= github.com/google/flatbuffers v25.2.10+incompatible/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-containerregistry v0.20.7 h1:24VGNpS0IwrOZ2ms2P1QE3Xa5X9p4phx0aUgzYzHW6I= github.com/google/go-containerregistry v0.20.7/go.mod h1:Lx5LCZQjLH1QBaMPeGwsME9biPeo1lPx6lbGj/UmzgM= github.com/google/go-github v17.0.0+incompatible h1:N0LgJ1j65A7kfXrZnUDaYCs/Sf4rEjNlfyDHW9dolSY= @@ -1926,15 +1926,15 @@ github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108 github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= github.com/onsi/ginkgo v1.16.5 h1:8xi0RTUf59SOSfEtZMvwTvXYMzG4gV23XVHOZiXNtnE= github.com/onsi/ginkgo v1.16.5/go.mod h1:+E8gABHa3K6zRBolWtd+ROzc/U5bkGt0FwiG042wbpU= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.5.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/open-telemetry/opentelemetry-collector-contrib/connector/routingconnector v0.147.0 h1:LBsvBOuEFrBcmvFSC8mC9pOuV70HNSW1/kVrt3vs2eA= github.com/open-telemetry/opentelemetry-collector-contrib/connector/routingconnector v0.147.0/go.mod h1:l8iHJuARluy9Cqsh4CMgXZOTTyO1oMssT9zE8Q6irO4= github.com/open-telemetry/opentelemetry-collector-contrib/connector/spanmetricsconnector v0.147.0 h1:sAjARhiJxByhuUz0JTUPthqetNp6rxACW6KMEDd6K3c= @@ -3572,8 +3572,8 @@ k8s.io/kms v0.34.1 h1:iCFOvewDPzWM9fMTfyIPO+4MeuZ0tcZbugxLNSHFG4w= k8s.io/kms v0.34.1/go.mod h1:s1CFkLG7w9eaTYvctOxosx88fl4spqmixnNpys0JAtM= k8s.io/kube-aggregator v0.34.1 h1:WNLV0dVNoFKmuyvdWLd92iDSyD/TSTjqwaPj0U9XAEU= k8s.io/kube-aggregator v0.34.1/go.mod h1:RU8j+5ERfp0h+gIvWtxRPfsa5nK7rboDm8RST8BJfYQ= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI= k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A= k8s.io/kubelet v0.34.1 h1:doAaTA9/Yfzbdq/u/LveZeONp96CwX9giW6b+oHn4m4= @@ -3582,8 +3582,8 @@ k8s.io/metrics v0.34.1 h1:374Rexmp1xxgRt64Bi0TsjAM8cA/Y8skwCoPdjtIslE= k8s.io/metrics v0.34.1/go.mod h1:Drf5kPfk2NJrlpcNdSiAAHn/7Y9KqxpRNagByM7Ei80= k8s.io/sample-controller v0.34.1 h1:VEbFn/pWei7B/Ym61q2lrgV14cRls0L6DNatpYtLLpY= k8s.io/sample-controller v0.34.1/go.mod h1:iTc/YrdH1fCK4DSjpGqEKp+MdniDdPE/+sOT0dYfnxA= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= layeh.com/radius v0.0.0-20231213012653-1006025d24f8 h1:orYXpi6BJZdvgytfHH4ybOe4wHnLbbS71Cmd8mWdZjs= layeh.com/radius v0.0.0-20231213012653-1006025d24f8/go.mod h1:QRf+8aRqXc019kHkpcs/CTgyWXFzf+bxlsyuo2nAl1o= mellium.im/sasl v0.3.2 h1:PT6Xp7ccn9XaXAnJ03FcEjmAn7kK1x7aoXV6F+Vmrl0= diff --git a/internal/tools/go.mod b/internal/tools/go.mod index ca53c939f08232..ae945f90608d65 100644 --- a/internal/tools/go.mod +++ b/internal/tools/go.mod @@ -198,6 +198,8 @@ require ( github.com/nishanths/exhaustive v0.12.0 // indirect github.com/nishanths/predeclared v0.2.2 // indirect github.com/nunnatsa/ginkgolinter v0.22.0 // indirect + github.com/onsi/ginkgo/v2 v2.27.5 // indirect + github.com/onsi/gomega v1.39.0 // indirect github.com/otiai10/copy v1.14.1 // indirect github.com/pelletier/go-toml/v2 v2.2.4 // indirect github.com/pjbgf/sha1cd v0.3.2 // indirect diff --git a/internal/tools/go.sum b/internal/tools/go.sum index 665aa70032c924..00b6fc950c62a5 100644 --- a/internal/tools/go.sum +++ b/internal/tools/go.sum @@ -437,10 +437,10 @@ github.com/nishanths/predeclared v0.2.2 h1:V2EPdZPliZymNAn79T8RkNApBjMmVKh5XRpLm github.com/nishanths/predeclared v0.2.2/go.mod h1:RROzoN6TnGQupbC+lqggsOlcgysk3LMK/HI84Mp280c= github.com/nunnatsa/ginkgolinter v0.22.0 h1:o9g7JN6efdBxAHhejvPkodEjWsOBze9zDnPePsvC/Qg= github.com/nunnatsa/ginkgolinter v0.22.0/go.mod h1:zIFAk36fhcHQIiYOGXLbrGTXz7cvpufhRYem6ToCVnY= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/otiai10/copy v1.2.0/go.mod h1:rrF5dJ5F0t/EWSYODDu4j9/vEeYHMkc8jt0zJChqQWw= github.com/otiai10/copy v1.14.1 h1:5/7E6qsUMBaH5AnQ0sSLzzTg1oTECmcCmT6lvF45Na8= github.com/otiai10/copy v1.14.1/go.mod h1:oQwrEDDOci3IM8dJF0d8+jnbfPDllW6vUjNc3DoZm9I= diff --git a/pkg/clusteragent/instrumentation/cel.go b/pkg/clusteragent/instrumentation/cel.go new file mode 100644 index 00000000000000..75c117f9505cc4 --- /dev/null +++ b/pkg/clusteragent/instrumentation/cel.go @@ -0,0 +1,53 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +package instrumentation + +import ( + "fmt" + "sort" + "strings" + + workloadfilter "github.com/DataDog/datadog-agent/comp/core/workloadfilter/def" + datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" +) + +// BuildCELSelector builds a CEL selector from a DatadogInstrumentation's Selector and namespace. +func BuildCELSelector(dwc *datadoghq.DatadogInstrumentation) workloadfilter.Rules { + hasAnnotations := len(dwc.Spec.Selector.MatchAnnotations) > 0 + hasLabels := len(dwc.Spec.Selector.MatchLabels) > 0 + var rules []string + if hasAnnotations { + rules = append(rules, BuildMapCELRules("container.pod.annotations", dwc.Spec.Selector.MatchAnnotations)...) + } + if hasLabels { + rules = append(rules, BuildMapCELRules("container.pod.labels", dwc.Spec.Selector.MatchLabels)...) + } + rules = append(rules, fmt.Sprintf("container.pod.namespace == '%s'", dwc.Namespace)) + combinedRules := strings.Join(rules, " && ") + return workloadfilter.Rules{Containers: []string{combinedRules}} +} + +// BuildMapCELRules generates CEL equality expressions for a map field. +// Each key-value pair becomes: fieldPath["key"] == "value". +// Keys are sorted for deterministic output. +func BuildMapCELRules(fieldPath string, m map[string]string) []string { + if len(m) == 0 { + return nil + } + keys := make([]string, 0, len(m)) + for k := range m { + keys = append(keys, k) + } + sort.Strings(keys) + + rules := make([]string, 0, len(m)) + for _, k := range keys { + rules = append(rules, fmt.Sprintf(`%s["%s"] == "%s"`, fieldPath, k, m[k])) + } + return rules +} diff --git a/pkg/clusteragent/instrumentation/cel_test.go b/pkg/clusteragent/instrumentation/cel_test.go new file mode 100644 index 00000000000000..ace2361b001fcb --- /dev/null +++ b/pkg/clusteragent/instrumentation/cel_test.go @@ -0,0 +1,36 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +package instrumentation + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestBuildMapCELRules(t *testing.T) { + rules := BuildMapCELRules("container.pod.annotations", map[string]string{ + "b-key": "val-b", + "a-key": "val-a", + }) + + require.Len(t, rules, 2) + assert.Equal(t, `container.pod.annotations["a-key"] == "val-a"`, rules[0]) + assert.Equal(t, `container.pod.annotations["b-key"] == "val-b"`, rules[1]) +} + +func TestBuildMapCELRules_Labels(t *testing.T) { + rules := BuildMapCELRules("container.pod.labels", map[string]string{"app": "nginx"}) + require.Len(t, rules, 1) + assert.Equal(t, `container.pod.labels["app"] == "nginx"`, rules[0]) +} + +func TestBuildMapCELRules_Empty(t *testing.T) { + assert.Nil(t, BuildMapCELRules("container.pod.labels", nil)) +} diff --git a/pkg/clusteragent/instrumentation/checks/convert.go b/pkg/clusteragent/instrumentation/checks/convert.go new file mode 100644 index 00000000000000..a33db5cde7af9b --- /dev/null +++ b/pkg/clusteragent/instrumentation/checks/convert.go @@ -0,0 +1,85 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +package checks + +import ( + "encoding/json" + "fmt" + + workloadfilter "github.com/DataDog/datadog-agent/comp/core/workloadfilter/def" + "github.com/DataDog/datadog-agent/pkg/clusteragent/instrumentation" + datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" + + "gopkg.in/yaml.v2" +) + +// adConfig represents an autodiscovery-compatible check configuration YAML. +// The fields match the configFormat struct in comp/core/autodiscovery/providers/config_reader.go. +type adConfig struct { + ADIdentifiers []string `yaml:"ad_identifiers,omitempty"` + CELSelector workloadfilter.Rules `yaml:"cel_selector,omitempty"` + InitConfig interface{} `yaml:"init_config"` + Instances []interface{} `yaml:"instances"` + Logs interface{} `yaml:"logs,omitempty"` +} + +// configMapKey returns the ConfigMap data key for a check within a DatadogInstrumentation CR. +func configMapKey(namespace, crName, checkName string) string { + return fmt.Sprintf("%s_%s_%s.yaml", namespace, crName, checkName) +} + +// convertCR converts a DatadogInstrumentation CR into a set of ConfigMap entries (key -> YAML). +// Each CheckConfig in the CR produces one entry. +func convertCR(dwc *datadoghq.DatadogInstrumentation) (map[string]string, error) { + celRules := instrumentation.BuildCELSelector(dwc) + + entries := make(map[string]string, len(dwc.Spec.Config.Checks)) + for i, check := range dwc.Spec.Config.Checks { + yamlBytes, err := convertCheckToADConfig(check, celRules) + if err != nil { + return nil, fmt.Errorf("check[%d] %q: %w", i, check.Integration, err) + } + key := configMapKey(dwc.Namespace, dwc.Name, check.Integration) + entries[key] = string(yamlBytes) + } + return entries, nil +} + +// convertCheckToADConfig converts a single CheckConfig into AD-compatible YAML. +func convertCheckToADConfig(check datadoghq.CheckConfig, celRules workloadfilter.Rules) ([]byte, error) { + cfg := adConfig{ + ADIdentifiers: check.ContainerImage, + CELSelector: celRules, + } + + if check.InitConfig != nil && check.InitConfig.Raw != nil { + var initConfig interface{} + if err := json.Unmarshal(check.InitConfig.Raw, &initConfig); err != nil { + return nil, fmt.Errorf("failed to parse initConfig: %w", err) + } + cfg.InitConfig = initConfig + } + + for i, inst := range check.Instances { + var instance interface{} + if err := json.Unmarshal(inst.Raw, &instance); err != nil { + return nil, fmt.Errorf("failed to parse instance[%d]: %w", i, err) + } + cfg.Instances = append(cfg.Instances, instance) + } + + if check.Logs != nil && check.Logs.Raw != nil { + var logs interface{} + if err := json.Unmarshal(check.Logs.Raw, &logs); err != nil { + return nil, fmt.Errorf("failed to parse logs: %w", err) + } + cfg.Logs = logs + } + + return yaml.Marshal(cfg) +} diff --git a/pkg/clusteragent/instrumentation/checks/convert_test.go b/pkg/clusteragent/instrumentation/checks/convert_test.go new file mode 100644 index 00000000000000..6a0f23f3bdd877 --- /dev/null +++ b/pkg/clusteragent/instrumentation/checks/convert_test.go @@ -0,0 +1,279 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +package checks + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestConvertCR_SingleCheck(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{ + Name: "nginx-check", + Namespace: "web-team", + }, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{ + MatchLabels: map[string]string{"app": "nginx"}, + }, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "nginx", + ContainerImage: []string{"nginx:latest"}, + InitConfig: &apiextensionsv1.JSON{Raw: []byte(`{}`)}, + Instances: []apiextensionsv1.JSON{ + {Raw: []byte(`{"nginx_status_url":"http://%%host%%:81/status/"}`)}, + }, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + require.Len(t, entries, 1) + + yaml := entries["web-team_nginx-check_nginx.yaml"] + assert.Contains(t, yaml, "ad_identifiers:\n- nginx:latest") + assert.Contains(t, yaml, "init_config: {}") + assert.Contains(t, yaml, "nginx_status_url") + assert.Contains(t, yaml, `container.pod.labels["app"] == "nginx"`) +} + +func TestConvertCR_MultipleChecks(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{ + Name: "multi-check", + Namespace: "default", + }, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{ + MatchLabels: map[string]string{"app": "myapp"}, + }, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "http_check", + ContainerImage: []string{"myapp:v1"}, + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://%%host%%:8080"}`)}}, + }, + { + Integration: "redisdb", + ContainerImage: []string{"redis:7"}, + InitConfig: &apiextensionsv1.JSON{Raw: []byte(`{}`)}, + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"host":"%%host%%","port":"6379"}`)}}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + require.Len(t, entries, 2) + + assert.Contains(t, entries, "default_multi-check_http_check.yaml") + assert.Contains(t, entries, "default_multi-check_redisdb.yaml") + + assert.Contains(t, entries["default_multi-check_http_check.yaml"], "myapp:v1") + assert.Contains(t, entries["default_multi-check_redisdb.yaml"], "redis:7") +} + +func TestConvertCR_NilInitConfig(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "check", Namespace: "default"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{MatchLabels: map[string]string{"app": "x"}}, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "http_check", + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://localhost"}`)}}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + + yaml := entries["default_check_http_check.yaml"] + assert.Contains(t, yaml, "init_config: null") +} + +func TestConvertCR_WithLogs(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "check", Namespace: "default"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{MatchLabels: map[string]string{"app": "x"}}, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "http_check", + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://localhost"}`)}}, + Logs: &apiextensionsv1.JSON{Raw: []byte(`[{"type":"file","path":"/var/log/app.log","service":"myapp"}]`)}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + + yaml := entries["default_check_http_check.yaml"] + assert.Contains(t, yaml, "logs:") + assert.Contains(t, yaml, "service: myapp") +} + +func TestConvertCR_WithAnnotationSelector(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "check", Namespace: "web-team"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{ + MatchAnnotations: map[string]string{ + "team": "web", + "env": "prod", + }, + }, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "nginx", + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://%%host%%"}`)}}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + + yaml := entries["web-team_check_nginx.yaml"] + assert.Contains(t, yaml, "cel_selector:") + assert.Contains(t, yaml, `annotations["env"]`) + assert.Contains(t, yaml, `annotations["team"]`) + assert.Contains(t, yaml, `namespace == 'web-team'`) +} + +func TestConvertCR_WithLabelSelector(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "check", Namespace: "default"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{ + MatchLabels: map[string]string{"app": "nginx"}, + }, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "nginx", + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://%%host%%"}`)}}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + + yaml := entries["default_check_nginx.yaml"] + assert.Contains(t, yaml, "cel_selector:") + assert.Contains(t, yaml, `container.pod.labels["app"] == "nginx"`) + assert.Contains(t, yaml, `container.pod.namespace == 'default'`) +} + +func TestConvertCR_WithBothLabelAndAnnotationSelector(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "check", Namespace: "web-team"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{ + MatchLabels: map[string]string{"app": "nginx"}, + MatchAnnotations: map[string]string{"team": "web"}, + }, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "nginx", + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://%%host%%"}`)}}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + + yaml := entries["web-team_check_nginx.yaml"] + assert.Contains(t, yaml, `container.pod.annotations["team"] == "web"`) + assert.Contains(t, yaml, `container.pod.labels["app"] == "nginx"`) + assert.Contains(t, yaml, `container.pod.namespace == 'web-team'`) +} + +func TestConvertCR_NoSelector(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "check", Namespace: "default"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{}, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "nginx", + ContainerImage: []string{"nginx"}, + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"url":"http://%%host%%"}`)}}, + }, + }, + }, + }, + } + + entries, err := convertCR(dwc) + require.NoError(t, err) + + yaml := entries["default_check_nginx.yaml"] + assert.Contains(t, yaml, "cel_selector:") + assert.Contains(t, yaml, `container.pod.namespace == 'default'`) +} + +func TestConfigMapKey(t *testing.T) { + assert.Equal(t, "web-team_nginx-check_nginx.yaml", configMapKey("web-team", "nginx-check", "nginx")) +} + +func TestConvertCR_InvalidJSON(t *testing.T) { + dwc := &datadoghq.DatadogInstrumentation{ + ObjectMeta: metav1.ObjectMeta{Name: "bad", Namespace: "default"}, + Spec: datadoghq.DatadogInstrumentationSpec{ + Selector: datadoghq.PodSelector{MatchLabels: map[string]string{"app": "x"}}, + Config: datadoghq.InstrumentationConfig{ + Checks: []datadoghq.CheckConfig{ + { + Integration: "test", + InitConfig: &apiextensionsv1.JSON{Raw: []byte(`not-json`)}, + Instances: []apiextensionsv1.JSON{{Raw: []byte(`{"ok": true}`)}}, + }, + }, + }, + }, + } + + _, err := convertCR(dwc) + assert.Error(t, err) + assert.Contains(t, err.Error(), "initConfig") +} diff --git a/pkg/clusteragent/instrumentation/checks/handler.go b/pkg/clusteragent/instrumentation/checks/handler.go new file mode 100644 index 00000000000000..d33845c4dda2c6 --- /dev/null +++ b/pkg/clusteragent/instrumentation/checks/handler.go @@ -0,0 +1,92 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +// Package checks provides the mapping logic turning checks defined in the +// DatadogInstrumentation CRD into equivalent file based autodiscovery check +// configs that are written to a ConfigMap for Node Agents to consume. +package checks + +import ( + "context" + "fmt" + "maps" + + datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" + + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +// DefaultConfigMapName is the name of the ConfigMap where CRD-based check +// configs are written for the Node Agent's file-based AD provider. +const DefaultConfigMapName = "datadog-crd-check-conf" + +// Handler implements ConfigSectionHandler for the checks section. +// It converts DatadogInstrumentation CRs into AD-compatible check configs +// and writes them to a ConfigMap that the Node Agent reads via file-based AD. +type Handler struct { + kubeClient kubernetes.Interface + configMapName string + configMapNamespace string +} + +// NewChecksHandler creates a new Handler. +func NewChecksHandler(kubeClient kubernetes.Interface, configMapName, configMapNamespace string) *Handler { + return &Handler{ + kubeClient: kubeClient, + configMapName: configMapName, + configMapNamespace: configMapNamespace, + } +} + +// Name returns the handler name. +func (h *Handler) Name() string { + return "checks" +} + +// Reconcile processes all CRs and writes their check configs to the ConfigMap. +func (h *Handler) Reconcile(crs []*datadoghq.DatadogInstrumentation) error { + data := make(map[string]string) + for _, dwc := range crs { + entries, err := convertCR(dwc) + if err != nil { + log.Warnf("Skipping DatadogInstrumentation %s/%s: %v", dwc.Namespace, dwc.Name, err) + continue + } + + for k, v := range entries { + data[k] = v + } + } + + return h.updateConfigMap(data) +} + +// updateConfigMap updates the ConfigMap only if the data has changed. +func (h *Handler) updateConfigMap(data map[string]string) error { + cm, err := h.kubeClient.CoreV1().ConfigMaps(h.configMapNamespace).Get( + context.TODO(), h.configMapName, metav1.GetOptions{}) + if err != nil { + return fmt.Errorf("failed to get ConfigMap %s/%s: %w", h.configMapNamespace, h.configMapName, err) + } + + if maps.Equal(cm.Data, data) { + return nil + } + + cm.Data = data + _, err = h.kubeClient.CoreV1().ConfigMaps(h.configMapNamespace).Update( + context.TODO(), cm, metav1.UpdateOptions{}) + if err != nil { + return fmt.Errorf("failed to update ConfigMap %s/%s: %w", h.configMapNamespace, h.configMapName, err) + } + + log.Infof("Updated ConfigMap %s/%s with %d check configs", h.configMapNamespace, h.configMapName, len(data)) + return nil +} diff --git a/pkg/clusteragent/instrumentation/controller.go b/pkg/clusteragent/instrumentation/controller.go new file mode 100644 index 00000000000000..0547e27eb9d344 --- /dev/null +++ b/pkg/clusteragent/instrumentation/controller.go @@ -0,0 +1,198 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +// Package instrumentation follows a controller architecture watching for +// DatadogInstrumentation custom resources and reconciles their state. +// +// The controller uses a dynamic informer to track add, update, and delete events +// on DatadogInstrumentation CRs. Rather than handling each event individually, it +// coalesces them through a rate-limited workqueue and performs a full-sync +// reconciliation: listing all CRs and fanning the complete set out to each +// registered ConfigSectionHandler. This means handlers always receive the full +// picture of deployed CRs on every cycle, simplifying their reconciliation logic. +// +// The controller is leader-aware and only reconciles when the current instance +// holds the leader election lock. +package instrumentation + +import ( + "fmt" + + datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/dynamic/dynamicinformer" + "k8s.io/client-go/tools/cache" + "k8s.io/client-go/util/workqueue" + + "github.com/DataDog/datadog-agent/pkg/util/log" +) + +const ( + maxRetries = 3 + // reconcileKey is a fixed key used for the workqueue since we always do a full sync. + reconcileKey = "reconcile" +) + +var gvrDDI = datadoghq.GroupVersion.WithResource("datadoginstrumentations") + +// InstrumentationController watches DatadogInstrumentation CRDs and delegates reconciliation +// to registered ConfigSectionHandler implementations. +type InstrumentationController struct { + lister cache.GenericLister + synced cache.InformerSynced + workqueue workqueue.TypedRateLimitingInterface[string] + isLeader func() bool + leadershipChangeNotif <-chan struct{} + handlers []ConfigSectionHandler +} + +// NewInstrumentationCRDController creates a new InstrumentationController. +func NewInstrumentationCRDController( + informerFactory dynamicinformer.DynamicSharedInformerFactory, + isLeader func() bool, + leadershipChangeNotif <-chan struct{}, + handlers []ConfigSectionHandler, +) (*InstrumentationController, error) { + dwcInformer := informerFactory.ForResource(gvrDDI) + + c := &InstrumentationController{ + lister: dwcInformer.Lister(), + synced: dwcInformer.Informer().HasSynced, + workqueue: workqueue.NewTypedRateLimitingQueueWithConfig( + workqueue.DefaultTypedItemBasedRateLimiter[string](), + workqueue.TypedRateLimitingQueueConfig[string]{Name: "instrumentation"}, + ), + isLeader: isLeader, + leadershipChangeNotif: leadershipChangeNotif, + handlers: handlers, + } + + if _, err := dwcInformer.Informer().AddEventHandler(cache.ResourceEventHandlerFuncs{ + AddFunc: func(_ interface{}) { c.enqueue() }, + UpdateFunc: func(_, _ interface{}) { c.enqueue() }, + DeleteFunc: func(_ interface{}) { c.enqueue() }, + }); err != nil { + return nil, fmt.Errorf("cannot add event handler to instrumentation informer: %w", err) + } + + return c, nil +} + +// Run starts the controller workers and blocks until stopCh is closed. +func (c *InstrumentationController) Run(stopCh <-chan struct{}) { + defer c.workqueue.ShutDown() + + log.Info("Starting WorkloadConfig CRD controller (waiting for cache sync)") + if !cache.WaitForCacheSync(stopCh, c.synced) { + log.Error("Failed to wait for WorkloadConfig CRD caches to sync") + return + } + log.Info("WorkloadConfig CRD controller started") + + go c.worker() + go c.watchLeadershipChanges(stopCh) + + <-stopCh + log.Info("Stopping WorkloadConfig CRD controller") +} + +func (c *InstrumentationController) enqueue() { + c.workqueue.AddRateLimited(reconcileKey) +} + +// watchLeadershipChanges watches for leadership changes and enqueues a reconcile +// when this instance becomes leader, ensuring CRs that existed before leadership +// acquisition are processed promptly. +func (c *InstrumentationController) watchLeadershipChanges(stopCh <-chan struct{}) { + for { + select { + case <-c.leadershipChangeNotif: + if c.isLeader() { + log.Warn("WorkloadConfig CRD controller gained leadership, enqueuing reconciliation") + c.enqueue() + } + case <-stopCh: + return + } + } +} + +func (c *InstrumentationController) worker() { + for c.processNext() { + } +} + +func (c *InstrumentationController) processNext() bool { + key, shutdown := c.workqueue.Get() + if shutdown { + return false + } + defer c.workqueue.Done(key) + + err := c.reconcile() + if err == nil { + c.workqueue.Forget(key) + return true + } + + if c.workqueue.NumRequeues(key) < maxRetries { + log.Warnf("Error reconciling WorkloadConfig CRD (will retry): %v", err) + } else { + log.Errorf("Error reconciling WorkloadConfig CRD after %d retries: %v", maxRetries, err) + c.workqueue.Forget(key) + } + return true +} + +// reconcile lists all CRs, converts them, and fans out to each handler. +func (c *InstrumentationController) reconcile() error { + if !c.isLeader() { + return nil + } + + objects, err := c.lister.List(labels.Everything()) + if err != nil { + return fmt.Errorf("failed to list DatadogInstrumentations: %w", err) + } + + crs := make([]*datadoghq.DatadogInstrumentation, 0, len(objects)) + for _, obj := range objects { + dwc, err := unstructuredToWorkloadConfig(obj) + if err != nil { + log.Warnf("Skipping malformed DatadogInstrumentation: %v", err) + continue + } + crs = append(crs, dwc) + } + + var firstErr error + for _, h := range c.handlers { + if err := h.Reconcile(crs); err != nil { + log.Errorf("Handler %q failed: %v", h.Name(), err) + if firstErr == nil { + firstErr = err + } + } + } + return firstErr +} + +// unstructuredToWorkloadConfig converts an unstructured object to a DatadogInstrumentation. +func unstructuredToWorkloadConfig(obj interface{}) (*datadoghq.DatadogInstrumentation, error) { + unstrObj, ok := obj.(*unstructured.Unstructured) + if !ok { + return nil, fmt.Errorf("could not cast to Unstructured: %T", obj) + } + dwc := &datadoghq.DatadogInstrumentation{} + if err := runtime.DefaultUnstructuredConverter.FromUnstructured(unstrObj.UnstructuredContent(), dwc); err != nil { + return nil, fmt.Errorf("failed to convert unstructured to DatadogInstrumentation: %w", err) + } + return dwc, nil +} diff --git a/pkg/clusteragent/instrumentation/controller_test.go b/pkg/clusteragent/instrumentation/controller_test.go new file mode 100644 index 00000000000000..b6c60d676ead13 --- /dev/null +++ b/pkg/clusteragent/instrumentation/controller_test.go @@ -0,0 +1,230 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +package instrumentation + +import ( + "context" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" + + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" + "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/dynamic/dynamicinformer" + dynamicfake "k8s.io/client-go/dynamic/fake" +) + +var testGVR = schema.GroupVersionResource{ + Group: "datadoghq.com", + Version: "v1alpha1", + Resource: "datadoginstrumentations", +} + +// fakeHandler records calls from the controller for testing. +type fakeHandler struct { + name string + callCount int + lastCRs []*datadoghq.DatadogInstrumentation + err error +} + +func (f *fakeHandler) Name() string { return f.name } +func (f *fakeHandler) Reconcile(crs []*datadoghq.DatadogInstrumentation) error { + f.callCount++ + f.lastCRs = crs + return f.err +} + +func newUnstructuredWorkloadConfig(namespace, name string, labels map[string]string, checks []interface{}) *unstructured.Unstructured { + selector := map[string]interface{}{} + if labels != nil { + matchLabels := make(map[string]interface{}, len(labels)) + for k, v := range labels { + matchLabels[k] = v + } + selector["matchLabels"] = matchLabels + } + + return &unstructured.Unstructured{ + Object: map[string]interface{}{ + "apiVersion": "datadoghq.com/v1alpha1", + "kind": "DatadogInstrumentation", + "metadata": map[string]interface{}{ + "name": name, + "namespace": namespace, + }, + "spec": map[string]interface{}{ + "selector": selector, + "config": map[string]interface{}{ + "checks": checks, + }, + }, + }, + } +} + +func makeCheck(integration string, containerImages []interface{}, instances []interface{}) map[string]interface{} { + check := map[string]interface{}{ + "integration": integration, + "initConfig": map[string]interface{}{}, + "instances": instances, + } + if containerImages != nil { + check["containerImage"] = containerImages + } + return check +} + +func setupTestController(t *testing.T, existingCRs []*unstructured.Unstructured, handlers ...ConfigSectionHandler) *InstrumentationController { + t.Helper() + + scheme := runtime.NewScheme() + + objs := make([]runtime.Object, len(existingCRs)) + for i, cr := range existingCRs { + objs[i] = cr + } + dynamicClient := dynamicfake.NewSimpleDynamicClientWithCustomListKinds(scheme, + map[schema.GroupVersionResource]string{ + testGVR: "DatadogInstrumentationList", + }, + objs..., + ) + + informerFactory := dynamicinformer.NewDynamicSharedInformerFactory(dynamicClient, 0) + + controller, err := NewInstrumentationCRDController( + informerFactory, + func() bool { return true }, + make(chan struct{}, 1), + handlers, + ) + require.NoError(t, err) + + ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) + defer cancel() + informerFactory.Start(ctx.Done()) + informerFactory.WaitForCacheSync(ctx.Done()) + + return controller +} + +func TestReconcile_SingleCR(t *testing.T) { + cr := newUnstructuredWorkloadConfig("web-team", "nginx-check", + map[string]string{"app": "nginx"}, + []interface{}{ + makeCheck("nginx", []interface{}{"nginx:latest"}, []interface{}{ + map[string]interface{}{"nginx_status_url": "http://%%host%%:81/status/"}, + }), + }) + + handler := &fakeHandler{name: "test"} + controller := setupTestController(t, []*unstructured.Unstructured{cr}, handler) + + err := controller.reconcile() + require.NoError(t, err) + + assert.Equal(t, 1, handler.callCount) + require.Len(t, handler.lastCRs, 1) + assert.Equal(t, "nginx-check", handler.lastCRs[0].Name) +} + +func TestReconcile_MultipleCRs(t *testing.T) { + cr1 := newUnstructuredWorkloadConfig("web-team", "nginx-check", + map[string]string{"app": "nginx"}, + []interface{}{ + makeCheck("nginx", []interface{}{"nginx:latest"}, []interface{}{map[string]interface{}{"url": "http://%%host%%/status/"}}), + }) + cr2 := newUnstructuredWorkloadConfig("data-team", "redis-check", + map[string]string{"app": "redis"}, + []interface{}{ + makeCheck("redisdb", []interface{}{"redis:7"}, []interface{}{map[string]interface{}{"host": "%%host%%", "port": "6379"}}), + }) + + handler := &fakeHandler{name: "test"} + controller := setupTestController(t, []*unstructured.Unstructured{cr1, cr2}, handler) + + err := controller.reconcile() + require.NoError(t, err) + + assert.Equal(t, 1, handler.callCount) + assert.Len(t, handler.lastCRs, 2) +} + +func TestReconcile_EmptyCRList(t *testing.T) { + handler := &fakeHandler{name: "test"} + controller := setupTestController(t, nil, handler) + + err := controller.reconcile() + require.NoError(t, err) + + assert.Equal(t, 1, handler.callCount) + assert.Empty(t, handler.lastCRs) +} + +func TestReconcile_NonLeaderSkips(t *testing.T) { + cr := newUnstructuredWorkloadConfig("web-team", "nginx-check", + map[string]string{"app": "nginx"}, + []interface{}{ + makeCheck("nginx", []interface{}{"nginx:latest"}, []interface{}{map[string]interface{}{"url": "http://%%host%%/status/"}}), + }) + + handler := &fakeHandler{name: "test"} + controller := setupTestController(t, []*unstructured.Unstructured{cr}, handler) + + controller.isLeader = func() bool { return false } + + err := controller.reconcile() + require.NoError(t, err) + + assert.Equal(t, 0, handler.callCount) +} + +func TestReconcile_MultipleHandlers(t *testing.T) { + cr := newUnstructuredWorkloadConfig("default", "check", + map[string]string{"app": "test"}, + []interface{}{ + makeCheck("http_check", nil, []interface{}{map[string]interface{}{"url": "http://localhost"}}), + }) + + handler1 := &fakeHandler{name: "handler1"} + handler2 := &fakeHandler{name: "handler2"} + controller := setupTestController(t, []*unstructured.Unstructured{cr}, handler1, handler2) + + err := controller.reconcile() + require.NoError(t, err) + + assert.Equal(t, 1, handler1.callCount) + assert.Equal(t, 1, handler2.callCount) + assert.Len(t, handler1.lastCRs, 1) + assert.Len(t, handler2.lastCRs, 1) +} + +func TestReconcile_HandlerErrorReturned(t *testing.T) { + cr := newUnstructuredWorkloadConfig("default", "check", + map[string]string{"app": "test"}, + []interface{}{ + makeCheck("http_check", nil, []interface{}{map[string]interface{}{"url": "http://localhost"}}), + }) + + handler1 := &fakeHandler{name: "handler1", err: assert.AnError} + handler2 := &fakeHandler{name: "handler2"} + controller := setupTestController(t, []*unstructured.Unstructured{cr}, handler1, handler2) + + err := controller.reconcile() + assert.ErrorIs(t, err, assert.AnError) + + // Both handlers should still be called + assert.Equal(t, 1, handler1.callCount) + assert.Equal(t, 1, handler2.callCount) +} diff --git a/pkg/clusteragent/instrumentation/handler.go b/pkg/clusteragent/instrumentation/handler.go new file mode 100644 index 00000000000000..a83bcb6e64ec35 --- /dev/null +++ b/pkg/clusteragent/instrumentation/handler.go @@ -0,0 +1,18 @@ +// Unless explicitly stated otherwise all files in this repository are licensed +// under the Apache License Version 2.0. +// This product includes software developed at Datadog (https://www.datadoghq.com/). +// Copyright 2016-present Datadog, Inc. + +//go:build kubeapiserver + +package instrumentation + +import datadoghq "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1" + +// ConfigSectionHandler processes one section of a DatadogInstrumentation CR. +// Handlers receive the full list of CRs each cycle (full-sync model). +// Errors in one handler do not block others. +type ConfigSectionHandler interface { + Name() string + Reconcile(crs []*datadoghq.DatadogInstrumentation) error +} diff --git a/pkg/collector/python/containers.go b/pkg/collector/python/containers.go index 68b097c45f05fa..cfd5f1e9539bcd 100644 --- a/pkg/collector/python/containers.go +++ b/pkg/collector/python/containers.go @@ -37,7 +37,7 @@ func IsContainerExcluded(name, image, namespace *C.char) C.int { goNs = C.GoString(namespace) } - filterablePod := workloadfilter.CreatePod("", "", goNs, nil) + filterablePod := workloadfilter.CreatePod("", "", goNs, nil, nil) filterableContainer := workloadfilter.CreateContainer("", goName, goImg, filterablePod) if checkContext.IsExcluded(filterableContainer) { diff --git a/pkg/config/setup/config.go b/pkg/config/setup/config.go index 43f68129ea6170..f8e09a3863bbd1 100644 --- a/pkg/config/setup/config.go +++ b/pkg/config/setup/config.go @@ -908,6 +908,9 @@ func InitConfig(config pkgconfigmodel.Setup) { config.BindEnvAndSetDefault("cluster_checks.ksm_sharding_enabled", false) // KSM resource sharding: splits KSM check by resource type (pods, nodes, others) config.BindEnvAndSetDefault("cluster_checks.crd_collection", false) + // Workload config CRD controller + config.BindEnvAndSetDefault("workload_config.enabled", true) + // Cluster check runner config.BindEnvAndSetDefault("clc_runner_enabled", false) config.BindEnvAndSetDefault("clc_runner_id", "") @@ -1612,6 +1615,11 @@ func autoconfig(config pkgconfigmodel.Setup) { config.BindEnvAndSetDefault("autoconf_template_dir", "/datadog/check_configs") config.BindEnvAndSetDefault("autoconf_config_files_poll", false) config.BindEnvAndSetDefault("autoconf_config_files_poll_interval", 60) + + // CRD-driven check configuration provider + config.BindEnvAndSetDefault("autoconf_crd_checks_dir", "/etc/datadog-agent/crd-conf.d") + config.BindEnvAndSetDefault("autoconf_crd_checks_poll_interval", 10) + config.BindEnvAndSetDefault("exclude_pause_container", true) config.BindEnvAndSetDefault("include_ephemeral_containers", false) config.BindEnvAndSetDefault("ac_include", []string{}) diff --git a/pkg/logs/schedulers/ad/scheduler.go b/pkg/logs/schedulers/ad/scheduler.go index 892a63419ef9a1..b29bfcfc12cb79 100644 --- a/pkg/logs/schedulers/ad/scheduler.go +++ b/pkg/logs/schedulers/ad/scheduler.go @@ -196,7 +196,7 @@ func CreateSources(config integration.Config) ([]*sourcesPkg.LogSource, error) { var err error switch config.Provider { - case names.File: + case names.File, names.CRDFile: // config defined in a file configs, err = logsConfig.ParseYAML(config.LogsConfig) case names.Container, names.Kubernetes, names.KubeContainer, names.ProcessLog: diff --git a/pkg/proto/datadog/workloadfilter/workloadfilter.proto b/pkg/proto/datadog/workloadfilter/workloadfilter.proto index 981f14363cee58..c0614ddc43e370 100644 --- a/pkg/proto/datadog/workloadfilter/workloadfilter.proto +++ b/pkg/proto/datadog/workloadfilter/workloadfilter.proto @@ -41,6 +41,7 @@ message FilterPod { string name = 2; string namespace = 3; map annotations = 4; + map labels = 5; } message FilterProcess { diff --git a/pkg/proto/pbgo/core/workloadfilter.pb.go b/pkg/proto/pbgo/core/workloadfilter.pb.go index 0302eac778757f..98388a1fbb8b6b 100644 --- a/pkg/proto/pbgo/core/workloadfilter.pb.go +++ b/pkg/proto/pbgo/core/workloadfilter.pb.go @@ -372,6 +372,7 @@ type FilterPod struct { Name string `protobuf:"bytes,2,opt,name=name,proto3" json:"name,omitempty"` Namespace string `protobuf:"bytes,3,opt,name=namespace,proto3" json:"namespace,omitempty"` Annotations map[string]string `protobuf:"bytes,4,rep,name=annotations,proto3" json:"annotations,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` + Labels map[string]string `protobuf:"bytes,5,rep,name=labels,proto3" json:"labels,omitempty" protobuf_key:"bytes,1,opt,name=key" protobuf_val:"bytes,2,opt,name=value"` unknownFields protoimpl.UnknownFields sizeCache protoimpl.SizeCache } @@ -434,6 +435,13 @@ func (x *FilterPod) GetAnnotations() map[string]string { return nil } +func (x *FilterPod) GetLabels() map[string]string { + if x != nil { + return x.Labels + } + return nil +} + type FilterProcess struct { state protoimpl.MessageState `protogen:"open.v1"` Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` @@ -742,14 +750,18 @@ const file_datadog_workloadfilter_workloadfilter_proto_rawDesc = "" + "\x05image\x18\x03 \x01(\v2#.datadog.workloadfilter.FilterImageR\x05image\x125\n" + "\x03pod\x18\x04 \x01(\v2!.datadog.workloadfilter.FilterPodH\x00R\x03pod\x12B\n" + "\becs_task\x18\x05 \x01(\v2%.datadog.workloadfilter.FilterECSTaskH\x00R\aecsTaskB\a\n" + - "\x05owner\"\xe3\x01\n" + + "\x05owner\"\xe5\x02\n" + "\tFilterPod\x12\x0e\n" + "\x02id\x18\x01 \x01(\tR\x02id\x12\x12\n" + "\x04name\x18\x02 \x01(\tR\x04name\x12\x1c\n" + "\tnamespace\x18\x03 \x01(\tR\tnamespace\x12T\n" + - "\vannotations\x18\x04 \x03(\v22.datadog.workloadfilter.FilterPod.AnnotationsEntryR\vannotations\x1a>\n" + + "\vannotations\x18\x04 \x03(\v22.datadog.workloadfilter.FilterPod.AnnotationsEntryR\vannotations\x12E\n" + + "\x06labels\x18\x05 \x03(\v2-.datadog.workloadfilter.FilterPod.LabelsEntryR\x06labels\x1a>\n" + "\x10AnnotationsEntry\x12\x10\n" + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\x1a9\n" + + "\vLabelsEntry\x12\x10\n" + + "\x03key\x18\x01 \x01(\tR\x03key\x12\x14\n" + "\x05value\x18\x02 \x01(\tR\x05value:\x028\x01\"l\n" + "\rFilterProcess\x12\x12\n" + "\x04name\x18\x01 \x01(\tR\x04name\x12\x18\n" + @@ -793,7 +805,7 @@ func file_datadog_workloadfilter_workloadfilter_proto_rawDescGZIP() []byte { } var file_datadog_workloadfilter_workloadfilter_proto_enumTypes = make([]protoimpl.EnumInfo, 1) -var file_datadog_workloadfilter_workloadfilter_proto_msgTypes = make([]protoimpl.MessageInfo, 12) +var file_datadog_workloadfilter_workloadfilter_proto_msgTypes = make([]protoimpl.MessageInfo, 13) var file_datadog_workloadfilter_workloadfilter_proto_goTypes = []any{ (WorkloadFilterResult)(0), // 0: datadog.workloadfilter.WorkloadFilterResult (*WorkloadFilterEvaluateRequest)(nil), // 1: datadog.workloadfilter.WorkloadFilterEvaluateRequest @@ -806,8 +818,9 @@ var file_datadog_workloadfilter_workloadfilter_proto_goTypes = []any{ (*FilterKubeEndpoint)(nil), // 8: datadog.workloadfilter.FilterKubeEndpoint (*FilterImage)(nil), // 9: datadog.workloadfilter.FilterImage nil, // 10: datadog.workloadfilter.FilterPod.AnnotationsEntry - nil, // 11: datadog.workloadfilter.FilterKubeService.AnnotationsEntry - nil, // 12: datadog.workloadfilter.FilterKubeEndpoint.AnnotationsEntry + nil, // 11: datadog.workloadfilter.FilterPod.LabelsEntry + nil, // 12: datadog.workloadfilter.FilterKubeService.AnnotationsEntry + nil, // 13: datadog.workloadfilter.FilterKubeEndpoint.AnnotationsEntry } var file_datadog_workloadfilter_workloadfilter_proto_depIdxs = []int32{ 3, // 0: datadog.workloadfilter.WorkloadFilterEvaluateRequest.container:type_name -> datadog.workloadfilter.FilterContainer @@ -820,13 +833,14 @@ var file_datadog_workloadfilter_workloadfilter_proto_depIdxs = []int32{ 4, // 7: datadog.workloadfilter.FilterContainer.pod:type_name -> datadog.workloadfilter.FilterPod 6, // 8: datadog.workloadfilter.FilterContainer.ecs_task:type_name -> datadog.workloadfilter.FilterECSTask 10, // 9: datadog.workloadfilter.FilterPod.annotations:type_name -> datadog.workloadfilter.FilterPod.AnnotationsEntry - 11, // 10: datadog.workloadfilter.FilterKubeService.annotations:type_name -> datadog.workloadfilter.FilterKubeService.AnnotationsEntry - 12, // 11: datadog.workloadfilter.FilterKubeEndpoint.annotations:type_name -> datadog.workloadfilter.FilterKubeEndpoint.AnnotationsEntry - 12, // [12:12] is the sub-list for method output_type - 12, // [12:12] is the sub-list for method input_type - 12, // [12:12] is the sub-list for extension type_name - 12, // [12:12] is the sub-list for extension extendee - 0, // [0:12] is the sub-list for field type_name + 11, // 10: datadog.workloadfilter.FilterPod.labels:type_name -> datadog.workloadfilter.FilterPod.LabelsEntry + 12, // 11: datadog.workloadfilter.FilterKubeService.annotations:type_name -> datadog.workloadfilter.FilterKubeService.AnnotationsEntry + 13, // 12: datadog.workloadfilter.FilterKubeEndpoint.annotations:type_name -> datadog.workloadfilter.FilterKubeEndpoint.AnnotationsEntry + 13, // [13:13] is the sub-list for method output_type + 13, // [13:13] is the sub-list for method input_type + 13, // [13:13] is the sub-list for extension type_name + 13, // [13:13] is the sub-list for extension extendee + 0, // [0:13] is the sub-list for field type_name } func init() { file_datadog_workloadfilter_workloadfilter_proto_init() } @@ -851,7 +865,7 @@ func file_datadog_workloadfilter_workloadfilter_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: unsafe.Slice(unsafe.StringData(file_datadog_workloadfilter_workloadfilter_proto_rawDesc), len(file_datadog_workloadfilter_workloadfilter_proto_rawDesc)), NumEnums: 1, - NumMessages: 12, + NumMessages: 13, NumExtensions: 0, NumServices: 0, }, diff --git a/pkg/ssi/testutils/go.mod b/pkg/ssi/testutils/go.mod index 2ff62313d4453a..40cfa5f7905615 100644 --- a/pkg/ssi/testutils/go.mod +++ b/pkg/ssi/testutils/go.mod @@ -27,7 +27,7 @@ require ( gopkg.in/inf.v0 v0.9.1 // indirect k8s.io/klog/v2 v2.130.1 // indirect k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/randfill v1.0.0 // indirect sigs.k8s.io/structured-merge-diff/v6 v6.3.2-0.20260122202528-d9cc6641c482 // indirect diff --git a/pkg/ssi/testutils/go.sum b/pkg/ssi/testutils/go.sum index 591071fb1d94b4..ff99b014ee9973 100644 --- a/pkg/ssi/testutils/go.sum +++ b/pkg/ssi/testutils/go.sum @@ -56,8 +56,8 @@ k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 h1:IpInykpT6ceI+QxKBbEflcR5EXP7sU1kvOlxwZh5txg= sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730/go.mod h1:mdzfpAEoE6DHQEN0uh9ZbOCuHbLK5wOm7dK4ctXE9Tg= sigs.k8s.io/randfill v1.0.0 h1:JfjMILfT8A6RbawdsK2JXGBR5AQVfd+9TbzrlneTyrU= diff --git a/pkg/util/kubernetes/apiserver/apiserver.go b/pkg/util/kubernetes/apiserver/apiserver.go index 7ecfdb4f6344f5..6f5767bf71c836 100644 --- a/pkg/util/kubernetes/apiserver/apiserver.go +++ b/pkg/util/kubernetes/apiserver/apiserver.go @@ -401,7 +401,8 @@ func (c *APIClient) connect() error { pkgconfigsetup.Datadog().GetBool("external_metrics_provider.wpa_controller") || pkgconfigsetup.Datadog().GetBool("cluster_checks.enabled") || pkgconfigsetup.Datadog().GetBool("autoscaling.workload.enabled") || - pkgconfigsetup.Datadog().GetBool("autoscaling.cluster.enabled") { + pkgconfigsetup.Datadog().GetBool("autoscaling.cluster.enabled") || + pkgconfigsetup.Datadog().GetBool("workload_config.enabled") { c.DynamicInformerFactory = dynamicinformer.NewDynamicSharedInformerFactory(c.DynamicInformerCl, c.defaultInformerResyncPeriod) } diff --git a/pkg/util/kubernetes/apiserver/controllers/controllers.go b/pkg/util/kubernetes/apiserver/controllers/controllers.go index e70478b29ba443..9f2acf4575bbe7 100644 --- a/pkg/util/kubernetes/apiserver/controllers/controllers.go +++ b/pkg/util/kubernetes/apiserver/controllers/controllers.go @@ -11,6 +11,7 @@ package controllers import ( "errors" + "fmt" "sync" k8serrors "k8s.io/apimachinery/pkg/util/errors" @@ -25,8 +26,11 @@ import ( datadogclient "github.com/DataDog/datadog-agent/comp/autoscaling/datadogclient/def" workloadmeta "github.com/DataDog/datadog-agent/comp/core/workloadmeta/def" + "github.com/DataDog/datadog-agent/pkg/clusteragent/instrumentation" + "github.com/DataDog/datadog-agent/pkg/clusteragent/instrumentation/checks" pkgconfigsetup "github.com/DataDog/datadog-agent/pkg/config/setup" "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver" + "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver/common/namespace" "github.com/DataDog/datadog-agent/pkg/util/log" "github.com/DataDog/datadog-agent/pkg/util/option" ) @@ -57,6 +61,10 @@ var controllerCatalog = map[controllerName]controllerFuncs{ func() bool { return pkgconfigsetup.Datadog().GetBool("cluster_checks.enabled") }, registerServicesInformer, }, + workloadConfigCrdControllerName: { + func() bool { return pkgconfigsetup.Datadog().GetBool("workload_config.enabled") }, + startWorkloadConfigCRDController, + }, endpointsControllerName: { func() bool { return pkgconfigsetup.Datadog().GetBool("cluster_checks.enabled") }, registerEndpointsInformer, @@ -75,6 +83,8 @@ var controllerCatalog = map[controllerName]controllerFuncs{ }, } +type leaderNotifier func() (leadershipChangeNotif <-chan struct{}, isLeader func() bool) + // ControllerContext holds all the attributes needed by the controllers type ControllerContext struct { informers map[apiserver.InformerName]cache.SharedInformer @@ -85,6 +95,7 @@ type ControllerContext struct { DynamicInformerFactory dynamicinformer.DynamicSharedInformerFactory Client kubernetes.Interface IsLeaderFunc func() bool + LeaderNotifier leaderNotifier EventRecorder record.EventRecorder WorkloadMeta workloadmeta.Component DatadogClient option.Option[datadogclient.Component] @@ -186,6 +197,34 @@ func startAutoscalersController(ctx *ControllerContext, c chan error) { autoscalersController.runControllerLoop(ctx.StopCh) } +// startWorkloadConfigCRDController starts the WorkloadConfig CRD controller that watches +// DatadogInstrumentation CRDs and delegates to registered config section handlers. +func startWorkloadConfigCRDController(ctx *ControllerContext, errChan chan error) { + configMapNamespace := namespace.GetResourcesNamespace() + leaderNotif, _ := ctx.LeaderNotifier() + + handlers := []instrumentation.ConfigSectionHandler{ + checks.NewChecksHandler(ctx.Client, checks.DefaultConfigMapName, configMapNamespace), + } + + controller, err := instrumentation.NewInstrumentationCRDController( + ctx.DynamicInformerFactory, + ctx.IsLeaderFunc, + leaderNotif, + handlers, + ) + if err != nil { + errChan <- fmt.Errorf("failed to create WorkloadConfig CRD controller: %w", err) + return + } + + if ctx.DynamicInformerFactory != nil { + ctx.DynamicInformerFactory.Start(ctx.StopCh) + } + + go controller.Run(ctx.StopCh) +} + // registerServicesInformer registers the services informer. func registerServicesInformer(ctx *ControllerContext, _ chan error) { informer := ctx.InformerFactory.Core().V1().Services().Informer() diff --git a/pkg/util/kubernetes/apiserver/controllers/names.go b/pkg/util/kubernetes/apiserver/controllers/names.go index fac89b4bf83647..1094f4a26d9107 100644 --- a/pkg/util/kubernetes/apiserver/controllers/names.go +++ b/pkg/util/kubernetes/apiserver/controllers/names.go @@ -12,12 +12,13 @@ import "github.com/DataDog/datadog-agent/pkg/util/kubernetes/apiserver" type controllerName string const ( - metadataControllerName controllerName = "metadata" - autoscalersControllerName controllerName = "autoscalers" - servicesControllerName controllerName = "services" - endpointsControllerName controllerName = "endpoints" - endpointSlicesControllerName controllerName = "endpointslices" - crdControllerName controllerName = "crd" + metadataControllerName controllerName = "metadata" + autoscalersControllerName controllerName = "autoscalers" + workloadConfigCrdControllerName controllerName = "workloadconfigcrd" + servicesControllerName controllerName = "services" + endpointsControllerName controllerName = "endpoints" + endpointSlicesControllerName controllerName = "endpointslices" + crdControllerName controllerName = "crd" ) const ( diff --git a/pkg/util/prometheus/go.mod b/pkg/util/prometheus/go.mod index f07d6bb9e99bfa..5ad01e0c690e23 100644 --- a/pkg/util/prometheus/go.mod +++ b/pkg/util/prometheus/go.mod @@ -37,6 +37,7 @@ require ( google.golang.org/grpc v1.79.1 // indirect google.golang.org/protobuf v1.36.11 // indirect k8s.io/client-go v0.35.1 // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect ) // This section was automatically added by 'dda inv modules.add-all-replace' command, do not edit manually diff --git a/pkg/util/prometheus/go.sum b/pkg/util/prometheus/go.sum index c11caa0bb87d14..c44b7bb56a5bb2 100644 --- a/pkg/util/prometheus/go.sum +++ b/pkg/util/prometheus/go.sum @@ -188,5 +188,5 @@ k8s.io/client-go v0.35.1/go.mod h1:1p1KxDt3a0ruRfc/pG4qT/3oHmUj1AhSHEcxNSGg+OA= k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= diff --git a/test/e2e-framework/go.mod b/test/e2e-framework/go.mod index 7595e0cd66464c..22be6a4c252857 100644 --- a/test/e2e-framework/go.mod +++ b/test/e2e-framework/go.mod @@ -124,7 +124,7 @@ require ( github.com/djherbis/times v1.6.0 // indirect github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect @@ -137,8 +137,8 @@ require ( github.com/go-git/go-git/v5 v5.14.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/swag v0.25.4 // indirect github.com/go-openapi/swag/cmdutils v0.25.4 // indirect github.com/go-openapi/swag/conv v0.25.4 // indirect @@ -156,7 +156,7 @@ require ( github.com/golang/glog v1.2.5 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 // indirect github.com/google/pprof v0.0.0-20260111202518-71be6bfdd440 // indirect github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect @@ -194,6 +194,8 @@ require ( github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f // indirect github.com/nxadm/tail v1.4.11 // indirect + github.com/onsi/ginkgo/v2 v2.27.5 // indirect + github.com/onsi/gomega v1.39.0 // indirect github.com/opencontainers/go-digest v1.0.0 // indirect github.com/opencontainers/image-spec v1.1.1 // indirect github.com/opentracing/basictracer-go v1.1.0 // indirect @@ -258,8 +260,8 @@ require ( gotest.tools/v3 v3.5.2 // indirect k8s.io/component-base v0.35.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect lukechampine.com/frand v1.5.1 // indirect pgregory.net/rapid v1.2.0 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect diff --git a/test/e2e-framework/go.sum b/test/e2e-framework/go.sum index d68fa5229a2b97..090b3817fcac36 100644 --- a/test/e2e-framework/go.sum +++ b/test/e2e-framework/go.sum @@ -158,8 +158,8 @@ github.com/docker/go-units v0.5.0 h1:69rxXcBk27SvSaaxTtLh/8llcHD8vYHT7WSdRZ/jvr4 github.com/docker/go-units v0.5.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= @@ -195,10 +195,10 @@ github.com/go-logr/logr v1.4.3 h1:CjnDlHq8ikf6E492q6eKboGOC0T8CDaOvkHCIg8idEI= github.com/go-logr/logr v1.4.3/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= @@ -244,8 +244,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -351,10 +351,10 @@ github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f h1:y5//uYreIhSUg3J github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U= github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM= github.com/opencontainers/image-spec v1.1.1 h1:y0fUlFfIZhPF1W537XOLg0/fcx6zcHCJwooC2xJA040= @@ -698,12 +698,12 @@ k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI= k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= lukechampine.com/frand v1.5.1 h1:fg0eRtdmGFIxhP5zQJzM1lFDbD6CUfu/f+7WgAZd5/w= lukechampine.com/frand v1.5.1/go.mod h1:4VstaWc2plN4Mjr10chUD46RAVGWhpkZ5Nja8+Azp0Q= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk= diff --git a/test/new-e2e/go.mod b/test/new-e2e/go.mod index 24e8b44cc3cef9..6e238798b77229 100644 --- a/test/new-e2e/go.mod +++ b/test/new-e2e/go.mod @@ -93,7 +93,7 @@ require ( github.com/djherbis/times v1.6.0 // indirect github.com/docker/go-connections v0.6.0 // indirect github.com/docker/go-units v0.5.0 // indirect - github.com/emicklei/go-restful/v3 v3.12.2 // indirect + github.com/emicklei/go-restful/v3 v3.13.0 // indirect github.com/emirpasic/gods v1.18.1 // indirect github.com/exponent-io/jsonpath v0.0.0-20210407135951-1de76d718b3f // indirect github.com/felixge/httpsnoop v1.0.4 // indirect @@ -104,15 +104,15 @@ require ( github.com/go-git/go-git/v5 v5.14.0 // indirect github.com/go-logr/logr v1.4.3 // indirect github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/jsonpointer v0.22.1 // indirect - github.com/go-openapi/jsonreference v0.21.3 // indirect + github.com/go-openapi/jsonpointer v0.22.4 // indirect + github.com/go-openapi/jsonreference v0.21.4 // indirect github.com/go-openapi/swag v0.25.4 // indirect github.com/goccy/go-json v0.10.5 // indirect github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/glog v1.2.5 // indirect github.com/golang/groupcache v0.0.0-20241129210726-2c02b8208cf8 // indirect github.com/google/btree v1.1.3 // indirect - github.com/google/gnostic-models v0.7.0 // indirect + github.com/google/gnostic-models v0.7.1 // indirect github.com/google/go-cmp v0.7.0 github.com/gorilla/websocket v1.5.4-0.20250319132907-e064f32e3674 // indirect github.com/gregjones/httpcache v0.0.0-20190611155906-901d90724c79 // indirect @@ -202,8 +202,8 @@ require ( gopkg.in/warnings.v0 v0.1.2 // indirect k8s.io/component-base v0.35.0 // indirect k8s.io/klog/v2 v2.130.1 // indirect - k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 // indirect - k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 // indirect + k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e // indirect + k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 // indirect lukechampine.com/frand v1.5.1 // indirect sigs.k8s.io/json v0.0.0-20250730193827-2d320260d730 // indirect sigs.k8s.io/kustomize/api v0.20.1 // indirect diff --git a/test/new-e2e/go.sum b/test/new-e2e/go.sum index 2df841e0185d90..5e76725fbb4eac 100644 --- a/test/new-e2e/go.sum +++ b/test/new-e2e/go.sum @@ -210,8 +210,8 @@ github.com/ebitengine/purego v0.10.0 h1:QIw4xfpWT6GWTzaW5XEKy3HXoqrJGx1ijYHzTF0/ github.com/ebitengine/purego v0.10.0/go.mod h1:iIjxzd6CiRiOG0UyXP+V1+jWqUXVjPKLAI0mRfJZTmQ= github.com/elazarl/goproxy v1.7.2 h1:Y2o6urb7Eule09PjlhQRGNsqRfPmYI3KKQLFpCAV3+o= github.com/elazarl/goproxy v1.7.2/go.mod h1:82vkLNir0ALaW14Rc399OTTjyNREgmdL2cVoIbS6XaE= -github.com/emicklei/go-restful/v3 v3.12.2 h1:DhwDP0vY3k8ZzE0RunuJy8GhNpPL6zqLkDf9B/a0/xU= -github.com/emicklei/go-restful/v3 v3.12.2/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= +github.com/emicklei/go-restful/v3 v3.13.0 h1:C4Bl2xDndpU6nJ4bc1jXd+uTmYPVUwkD6bFY/oTyCes= +github.com/emicklei/go-restful/v3 v3.13.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/emirpasic/gods v1.18.1/go.mod h1:8tpGGwCnJ5H4r6BWwaV6OrWmMoPhUl5jm/FMNAnJvWQ= github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f h1:Y/CXytFA4m6baUTXGLOoWe4PQhGxaX0KpnayAqC48p4= @@ -252,10 +252,10 @@ github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0= github.com/go-ole/go-ole v1.3.0 h1:Dt6ye7+vXGIKZ7Xtk4s6/xVdGDQynvom7xCFEdWr6uE= github.com/go-ole/go-ole v1.3.0/go.mod h1:5LS6F96DhAwUc7C+1HLexzMXY1xGRSryjyPPKW6zv78= -github.com/go-openapi/jsonpointer v0.22.1 h1:sHYI1He3b9NqJ4wXLoJDKmUmHkWy/L7rtEo92JUxBNk= -github.com/go-openapi/jsonpointer v0.22.1/go.mod h1:pQT9OsLkfz1yWoMgYFy4x3U5GY5nUlsOn1qSBH5MkCM= -github.com/go-openapi/jsonreference v0.21.3 h1:96Dn+MRPa0nYAR8DR1E03SblB5FJvh7W6krPI0Z7qMc= -github.com/go-openapi/jsonreference v0.21.3/go.mod h1:RqkUP0MrLf37HqxZxrIAtTWW4ZJIK1VzduhXYBEeGc4= +github.com/go-openapi/jsonpointer v0.22.4 h1:dZtK82WlNpVLDW2jlA1YCiVJFVqkED1MegOUy9kR5T4= +github.com/go-openapi/jsonpointer v0.22.4/go.mod h1:elX9+UgznpFhgBuaMQ7iu4lvvX1nvNsesQ3oxmYTw80= +github.com/go-openapi/jsonreference v0.21.4 h1:24qaE2y9bx/q3uRK/qN+TDwbok1NhbSmGjjySRCHtC8= +github.com/go-openapi/jsonreference v0.21.4/go.mod h1:rIENPTjDbLpzQmQWCj5kKj3ZlmEh+EFVbz3RTUh30/4= github.com/go-openapi/swag v0.25.4 h1:OyUPUFYDPDBMkqyxOTkqDYFnrhuhi9NR6QVUvIochMU= github.com/go-openapi/swag v0.25.4/go.mod h1:zNfJ9WZABGHCFg2RnY0S4IOkAcVTzJ6z2Bi+Q4i6qFQ= github.com/go-openapi/swag/cmdutils v0.25.4 h1:8rYhB5n6WawR192/BfUu2iVlxqVR9aRgGJP6WaBoW+4= @@ -309,8 +309,8 @@ github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg= github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/gnostic-models v0.7.0 h1:qwTtogB15McXDaNqTZdzPJRHvaVJlAl+HVQnLmJEJxo= -github.com/google/gnostic-models v0.7.0/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= +github.com/google/gnostic-models v0.7.1 h1:SisTfuFKJSKM5CPZkffwi6coztzzeYUhc3v4yxLWH8c= +github.com/google/gnostic-models v0.7.1/go.mod h1:whL5G0m6dmc5cPxKc5bdKdEN3UjI7OUGxBlw57miDrQ= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8= github.com/google/go-cmp v0.7.0/go.mod h1:pXiqmnSA92OHEEa9HXL2W4E7lf9JzCmGVUdgjX3N/iU= @@ -447,10 +447,10 @@ github.com/nats-io/nuid v1.0.1 h1:5iA8DT8V7q8WK2EScv2padNa/rTESc1KdnPw4TC2paw= github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= github.com/nxadm/tail v1.4.11 h1:8feyoE3OzPrcshW5/MJ4sGESc5cqmGkGCWlco4l0bqY= github.com/nxadm/tail v1.4.11/go.mod h1:OTaG3NK980DZzxbRq6lEuzgU+mug70nY11sMd4JXXHc= -github.com/onsi/ginkgo/v2 v2.27.2 h1:LzwLj0b89qtIy6SSASkzlNvX6WktqurSHwkk2ipF/Ns= -github.com/onsi/ginkgo/v2 v2.27.2/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= -github.com/onsi/gomega v1.38.2 h1:eZCjf2xjZAqe+LeWvKb5weQ+NcPwX84kqJ0cZNxok2A= -github.com/onsi/gomega v1.38.2/go.mod h1:W2MJcYxRGV63b418Ai34Ud0hEdTVXq9NW9+Sx6uXf3k= +github.com/onsi/ginkgo/v2 v2.27.5 h1:ZeVgZMx2PDMdJm/+w5fE/OyG6ILo1Y3e+QX4zSR0zTE= +github.com/onsi/ginkgo/v2 v2.27.5/go.mod h1:ArE1D/XhNXBXCBkKOLkbsb2c81dQHCRcF5zwn/ykDRo= +github.com/onsi/gomega v1.39.0 h1:y2ROC3hKFmQZJNFeGAMeHZKkjBL65mIZcvrLQBF9k6Q= +github.com/onsi/gomega v1.39.0/go.mod h1:ZCU1pkQcXDO5Sl9/VVEGlDyp+zm0m1cmeG5TOzLgdh4= github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.147.0 h1:giBpdFTrjPFKwqSmLljq1E47JKwY9/73Ll/3EZVZihQ= github.com/open-telemetry/opentelemetry-collector-contrib/pkg/sampling v0.147.0/go.mod h1:Lbs/2bXiy9UVh3M3H2mNXk396ffeMYj4jewYY2NE4BA= github.com/open-telemetry/opentelemetry-collector-contrib/processor/probabilisticsamplerprocessor v0.147.0 h1:c7rbFBMmlUdOlOycADQUkxLIV/O16jYO5A4QWb0BviA= @@ -908,12 +908,12 @@ k8s.io/component-base v0.35.0 h1:+yBrOhzri2S1BVqyVSvcM3PtPyx5GUxCK2tinZz1G94= k8s.io/component-base v0.35.0/go.mod h1:85SCX4UCa6SCFt6p3IKAPej7jSnF3L8EbfSyMZayJR0= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912 h1:Y3gxNAuB0OBLImH611+UDZcmKS3g6CthxToOb37KgwE= -k8s.io/kube-openapi v0.0.0-20250910181357-589584f1c912/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e h1:iW9ChlU0cU16w8MpVYjXk12dqQ4BPFBEgif+ap7/hqQ= +k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e/go.mod h1:kdmbQkyfwUagLfXIad1y2TdrjPFWp2Q89B3qkRwf/pQ= k8s.io/kubectl v0.34.1 h1:1qP1oqT5Xc93K+H8J7ecpBjaz511gan89KO9Vbsh/OI= k8s.io/kubectl v0.34.1/go.mod h1:JRYlhJpGPyk3dEmJ+BuBiOB9/dAvnrALJEiY/C5qa6A= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4 h1:SjGebBtkBqHFOli+05xYbK8YF1Dzkbzn+gDM4X9T4Ck= -k8s.io/utils v0.0.0-20251002143259-bc988d571ff4/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2 h1:OfgiEo21hGiwx1oJUU5MpEaeOEg6coWndBkZF/lkFuE= +k8s.io/utils v0.0.0-20251222233032-718f0e51e6d2/go.mod h1:xDxuJ0whA3d0I4mf/C4ppKHxXynQ+fxnkmQH0vTHnuk= lukechampine.com/frand v1.5.1 h1:fg0eRtdmGFIxhP5zQJzM1lFDbD6CUfu/f+7WgAZd5/w= lukechampine.com/frand v1.5.1/go.mod h1:4VstaWc2plN4Mjr10chUD46RAVGWhpkZ5Nja8+Azp0Q= pgregory.net/rapid v1.2.0 h1:keKAYRcjm+e1F0oAuU5F5+YPAWcyxNNRK2wud503Gnk=