From 375ffe5ce8daef1ea0d9dfe34af5a20548a3ffa3 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Mon, 9 Mar 2026 10:58:51 -0400 Subject: [PATCH 01/12] create DatadogPodCheck CRD --- .../v1alpha1/datadogpodcheck_types.go | 104 ++++++++ .../v1alpha1/zz_generated.deepcopy.go | 166 ++++++++++++ .../v1alpha1/zz_generated.openapi.go | 237 ++++++++++++++++++ .../v1/datadoghq.com_datadogpodchecks.yaml | 179 +++++++++++++ ...tadoghq.com_datadogpodchecks_v1alpha1.json | 157 ++++++++++++ go.sum | 1 + go.work.sum | 70 +++++- 7 files changed, 912 insertions(+), 2 deletions(-) create mode 100644 api/datadoghq/v1alpha1/datadogpodcheck_types.go create mode 100644 config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml create mode 100644 config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_types.go b/api/datadoghq/v1alpha1/datadogpodcheck_types.go new file mode 100644 index 000000000..37b5dfb57 --- /dev/null +++ b/api/datadoghq/v1alpha1/datadogpodcheck_types.go @@ -0,0 +1,104 @@ +// 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 v1alpha1 + +import ( + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. +// +k8s:openapi-gen=true +type DatadogPodCheckSpec struct { + // ContainerImage is the container image name used for autodiscovery template matching. + // The check is resolved per-pod against containers running this image + // and supports AD template variables (%%host%%, %%port%%, etc). + ContainerImage string `json:"containerImage"` + + // Selector provides additional targeting criteria to narrow which pods this + // check applies to. When specified, all conditions (containerImage + selector + // fields) must match for a pod to be targeted (AND semantics). + // +optional + Selector *PodSelector `json:"selector,omitempty"` + + // Check defines the integration check configuration. + Check CheckConfig `json:"check"` + + // Logs defines optional log collection configurations. + // +optional + // +listType=atomic + Logs []apiextensionsv1.JSON `json:"logs,omitempty"` +} + +// PodSelector defines criteria for selecting pods by labels and annotations. +// All specified fields are ANDed together. +// +k8s:openapi-gen=true +type PodSelector struct { + // MatchLabels is a map of key-value pairs that must match a pod's labels. + // +optional + MatchLabels map[string]string `json:"matchLabels,omitempty"` + + // MatchAnnotations is a map of key-value pairs that must match a pod's annotations. + // +optional + MatchAnnotations map[string]string `json:"matchAnnotations,omitempty"` +} + +// CheckConfig defines a Datadog integration check configuration. +// +k8s:openapi-gen=true +type CheckConfig struct { + // Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + Name string `json:"name"` + + // InitConfig is the init_config section passed to the integration check. + // +optional + InitConfig *apiextensionsv1.JSON `json:"initConfig,omitempty"` + + // Instances is the list of check instance configurations. + // At least one instance is required. + // +kubebuilder:validation:MinItems=1 + // +listType=atomic + Instances []apiextensionsv1.JSON `json:"instances"` +} + +// DatadogPodCheckStatus defines the observed state of a DatadogPodCheck. +// +k8s:openapi-gen=true +type DatadogPodCheckStatus struct { + // Conditions represents the latest available observations of the state of a DatadogPodCheck. + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty"` +} + +// DatadogPodCheck allows a user to define Datadog integration checks that are +// scheduled against pods via the autodiscovery system, without requiring pod +// annotation changes or agent restarts. +// +kubebuilder:object:root=true +// +kubebuilder:subresource:status +// +kubebuilder:resource:path=datadogpodchecks,scope=Namespaced,shortName=ddpc +// +kubebuilder:printcolumn:name="check",type="string",JSONPath=".spec.check.name" +// +kubebuilder:printcolumn:name="image",type="string",JSONPath=".spec.containerImage" +// +kubebuilder:printcolumn:name="age",type="date",JSONPath=".metadata.creationTimestamp" +// +k8s:openapi-gen=true +// +genclient +type DatadogPodCheck struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec DatadogPodCheckSpec `json:"spec,omitempty"` + Status DatadogPodCheckStatus `json:"status,omitempty"` +} + +// DatadogPodCheckList contains a list of DatadogPodCheck resources. +// +kubebuilder:object:root=true +type DatadogPodCheckList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []DatadogPodCheck `json:"items"` +} + +func init() { + SchemeBuilder.Register(&DatadogPodCheck{}, &DatadogPodCheckList{}) +} diff --git a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go index bd1f58191..e5c89b1b0 100644 --- a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go @@ -14,10 +14,38 @@ import ( "github.com/DataDog/datadog-operator/api/datadoghq/common" "github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1" corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CheckConfig) DeepCopyInto(out *CheckConfig) { + *out = *in + if in.InitConfig != nil { + in, out := &in.InitConfig, &out.InitConfig + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } + if in.Instances != nil { + in, out := &in.Instances, &out.Instances + *out = make([]apiextensionsv1.JSON, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckConfig. +func (in *CheckConfig) DeepCopy() *CheckConfig { + if in == nil { + return nil + } + out := new(CheckConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CreateStrategy) DeepCopyInto(out *CreateStrategy) { *out = *in @@ -1309,6 +1337,115 @@ func (in *DatadogPodAutoscalerSpec) DeepCopy() *DatadogPodAutoscalerSpec { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogPodCheck) DeepCopyInto(out *DatadogPodCheck) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheck. +func (in *DatadogPodCheck) DeepCopy() *DatadogPodCheck { + if in == nil { + return nil + } + out := new(DatadogPodCheck) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DatadogPodCheck) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogPodCheckList) DeepCopyInto(out *DatadogPodCheckList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DatadogPodCheck, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheckList. +func (in *DatadogPodCheckList) DeepCopy() *DatadogPodCheckList { + if in == nil { + return nil + } + out := new(DatadogPodCheckList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DatadogPodCheckList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogPodCheckSpec) DeepCopyInto(out *DatadogPodCheckSpec) { + *out = *in + if in.Selector != nil { + in, out := &in.Selector, &out.Selector + *out = new(PodSelector) + (*in).DeepCopyInto(*out) + } + in.Check.DeepCopyInto(&out.Check) + if in.Logs != nil { + in, out := &in.Logs, &out.Logs + *out = make([]apiextensionsv1.JSON, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheckSpec. +func (in *DatadogPodCheckSpec) DeepCopy() *DatadogPodCheckSpec { + if in == nil { + return nil + } + out := new(DatadogPodCheckSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogPodCheckStatus) DeepCopyInto(out *DatadogPodCheckStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheckStatus. +func (in *DatadogPodCheckStatus) DeepCopy() *DatadogPodCheckStatus { + if in == nil { + return nil + } + out := new(DatadogPodCheckStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DatadogSLO) DeepCopyInto(out *DatadogSLO) { *out = *in @@ -1484,6 +1621,35 @@ func (in *DatadogSLOStatus) DeepCopy() *DatadogSLOStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PodSelector) DeepCopyInto(out *PodSelector) { + *out = *in + if in.MatchLabels != nil { + in, out := &in.MatchLabels, &out.MatchLabels + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.MatchAnnotations != nil { + in, out := &in.MatchAnnotations, &out.MatchAnnotations + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PodSelector. +func (in *PodSelector) DeepCopy() *PodSelector { + if in == nil { + return nil + } + out := new(PodSelector) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ProfileAffinity) DeepCopyInto(out *ProfileAffinity) { *out = *in diff --git a/api/datadoghq/v1alpha1/zz_generated.openapi.go b/api/datadoghq/v1alpha1/zz_generated.openapi.go index 768486a6e..3f2260bbf 100644 --- a/api/datadoghq/v1alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v1alpha1/zz_generated.openapi.go @@ -17,6 +17,7 @@ import ( func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenAPIDefinition { return map[string]common.OpenAPIDefinition{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig": schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CreateStrategy": schema_datadog_operator_api_datadoghq_v1alpha1_CreateStrategy(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DashboardTemplateVariable": schema_datadog_operator_api_datadoghq_v1alpha1_DashboardTemplateVariable(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DashboardTemplateVariablePreset": schema_datadog_operator_api_datadoghq_v1alpha1_DashboardTemplateVariablePreset(ref), @@ -47,11 +48,63 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitorSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorSpec(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitorStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorStatus(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitorTriggeredState": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorTriggeredState(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheck": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheck(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckStatus(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLO": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLO(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOControllerOptions": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOControllerOptions(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOQuery": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOQuery(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOSpec(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOStatus(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector": schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref), + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "CheckConfig defines a Datadog integration check configuration.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "initConfig": { + SchemaProps: spec.SchemaProps{ + Description: "InitConfig is the init_config section passed to the integration check.", + Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), + }, + }, + "instances": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Instances is the list of check instance configurations. At least one instance is required.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), + }, + }, + }, + }, + }, + }, + Required: []string{"name", "instances"}, + }, + }, + Dependencies: []string{ + "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"}, } } @@ -1818,6 +1871,145 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorTriggeredState } } +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheck(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogPodCheck allows a user to define Datadog integration checks that are scheduled against pods via the autodiscovery system, without requiring pod annotation changes or agent restarts.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckSpec", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "containerImage": { + SchemaProps: spec.SchemaProps{ + Description: "ContainerImage is the container image name used for autodiscovery template matching. The check is resolved per-pod against containers running this image and supports AD template variables (%%host%%, %%port%%, etc).", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "selector": { + SchemaProps: spec.SchemaProps{ + Description: "Selector provides additional targeting criteria to narrow which pods this check applies to. When specified, all conditions (containerImage + selector fields) must match for a pod to be targeted (AND semantics).", + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), + }, + }, + "check": { + SchemaProps: spec.SchemaProps{ + Description: "Check defines the integration check configuration.", + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), + }, + }, + "logs": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Logs defines optional log collection configurations.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), + }, + }, + }, + }, + }, + }, + Required: []string{"containerImage", "check"}, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"}, + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogPodCheckStatus defines the observed state of a DatadogPodCheck.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "type", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Conditions represents the latest available observations of the state of a DatadogPodCheck.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, + } +} + func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLO(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2120,3 +2312,48 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOStatus(ref common. "k8s.io/apimachinery/pkg/apis/meta/v1.Condition", "k8s.io/apimachinery/pkg/apis/meta/v1.Time"}, } } + +func schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PodSelector defines criteria for selecting pods by labels and annotations. All specified fields are ANDed together.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "matchLabels": { + SchemaProps: spec.SchemaProps{ + Description: "MatchLabels is a map of key-value pairs that must match a pod's labels.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "matchAnnotations": { + SchemaProps: spec.SchemaProps{ + Description: "MatchAnnotations is a map of key-value pairs that must match a pod's annotations.", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + }, + }, + }, + } +} diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml new file mode 100644 index 000000000..cbc82a8b9 --- /dev/null +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml @@ -0,0 +1,179 @@ +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.17.3 + name: datadogpodchecks.datadoghq.com +spec: + group: datadoghq.com + names: + kind: DatadogPodCheck + listKind: DatadogPodCheckList + plural: datadogpodchecks + shortNames: + - ddpc + singular: datadogpodcheck + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.check.name + name: check + type: string + - jsonPath: .spec.containerImage + name: image + type: string + - jsonPath: .metadata.creationTimestamp + name: age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + description: |- + DatadogPodCheck allows a user to define Datadog integration checks that are + scheduled against pods via the autodiscovery system, without requiring pod + annotation changes or agent restarts. + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. + properties: + check: + description: Check defines the integration check configuration. + properties: + initConfig: + description: InitConfig is the init_config section passed to the integration check. + x-kubernetes-preserve-unknown-fields: true + instances: + description: |- + Instances is the list of check instance configurations. + At least one instance is required. + items: + x-kubernetes-preserve-unknown-fields: true + minItems: 1 + type: array + x-kubernetes-list-type: atomic + name: + description: Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + type: string + required: + - instances + - name + type: object + containerImage: + description: |- + ContainerImage is the container image name used for autodiscovery template matching. + The check is resolved per-pod against containers running this image + and supports AD template variables (%%host%%, %%port%%, etc). + type: string + logs: + description: Logs defines optional log collection configurations. + items: + x-kubernetes-preserve-unknown-fields: true + type: array + x-kubernetes-list-type: atomic + selector: + description: |- + Selector provides additional targeting criteria to narrow which pods this + check applies to. When specified, all conditions (containerImage + selector + fields) must match for a pod to be targeted (AND semantics). + properties: + matchAnnotations: + additionalProperties: + type: string + description: MatchAnnotations is a map of key-value pairs that must match a pod's annotations. + type: object + matchLabels: + additionalProperties: + type: string + description: MatchLabels is a map of key-value pairs that must match a pod's labels. + type: object + type: object + required: + - check + - containerImage + type: object + status: + description: DatadogPodCheckStatus defines the observed state of a DatadogPodCheck. + properties: + conditions: + description: Conditions represents the latest available observations of the state of a DatadogPodCheck. + items: + description: Condition contains details for one aspect of the current state of this API Resource. + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: type of condition in CamelCase or in foo.example.com/CamelCase. + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json new file mode 100644 index 000000000..7e5695231 --- /dev/null +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json @@ -0,0 +1,157 @@ +{ + "additionalProperties": false, + "description": "DatadogPodCheck allows a user to define Datadog integration checks that are\nscheduled against pods via the autodiscovery system, without requiring pod\nannotation changes or agent restarts.", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents.\nServers may infer this from the endpoint the client submits requests to.\nCannot be updated.\nIn CamelCase.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "type": "object" + }, + "spec": { + "additionalProperties": false, + "description": "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", + "properties": { + "check": { + "additionalProperties": false, + "description": "Check defines the integration check configuration.", + "properties": { + "initConfig": { + "description": "InitConfig is the init_config section passed to the integration check.", + "x-kubernetes-preserve-unknown-fields": true + }, + "instances": { + "description": "Instances is the list of check instance configurations.\nAt least one instance is required.", + "items": { + "x-kubernetes-preserve-unknown-fields": true + }, + "minItems": 1, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "name": { + "description": "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").", + "type": "string" + } + }, + "required": [ + "instances", + "name" + ], + "type": "object" + }, + "containerImage": { + "description": "ContainerImage is the container image name used for autodiscovery template matching.\nThe check is resolved per-pod against containers running this image\nand supports AD template variables (%%host%%, %%port%%, etc).", + "type": "string" + }, + "logs": { + "description": "Logs defines optional log collection configurations.", + "items": { + "x-kubernetes-preserve-unknown-fields": true + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "selector": { + "additionalProperties": false, + "description": "Selector provides additional targeting criteria to narrow which pods this\ncheck applies to. When specified, all conditions (containerImage + selector\nfields) must match for a pod to be targeted (AND semantics).", + "properties": { + "matchAnnotations": { + "additionalProperties": { + "type": "string" + }, + "description": "MatchAnnotations is a map of key-value pairs that must match a pod's annotations.", + "type": "object" + }, + "matchLabels": { + "additionalProperties": { + "type": "string" + }, + "description": "MatchLabels is a map of key-value pairs that must match a pod's labels.", + "type": "object" + } + }, + "type": "object" + } + }, + "required": [ + "check", + "containerImage" + ], + "type": "object" + }, + "status": { + "additionalProperties": false, + "description": "DatadogPodCheckStatus defines the observed state of a DatadogPodCheck.", + "properties": { + "conditions": { + "description": "Conditions represents the latest available observations of the state of a DatadogPodCheck.", + "items": { + "additionalProperties": false, + "description": "Condition contains details for one aspect of the current state of this API Resource.", + "properties": { + "lastTransitionTime": { + "description": "lastTransitionTime is the last time the condition transitioned from one status to another.\nThis should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.", + "format": "date-time", + "type": "string" + }, + "message": { + "description": "message is a human readable message indicating details about the transition.\nThis may be an empty string.", + "maxLength": 32768, + "type": "string" + }, + "observedGeneration": { + "description": "observedGeneration represents the .metadata.generation that the condition was set based upon.\nFor instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date\nwith respect to the current state of the instance.", + "format": "int64", + "minimum": 0, + "type": "integer" + }, + "reason": { + "description": "reason contains a programmatic identifier indicating the reason for the condition's last transition.\nProducers of specific condition types may define expected values and meanings for this field,\nand whether the values are considered a guaranteed API.\nThe value should be a CamelCase string.\nThis field may not be empty.", + "maxLength": 1024, + "minLength": 1, + "pattern": "^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$", + "type": "string" + }, + "status": { + "description": "status of the condition, one of True, False, Unknown.", + "enum": [ + "True", + "False", + "Unknown" + ], + "type": "string" + }, + "type": { + "description": "type of condition in CamelCase or in foo.example.com/CamelCase.", + "maxLength": 316, + "pattern": "^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$", + "type": "string" + } + }, + "required": [ + "lastTransitionTime", + "message", + "reason", + "status", + "type" + ], + "type": "object" + }, + "type": "array", + "x-kubernetes-list-map-keys": [ + "type" + ], + "x-kubernetes-list-type": "map" + } + }, + "type": "object" + } + }, + "type": "object" +} \ No newline at end of file diff --git a/go.sum b/go.sum index 6cc66029d..4abc748e1 100644 --- a/go.sum +++ b/go.sum @@ -1267,6 +1267,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= +go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/contrib/bridges/prometheus v0.57.0 h1:UW0+QyeyBVhn+COBec3nGhfnFe5lwB0ic1JBVjzhk0w= go.opentelemetry.io/contrib/bridges/prometheus v0.57.0/go.mod h1:ppciCHRLsyCio54qbzQv0E4Jyth/fLWDTJYfvWpcSVk= go.opentelemetry.io/contrib/exporters/autoexport v0.57.0 h1:jmTVJ86dP60C01K3slFQa2NQ/Aoi7zA+wy7vMOKD9H4= diff --git a/go.work.sum b/go.work.sum index b01816486..a0aa3d28f 100644 --- a/go.work.sum +++ b/go.work.sum @@ -210,6 +210,7 @@ cloud.google.com/go/spanner v1.67.0 h1:h8xfobxh5lQu4qJVMPH+wSiyU+ZM6ZTxRNqGeu9iI cloud.google.com/go/spanner v1.67.0/go.mod h1:Um+TNmxfcCHqNCKid4rmAMvoe/Iu1vdz6UfxJ9GPxRQ= cloud.google.com/go/speech v1.25.0 h1:q/ZPuG5G//DHm9hBehaP5c/wuD2qP77OpiPQrE7hEbg= cloud.google.com/go/speech v1.25.0/go.mod h1:2IUTYClcJhqPgee5Ko+qJqq29/bglVizgIap0c5MvYs= +cloud.google.com/go/storage v1.35.1 h1:B59ahL//eDfx2IIKFBeT5Atm9wnNmj3+8xG/W4WB//w= cloud.google.com/go/storage v1.35.1/go.mod h1:M6M/3V/D3KpzMTJyPOR/HU6n2Si5QdaXYEsng2xgOs8= cloud.google.com/go/storage v1.39.1 h1:MvraqHKhogCOTXTlct/9C3K3+Uy2jBmFYb3/Sp6dVtY= cloud.google.com/go/storage v1.39.1/go.mod h1:xK6xZmxZmo+fyP7+DEF6FhNc24/JAe95OLyOHCXFH1o= @@ -308,6 +309,7 @@ github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0 h1:oVLqHXhnYtUwM89y9T1 github.com/GoogleCloudPlatform/grpc-gcp-go/grpcgcp v1.5.0/go.mod h1:dppbR7CwXD4pgtV9t3wD1812RaLDcBjtblcDF5f1vI0= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2 h1:cZpsGsWTIFKymTA0je7IIvi1O7Es7apb9CF3EQlOcfE= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.24.2/go.mod h1:itPGVDKf9cC/ov4MdvJ2QZ0khw4bfoo9jzwTJlaxy2k= +github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0 h1:f2Qw/Ehhimh5uO1fayV0QIW7DShEQqhtUfhYc+cBPlw= github.com/GoogleCloudPlatform/opentelemetry-operations-go/detectors/gcp v1.26.0/go.mod h1:2bIszWvQRlJVmJLiuLhukLImRjKPcYdzzsx6darK02A= github.com/IBM/sarama v1.40.0 h1:QTVmX+gMKye52mT5x+Ve/Bod2D0Gy7ylE2Wslv+RHtc= github.com/IBM/sarama v1.40.0/go.mod h1:6pBloAs1WanL/vsq5qFTyTGulJUntZHhMLOUYEIs9mg= @@ -343,6 +345,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751 h1:JYp7IbQjafo github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137 h1:s6gZFSlWYmbqAuRjVTiNNhvNRfY2Wxp9nhfyel4rklc= github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= +github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b h1:mimo19zliBX/vSQ6PWWSL9lK8qwHozUj03+zLoEB8O0= github.com/alecthomas/units v0.0.0-20240927000941-0f3dac36c52b/go.mod h1:fvzegU4vN3H1qMT+8wDmzjAcDONcgo2/SZ/TyfdUOFs= github.com/alexflint/go-filemutex v0.0.0-20171022225611-72bdc8eae2ae h1:AMzIhMUqU3jMrZiTuW0zkYeKlKDAFD+DG20IoO421/Y= github.com/andybalholm/cascadia v1.3.3 h1:AG2YHrzJIm4BZ19iwJ/DAua6Btl3IwJX+VI4kktS1LM= @@ -363,13 +366,16 @@ github.com/aws/amazon-vpc-resource-controller-k8s v1.6.3 h1:B4o15iZP8CQoyDjoNAoQ github.com/aws/amazon-vpc-resource-controller-k8s v1.6.3/go.mod h1:k4zcf2Dz/Mvrgo8NVzAEWP5HK4USqbJTD93pVVDxvc0= github.com/aws/aws-lambda-go v1.13.3 h1:SuCy7H3NLyp+1Mrfp+m80jcbi9KYWAs9/BXwppwRDzY= github.com/aws/aws-lambda-go v1.13.3/go.mod h1:4UKl9IzQMoD+QF79YdCuzCwp8VbmG4VAQwij/eHl5CU= +github.com/aws/aws-sdk-go v1.44.327 h1:ZS8oO4+7MOBLhkdwIhgtVeDzCeWOlTfKJS7EgggbIEY= github.com/aws/aws-sdk-go v1.44.327/go.mod h1:aVsgQcEevwlmQ7qHE9I3h+dtQgpqhFB+i8Phjh7fkwI= github.com/aws/aws-sdk-go-v2 v1.36.3/go.mod h1:LLXuLpgzEbD766Z5ECcRmi8AzSwfZItDtmABVkRLGzg= +github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13 h1:OPLEkmhXf6xFPiz0bLeDArZIDx1NNS4oJyG4nv3Gct0= github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.4.13/go.mod h1:gpAbvyDGQFozTEmlTFO8XcQKHzubdq0LzRyJpG6MiXM= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.15 h1:7Zwtt/lP3KNRkeZre7soMELMGNoBrutx8nobg1jKWmo= github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.16.15/go.mod h1:436h2adoHb57yd+8W+gYPrrA9U/R/SuAuOO42Ushzhw= github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.34/go.mod h1:p4VfIceZokChbA9FzMbRGz5OV+lekcVtHlPKEO0gSZY= github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.34/go.mod h1:dFZsC0BLo346mvKQLWmoJxT+Sjp+qcVR1tRVHQGOH9Q= +github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.3 h1:uHhWcrNBgpm9gi3o8NSQcsAqha/U9OFYzi2k4+0UVz8= github.com/aws/aws-sdk-go-v2/internal/v4a v1.1.3/go.mod h1:jYLMm3Dh0wbeV3lxth5ryks/O2M/omVXWyYm3YcEVqQ= github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.4 h1:x3V1JRHq7q9RUbDpaeNpLH7QoipGpCo3fdnMMuSeABU= github.com/aws/aws-sdk-go-v2/service/dynamodb v1.21.4/go.mod h1:aryF4jxgjhbqpdhj8QybUZI3xYrX8MQIKm4WbOv8Whg= @@ -378,15 +384,18 @@ github.com/aws/aws-sdk-go-v2/service/eventbridge v1.20.4/go.mod h1:XlbY5AGZhlipC github.com/aws/aws-sdk-go-v2/service/fis v1.33.0 h1:j3Tmcms3EivmY+KdqAnniLZWX72dTdzZ3HtCk/iNrOk= github.com/aws/aws-sdk-go-v2/service/fis v1.33.0/go.mod h1:2kPhevhXIbi6WFuc+ss9krg2bNAuRqzBGZQX+7TMD/o= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.3/go.mod h1:0yKJC/kb8sAnmlYa6Zs3QVYqaC8ug2AbnNChv5Ox3uA= +github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.35 h1:oCUrlTzh9GwhlYdyDGNAS6UgqJRzJp5rKoYCJWqLyZI= github.com/aws/aws-sdk-go-v2/service/internal/checksum v1.1.35/go.mod h1:YVHrksq36j0sbXCT6rSuQafpfYkMYqy0QTk7JTCTBIU= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.34 h1:JlxVMFDHivlhNOIxd2O/9z4O0wC2zIC4lRB71lejVHU= github.com/aws/aws-sdk-go-v2/service/internal/endpoint-discovery v1.7.34/go.mod h1:CDPcT6pljRaqz1yLsOgPUvOPOczFvXuJxOKzDzAbF0c= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.15/go.mod h1:SwFBy2vjtA0vZbjjaFtfN045boopadnoVPhu4Fv66vY= +github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.3 h1:rPDAISw3FjEhrJoaxmQjuD+GgBfv2p3AVhmAcnyqq3k= github.com/aws/aws-sdk-go-v2/service/internal/s3shared v1.15.3/go.mod h1:TXBww3ANB+QRj+/dUoYDvI8d/u4F4WzTxD4mxtDoxrg= github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.4 h1:UohaQds+Puk9BEbvncXkZduIGYImxohbFpVmSoymXck= github.com/aws/aws-sdk-go-v2/service/kinesis v1.18.4/go.mod h1:HnjgmL8TNmYtGcrA3N6EeCnDvlX6CteCdUbZ1wV8QWQ= github.com/aws/aws-sdk-go-v2/service/kms v1.30.1 h1:SBn4I0fJXF9FYOVRSVMWuhvEKoAHDikjGpS3wlmw5DE= github.com/aws/aws-sdk-go-v2/service/kms v1.30.1/go.mod h1:2snWQJQUKsbN66vAawJuOGX7dr37pfOq9hb0tZDGIqQ= +github.com/aws/aws-sdk-go-v2/service/s3 v1.32.0 h1:NAc8WQsVQ3+kz3rU619mlz8NcbpZI6FVJHQfH33QK0g= github.com/aws/aws-sdk-go-v2/service/s3 v1.32.0/go.mod h1:aSl9/LJltSz1cVusiR/Mu8tvI4Sv/5w/WWrJmmkNii0= github.com/aws/aws-sdk-go-v2/service/sfn v1.19.4 h1:yIyFY2kbCOoHvuivf9minqnP2RLYJgmvQRYxakIb2oI= github.com/aws/aws-sdk-go-v2/service/sfn v1.19.4/go.mod h1:uWCH4ATwNrkRO40j8Dmy7u/Y1/BVWgCM+YjBNYZeOro= @@ -425,6 +434,7 @@ github.com/ccojocar/zxcvbn-go v1.0.1 h1:+sxrANSCj6CdadkcMnvde/GWU1vZiiXRbqYSCalV github.com/ccojocar/zxcvbn-go v1.0.1/go.mod h1:g1qkXtUSvHP8lhHp5GrSmTz6uWALGRMQdw6Qnz/hi60= github.com/cenkalti/backoff/v3 v3.2.2 h1:cfUAAO3yvKMYKPrvhDuHSwQnhZNk/RMHKdZqKTxfm6M= github.com/cenkalti/backoff/v3 v3.2.2/go.mod h1:cIeZDE3IrqwwJl6VUwCN6trj1oXrTS4rc0ij+ULvLYs= +github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk= github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= @@ -458,6 +468,7 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f h1:WBZRG4aNOuI15bLRrC github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403 h1:cqQfy1jclcSy/FwLjemeg3SR1yaINm74aQyupQ0Bl8M= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78 h1:QVw89YDxXxEe+l8gU8ETbOasdwEV+avkR75ZzsVV9WI= github.com/cncf/xds/go v0.0.0-20240905190251-b4127c9b8d78/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= +github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42 h1:Om6kYQYDUk5wWbT0t0q6pvyM49i9XZAv9dDrkDA7gjk= github.com/cncf/xds/go v0.0.0-20250121191232-2f005788dc42/go.mod h1:W+zGtBO5Y1IgJhy4+A9GOqVhqLpfZi+vwmdNXUehLA8= github.com/cockroachdb/datadriven v0.0.0-20190809214429-80d97fb3cbaa h1:OaNxuTZr7kxeODyLWsRMC+OD03aFUH+mW6r2d+MWa5Y= github.com/cockroachdb/datadriven v1.0.2 h1:H9MtNqVoVhvd9nCBwOyDjUEdZCREqbIdCJD93PBm/jA= @@ -477,6 +488,7 @@ github.com/containerd/cgroups v1.1.0 h1:v8rEWFl6EoqHB+swVNjVoCJE8o3jX7e8nqBGPLaD github.com/containerd/cgroups v1.1.0/go.mod h1:6ppBcbh/NOOUU+dMKrykgaBnK9lCIBxHqJDGwsa1mIw= github.com/containerd/cgroups/v3 v3.0.2 h1:f5WFqIVSgo5IZmtTT3qVBo6TzI1ON6sycSBKkymb9L0= github.com/containerd/cgroups/v3 v3.0.2/go.mod h1:JUgITrzdFqp42uI2ryGA+ge0ap/nxzYgkGmIcetmErE= +github.com/containerd/console v1.0.3 h1:lIr7SlA5PxZyMV30bDW0MGbiOPXwc63yRuCP0ARubLw= github.com/containerd/console v1.0.3/go.mod h1:7LqA/THxQ86k76b8c/EMSiaJ3h1eZkMkXar0TQ1gf3U= github.com/containerd/console v1.0.4 h1:F2g4+oChYvBTsASRTz8NP6iIAi97J3TtSAsLbIFn4ro= github.com/containerd/console v1.0.4/go.mod h1:YynlIjWYF8myEu6sdkwKIvGQq+cOckRm6So2avqoYAk= @@ -561,8 +573,12 @@ github.com/dimchansky/utfbom v1.1.1/go.mod h1:SxdoEBH5qIqFocHMyGOXVAybYJdr71b1Q/ github.com/dimfeld/httptreemux/v5 v5.5.0 h1:p8jkiMrCuZ0CmhwYLcbNbl7DDo21fozhKHQ2PccwOFQ= github.com/dimfeld/httptreemux/v5 v5.5.0/go.mod h1:QeEylH57C0v3VO0tkKraVz9oD3Uu93CKPnTLbsidvSw= github.com/dnaeon/go-vcr v1.0.1 h1:r8L/HqC0Hje5AXMu1ooW8oyQyOFv4GxqpL0nRP7SLLY= +github.com/docker/docker v28.0.1+incompatible h1:FCHjSRdXhNRFjlHMTv4jUNlIBbTeRjrWfeFuJp7jpo0= github.com/docker/docker v28.0.1+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/docker v28.5.2+incompatible h1:DBX0Y0zAjZbSrm1uzOkdr1onVghKaftjlSWt4AFexzM= github.com/docker/docker v28.5.2+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk= +github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ= +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/docker/libtrust v0.0.0-20150114040149-fa567046d9b1 h1:ZClxb8laGDf5arXfYcAtECDFgAgHklGI8CxgjHnXKJ4= github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96 h1:cenwrSVm+Z7QLSV/BsnenAOcDXdX4cMv4wP0B/5QbPg= @@ -583,16 +599,21 @@ github.com/elastic/go-elasticsearch/v7 v7.17.1 h1:49mHcHx7lpCL8cW1aioEwSEVKQF3s+ github.com/elastic/go-elasticsearch/v7 v7.17.1/go.mod h1:OJ4wdbtDNk5g503kvlHLyErCgQwwzmDtaFC4XyOxXA4= github.com/elastic/go-elasticsearch/v8 v8.4.0 h1:Rn1mcqaIMcNT43hnx2H62cIFZ+B6mjWtzj85BDKrvCE= github.com/elastic/go-elasticsearch/v8 v8.4.0/go.mod h1:yY52i2Vj0unLz+N3Nwx1gM5LXwoj3h2dgptNGBYkMLA= +github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/emicklei/go-restful v2.16.0+incompatible h1:rgqiKNjTnFQA6kkhFe16D8epTksy9HQ1MyrbDXSdYhM= github.com/emicklei/go-restful v2.16.0+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/emicklei/go-restful/v3 v3.11.0/go.mod h1:6n3XBCmQQb25CM2LCACGz8ukIrRry+4bhvbpWn3mrbc= github.com/envoyproxy/go-control-plane v0.13.1 h1:vPfJZCkob6yTMEgS+0TwfTUfbHjfy/6vOJ8hUWX/uXE= github.com/envoyproxy/go-control-plane v0.13.1/go.mod h1:X45hY0mufo6Fd0KW3rqsGvQMw58jvjymeCzBU3mWyHw= +github.com/envoyproxy/go-control-plane v0.13.4 h1:zEqyPVyku6IvWCFwux4x9RxkLOMUL+1vC9xUFv5l2/M= github.com/envoyproxy/go-control-plane v0.13.4/go.mod h1:kDfuBlDVsSj2MjrLEtRWtHlsWIFcGyB2RMO44Dc5GZA= +github.com/envoyproxy/go-control-plane/envoy v1.32.4 h1:jb83lalDRZSpPWW2Z7Mck/8kXZ5CQAFYVjQcdVIr83A= github.com/envoyproxy/go-control-plane/envoy v1.32.4/go.mod h1:Gzjc5k8JcJswLjAx1Zm+wSYE20UrLtt7JZMWiWQXQEw= +github.com/envoyproxy/go-control-plane/ratelimit v0.1.0 h1:/G9QYbddjL25KvtKTv3an9lx6VBE2cnb8wp1vEGNYGI= github.com/envoyproxy/go-control-plane/ratelimit v0.1.0/go.mod h1:Wk+tMFAFbCXaJPzVVHnPgRKdUdwW/KdbRt94AzgRee4= github.com/envoyproxy/protoc-gen-validate v1.1.0 h1:tntQDh69XqOCOZsDz0lVJQez/2L6Uu2PdjCQwWCJ3bM= github.com/envoyproxy/protoc-gen-validate v1.1.0/go.mod h1:sXRDRVmzEbkM7CVcM06s9shE/m23dg3wzjl0UWqJ2q4= +github.com/envoyproxy/protoc-gen-validate v1.2.1 h1:DEo3O99U8j4hBFwbJfrz9VtgcDfUKS7KJ7spH3d86P8= github.com/envoyproxy/protoc-gen-validate v1.2.1/go.mod h1:d/C80l/jxXLdfEIhX1W2TmLfsJ31lvEjwamM4DxlWXU= github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8= github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc= @@ -610,8 +631,11 @@ github.com/gin-contrib/sse v0.1.0 h1:Y/yl/+YNO8GZSjAhjMsSuLt29uWRFHdHYUb5lYOV9qE github.com/gin-contrib/sse v0.1.0/go.mod h1:RHrZQHXnP2xjPF+u1gW/2HnVO7nvIa9PG3Gm+fLHvGI= github.com/gin-gonic/gin v1.9.1 h1:4idEAncQnU5cB7BeOkPtxjfCSye0AAm1R0RVIqJ+Jmg= github.com/gin-gonic/gin v1.9.1/go.mod h1:hPrL7YrpYKXt5YId3A/Tnip5kqbEAP+KLuI3SUcPTeU= +github.com/gkampitakis/ciinfo v0.3.2 h1:JcuOPk8ZU7nZQjdUhctuhQofk7BGHuIy0c9Ez8BNhXs= github.com/gkampitakis/ciinfo v0.3.2/go.mod h1:1NIwaOcFChN4fa/B0hEBdAb6npDlFL8Bwx4dfRLRqAo= +github.com/gkampitakis/go-diff v1.3.2 h1:Qyn0J9XJSDTgnsgHRdz9Zp24RaJeKMUHg2+PDZZdC4M= github.com/gkampitakis/go-diff v1.3.2/go.mod h1:LLgOrpqleQe26cte8s36HTWcTmMEur6OPYerdAAS9tk= +github.com/gkampitakis/go-snaps v0.5.15 h1:amyJrvM1D33cPHwVrjo9jQxX8g/7E2wYdZ+01KS3zGE= github.com/gkampitakis/go-snaps v0.5.15/go.mod h1:HNpx/9GoKisdhw9AFOBT1N7DBs9DiHo/hGheFGBZ+mc= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8 h1:DujepqpGd1hyOd7aW59XpK7Qymp8iy83xq74fLr21is= github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q= @@ -626,6 +650,7 @@ github.com/go-jose/go-jose/v3 v3.0.3 h1:fFKWeig/irsp7XD2zBxvnmA/XaRWp5V3CBsZXJF7 github.com/go-jose/go-jose/v3 v3.0.3/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= github.com/go-jose/go-jose/v3 v3.0.4 h1:Wp5HA7bLQcKnf6YYao/4kpRpVMp/yf6+pJKV8WFSaNY= github.com/go-jose/go-jose/v3 v3.0.4/go.mod h1:5b+7YgP7ZICgJDBdfjZaIt+H/9L9T/YQrVfLAMboGkQ= +github.com/go-jose/go-jose/v4 v4.0.4 h1:VsjPI33J0SB9vQM6PLmNjoHqMQNGPiZ0rHL7Ni7Q6/E= github.com/go-jose/go-jose/v4 v4.0.4/go.mod h1:NKb5HO1EZccyMpiZNbdUw/14tiXNyUJh188dfnMCAfc= github.com/go-kit/kit v0.9.0 h1:wDJmvq38kDhkVxi50ni9ykkdUr1PKgqKOoi01fa0Mdk= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= @@ -662,6 +687,7 @@ github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/goccy/go-yaml v1.18.0 h1:8W7wMFS12Pcas7KU+VVkaiCng+kG8QiFeFwzFb+rwuw= github.com/goccy/go-yaml v1.18.0/go.mod h1:XBurs7gK8ATbW4ZPGKgcbrY1Br56PdM69F7LkFRi1kA= github.com/gocql/gocql v1.6.0 h1:IdFdOTbnpbd0pDhl4REKQDM+Q0SzKXQ1Yh+YZZ8T/qU= github.com/gocql/gocql v1.6.0/go.mod h1:3gM2c4D3AnkISwBxGnMMsS8Oy4y2lhbPRsH4xnJrHG8= @@ -686,13 +712,17 @@ github.com/golang-jwt/jwt/v4 v4.5.2 h1:YtQM7lnr8iZ+j5q71MGKkNw9Mn7AjHM68uc9g5fXe github.com/golang-jwt/jwt/v4 v4.5.2/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0= github.com/golang-jwt/jwt/v5 v5.2.1 h1:OuVbFODueb089Lh128TAcimifWaLhJwVflnrgM17wHk= github.com/golang-jwt/jwt/v5 v5.2.1/go.mod h1:pqrtFR0X4osieyHYxtmOUWsAWrfe1Q5UVIyoH402zdk= +github.com/golang-jwt/jwt/v5 v5.3.0 h1:pv4AsKCKKZuqlgs5sUmn4x8UlGa0kEVt/puTpKx9vvo= github.com/golang-jwt/jwt/v5 v5.3.0/go.mod h1:fxCRLWMO43lRc8nhHWY6LGqRcf+1gQWArsqaEUEa5bE= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9 h1:au07oEsX2xN0ktxqI+Sida1w446QrXBRJ0nee3SNZlA= github.com/golang-sql/civil v0.0.0-20220223132316-b832511892a9/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0= github.com/golang-sql/sqlexp v0.1.0 h1:ZCD6MBpcuOVfGVqsEmY5/4FtYiKz6tSyUv9LPEDei6A= github.com/golang-sql/sqlexp v0.1.0/go.mod h1:J4ad9Vo8ZCWQ2GMrC4UCQy1JpCbwU9m3EOqtpKwwwHI= +github.com/golang/glog v1.2.2 h1:1+mZ9upx1Dh6FmUTFR1naJ77miKiXgALjWOZ3NVFPmY= github.com/golang/glog v1.2.2/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= +github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.7.0-rc.1 h1:YojYx61/OLFsiv6Rw1Z96LpldJIy31o+UHmwAUMJ6/U= github.com/golang/mock v1.7.0-rc.1/go.mod h1:s42URUywIqd+OcERslBJvOjepvNymP31m3q8d/GkuRs= @@ -736,6 +766,7 @@ github.com/googleapis/enterprise-certificate-proxy v0.3.2 h1:Vie5ybvEvT75RniqhfF github.com/googleapis/enterprise-certificate-proxy v0.3.2/go.mod h1:VLSiSSBs/ksPL8kq3OBOQ6WRI2QnaFynd1DCjZ62+V0= github.com/googleapis/enterprise-certificate-proxy v0.3.3 h1:QRje2j5GZimBzlbhGA2V2QlGNgL8G6e+wGo/+/2bWI0= github.com/googleapis/enterprise-certificate-proxy v0.3.3/go.mod h1:YKe7cfqYXjKGpGvmSg28/fFvhNzinZQm8DGnaburhGA= +github.com/googleapis/gax-go/v2 v2.12.0 h1:A+gCJKdRfqXkr+BIRGtZLibNXf0m1f9E4HG56etFpas= github.com/googleapis/gax-go/v2 v2.12.0/go.mod h1:y+aIqrI5eb1YGMVJfuV3185Ts/D7qKpsEkdD5+I6QGU= github.com/googleapis/gax-go/v2 v2.12.2 h1:mhN09QQW1jEWeMF74zGR81R30z4VJzjZsfkUhuHF+DA= github.com/googleapis/gax-go/v2 v2.12.2/go.mod h1:61M8vcyyXR2kqKFxKrfA22jaA8JGF7Dc8App1U3H6jc= @@ -756,7 +787,9 @@ github.com/graphql-go/graphql v0.8.1 h1:p7/Ou/WpmulocJeEx7wjQy611rtXGQaAcXGqanuM github.com/graphql-go/graphql v0.8.1/go.mod h1:nKiHzRM0qopJEwCITUuIsxk9PlVlwIiiI8pnJEhordQ= github.com/graphql-go/handler v0.2.3 h1:CANh8WPnl5M9uA25c2GBhPqJhE53Fg0Iue/fRNla71E= github.com/graphql-go/handler v0.2.3/go.mod h1:leLF6RpV5uZMN1CdImAxuiayrYYhOk33bZciaUGaXeU= +github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1 h1:qnpSQwGEnkcRpTqNOIR6bJbR0gAorgP9CSALpRcKoAA= github.com/grpc-ecosystem/go-grpc-middleware/providers/prometheus v1.0.1/go.mod h1:lXGCsh6c22WGtjr+qGHj1otzZpV/1kwTMAqkwZsnWRU= +github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0 h1:FbSCl+KggFl+Ocym490i/EyXF4lPgLoUtcSWquBM0Rs= github.com/grpc-ecosystem/go-grpc-middleware/v2 v2.3.0/go.mod h1:qOchhhIlmRcqk/O9uCo/puJlyo07YINaIqdZfZG3Jkc= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed h1:5upAirOpQc1Q53c0bnx2ufif5kANL7bfZWcc6VJWJd8= github.com/hailocab/go-hostpool v0.0.0-20160125115350-e80d13ce29ed/go.mod h1:tMWxXQ9wFIaZeTI9F+hmhFiGpFmhOHzyShyFUhRm0H4= @@ -788,6 +821,7 @@ github.com/hashicorp/serf v0.10.1 h1:Z1H2J60yRKvfDYAOZLd2MU0ND4AH/WDz7xYHDWQsIPY github.com/hashicorp/serf v0.10.1/go.mod h1:yL2t6BqATOLGc5HF7qbFkTfXoPIY0WZdWHfEvMqbG+4= github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY= github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk= +github.com/hashicorp/vault/api v1.9.2 h1:YjkZLJ7K3inKgMZ0wzCU9OHqc+UqMQyXsPXnf3Cl2as= github.com/hashicorp/vault/api v1.9.2/go.mod h1:jo5Y/ET+hNyz+JnKDt8XLAdKs+AM0G5W0Vp1IrFI8N8= github.com/hashicorp/vault/api v1.12.0 h1:meCpJSesvzQyao8FCOgk2fGdoADAnbDu2WPJN1lDLJ4= github.com/hashicorp/vault/api v1.12.0/go.mod h1:si+lJCYO7oGkIoNPAN8j3azBLTn9SjMGS+jFaHd1Cck= @@ -804,6 +838,7 @@ github.com/iancoleman/strcase v0.3.0 h1:nTXanmYxhfFAMjZL34Ov6gkzEsSJZ5DbhxWjvSAS github.com/iancoleman/strcase v0.3.0/go.mod h1:iwCmte+B7n89clKwxIoIXy/HfoL7AsD47ZCWhYzw7ho= github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465 h1:KwWnWVWCNtNq/ewIX7HIKnELmEx2nDP42yskD/pi7QE= github.com/ianlancetaylor/demangle v0.0.0-20240312041847-bd984b5ce465/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= +github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b h1:ogbOPx86mIhFy764gGkqnkFC8m5PJA7sPzlk9ppLVQA= github.com/ianlancetaylor/demangle v0.0.0-20250417193237-f615e6bd150b/go.mod h1:gx7rwoVhcfuVKG5uya9Hs3Sxj7EIvldVofAWIUtGouw= github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd h1:anPrsicrIi2ColgWTVPk+TrN42hJIWlfPHSBP9S0ZkM= github.com/ijc/Gotty v0.0.0-20170406111628-a8b993ba6abd/go.mod h1:3LVOLeyx9XVvwPgrt2be44XgSqndprz1G18rSk8KD84= @@ -840,6 +875,7 @@ github.com/jinzhu/inflection v1.0.0 h1:K317FqzuhWc8YvSVlFMCCUb36O/S9MCKRDI7QkRKD github.com/jinzhu/inflection v1.0.0/go.mod h1:h+uFLlag+Qp1Va5pdKtLDYj+kHp5pxUVkryuEj+Srlc= github.com/jinzhu/now v1.1.5 h1:/o9tlHleP7gOFmsnYNz3RGnqzefHA47wQpKrrdTIwXQ= github.com/jinzhu/now v1.1.5/go.mod h1:d3SSVoowX0Lcu0IBviAWJpolVfI5UJVZZ7cO71lE/z8= +github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmoiron/sqlx v1.3.5 h1:vFFPA71p1o5gAeqtEAwLU4dnX2napprKtHr7PYIcN3g= github.com/jmoiron/sqlx v1.3.5/go.mod h1:nRVWtLre0KfCLJvgxzCsLVMogSvQ1zNJtpYr2Ccp0mQ= @@ -847,9 +883,11 @@ github.com/jonathan-innis/aws-sdk-go-prometheus v0.1.1 h1:gmpuckrozJ3lfKqSIia9YM github.com/jonathan-innis/aws-sdk-go-prometheus v0.1.1/go.mod h1:168XvZFghCqo32ISSWnTXwdlMKzEq+x9TqdfswCjkrQ= github.com/jonboulle/clockwork v0.4.0 h1:p4Cf1aMWXnXAUh8lVfewRBx1zaTSYKrKMF2g3ST4RZ4= github.com/jonboulle/clockwork v0.4.0/go.mod h1:xgRqUGwRcjKCO1vbZUEtSLrqKoPSsUpK7fnezOII0kc= +github.com/jonboulle/clockwork v0.5.0 h1:Hyh9A8u51kptdkR+cqRpT1EebBwTn1oK9YfGYbdFz6I= github.com/jonboulle/clockwork v0.5.0/go.mod h1:3mZlmanh0g2NDKO5TWZVJAfofYk64M7XN3SzBPjZF60= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= +github.com/joshdk/go-junit v1.0.0 h1:S86cUKIdwBHWwA6xCmFlf3RTLfVXYQfvanM5Uh+K6GE= github.com/joshdk/go-junit v1.0.0/go.mod h1:TiiV0PqkaNfFXjEiyjWM3XXrhVyCa1K4Zfga6W52ung= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -867,6 +905,7 @@ github.com/klauspost/cpuid/v2 v2.2.5 h1:0E5MSMDEoAulmXNFquVs//DdoomxaoTY1kUhbc/q github.com/klauspost/cpuid/v2 v2.2.5/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZYpaMropDUws= github.com/konsorten/go-windows-terminal-sequences v1.0.1 h1:mweAR1A6xJ3oS2pRaGiHgQ4OO8tzTaLawm8vnODuwDk= github.com/konsorten/go-windows-terminal-sequences v1.0.3 h1:CE8S1cTafDpPvMhIxNJKvHsGVBgn1xWYf1NbHQhywc8= +github.com/kr/fs v0.1.0 h1:Jskdu9ieNAYnjxsi0LbQp1ulIKZV1LAFgK1tWhpZgl8= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515 h1:T+h1c/A9Gawja4Y9mFVWj2vyii2bbUNDw3kt9VxK2EY= github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.5 h1:hyz3dwM5QLc1Rfoz4FuWJQG5BN7tc6K1MndAUnGpQr4= @@ -889,6 +928,7 @@ github.com/magefile/mage v1.14.0/go.mod h1:z5UZb/iS3GoOSn0JgWuiw7dxlurVYTu+/jHXq github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/marstr/guid v1.1.0 h1:/M4H/1G4avsieL6BbUwCOBzulmoeKVP5ux/3mQNnbyI= +github.com/maruel/natural v1.1.1 h1:Hja7XhhmvEFhcByqDoHz9QZbkWey+COd9xWfCfn1ioo= github.com/maruel/natural v1.1.1/go.mod h1:v+Rfd79xlw1AgVBjbO0BEQmptqb5HvL/k9GRHB7ZKEg= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3 h1:BXxTozrOU8zgC5dkpn3J6NTRdoP+hjok/e+ACr4Hibk= github.com/mattn/go-ciede2000 v0.0.0-20170301095244-782e8c62fec3/go.mod h1:x1uk6vxTiVuNt6S5R2UYgdhpj3oKojXvOXauHZ7dEnI= @@ -903,6 +943,7 @@ github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0j github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 h1:I0XW9+e1XWDxdcEniV4rQAIOPUGDq67JSCiRCgGCZLI= github.com/matttproud/golang_protobuf_extensions v1.0.4 h1:mmDVorXM7PCGKw94cs5zkfA9PSy5pEvNWRP0ET0TIVo= github.com/matttproud/golang_protobuf_extensions v1.0.4/go.mod h1:BSXmuO+STAnVfrANrmjBb36TMTDstsz7MSK+HVaYKv4= +github.com/mfridman/tparse v0.18.0 h1:wh6dzOKaIwkUGyKgOntDW4liXSo37qg5AXbIhkMV3vE= github.com/mfridman/tparse v0.18.0/go.mod h1:gEvqZTuCgEhPbYk/2lS3Kcxg1GmTxxU7kTC8DvP0i/A= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b h1:j7+1HpAFS1zy5+Q4qx1fWh90gTKwiN4QCGoY9TWyyO4= github.com/mgutz/ansi v0.0.0-20170206155736-9520e82c474b/go.mod h1:01TrycV0kFyexm33Z7vhZRXopbI8J3TDReVlkTgMUxE= @@ -948,6 +989,7 @@ github.com/moby/sys/userns v0.1.0 h1:tVLXkFOxVu9A64/yh59slHVv9ahO9UIev4JZusOLG/g github.com/moby/sys/userns v0.1.0/go.mod h1:IHUYgu/kao6N8YZlp9Cf444ySSvCmDlmzUcYfDHOl28= github.com/montanaflynn/stats v0.6.6 h1:Duep6KMIDpY4Yo11iFsvyqJDyfzLF9+sndUKT+v64GQ= github.com/montanaflynn/stats v0.6.6/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= +github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A= github.com/mrunalp/fileutils v0.5.0 h1:NKzVxiH7eSk+OQ4M+ZYW1K6h27RUV3MI6NUTsHhU6Z4= github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s= github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8= @@ -992,7 +1034,9 @@ github.com/pgavlin/text v0.0.0-20240821195002-b51d0990e284 h1:qpLdAFg3kyV/mEsuMP github.com/pgavlin/text v0.0.0-20240821195002-b51d0990e284/go.mod h1:fk4+YyTLi0Ap0CsL1HA70/tAs6evqw3hbPGdR8rD/3E= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e h1:aoZm08cpOy4WuID//EZDgcC4zIxODThtZNPirFr42+A= github.com/pkg/diff v0.0.0-20210226163009-20ebb0f2a09e/go.mod h1:pJLUxLENpZxwdsKMEsNbx1VGcRFpLqf3715MtcvvzbA= +github.com/pkg/sftp v1.13.6 h1:JFZT4XbOU7l77xGSpOdW+pwIMqP044IyjXX6FGyEKFo= github.com/pkg/sftp v1.13.6/go.mod h1:tz1ryNURKu77RL+GuCzmoJYxQczL3wLNNpPWagdg4Qk= +github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10 h1:GFCKgmp0tecUJ0sJuv4pzYCqS9+RGSn52M3FUwPs+uo= github.com/planetscale/vtprotobuf v0.6.1-0.20240319094008-0393e58bdf10/go.mod h1:t/avpk3KcrXxUnYOhZhMXJlSEyie6gQbtLq5NM3loB8= github.com/posener/complete v1.1.1 h1:ccV59UEOTzVDnDUEFdT95ZzHVZ+5+158q8+SJb2QV5w= github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo= @@ -1036,6 +1080,7 @@ github.com/ryanuber/columnize v2.1.2+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo github.com/safchain/ethtool v0.0.0-20190326074333-42ed695e3de8 h1:2c1EFnZHIPCW8qKWgHMH/fX2PkSabFc5mrVzfUNdg5U= github.com/sahilm/fuzzy v0.1.1 h1:ceu5RHF8DGgoi+/dR5PsECjCDH1BE3Fnmpo7aVXOdRA= github.com/sahilm/fuzzy v0.1.1/go.mod h1:VFvziUEIMCrT6A6tw2RFIXPXXmzXbOsSHF0DOI8ZK9Y= +github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 h1:lZUw3E0/J3roVtGQ+SCrUrg3ON6NgVqpn3+iol9aGu4= github.com/santhosh-tekuri/jsonschema/v5 v5.3.1/go.mod h1:uToXkOrWAZ6/Oc07xWQrPOhJotwFIyu2bBVN41fcDUY= github.com/satori/go.uuid v1.2.0 h1:0uYX9dsZ2yD7q2RtLRtPSdGDWzjeM3TbMJP9utgA0ww= github.com/sean-/seed v0.0.0-20170313163322-e2103e2c3529 h1:nn5Wsu0esKSJiIVhscUtVbo7ada43DJhG55ua/hjS5I= @@ -1059,6 +1104,7 @@ github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.8.1 h1:Kq1fyeebqsBfbjZj4EL7gj2IO0mMaiyjYUWcUsl2O44= +github.com/spiffe/go-spiffe/v2 v2.5.0 h1:N2I01KCUkv1FAjZXJMwh95KK1ZIQLYbPfhaxw8WS0hE= github.com/spiffe/go-spiffe/v2 v2.5.0/go.mod h1:P+NxobPc6wXhVtINNtFjNWGBTreew1GBUCwT2wPmb7g= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980 h1:lIOOHPEbXzO3vnmx2gok1Tfs31Q8GQqKLc8vVqyQq/I= github.com/stefanberger/go-pkcs11uri v0.0.0-20230803200340-78284954bff6 h1:pnnLyeX7o/5aX8qUQ69P/mLojDqwda8hFOCBTmP/6hw= @@ -1078,6 +1124,7 @@ github.com/tidwall/buntdb v1.3.0 h1:gdhWO+/YwoB2qZMeAU9JcWWsHSYU3OvcieYgFRS0zwA= github.com/tidwall/buntdb v1.3.0/go.mod h1:lZZrZUWzlyDJKlLQ6DKAy53LnG7m5kHyrEHvvcDmBpU= github.com/tidwall/gjson v1.16.0 h1:SyXa+dsSPpUlcwEDuKuEBJEz5vzTvOea+9rjyYodQFg= github.com/tidwall/gjson v1.16.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= +github.com/tidwall/gjson v1.18.0 h1:FIDeeyB800efLX89e5a8Y0BNH+LOngJyGrIWxG2FKQY= github.com/tidwall/gjson v1.18.0/go.mod h1:/wbyibRr2FHMks5tjHJ5F8dMZh3AcwJEMf5vlfC0lxk= github.com/tidwall/grect v0.1.4 h1:dA3oIgNgWdSspFzn1kS4S/RDpZFLrIxAZOdJKjYapOg= github.com/tidwall/grect v0.1.4/go.mod h1:9FBsaYRaR0Tcy4UwefBX/UDcDcDy9V5jUcxHzv2jd5Q= @@ -1087,6 +1134,7 @@ 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/rtred v0.1.2 h1:exmoQtOLvDoO8ud++6LwVsAMTu0KPzLTUrMln8u1yu8= github.com/tidwall/rtred v0.1.2/go.mod h1:hd69WNXQ5RP9vHd7dqekAz+RIdtfBogmglkZSRxCHFQ= +github.com/tidwall/sjson v1.2.5 h1:kLy8mja+1c9jlljvWTlSazM7cKDRfJuR/bOJhcY5NcY= github.com/tidwall/sjson v1.2.5/go.mod h1:Fvgq9kS/6ociJEDnK0Fk1cpYF4FIW6ZF7LAe+6jwd28= github.com/tidwall/tinyqueue v0.1.1 h1:SpNEvEggbpyN5DIReaJ2/1ndroY8iyEGxPYxoSaymYE= github.com/tidwall/tinyqueue v0.1.1/go.mod h1:O/QNHwrnjqr6IHItYrzoHAKYhBkLI67Q096fQP5zMYw= @@ -1133,9 +1181,11 @@ github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f h1:p4VB7kIXpOQvV github.com/vishvananda/netns v0.0.0-20210104183010-2eb08e3e575f/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vmihailenco/bufpool v0.1.11 h1:gOq2WmBrq0i2yW5QJ16ykccQ4wH9UyEsgLm6czKAd94= github.com/vmihailenco/bufpool v0.1.11/go.mod h1:AFf/MOy3l2CFTKbxwt0mp2MwnqjNEs5H/UxrkA5jxTQ= +github.com/vmihailenco/msgpack/v4 v4.3.13 h1:A2wsiTbvp63ilDaWmsk2wjx6xZdxQOvpiNlKBGKKXKI= github.com/vmihailenco/msgpack/v4 v4.3.13/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4= github.com/vmihailenco/msgpack/v5 v5.4.1 h1:cQriyiUvjTwOHg8QZaPihLWeRAAVoCpE00IUPn0Bjt8= github.com/vmihailenco/msgpack/v5 v5.4.1/go.mod h1:GaZTsDaehaPpQVyxrf5mtQlH+pc21PIudVV/E3rRQok= +github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc= github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= @@ -1146,9 +1196,11 @@ github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY= github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4= github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8= github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f h1:J9EGpcZtP0E/raorCMxlFGSTBrsSlaDGf3jU/qvAE2c= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb h1:zGWFAtiMcyryUHoUjUJX0/lt1H2+i2Ka2n+D3DImSNo= github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 h1:EzJWgHovont7NscjpAxXsDA8S8BMYve8Y5+7cuRE7R0= +github.com/xeipuuv/gojsonschema v0.0.0-20180618132009-1d523034197f h1:mvXjJIHRZyhNuGassLTcXTwjiWq7NmjdavZsUnmFybQ= github.com/xeipuuv/gojsonschema v1.2.0 h1:LhYJRs+L4fBtjZUfuSZIKGeVu0QRy8e5Xi7D17UxZ74= github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= @@ -1158,6 +1210,7 @@ github.com/xiang90/probing v0.0.0-20221125231312-a49e3df8f510/go.mod h1:UETIi67q github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77 h1:ESFSdwYZvkeru3RtdrYueztKhOBCSAAzS4Gf+k0tEow= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA= github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= +github.com/yuin/goldmark v1.4.13 h1:fVcFKWvrslecOb/tg+Cc05dkeYx540o0FuFt3nUVDoE= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/yuin/goldmark v1.5.2 h1:ALmeCk/px5FSm1MAcFBAsVKZjDuMVj8Tm7FFIlMJnqU= github.com/yuin/goldmark v1.5.2/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= @@ -1168,6 +1221,7 @@ github.com/yvasiyarov/gorelic v0.0.0-20141212073537-a9bba5b9ab50 h1:hlE8//ciYMzt github.com/yvasiyarov/newrelic_platform_go v0.0.0-20140908184405-b21fdbd4370f h1:ERexzlUfuTvpE74urLSbIQW0Z/6hF9t8U4NsJLaioAY= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940 h1:4r45xpDWB6ZMSMNJFMOjqrGHynW3DIBuR2H9j0ug+Mo= github.com/zclconf/go-cty-debug v0.0.0-20240509010212-0d6042c53940/go.mod h1:CmBdvvj3nqzfzJ6nTCIwDTPZ56aVGvDrmztiO5g3qrM= +github.com/zeebo/errs v1.4.0 h1:XNdoD/RRMKP7HD0UhJnIzUy74ISdGGxURlYG8HSWSfM= github.com/zeebo/errs v1.4.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4= github.com/zeebo/xxh3 v1.0.2 h1:xZmwmqxHZA8AI603jOQ0tMqmBr9lPeFwGg6d+xy9DC0= github.com/zeebo/xxh3 v1.0.2/go.mod h1:5NWz9Sef7zIDm2JHfFlcQvNekmcEl9ekUZQQKCYaDcA= @@ -1175,26 +1229,30 @@ github.com/zenazn/goji v1.0.1 h1:4lbD8Mx2h7IvloP7r2C0D6ltZP6Ufip8Hn0wmSK5LR8= github.com/zenazn/goji v1.0.1/go.mod h1:7S9M489iMyHBNxwZnk9/EHS098H4/F6TATF2mIxtB1Q= go.einride.tech/aip v0.67.1 h1:d/4TW92OxXBngkSOwWS2CH5rez869KpKMaN44mdxkFI= go.einride.tech/aip v0.67.1/go.mod h1:ZGX4/zKw8dcgzdLsrvpOOGxfxI2QSk12SlP7d6c0/XI= +go.etcd.io/etcd/client/v2 v2.305.0 h1:ftQ0nOOHMcbMS3KIaDQ0g5Qcd6bhaBrQT6b89DfwLTs= go.etcd.io/etcd/client/v2 v2.305.21 h1:eLiFfexc2mE+pTLz9WwnoEsX5JTTpLCYVivKkmVXIRA= go.etcd.io/etcd/client/v2 v2.305.21/go.mod h1:OKkn4hlYNf43hpjEM3Ke3aRdUkhSl8xjKjSf8eCq2J8= go.etcd.io/etcd/pkg/v3 v3.5.21 h1:jUItxeKyrDuVuWhdh0HtjUANwyuzcb7/FAeUfABmQsk= go.etcd.io/etcd/pkg/v3 v3.5.21/go.mod h1:wpZx8Egv1g4y+N7JAsqi2zoUiBIUWznLjqJbylDjWgU= +go.etcd.io/etcd/pkg/v3 v3.6.5 h1:byxWB4AqIKI4SBmquZUG1WGtvMfMaorXFoCcFbVeoxM= go.etcd.io/etcd/pkg/v3 v3.6.5/go.mod h1:uqrXrzmMIJDEy5j00bCqhVLzR5jEJIwDp5wTlLwPGOU= go.etcd.io/etcd/raft/v3 v3.5.21 h1:dOmE0mT55dIUsX77TKBLq+RgyumsQuYeiRQnW/ylugk= go.etcd.io/etcd/raft/v3 v3.5.21/go.mod h1:fmcuY5R2SNkklU4+fKVBQi2biVp5vafMrWUEj4TJ4Cs= go.etcd.io/etcd/server/v3 v3.5.21 h1:9w0/k12majtgarGmlMVuhwXRI2ob3/d1Ik3X5TKo0yU= go.etcd.io/etcd/server/v3 v3.5.21/go.mod h1:G1mOzdwuzKT1VRL7SqRchli/qcFrtLBTAQ4lV20sXXo= +go.etcd.io/etcd/server/v3 v3.6.5 h1:4RbUb1Bd4y1WkBHmuF+cZII83JNQMuNXzyjwigQ06y0= go.etcd.io/etcd/server/v3 v3.6.5/go.mod h1:PLuhyVXz8WWRhzXDsl3A3zv/+aK9e4A9lpQkqawIaH0= go.etcd.io/gofail v0.1.0 h1:XItAMIhOojXFQMgrxjnd2EIIHun/d5qL0Pf7FzVTkFg= go.etcd.io/gofail v0.1.0/go.mod h1:VZBCXYGZhHAinaBiiqYvuDynvahNsAyLFwB3kEHKz1M= +go.etcd.io/gofail v0.2.0 h1:p19drv16FKK345a09a1iubchlw/vmRuksmRzgBIGjcA= go.etcd.io/gofail v0.2.0/go.mod h1:nL3ILMGfkXTekKI3clMBNazKnjUZjYLKmBHzsVAnC1o= +go.etcd.io/raft/v3 v3.6.0 h1:5NtvbDVYpnfZWcIHgGRk9DyzkBIXOi8j+DDp1IcnUWQ= go.etcd.io/raft/v3 v3.6.0/go.mod h1:nLvLevg6+xrVtHUmVaTcTz603gQPHfh7kUAwV6YpfGo= go.mongodb.org/mongo-driver v1.12.1 h1:nLkghSU8fQNaK7oUmDhQFsnrtcoNy7Z6LVFKsEecqgE= go.mongodb.org/mongo-driver v1.12.1/go.mod h1:/rGBTebI3XYboVmgz+Wv3Bcbl3aD0QF9zl6kDDw18rQ= go.mozilla.org/pkcs7 v0.0.0-20200128120323-432b2356ecb1 h1:A/5uWzF44DlIgdm/PQFwfMkW0JX+cIcQi/SwLAmZP5M= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= -go.opentelemetry.io/auto/sdk v1.1.0 h1:cH53jehLUN6UFLY71z+NDOiNJqDdPRaXzTel0sJySYA= go.opentelemetry.io/auto/sdk v1.1.0/go.mod h1:3wSPjt5PWp2RhlCcmmOial7AvC4DQqZb7a7wCow3W8A= go.opentelemetry.io/collector/component v0.118.0 h1:sSO/ObxJ+yH77Z4DmT1mlSuxhbgUmY1ztt7xCA1F/8w= go.opentelemetry.io/collector/component v0.118.0/go.mod h1:LUJ3AL2b+tmFr3hZol3hzKzCMvNdqNq0M5CF3SWdv4M= @@ -1206,6 +1264,7 @@ go.opentelemetry.io/collector/pdata v1.24.0 h1:D6j92eAzmAbQgivNBUnt8r9juOl8ugb+i go.opentelemetry.io/collector/pdata v1.24.0/go.mod h1:cf3/W9E/uIvPS4MR26SnMFJhraUCattzzM6qusuONuc= go.opentelemetry.io/contrib/detectors/gcp v1.31.0 h1:G1JQOreVrfhRkner+l4mrGxmfqYCAuy76asTDAo0xsA= go.opentelemetry.io/contrib/detectors/gcp v1.31.0/go.mod h1:tzQL6E1l+iV44YFTkcAeNQqzXUiekSYP9jjJjXwEd00= +go.opentelemetry.io/contrib/detectors/gcp v1.34.0 h1:JRxssobiPg23otYU5SbWtQC//snGVIM3Tx6QRzlQBao= go.opentelemetry.io/contrib/detectors/gcp v1.34.0/go.mod h1:cV4BMFcscUR/ckqLkbfQmF0PRsq8w/lMGzdbCSveBHo= go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.53.0/go.mod h1:azvtTADFQJA8mX80jIH/akaE7h+dbm/sVuaHqN13w74= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.53.0/go.mod h1:jjdQuTGVsXV4vSs+CJ2qYDeDPf9yIJV23qlIzBm73Vg= @@ -1218,12 +1277,12 @@ go.opentelemetry.io/otel/metric v1.29.0/go.mod h1:auu/QWieFVWx+DmQOUMgj0F8LHWdga go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= go.opentelemetry.io/otel/sdk v1.28.0/go.mod h1:oYj7ClPUA7Iw3m+r7GeEjz0qckQRJK2B8zjcZEfu7Pg= go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= -go.opentelemetry.io/otel/sdk/metric v1.40.0/go.mod h1:4Z2bGMf0KSK3uRjlczMOeMhKU2rhUqdWNoKcYrtcBPg= go.opentelemetry.io/otel/trace v1.28.0/go.mod h1:jPyXzNPg6da9+38HEwElrQiHlVMTnVfM3/yv2OlIHaI= go.opentelemetry.io/otel/trace v1.29.0/go.mod h1:eHl3w0sp3paPkYstJOmAimxhiFXPg+MMTlEh3nsQgWQ= go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= go.starlark.net v0.0.0-20231101134539-556fd59b42f6 h1:+eC0F/k4aBLC4szgOcjd7bDTEnpxADJyWJE0yowgM3E= go.starlark.net v0.0.0-20231101134539-556fd59b42f6/go.mod h1:LcLNIzVOMp4oV+uusnpk+VU+SzXaJakUuBjoCSWH5dM= +go.uber.org/automaxprocs v1.6.0 h1:O3y2/QNTOdbF+e/dpXNNW7Rx2hZ4sTIPyybbxyNqTUs= go.uber.org/automaxprocs v1.6.0/go.mod h1:ifeIMSnPZuznNm6jmdzmU3/bfk01Fe2fotchwEFJ8r8= go.uber.org/goleak v1.2.0/go.mod h1:XJYK+MuIchqpmGmUSAzotztawfKvYLUIgg7guXrwVUo= go.uber.org/tools v0.0.0-20190618225709-2cfd321de3ee h1:0mgffUl7nfd+FpvXMVz4IDEaUSmT1ysygQC7qYo7sG4= @@ -1231,6 +1290,7 @@ gocloud.dev v0.37.0 h1:XF1rN6R0qZI/9DYjN16Uy0durAmSlf58DHOcb28GPro= gocloud.dev v0.37.0/go.mod h1:7/O4kqdInCNsc6LqgmuFnS0GRew4XNNYWpA44yQnwco= gocloud.dev/secrets/hashivault v0.37.0 h1:5ehGtUBP29DFAgAs6bPw7fVSgqQ3TxaoK2xVcLp1x+c= gocloud.dev/secrets/hashivault v0.37.0/go.mod h1:4ClUWjBfP8wLdGts56acjHz3mWLuATMoH9vi74FjIv8= +golang.org/x/arch v0.4.0 h1:A8WCeEWhLwPBKNbFi5Wv5UTCBx5zzubnXDlMOFAzFMc= golang.org/x/arch v0.4.0/go.mod h1:5om86z9Hs0C8fWVUuoMHwpExlXzs5Tkyp9hOrfG7pp8= golang.org/x/arch v0.6.0 h1:S0JTfE48HbRj80+4tbvZDYsJ3tGv6BUU3XxyZ7CirAc= golang.org/x/arch v0.6.0/go.mod h1:FEVrYAQjsQXMVJ1nsMoVVXPZg6p2JE2mx8psSWTDQys= @@ -1294,6 +1354,7 @@ golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457 h1:zf5N6UOrA487eEFacMe golang.org/x/telemetry v0.0.0-20240521205824-bda55230c457/go.mod h1:pRgIJT+bRLFKnoM1ldnzKoxTIn14Yxz928LQRYYgIN0= golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8 h1:LvzTn0GQhWuvKH/kVRS3R3bVAsdQWI7hvfLHGgh9+lU= golang.org/x/telemetry v0.0.0-20251008203120-078029d740a8/go.mod h1:Pi4ztBfryZoJEkyFTI5/Ocsu2jXyDr6iSdgJiYE/uwE= +golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc h1:bH6xUXay0AIFMElXG2rQ4uiE+7ncwtiOdPfYK1NK2XA= golang.org/x/telemetry v0.0.0-20251203150158-8fff8a5912fc/go.mod h1:hKdjCMrbv9skySur+Nek8Hd0uJ0GuxJIoIX2payrIdQ= golang.org/x/term v0.25.0/go.mod h1:RPyXicDX+6vLxogjjRxjgD2TKtmAO6NZBsBRfrOLu7M= golang.org/x/term v0.30.0/go.mod h1:NYYFdzHoI5wRh/h5tDMdMqCqPJZEuNqVR5xJLd/n67g= @@ -1315,11 +1376,13 @@ golang.org/x/tools v0.26.0/go.mod h1:TPVVj70c7JJ3WCazhD8OdXcZg/og+b9+tH/KxylGwH0 golang.org/x/tools v0.29.0/go.mod h1:KMQVMRsVxU6nHCFXrBPhDB8XncLNLM0lIy/F14RP588= golang.org/x/tools v0.30.0/go.mod h1:c347cR/OJfw5TI+GfX7RUPNMdDRRbjvYTS0jPyvsVtY= golang.org/x/tools v0.37.0/go.mod h1:MBN5QPQtLMHVdvsbtarmTNukZDdgwdwlO5qGacAzF0w= +google.golang.org/api v0.152.0 h1:t0r1vPnfMc260S2Ci+en7kfCZaLOPs5KI0sVV/6jZrY= google.golang.org/api v0.152.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= google.golang.org/api v0.169.0 h1:QwWPy71FgMWqJN/l6jVlFHUa29a7dcUy02I8o799nPY= google.golang.org/api v0.169.0/go.mod h1:gpNOiMA2tZ4mf5R9Iwf4rK/Dcz0fbdIgWYWVoxmsyLg= google.golang.org/api v0.194.0 h1:dztZKG9HgtIpbI35FhfuSNR/zmaMVdxNlntHj1sIS4s= google.golang.org/api v0.194.0/go.mod h1:AgvUFdojGANh3vI+P7EVnxj3AISHllxGCJSFmggmnd0= +google.golang.org/appengine v1.6.8 h1:IhEN5q69dyKagZPYMSdIjS2HqprW324FRQZJcGqPAsM= google.golang.org/appengine v1.6.8/go.mod h1:1jJ3jBArFh5pcgW8gCtRJnepW8FzD1V44FJffLiz/Ds= google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8 h1:Cpp2P6TPjujNoC5M2KHY6g7wfyLYfIWRZaSdIKfDasA= google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80/go.mod h1:cc8bqMqtv9gMOr0zHg2Vzff5ULhhL2IXP4sbcn32Dro= @@ -1394,6 +1457,7 @@ k8s.io/code-generator v0.32.2 h1:CIvyPrLWP7cMgrqval2qYT839YAwCDeSvGfXgWSNpHQ= k8s.io/code-generator v0.32.2/go.mod h1:plh7bWk7JztAUkHM4zpbdy0KOMdrhsePcZL2HLWFH7Y= k8s.io/code-generator v0.33.3 h1:6+34LhYkIuQ/yn/E3qlpVqjQaP8smzCu4NE1A8b0LWs= k8s.io/code-generator v0.33.3/go.mod h1:6Y02+HQJYgNphv9z3wJB5w+sjYDIEBQW7sh62PkufvA= +k8s.io/code-generator v0.35.1 h1:yLKR2la7Z9cWT5qmk67ayx8xXLM4RRKQMnC8YPvTWRI= k8s.io/code-generator v0.35.1/go.mod h1:F2Fhm7aA69tC/VkMXLDokdovltXEF026Tb9yfQXQWKg= k8s.io/component-base v0.32.1/go.mod h1:j1iMMHi/sqAHeG5z+O9BFNCF698a1u0186zkjMZQ28w= k8s.io/component-helpers v0.31.2 h1:V2yjoNeyg8WfvwrJwzfYz+RUwjlbcAIaDaHEStBbaZM= @@ -1404,6 +1468,7 @@ k8s.io/component-helpers v0.33.3 h1:fjWVORSQfI0WKzPeIFSju/gMD9sybwXBJ7oPbqQu6eM= k8s.io/component-helpers v0.33.3/go.mod h1:7iwv+Y9Guw6X4RrnNQOyQlXcvJrVjPveHVqUA5dm31c= k8s.io/controller-manager v0.32.2 h1:/9XuHWEqofO2Aqa4l7KJGckJUcLVRWfx+qnVkdXoStI= k8s.io/controller-manager v0.32.2/go.mod h1:o5uo2tLCQhuoMt0RfKcQd0eqaNmSKOKiT+0YELCqXOk= +k8s.io/controller-manager v0.35.0 h1:KteodmfVIRzfZ3RDaxhnHb72rswBxEngvdL9vuZOA9A= k8s.io/controller-manager v0.35.0/go.mod h1:1bVuPNUG6/dpWpevsJpXioS0E0SJnZ7I/Wqc9Awyzm4= k8s.io/cri-api v0.20.6 h1:iXX0K2pRrbR8yXbZtDK/bSnmg/uSqIFiVJK1x4LUOMc= k8s.io/cri-api v0.27.1 h1:KWO+U8MfI9drXB/P4oU9VchaWYOlwDglJZVHWMpTT3Q= @@ -1418,6 +1483,7 @@ k8s.io/kms v0.32.2 h1:7Ff23ht7W40gTcDwUC8G5WjX5W/nxD8WxbNhIYYNZCI= k8s.io/kms v0.32.2/go.mod h1:Bk2evz/Yvk0oVrvm4MvZbgq8BD34Ksxs2SRHn4/UiOM= k8s.io/kms v0.33.3 h1:7cQWC+GSH211NgY8LRKjBXNtkzra5SkpYzeZrOt5D+8= k8s.io/kms v0.33.3/go.mod h1:C1I8mjFFBNzfUZXYt9FZVJ8MJl7ynFbGgZFbBzkBJ3E= +k8s.io/kms v0.35.1 h1:kjv2r9g1mY7uL+l1RhyAZvWVZIA/4qIfBHXyjFGLRhU= k8s.io/kms v0.35.1/go.mod h1:VT+4ekZAdrZDMgShK37vvlyHUVhwI9t/9tvh0AyCWmQ= k8s.io/kube-openapi v0.0.0-20241105132330-32ad38e42d3f/go.mod h1:R/HEjbvWI0qdfb8viZUeVZm0X6IZnxAydC7YU42CMw4= k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas= From 000c21347b4054b0deb23dee3e66fe3b544d9ced Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Mon, 9 Mar 2026 13:28:29 -0400 Subject: [PATCH 02/12] mount configmap and rbac permissions for pod check feature --- config/crd/kustomization.yaml | 1 + config/rbac/role.yaml | 2 + .../controller/datadogagent/controller.go | 1 + .../controller/datadogagent/feature/ids.go | 2 + .../datadogagent/feature/podcheck/feature.go | 163 ++++++++++++++++++ .../controller/datadogagent_controller.go | 4 + 6 files changed, 173 insertions(+) create mode 100644 internal/controller/datadogagent/feature/podcheck/feature.go diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 26fc1ca1e..cae274087 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -13,6 +13,7 @@ resources: - bases/v1/datadoghq.com_datadogdashboards.yaml - bases/v1/datadoghq.com_datadoggenericresources.yaml - bases/v1/datadoghq.com_datadogagentinternals.yaml +- bases/v1/datadoghq.com_datadogpodchecks.yaml # +kubebuilder:scaffold:crdkustomizeresource #patches: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index d0e9e790b..f61166588 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -258,6 +258,7 @@ rules: - datadogdashboards/status - datadoggenericresources/status - datadogmonitors/status + - datadogpodchecks/status - datadogslos/status verbs: - get @@ -290,6 +291,7 @@ rules: - apiGroups: - datadoghq.com resources: + - datadogpodchecks - extendeddaemonsetreplicasets - watermarkpodautoscalers verbs: diff --git a/internal/controller/datadogagent/controller.go b/internal/controller/datadogagent/controller.go index 1f508e601..69d3f6328 100644 --- a/internal/controller/datadogagent/controller.go +++ b/internal/controller/datadogagent/controller.go @@ -52,6 +52,7 @@ import ( _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/otelagentgateway" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/otelcollector" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/otlp" + _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/podcheck" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/privateactionrunner" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/processdiscovery" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/prometheusscrape" diff --git a/internal/controller/datadogagent/feature/ids.go b/internal/controller/datadogagent/feature/ids.go index b2bbe182f..95d6d6ef5 100644 --- a/internal/controller/datadogagent/feature/ids.go +++ b/internal/controller/datadogagent/feature/ids.go @@ -85,4 +85,6 @@ const ( PrivateActionRunnerIDType = "private_action_runner" // DataPlaneIDType Data Plane feature. DataPlaneIDType = "data_plane" + // PodCheckIDType Pod Check feature. + PodCheckIDType = "pod_check" ) diff --git a/internal/controller/datadogagent/feature/podcheck/feature.go b/internal/controller/datadogagent/feature/podcheck/feature.go new file mode 100644 index 000000000..7909a2433 --- /dev/null +++ b/internal/controller/datadogagent/feature/podcheck/feature.go @@ -0,0 +1,163 @@ +// 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 podcheck + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + rbacv1 "k8s.io/api/rbac/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + + apicommon "github.com/DataDog/datadog-operator/api/datadoghq/common" + "github.com/DataDog/datadog-operator/api/datadoghq/v2alpha1" + apiutils "github.com/DataDog/datadog-operator/api/utils" + "github.com/DataDog/datadog-operator/internal/controller/datadogagent/common" + "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature" + "github.com/DataDog/datadog-operator/internal/controller/datadogagent/object/volume" + "github.com/DataDog/datadog-operator/pkg/constants" + "github.com/DataDog/datadog-operator/pkg/kubernetes" + "github.com/DataDog/datadog-operator/pkg/kubernetes/rbac" +) + +const ( + podCheckRBACPrefix = "pod-check" + podCheckVolumeName = "podcheck-config" + podCheckFolderName = "pod-check.d" + podCheckConfigMapSuffix = "podcheck-config" +) + +func init() { + err := feature.Register(feature.PodCheckIDType, buildPodCheckFeature) + if err != nil { + panic(err) + } +} + +func buildPodCheckFeature(_ *feature.Options) feature.Feature { + return &podCheckFeature{} +} + +type podCheckFeature struct { + owner metav1.Object + configMapName string + serviceAccountName string + rbacSuffix string +} + +func (f *podCheckFeature) ID() feature.IDType { + return feature.PodCheckIDType +} + +func (f *podCheckFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) feature.RequiredComponents { + f.owner = dda + f.configMapName = fmt.Sprintf("%s-%s", dda.GetName(), podCheckConfigMapSuffix) + f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) + f.rbacSuffix = common.ClusterAgentSuffix + + return feature.RequiredComponents{ + ClusterAgent: feature.RequiredComponent{ + IsRequired: apiutils.NewBoolPointer(true), + Containers: []apicommon.AgentContainerName{apicommon.ClusterAgentContainerName}, + }, + Agent: feature.RequiredComponent{ + IsRequired: apiutils.NewBoolPointer(true), + Containers: []apicommon.AgentContainerName{apicommon.CoreAgentContainerName}, + }, + } +} + +func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, _ string) error { + // Create the empty ConfigMap that the DCA will populate with check configs. + cm := &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: f.configMapName, + Namespace: f.owner.GetNamespace(), + }, + Data: map[string]string{}, + } + if err := managers.Store().AddOrUpdate(kubernetes.ConfigMapKind, cm); err != nil { + return err + } + + // RBAC: allow the Cluster Agent to read DatadogPodCheck CRDs and update the ConfigMap. + rbacName := getRBACResourceName(f.owner, f.rbacSuffix) + return managers.RBACManager().AddClusterPolicyRules( + f.owner.GetNamespace(), + rbacName, + f.serviceAccountName, + getPolicyRules(f.configMapName), + ) +} + +func (f *podCheckFeature) ManageClusterAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) + volMount := corev1.VolumeMount{ + Name: podCheckVolumeName, + MountPath: fmt.Sprintf("%s%s/%s", common.ConfigVolumePath, common.ConfdVolumePath, podCheckFolderName), + ReadOnly: true, + } + + managers.Volume().AddVolume(&vol) + managers.VolumeMount().AddVolumeMountToContainer(&volMount, apicommon.ClusterAgentContainerName) + return nil +} + +func (f *podCheckFeature) ManageNodeAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) + volMount := corev1.VolumeMount{ + Name: podCheckVolumeName, + MountPath: fmt.Sprintf("%s%s/%s", common.ConfigVolumePath, common.ConfdVolumePath, podCheckFolderName), + ReadOnly: true, + } + + managers.Volume().AddVolume(&vol) + managers.VolumeMount().AddVolumeMountToContainer(&volMount, apicommon.CoreAgentContainerName) + return nil +} + +func (f *podCheckFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) + volMount := corev1.VolumeMount{ + Name: podCheckVolumeName, + MountPath: fmt.Sprintf("%s%s/%s", common.ConfigVolumePath, common.ConfdVolumePath, podCheckFolderName), + ReadOnly: true, + } + + managers.Volume().AddVolume(&vol) + managers.VolumeMount().AddVolumeMountToContainer(&volMount, apicommon.UnprivilegedSingleAgentContainerName) + return nil +} + +func (f *podCheckFeature) ManageClusterChecksRunner(_ feature.PodTemplateManagers, _ string) error { + return nil +} + +func (f *podCheckFeature) ManageOtelAgentGateway(_ feature.PodTemplateManagers, _ string) error { + return nil +} + +func getRBACResourceName(owner metav1.Object, suffix string) string { + return fmt.Sprintf("%s-%s-%s-%s", owner.GetNamespace(), owner.GetName(), podCheckRBACPrefix, suffix) +} + +func getPolicyRules(configMapName string) []rbacv1.PolicyRule { + return []rbacv1.PolicyRule{ + // Read DatadogPodCheck CRDs + { + APIGroups: []string{rbac.DatadogAPIGroup}, + Resources: []string{"datadogpodchecks"}, + Verbs: []string{"get", "list", "watch"}, + }, + // Read/update the ConfigMap used to pass check configs between DCA and Node Agent + { + APIGroups: []string{rbac.CoreAPIGroup}, + Resources: []string{rbac.ConfigMapsResource}, + ResourceNames: []string{configMapName}, + Verbs: []string{"get", "update"}, + }, + } +} diff --git a/internal/controller/datadogagent_controller.go b/internal/controller/datadogagent_controller.go index d986ccff6..23993a099 100644 --- a/internal/controller/datadogagent_controller.go +++ b/internal/controller/datadogagent_controller.go @@ -93,6 +93,10 @@ type DatadogAgentReconciler struct { // +kubebuilder:rbac:groups=karpenter.sh,resources=*,verbs=get;list;watch;create;patch;update;delete // +kubebuilder:rbac:groups=karpenter.k8s.aws,resources=*,verbs=get;list +// Pod Check CRD +// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogpodchecks,verbs=get;list;watch +// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogpodchecks/status,verbs=get;update;patch + // Use ExtendedDaemonSet // +kubebuilder:rbac:groups=datadoghq.com,resources=extendeddaemonsets,verbs=get;list;watch;create;update;patch;delete // +kubebuilder:rbac:groups=datadoghq.com,resources=extendeddaemonsetreplicasets,verbs=get;list;watch From 11ef216110e66db3bc5eb569fa2681e5afc79beb Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Mon, 9 Mar 2026 16:30:09 -0400 Subject: [PATCH 03/12] rework pod check spec --- .../v1alpha1/datadogpodcheck_types.go | 35 ++++---- .../v1alpha1/zz_generated.deepcopy.go | 23 ++++-- .../v1alpha1/zz_generated.openapi.go | 55 ++++++++----- .../v1/datadoghq.com_datadogpodchecks.yaml | 82 +++++++++---------- ...tadoghq.com_datadogpodchecks_v1alpha1.json | 78 ++++++++++-------- 5 files changed, 147 insertions(+), 126 deletions(-) diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_types.go b/api/datadoghq/v1alpha1/datadogpodcheck_types.go index 37b5dfb57..44f01e187 100644 --- a/api/datadoghq/v1alpha1/datadogpodcheck_types.go +++ b/api/datadoghq/v1alpha1/datadogpodcheck_types.go @@ -13,24 +13,15 @@ import ( // DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. // +k8s:openapi-gen=true type DatadogPodCheckSpec struct { - // ContainerImage is the container image name used for autodiscovery template matching. - // The check is resolved per-pod against containers running this image - // and supports AD template variables (%%host%%, %%port%%, etc). - ContainerImage string `json:"containerImage"` - - // Selector provides additional targeting criteria to narrow which pods this - // check applies to. When specified, all conditions (containerImage + selector - // fields) must match for a pod to be targeted (AND semantics). - // +optional - Selector *PodSelector `json:"selector,omitempty"` - - // Check defines the integration check configuration. - Check CheckConfig `json:"check"` + // Selector provides targeting criteria to narrow which pods these + // checks apply to. At least one of matchLabels or matchAnnotations must be set. + // When both are specified, all fields are ANDed together. + Selector PodSelector `json:"selector"` - // Logs defines optional log collection configurations. - // +optional + // Checks is the list of integration check configurations to schedule. + // +kubebuilder:validation:MinItems=1 // +listType=atomic - Logs []apiextensionsv1.JSON `json:"logs,omitempty"` + Checks []CheckConfig `json:"checks"` } // PodSelector defines criteria for selecting pods by labels and annotations. @@ -52,6 +43,12 @@ type CheckConfig struct { // Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). Name string `json:"name"` + // ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names) + // used for template matching against discovered containers. + // +optional + // +listType=atomic + ADIdentifiers []string `json:"adIdentifiers,omitempty"` + // InitConfig is the init_config section passed to the integration check. // +optional InitConfig *apiextensionsv1.JSON `json:"initConfig,omitempty"` @@ -61,6 +58,10 @@ type CheckConfig struct { // +kubebuilder:validation:MinItems=1 // +listType=atomic Instances []apiextensionsv1.JSON `json:"instances"` + + // Logs defines optional log collection configuration for this check. + // +optional + Logs *apiextensionsv1.JSON `json:"logs,omitempty"` } // DatadogPodCheckStatus defines the observed state of a DatadogPodCheck. @@ -78,8 +79,6 @@ type DatadogPodCheckStatus struct { // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:path=datadogpodchecks,scope=Namespaced,shortName=ddpc -// +kubebuilder:printcolumn:name="check",type="string",JSONPath=".spec.check.name" -// +kubebuilder:printcolumn:name="image",type="string",JSONPath=".spec.containerImage" // +kubebuilder:printcolumn:name="age",type="date",JSONPath=".metadata.creationTimestamp" // +k8s:openapi-gen=true // +genclient diff --git a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go index e5c89b1b0..903aa895b 100644 --- a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go @@ -22,6 +22,11 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheckConfig) DeepCopyInto(out *CheckConfig) { *out = *in + if in.ADIdentifiers != nil { + in, out := &in.ADIdentifiers, &out.ADIdentifiers + *out = make([]string, len(*in)) + copy(*out, *in) + } if in.InitConfig != nil { in, out := &in.InitConfig, &out.InitConfig *out = new(apiextensionsv1.JSON) @@ -34,6 +39,11 @@ func (in *CheckConfig) DeepCopyInto(out *CheckConfig) { (*in)[i].DeepCopyInto(&(*out)[i]) } } + if in.Logs != nil { + in, out := &in.Logs, &out.Logs + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } } // DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CheckConfig. @@ -1399,15 +1409,10 @@ func (in *DatadogPodCheckList) DeepCopyObject() runtime.Object { // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DatadogPodCheckSpec) DeepCopyInto(out *DatadogPodCheckSpec) { *out = *in - if in.Selector != nil { - in, out := &in.Selector, &out.Selector - *out = new(PodSelector) - (*in).DeepCopyInto(*out) - } - in.Check.DeepCopyInto(&out.Check) - if in.Logs != nil { - in, out := &in.Logs, &out.Logs - *out = make([]apiextensionsv1.JSON, len(*in)) + in.Selector.DeepCopyInto(&out.Selector) + if in.Checks != nil { + in, out := &in.Checks, &out.Checks + *out = make([]CheckConfig, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } diff --git a/api/datadoghq/v1alpha1/zz_generated.openapi.go b/api/datadoghq/v1alpha1/zz_generated.openapi.go index 3f2260bbf..c5bfb870f 100644 --- a/api/datadoghq/v1alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v1alpha1/zz_generated.openapi.go @@ -75,6 +75,26 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer Format: "", }, }, + "adIdentifiers": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names) used for template matching against discovered containers.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, "initConfig": { SchemaProps: spec.SchemaProps{ Description: "InitConfig is the init_config section passed to the integration check.", @@ -99,6 +119,12 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer }, }, }, + "logs": { + SchemaProps: spec.SchemaProps{ + Description: "Logs defines optional log collection configuration for this check.", + Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), + }, + }, }, Required: []string{"name", "instances"}, }, @@ -1925,51 +1951,38 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref comm Description: "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "containerImage": { - SchemaProps: spec.SchemaProps{ - Description: "ContainerImage is the container image name used for autodiscovery template matching. The check is resolved per-pod against containers running this image and supports AD template variables (%%host%%, %%port%%, etc).", - Default: "", - Type: []string{"string"}, - Format: "", - }, - }, "selector": { SchemaProps: spec.SchemaProps{ - Description: "Selector provides additional targeting criteria to narrow which pods this check applies to. When specified, all conditions (containerImage + selector fields) must match for a pod to be targeted (AND semantics).", - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), - }, - }, - "check": { - SchemaProps: spec.SchemaProps{ - Description: "Check defines the integration check configuration.", + Description: "Selector provides targeting criteria to narrow which pods these checks apply to. At least one of matchLabels or matchAnnotations must be set. When both are specified, all fields are ANDed together.", Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), }, }, - "logs": { + "checks": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ "x-kubernetes-list-type": "atomic", }, }, SchemaProps: spec.SchemaProps{ - Description: "Logs defines optional log collection configurations.", + Description: "Checks is the list of integration check configurations to schedule.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ - Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), }, }, }, }, }, }, - Required: []string{"containerImage", "check"}, + Required: []string{"selector", "checks"}, }, }, Dependencies: []string{ - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector", "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"}, + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"}, } } diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml index cbc82a8b9..9b2408f87 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml @@ -17,12 +17,6 @@ spec: scope: Namespaced versions: - additionalPrinterColumns: - - jsonPath: .spec.check.name - name: check - type: string - - jsonPath: .spec.containerImage - name: image - type: string - jsonPath: .metadata.creationTimestamp name: age type: date @@ -54,45 +48,49 @@ spec: spec: description: DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. properties: - check: - description: Check defines the integration check configuration. - properties: - initConfig: - description: InitConfig is the init_config section passed to the integration check. - x-kubernetes-preserve-unknown-fields: true - instances: - description: |- - Instances is the list of check instance configurations. - At least one instance is required. - items: - x-kubernetes-preserve-unknown-fields: true - minItems: 1 - type: array - x-kubernetes-list-type: atomic - name: - description: Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). - type: string - required: - - instances - - name - type: object - containerImage: - description: |- - ContainerImage is the container image name used for autodiscovery template matching. - The check is resolved per-pod against containers running this image - and supports AD template variables (%%host%%, %%port%%, etc). - type: string - logs: - description: Logs defines optional log collection configurations. + checks: + description: Checks is the list of integration check configurations to schedule. items: - x-kubernetes-preserve-unknown-fields: true + description: CheckConfig defines a Datadog integration check configuration. + properties: + adIdentifiers: + description: |- + ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names) + used for template matching against discovered containers. + items: + type: string + type: array + x-kubernetes-list-type: atomic + initConfig: + description: InitConfig is the init_config section passed to the integration check. + x-kubernetes-preserve-unknown-fields: true + instances: + description: |- + Instances is the list of check instance configurations. + At least one instance is required. + items: + x-kubernetes-preserve-unknown-fields: true + minItems: 1 + type: array + x-kubernetes-list-type: atomic + logs: + description: Logs defines optional log collection configuration for this check. + x-kubernetes-preserve-unknown-fields: true + name: + description: Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + type: string + required: + - instances + - name + type: object + minItems: 1 type: array x-kubernetes-list-type: atomic selector: description: |- - Selector provides additional targeting criteria to narrow which pods this - check applies to. When specified, all conditions (containerImage + selector - fields) must match for a pod to be targeted (AND semantics). + Selector provides targeting criteria to narrow which pods these + checks apply to. At least one of matchLabels or matchAnnotations must be set. + When both are specified, all fields are ANDed together. properties: matchAnnotations: additionalProperties: @@ -106,8 +104,8 @@ spec: type: object type: object required: - - check - - containerImage + - checks + - selector type: object status: description: DatadogPodCheckStatus defines the observed state of a DatadogPodCheck. diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json index 7e5695231..9d839eb0b 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json @@ -17,49 +17,55 @@ "additionalProperties": false, "description": "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", "properties": { - "check": { - "additionalProperties": false, - "description": "Check defines the integration check configuration.", - "properties": { - "initConfig": { - "description": "InitConfig is the init_config section passed to the integration check.", - "x-kubernetes-preserve-unknown-fields": true - }, - "instances": { - "description": "Instances is the list of check instance configurations.\nAt least one instance is required.", - "items": { + "checks": { + "description": "Checks is the list of integration check configurations to schedule.", + "items": { + "additionalProperties": false, + "description": "CheckConfig defines a Datadog integration check configuration.", + "properties": { + "adIdentifiers": { + "description": "ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names)\nused for template matching against discovered containers.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "initConfig": { + "description": "InitConfig is the init_config section passed to the integration check.", "x-kubernetes-preserve-unknown-fields": true }, - "minItems": 1, - "type": "array", - "x-kubernetes-list-type": "atomic" + "instances": { + "description": "Instances is the list of check instance configurations.\nAt least one instance is required.", + "items": { + "x-kubernetes-preserve-unknown-fields": true + }, + "minItems": 1, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "logs": { + "description": "Logs defines optional log collection configuration for this check.", + "x-kubernetes-preserve-unknown-fields": true + }, + "name": { + "description": "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").", + "type": "string" + } }, - "name": { - "description": "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").", - "type": "string" - } - }, - "required": [ - "instances", - "name" - ], - "type": "object" - }, - "containerImage": { - "description": "ContainerImage is the container image name used for autodiscovery template matching.\nThe check is resolved per-pod against containers running this image\nand supports AD template variables (%%host%%, %%port%%, etc).", - "type": "string" - }, - "logs": { - "description": "Logs defines optional log collection configurations.", - "items": { - "x-kubernetes-preserve-unknown-fields": true + "required": [ + "instances", + "name" + ], + "type": "object" }, + "minItems": 1, "type": "array", "x-kubernetes-list-type": "atomic" }, "selector": { "additionalProperties": false, - "description": "Selector provides additional targeting criteria to narrow which pods this\ncheck applies to. When specified, all conditions (containerImage + selector\nfields) must match for a pod to be targeted (AND semantics).", + "description": "Selector provides targeting criteria to narrow which pods these\nchecks apply to. At least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, all fields are ANDed together.", "properties": { "matchAnnotations": { "additionalProperties": { @@ -80,8 +86,8 @@ } }, "required": [ - "check", - "containerImage" + "checks", + "selector" ], "type": "object" }, From 8619ff56c99e22ce4a582b47aad2fca1f69582c8 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Tue, 10 Mar 2026 10:49:32 -0400 Subject: [PATCH 04/12] dont mount configmap to dca and add createOnly store feature --- .../v1alpha1/datadogpodcheck_validation.go | 16 +++++++++++ .../datadogagent/feature/podcheck/feature.go | 13 ++------- .../controller/datadogagent/store/store.go | 27 ++++++++++++++++--- 3 files changed, 41 insertions(+), 15 deletions(-) create mode 100644 api/datadoghq/v1alpha1/datadogpodcheck_validation.go diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_validation.go b/api/datadoghq/v1alpha1/datadogpodcheck_validation.go new file mode 100644 index 000000000..91c098a32 --- /dev/null +++ b/api/datadoghq/v1alpha1/datadogpodcheck_validation.go @@ -0,0 +1,16 @@ +// 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 v1alpha1 + +import "fmt" + +// IsValidDatadogPodCheck validates the DatadogPodCheck spec. +func IsValidDatadogPodCheck(spec *DatadogPodCheckSpec) error { + if len(spec.Selector.MatchLabels) == 0 && len(spec.Selector.MatchAnnotations) == 0 { + return fmt.Errorf("spec.selector must have at least one of matchLabels or matchAnnotations set") + } + return nil +} diff --git a/internal/controller/datadogagent/feature/podcheck/feature.go b/internal/controller/datadogagent/feature/podcheck/feature.go index 7909a2433..f7299a2b2 100644 --- a/internal/controller/datadogagent/feature/podcheck/feature.go +++ b/internal/controller/datadogagent/feature/podcheck/feature.go @@ -79,7 +79,7 @@ func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, }, Data: map[string]string{}, } - if err := managers.Store().AddOrUpdate(kubernetes.ConfigMapKind, cm); err != nil { + if err := managers.Store().AddCreateOnly(kubernetes.ConfigMapKind, cm); err != nil { return err } @@ -93,16 +93,7 @@ func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, ) } -func (f *podCheckFeature) ManageClusterAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) - volMount := corev1.VolumeMount{ - Name: podCheckVolumeName, - MountPath: fmt.Sprintf("%s%s/%s", common.ConfigVolumePath, common.ConfdVolumePath, podCheckFolderName), - ReadOnly: true, - } - - managers.Volume().AddVolume(&vol) - managers.VolumeMount().AddVolumeMountToContainer(&volMount, apicommon.ClusterAgentContainerName) +func (f *podCheckFeature) ManageClusterAgent(_ feature.PodTemplateManagers, _ string) error { return nil } diff --git a/internal/controller/datadogagent/store/store.go b/internal/controller/datadogagent/store/store.go index bc0e97779..18bdb3870 100644 --- a/internal/controller/datadogagent/store/store.go +++ b/internal/controller/datadogagent/store/store.go @@ -40,6 +40,10 @@ const ( // StoreClient dependencies store client interface type StoreClient interface { AddOrUpdate(kind kubernetes.ObjectKind, obj client.Object) error + // AddCreateOnly adds an object to the store that will only be created if it + // does not already exist on the API server. It will never be updated by the + // store, allowing external components to write to the resource freely. + AddCreateOnly(kind kubernetes.ObjectKind, obj client.Object) error Get(kind kubernetes.ObjectKind, namespace, name string) (client.Object, bool) GetOrCreate(kind kubernetes.ObjectKind, namespace, name string) (client.Object, bool) GetPlatformInfo() kubernetes.PlatformInfo @@ -51,8 +55,9 @@ type StoreClient interface { // NewStore returns a new Store instance func NewStore(owner metav1.Object, options *StoreOptions) *Store { store := &Store{ - deps: make(map[kubernetes.ObjectKind]map[string]client.Object), - owner: owner, + deps: make(map[kubernetes.ObjectKind]map[string]client.Object), + createOnly: make(map[string]bool), + owner: owner, } if options != nil { store.supportCilium = options.SupportCilium @@ -68,8 +73,9 @@ func NewStore(owner metav1.Object, options *StoreOptions) *Store { // Store Kubernetes resource dependencies store // this store helps to keep track of every resources that the different agent deployments depend on. type Store struct { - deps map[kubernetes.ObjectKind]map[string]client.Object - mutex sync.RWMutex + deps map[kubernetes.ObjectKind]map[string]client.Object + createOnly map[string]bool // tracks objects that should only be created, never updated + mutex sync.RWMutex supportCilium bool platformInfo kubernetes.PlatformInfo @@ -153,6 +159,15 @@ func (ds *Store) AddOrUpdateStore(kind kubernetes.ObjectKind, obj client.Object) return ds } +// AddCreateOnly adds an object to the store that will only be created if it does not +// already exist on the API server. Once created, the store will never overwrite it, +// allowing external components to modify the resource freely. +func (ds *Store) AddCreateOnly(kind kubernetes.ObjectKind, obj client.Object) error { + id := buildID(obj.GetNamespace(), obj.GetName()) + ds.createOnly[id] = true + return ds.AddOrUpdate(kind, obj) +} + // Get returns the client.Object instance if it was previously added in the Store. // kind correspond to the object kind, and id can be `namespace/name` identifier of just // `name` if we are talking about a cluster scope object like `ClusterRole`. @@ -240,6 +255,10 @@ func (ds *Store) Apply(ctx context.Context, k8sClient client.Client) []error { } if !equality.IsEqualObject(kind, objStore, objAPIServer) { + if ds.createOnly[objID] { + ds.logger.V(2).Info("store.store Skipping update for create-only object", "obj.namespace", objStore.GetNamespace(), "obj.name", objStore.GetName(), "obj.kind", kind) + continue + } ds.logger.V(2).Info("store.store Add object to update", "obj.namespace", objStore.GetNamespace(), "obj.name", objStore.GetName(), "obj.kind", kind) objsToUpdate = append(objsToUpdate, objStore) continue From a2dc143d4c211a685631fc8417d6da46680cacdb Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Tue, 10 Mar 2026 13:21:01 -0400 Subject: [PATCH 05/12] rename pod check config map --- .../datadogagent/feature/podcheck/feature.go | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/internal/controller/datadogagent/feature/podcheck/feature.go b/internal/controller/datadogagent/feature/podcheck/feature.go index f7299a2b2..a5bd31660 100644 --- a/internal/controller/datadogagent/feature/podcheck/feature.go +++ b/internal/controller/datadogagent/feature/podcheck/feature.go @@ -25,9 +25,9 @@ import ( const ( podCheckRBACPrefix = "pod-check" - podCheckVolumeName = "podcheck-config" - podCheckFolderName = "pod-check.d" - podCheckConfigMapSuffix = "podcheck-config" + podCheckVolumeName = "crd-check-conf" + crdConfigDirectory = "crd-conf.d" + podCheckConfigMapSuffix = "crd-check-conf" ) func init() { @@ -101,7 +101,7 @@ func (f *podCheckFeature) ManageNodeAgent(managers feature.PodTemplateManagers, vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) volMount := corev1.VolumeMount{ Name: podCheckVolumeName, - MountPath: fmt.Sprintf("%s%s/%s", common.ConfigVolumePath, common.ConfdVolumePath, podCheckFolderName), + MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), ReadOnly: true, } @@ -114,7 +114,7 @@ func (f *podCheckFeature) ManageSingleContainerNodeAgent(managers feature.PodTem vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) volMount := corev1.VolumeMount{ Name: podCheckVolumeName, - MountPath: fmt.Sprintf("%s%s/%s", common.ConfigVolumePath, common.ConfdVolumePath, podCheckFolderName), + MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), ReadOnly: true, } From 57b447ba73a83578b7f61fd276e1d112090087bf Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Tue, 10 Mar 2026 13:24:01 -0400 Subject: [PATCH 06/12] rename to AddOnly --- .../controller/datadogagent/feature/podcheck/feature.go | 2 +- internal/controller/datadogagent/store/store.go | 8 +++++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/internal/controller/datadogagent/feature/podcheck/feature.go b/internal/controller/datadogagent/feature/podcheck/feature.go index a5bd31660..03a80318e 100644 --- a/internal/controller/datadogagent/feature/podcheck/feature.go +++ b/internal/controller/datadogagent/feature/podcheck/feature.go @@ -79,7 +79,7 @@ func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, }, Data: map[string]string{}, } - if err := managers.Store().AddCreateOnly(kubernetes.ConfigMapKind, cm); err != nil { + if err := managers.Store().AddOnly(kubernetes.ConfigMapKind, cm); err != nil { return err } diff --git a/internal/controller/datadogagent/store/store.go b/internal/controller/datadogagent/store/store.go index 18bdb3870..b933ad51f 100644 --- a/internal/controller/datadogagent/store/store.go +++ b/internal/controller/datadogagent/store/store.go @@ -40,10 +40,12 @@ const ( // StoreClient dependencies store client interface type StoreClient interface { AddOrUpdate(kind kubernetes.ObjectKind, obj client.Object) error - // AddCreateOnly adds an object to the store that will only be created if it + + // AddOnly adds an object to the store that will only be created if it // does not already exist on the API server. It will never be updated by the // store, allowing external components to write to the resource freely. - AddCreateOnly(kind kubernetes.ObjectKind, obj client.Object) error + AddOnly(kind kubernetes.ObjectKind, obj client.Object) error + Get(kind kubernetes.ObjectKind, namespace, name string) (client.Object, bool) GetOrCreate(kind kubernetes.ObjectKind, namespace, name string) (client.Object, bool) GetPlatformInfo() kubernetes.PlatformInfo @@ -162,7 +164,7 @@ func (ds *Store) AddOrUpdateStore(kind kubernetes.ObjectKind, obj client.Object) // AddCreateOnly adds an object to the store that will only be created if it does not // already exist on the API server. Once created, the store will never overwrite it, // allowing external components to modify the resource freely. -func (ds *Store) AddCreateOnly(kind kubernetes.ObjectKind, obj client.Object) error { +func (ds *Store) AddOnly(kind kubernetes.ObjectKind, obj client.Object) error { id := buildID(obj.GetNamespace(), obj.GetName()) ds.createOnly[id] = true return ds.AddOrUpdate(kind, obj) From e2727b40885568056c5d63fa3366583cd96e9f4e Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Tue, 10 Mar 2026 15:56:14 -0400 Subject: [PATCH 07/12] chore: rewording and remove validation --- .../v1alpha1/datadogpodcheck_types.go | 45 ++++++++++------ .../v1alpha1/datadogpodcheck_validation.go | 16 ------ .../v1alpha1/zz_generated.openapi.go | 24 ++++----- .../v1/datadoghq.com_datadogpodchecks.yaml | 52 +++++++++++++------ ...tadoghq.com_datadogpodchecks_v1alpha1.json | 22 ++++---- .../datadogagent/feature/podcheck/feature.go | 2 - 6 files changed, 86 insertions(+), 75 deletions(-) delete mode 100644 api/datadoghq/v1alpha1/datadogpodcheck_validation.go diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_types.go b/api/datadoghq/v1alpha1/datadogpodcheck_types.go index 44f01e187..6da3d3163 100644 --- a/api/datadoghq/v1alpha1/datadogpodcheck_types.go +++ b/api/datadoghq/v1alpha1/datadogpodcheck_types.go @@ -13,53 +13,64 @@ import ( // DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. // +k8s:openapi-gen=true type DatadogPodCheckSpec struct { - // Selector provides targeting criteria to narrow which pods these - // checks apply to. At least one of matchLabels or matchAnnotations must be set. - // When both are specified, all fields are ANDed together. + // Selector determines which pods this DatadogPodCheck applies to. + // At least one of matchLabels or matchAnnotations must be set. + // When both are specified, a pod must match all criteria to be selected. Selector PodSelector `json:"selector"` - // Checks is the list of integration check configurations to schedule. + // Checks is the list of Datadog integration checks to run on the selected pods. + // Each entry defines one check, including what to monitor and how to connect to it. // +kubebuilder:validation:MinItems=1 // +listType=atomic Checks []CheckConfig `json:"checks"` } // PodSelector defines criteria for selecting pods by labels and annotations. -// All specified fields are ANDed together. // +k8s:openapi-gen=true type PodSelector struct { - // MatchLabels is a map of key-value pairs that must match a pod's labels. + // MatchLabels is a map of label key-value pairs. A pod must have all + // these labels with the exact values specified to be selected. // +optional MatchLabels map[string]string `json:"matchLabels,omitempty"` - // MatchAnnotations is a map of key-value pairs that must match a pod's annotations. + // MatchAnnotations is a map of annotation key-value pairs. A pod must have all + // these annotations with the exact values specified to be selected. // +optional MatchAnnotations map[string]string `json:"matchAnnotations,omitempty"` } -// CheckConfig defines a Datadog integration check configuration. +// CheckConfig defines a single Datadog integration check to run on matched pods. // +k8s:openapi-gen=true type CheckConfig struct { // Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + // Must correspond to a valid Datadog integration. Name string `json:"name"` - // ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names) - // used for template matching against discovered containers. + // ADIdentifiers is a list of container identifiers (typically image names like + // "nginx" or "redis") that the Datadog Agent uses to determine which container + // in a pod this check should monitor. When omitted, the check applies to the + // pod as a whole without targeting a specific container. // +optional // +listType=atomic ADIdentifiers []string `json:"adIdentifiers,omitempty"` - // InitConfig is the init_config section passed to the integration check. + // InitConfig holds shared configuration that applies across all instances of + // this check. This corresponds to the init_config section in a Datadog + // integration YAML file. Most checks do not require this. // +optional InitConfig *apiextensionsv1.JSON `json:"initConfig,omitempty"` - // Instances is the list of check instance configurations. - // At least one instance is required. + // Instances defines how the Agent connects to and collects metrics from the + // monitored service. Each entry represents one independent check execution. + // Template variables such as %%host%% and %%port%% can be used and will be + // resolved at runtime to the pod's IP and exposed port. // +kubebuilder:validation:MinItems=1 // +listType=atomic Instances []apiextensionsv1.JSON `json:"instances"` - // Logs defines optional log collection configuration for this check. + // Logs configures log collection from containers matched by this check. + // When set, the Datadog Agent will tail and forward logs according to + // the provided rules (e.g. source, service, log processing pipelines). // +optional Logs *apiextensionsv1.JSON `json:"logs,omitempty"` } @@ -73,9 +84,9 @@ type DatadogPodCheckStatus struct { Conditions []metav1.Condition `json:"conditions,omitempty"` } -// DatadogPodCheck allows a user to define Datadog integration checks that are -// scheduled against pods via the autodiscovery system, without requiring pod -// annotation changes or agent restarts. +// DatadogPodCheck defines Datadog integration checks to run on pods that match +// the given selector. This enables monitoring without modifying pod annotations +// or restarting the Datadog Agent. // +kubebuilder:object:root=true // +kubebuilder:subresource:status // +kubebuilder:resource:path=datadogpodchecks,scope=Namespaced,shortName=ddpc diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_validation.go b/api/datadoghq/v1alpha1/datadogpodcheck_validation.go deleted file mode 100644 index 91c098a32..000000000 --- a/api/datadoghq/v1alpha1/datadogpodcheck_validation.go +++ /dev/null @@ -1,16 +0,0 @@ -// 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 v1alpha1 - -import "fmt" - -// IsValidDatadogPodCheck validates the DatadogPodCheck spec. -func IsValidDatadogPodCheck(spec *DatadogPodCheckSpec) error { - if len(spec.Selector.MatchLabels) == 0 && len(spec.Selector.MatchAnnotations) == 0 { - return fmt.Errorf("spec.selector must have at least one of matchLabels or matchAnnotations set") - } - return nil -} diff --git a/api/datadoghq/v1alpha1/zz_generated.openapi.go b/api/datadoghq/v1alpha1/zz_generated.openapi.go index c5bfb870f..9cef87b78 100644 --- a/api/datadoghq/v1alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v1alpha1/zz_generated.openapi.go @@ -64,12 +64,12 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "CheckConfig defines a Datadog integration check configuration.", + Description: "CheckConfig defines a single Datadog integration check to run on matched pods.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "name": { SchemaProps: spec.SchemaProps{ - Description: "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").", + Description: "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\"). Must correspond to a valid Datadog integration.", Default: "", Type: []string{"string"}, Format: "", @@ -82,7 +82,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer }, }, SchemaProps: spec.SchemaProps{ - Description: "ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names) used for template matching against discovered containers.", + Description: "ADIdentifiers is a list of container identifiers (typically image names like \"nginx\" or \"redis\") that the Datadog Agent uses to determine which container in a pod this check should monitor. When omitted, the check applies to the pod as a whole without targeting a specific container.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -97,7 +97,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer }, "initConfig": { SchemaProps: spec.SchemaProps{ - Description: "InitConfig is the init_config section passed to the integration check.", + Description: "InitConfig holds shared configuration that applies across all instances of this check. This corresponds to the init_config section in a Datadog integration YAML file. Most checks do not require this.", Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), }, }, @@ -108,7 +108,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer }, }, SchemaProps: spec.SchemaProps{ - Description: "Instances is the list of check instance configurations. At least one instance is required.", + Description: "Instances defines how the Agent connects to and collects metrics from the monitored service. Each entry represents one independent check execution. Template variables such as %%host%% and %%port%% can be used and will be resolved at runtime to the pod's IP and exposed port.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -121,7 +121,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer }, "logs": { SchemaProps: spec.SchemaProps{ - Description: "Logs defines optional log collection configuration for this check.", + Description: "Logs configures log collection from containers matched by this check. When set, the Datadog Agent will tail and forward logs according to the provided rules (e.g. source, service, log processing pipelines).", Ref: ref("k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1.JSON"), }, }, @@ -1901,7 +1901,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheck(ref common.R return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "DatadogPodCheck allows a user to define Datadog integration checks that are scheduled against pods via the autodiscovery system, without requiring pod annotation changes or agent restarts.", + Description: "DatadogPodCheck defines Datadog integration checks to run on pods that match the given selector. This enables monitoring without modifying pod annotations or restarting the Datadog Agent.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "kind": { @@ -1953,7 +1953,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref comm Properties: map[string]spec.Schema{ "selector": { SchemaProps: spec.SchemaProps{ - Description: "Selector provides targeting criteria to narrow which pods these checks apply to. At least one of matchLabels or matchAnnotations must be set. When both are specified, all fields are ANDed together.", + Description: "Selector determines which pods this DatadogPodCheck applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected.", Default: map[string]interface{}{}, Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), }, @@ -1965,7 +1965,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref comm }, }, SchemaProps: spec.SchemaProps{ - Description: "Checks is the list of integration check configurations to schedule.", + Description: "Checks is the list of Datadog integration checks to run on the selected pods. Each entry defines one check, including what to monitor and how to connect to it.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -2330,12 +2330,12 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref common.Refer return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "PodSelector defines criteria for selecting pods by labels and annotations. All specified fields are ANDed together.", + Description: "PodSelector defines criteria for selecting pods by labels and annotations.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "matchLabels": { SchemaProps: spec.SchemaProps{ - Description: "MatchLabels is a map of key-value pairs that must match a pod's labels.", + Description: "MatchLabels is a map of label key-value pairs. A pod must have all these labels with the exact values specified to be selected.", Type: []string{"object"}, AdditionalProperties: &spec.SchemaOrBool{ Allows: true, @@ -2351,7 +2351,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref common.Refer }, "matchAnnotations": { SchemaProps: spec.SchemaProps{ - Description: "MatchAnnotations is a map of key-value pairs that must match a pod's annotations.", + Description: "MatchAnnotations is a map of annotation key-value pairs. A pod must have all these annotations with the exact values specified to be selected.", Type: []string{"object"}, AdditionalProperties: &spec.SchemaOrBool{ Allows: true, diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml index 9b2408f87..a7d02edf4 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml @@ -24,9 +24,9 @@ spec: schema: openAPIV3Schema: description: |- - DatadogPodCheck allows a user to define Datadog integration checks that are - scheduled against pods via the autodiscovery system, without requiring pod - annotation changes or agent restarts. + DatadogPodCheck defines Datadog integration checks to run on pods that match + the given selector. This enables monitoring without modifying pod annotations + or restarting the Datadog Agent. properties: apiVersion: description: |- @@ -49,35 +49,49 @@ spec: description: DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. properties: checks: - description: Checks is the list of integration check configurations to schedule. + description: |- + Checks is the list of Datadog integration checks to run on the selected pods. + Each entry defines one check, including what to monitor and how to connect to it. items: - description: CheckConfig defines a Datadog integration check configuration. + description: CheckConfig defines a single Datadog integration check to run on matched pods. properties: adIdentifiers: description: |- - ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names) - used for template matching against discovered containers. + ADIdentifiers is a list of container identifiers (typically image names like + "nginx" or "redis") that the Datadog Agent uses to determine which container + in a pod this check should monitor. When omitted, the check applies to the + pod as a whole without targeting a specific container. items: type: string type: array x-kubernetes-list-type: atomic initConfig: - description: InitConfig is the init_config section passed to the integration check. + description: |- + InitConfig holds shared configuration that applies across all instances of + this check. This corresponds to the init_config section in a Datadog + integration YAML file. Most checks do not require this. x-kubernetes-preserve-unknown-fields: true instances: description: |- - Instances is the list of check instance configurations. - At least one instance is required. + Instances defines how the Agent connects to and collects metrics from the + monitored service. Each entry represents one independent check execution. + Template variables such as %%host%% and %%port%% can be used and will be + resolved at runtime to the pod's IP and exposed port. items: x-kubernetes-preserve-unknown-fields: true minItems: 1 type: array x-kubernetes-list-type: atomic logs: - description: Logs defines optional log collection configuration for this check. + description: |- + Logs configures log collection from containers matched by this check. + When set, the Datadog Agent will tail and forward logs according to + the provided rules (e.g. source, service, log processing pipelines). x-kubernetes-preserve-unknown-fields: true name: - description: Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + description: |- + Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + Must correspond to a valid Datadog integration. type: string required: - instances @@ -88,19 +102,23 @@ spec: x-kubernetes-list-type: atomic selector: description: |- - Selector provides targeting criteria to narrow which pods these - checks apply to. At least one of matchLabels or matchAnnotations must be set. - When both are specified, all fields are ANDed together. + Selector determines which pods this DatadogPodCheck applies to. + At least one of matchLabels or matchAnnotations must be set. + When both are specified, a pod must match all criteria to be selected. properties: matchAnnotations: additionalProperties: type: string - description: MatchAnnotations is a map of key-value pairs that must match a pod's annotations. + description: |- + MatchAnnotations is a map of annotation key-value pairs. A pod must have all + these annotations with the exact values specified to be selected. type: object matchLabels: additionalProperties: type: string - description: MatchLabels is a map of key-value pairs that must match a pod's labels. + description: |- + MatchLabels is a map of label key-value pairs. A pod must have all + these labels with the exact values specified to be selected. type: object type: object required: diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json index 9d839eb0b..0d4399622 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json @@ -1,6 +1,6 @@ { "additionalProperties": false, - "description": "DatadogPodCheck allows a user to define Datadog integration checks that are\nscheduled against pods via the autodiscovery system, without requiring pod\nannotation changes or agent restarts.", + "description": "DatadogPodCheck defines Datadog integration checks to run on pods that match\nthe given selector. This enables monitoring without modifying pod annotations\nor restarting the Datadog Agent.", "properties": { "apiVersion": { "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", @@ -18,13 +18,13 @@ "description": "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", "properties": { "checks": { - "description": "Checks is the list of integration check configurations to schedule.", + "description": "Checks is the list of Datadog integration checks to run on the selected pods.\nEach entry defines one check, including what to monitor and how to connect to it.", "items": { "additionalProperties": false, - "description": "CheckConfig defines a Datadog integration check configuration.", + "description": "CheckConfig defines a single Datadog integration check to run on matched pods.", "properties": { "adIdentifiers": { - "description": "ADIdentifiers is the list of autodiscovery identifiers (e.g. container image names)\nused for template matching against discovered containers.", + "description": "ADIdentifiers is a list of container identifiers (typically image names like\n\"nginx\" or \"redis\") that the Datadog Agent uses to determine which container\nin a pod this check should monitor. When omitted, the check applies to the\npod as a whole without targeting a specific container.", "items": { "type": "string" }, @@ -32,11 +32,11 @@ "x-kubernetes-list-type": "atomic" }, "initConfig": { - "description": "InitConfig is the init_config section passed to the integration check.", + "description": "InitConfig holds shared configuration that applies across all instances of\nthis check. This corresponds to the init_config section in a Datadog\nintegration YAML file. Most checks do not require this.", "x-kubernetes-preserve-unknown-fields": true }, "instances": { - "description": "Instances is the list of check instance configurations.\nAt least one instance is required.", + "description": "Instances defines how the Agent connects to and collects metrics from the\nmonitored service. Each entry represents one independent check execution.\nTemplate variables such as %%host%% and %%port%% can be used and will be\nresolved at runtime to the pod's IP and exposed port.", "items": { "x-kubernetes-preserve-unknown-fields": true }, @@ -45,11 +45,11 @@ "x-kubernetes-list-type": "atomic" }, "logs": { - "description": "Logs defines optional log collection configuration for this check.", + "description": "Logs configures log collection from containers matched by this check.\nWhen set, the Datadog Agent will tail and forward logs according to\nthe provided rules (e.g. source, service, log processing pipelines).", "x-kubernetes-preserve-unknown-fields": true }, "name": { - "description": "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").", + "description": "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").\nMust correspond to a valid Datadog integration.", "type": "string" } }, @@ -65,20 +65,20 @@ }, "selector": { "additionalProperties": false, - "description": "Selector provides targeting criteria to narrow which pods these\nchecks apply to. At least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, all fields are ANDed together.", + "description": "Selector determines which pods this DatadogPodCheck applies to.\nAt least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, a pod must match all criteria to be selected.", "properties": { "matchAnnotations": { "additionalProperties": { "type": "string" }, - "description": "MatchAnnotations is a map of key-value pairs that must match a pod's annotations.", + "description": "MatchAnnotations is a map of annotation key-value pairs. A pod must have all\nthese annotations with the exact values specified to be selected.", "type": "object" }, "matchLabels": { "additionalProperties": { "type": "string" }, - "description": "MatchLabels is a map of key-value pairs that must match a pod's labels.", + "description": "MatchLabels is a map of label key-value pairs. A pod must have all\nthese labels with the exact values specified to be selected.", "type": "object" } }, diff --git a/internal/controller/datadogagent/feature/podcheck/feature.go b/internal/controller/datadogagent/feature/podcheck/feature.go index 03a80318e..a97c19d99 100644 --- a/internal/controller/datadogagent/feature/podcheck/feature.go +++ b/internal/controller/datadogagent/feature/podcheck/feature.go @@ -137,13 +137,11 @@ func getRBACResourceName(owner metav1.Object, suffix string) string { func getPolicyRules(configMapName string) []rbacv1.PolicyRule { return []rbacv1.PolicyRule{ - // Read DatadogPodCheck CRDs { APIGroups: []string{rbac.DatadogAPIGroup}, Resources: []string{"datadogpodchecks"}, Verbs: []string{"get", "list", "watch"}, }, - // Read/update the ConfigMap used to pass check configs between DCA and Node Agent { APIGroups: []string{rbac.CoreAPIGroup}, Resources: []string{rbac.ConfigMapsResource}, From 20e3d46e3d33afb18dd40ea6313d73ea7ab3a613 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Wed, 11 Mar 2026 10:21:28 -0400 Subject: [PATCH 08/12] chore: rename 'name' and 'adidentifer' to more descriptive names --- .../v1alpha1/datadogpodcheck_types.go | 14 ++++++------- .../v1alpha1/zz_generated.deepcopy.go | 4 ++-- .../v1alpha1/zz_generated.openapi.go | 10 ++++----- .../v1/datadoghq.com_datadogpodchecks.yaml | 21 +++++++++---------- ...tadoghq.com_datadogpodchecks_v1alpha1.json | 14 ++++++------- 5 files changed, 30 insertions(+), 33 deletions(-) diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_types.go b/api/datadoghq/v1alpha1/datadogpodcheck_types.go index 6da3d3163..7fd6f2f19 100644 --- a/api/datadoghq/v1alpha1/datadogpodcheck_types.go +++ b/api/datadoghq/v1alpha1/datadogpodcheck_types.go @@ -42,17 +42,15 @@ type PodSelector struct { // CheckConfig defines a single Datadog integration check to run on matched pods. // +k8s:openapi-gen=true type CheckConfig struct { - // Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + // Integration is the Datadog integration name (e.g. "nginx", "http_check", "redis"). // Must correspond to a valid Datadog integration. - Name string `json:"name"` + Integration string `json:"integration"` - // ADIdentifiers is a list of container identifiers (typically image names like - // "nginx" or "redis") that the Datadog Agent uses to determine which container - // in a pod this check should monitor. When omitted, the check applies to the - // pod as a whole without targeting a specific container. - // +optional + // ContainerImage is a list of container image names (e.g. "nginx", "redis") + // that the Datadog Agent uses to determine which container in a pod this + // check should monitor. // +listType=atomic - ADIdentifiers []string `json:"adIdentifiers,omitempty"` + ContainerImage []string `json:"containerImage,omitempty"` // InitConfig holds shared configuration that applies across all instances of // this check. This corresponds to the init_config section in a Datadog diff --git a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go index 903aa895b..220632c2f 100644 --- a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go @@ -22,8 +22,8 @@ import ( // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *CheckConfig) DeepCopyInto(out *CheckConfig) { *out = *in - if in.ADIdentifiers != nil { - in, out := &in.ADIdentifiers, &out.ADIdentifiers + if in.ContainerImage != nil { + in, out := &in.ContainerImage, &out.ContainerImage *out = make([]string, len(*in)) copy(*out, *in) } diff --git a/api/datadoghq/v1alpha1/zz_generated.openapi.go b/api/datadoghq/v1alpha1/zz_generated.openapi.go index 9cef87b78..bf4c41b88 100644 --- a/api/datadoghq/v1alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v1alpha1/zz_generated.openapi.go @@ -67,22 +67,22 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer Description: "CheckConfig defines a single Datadog integration check to run on matched pods.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "name": { + "integration": { SchemaProps: spec.SchemaProps{ - Description: "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\"). Must correspond to a valid Datadog integration.", + Description: "Integration is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\"). Must correspond to a valid Datadog integration.", Default: "", Type: []string{"string"}, Format: "", }, }, - "adIdentifiers": { + "containerImage": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ "x-kubernetes-list-type": "atomic", }, }, SchemaProps: spec.SchemaProps{ - Description: "ADIdentifiers is a list of container identifiers (typically image names like \"nginx\" or \"redis\") that the Datadog Agent uses to determine which container in a pod this check should monitor. When omitted, the check applies to the pod as a whole without targeting a specific container.", + Description: "ContainerImage is a list of container image names (e.g. \"nginx\", \"redis\") that the Datadog Agent uses to determine which container in a pod this check should monitor.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -126,7 +126,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_CheckConfig(ref common.Refer }, }, }, - Required: []string{"name", "instances"}, + Required: []string{"integration", "instances"}, }, }, Dependencies: []string{ diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml index a7d02edf4..3e915b8e0 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml @@ -55,12 +55,11 @@ spec: items: description: CheckConfig defines a single Datadog integration check to run on matched pods. properties: - adIdentifiers: + containerImage: description: |- - ADIdentifiers is a list of container identifiers (typically image names like - "nginx" or "redis") that the Datadog Agent uses to determine which container - in a pod this check should monitor. When omitted, the check applies to the - pod as a whole without targeting a specific container. + ContainerImage is a list of container image names (e.g. "nginx", "redis") + that the Datadog Agent uses to determine which container in a pod this + check should monitor. items: type: string type: array @@ -82,20 +81,20 @@ spec: minItems: 1 type: array x-kubernetes-list-type: atomic + integration: + description: |- + Integration is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + Must correspond to a valid Datadog integration. + type: string logs: description: |- Logs configures log collection from containers matched by this check. When set, the Datadog Agent will tail and forward logs according to the provided rules (e.g. source, service, log processing pipelines). x-kubernetes-preserve-unknown-fields: true - name: - description: |- - Name is the Datadog integration name (e.g. "nginx", "http_check", "redis"). - Must correspond to a valid Datadog integration. - type: string required: - instances - - name + - integration type: object minItems: 1 type: array diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json index 0d4399622..68962b91a 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json @@ -23,8 +23,8 @@ "additionalProperties": false, "description": "CheckConfig defines a single Datadog integration check to run on matched pods.", "properties": { - "adIdentifiers": { - "description": "ADIdentifiers is a list of container identifiers (typically image names like\n\"nginx\" or \"redis\") that the Datadog Agent uses to determine which container\nin a pod this check should monitor. When omitted, the check applies to the\npod as a whole without targeting a specific container.", + "containerImage": { + "description": "ContainerImage is a list of container image names (e.g. \"nginx\", \"redis\")\nthat the Datadog Agent uses to determine which container in a pod this\ncheck should monitor.", "items": { "type": "string" }, @@ -44,18 +44,18 @@ "type": "array", "x-kubernetes-list-type": "atomic" }, + "integration": { + "description": "Integration is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").\nMust correspond to a valid Datadog integration.", + "type": "string" + }, "logs": { "description": "Logs configures log collection from containers matched by this check.\nWhen set, the Datadog Agent will tail and forward logs according to\nthe provided rules (e.g. source, service, log processing pipelines).", "x-kubernetes-preserve-unknown-fields": true - }, - "name": { - "description": "Name is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").\nMust correspond to a valid Datadog integration.", - "type": "string" } }, "required": [ "instances", - "name" + "integration" ], "type": "object" }, From 56ca33852447879c6f7a904b63772fac2b83a48d Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Wed, 11 Mar 2026 15:31:59 -0400 Subject: [PATCH 09/12] feat: rename to general DatadogWorkloadConfig CRD --- ...ypes.go => datadogworkloadconfig_types.go} | 46 +-- .../v1alpha1/zz_generated.deepcopy.go | 224 +++++++------- .../v1alpha1/zz_generated.openapi.go | 281 ++++++++++-------- ...datadoghq.com_datadogworkloadconfigs.yaml} | 134 +++++---- ....com_datadogworkloadconfigs_v1alpha1.json} | 103 ++++--- config/crd/kustomization.yaml | 2 +- config/rbac/role.yaml | 4 +- .../controller/datadogagent/controller.go | 2 +- .../controller/datadogagent/feature/ids.go | 4 +- .../{podcheck => workloadconfig}/feature.go | 52 ++-- .../controller/datadogagent_controller.go | 6 +- 11 files changed, 459 insertions(+), 399 deletions(-) rename api/datadoghq/v1alpha1/{datadogpodcheck_types.go => datadogworkloadconfig_types.go} (69%) rename config/crd/bases/v1/{datadoghq.com_datadogpodchecks.yaml => datadoghq.com_datadogworkloadconfigs.yaml} (58%) rename config/crd/bases/v1/{datadoghq.com_datadogpodchecks_v1alpha1.json => datadoghq.com_datadogworkloadconfigs_v1alpha1.json} (57%) rename internal/controller/datadogagent/feature/{podcheck => workloadconfig}/feature.go (64%) diff --git a/api/datadoghq/v1alpha1/datadogpodcheck_types.go b/api/datadoghq/v1alpha1/datadogworkloadconfig_types.go similarity index 69% rename from api/datadoghq/v1alpha1/datadogpodcheck_types.go rename to api/datadoghq/v1alpha1/datadogworkloadconfig_types.go index 7fd6f2f19..93f8bcfe5 100644 --- a/api/datadoghq/v1alpha1/datadogpodcheck_types.go +++ b/api/datadoghq/v1alpha1/datadogworkloadconfig_types.go @@ -10,19 +10,29 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. +// DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig. // +k8s:openapi-gen=true -type DatadogPodCheckSpec struct { - // Selector determines which pods this DatadogPodCheck applies to. +type DatadogWorkloadConfigSpec struct { + // Selector determines which pods this DatadogWorkloadConfig applies to. // At least one of matchLabels or matchAnnotations must be set. // When both are specified, a pod must match all criteria to be selected. Selector PodSelector `json:"selector"` + // Config holds the Datadog feature configurations to apply to the selected pods. + Config WorkloadConfig `json:"config"` +} + +// WorkloadConfig holds the set of Datadog features to configure for the +// selected pods. Currently supports integration checks; APM instrumentation +// will be added in a future release. +// +k8s:openapi-gen=true +type WorkloadConfig struct { // Checks is the list of Datadog integration checks to run on the selected pods. // Each entry defines one check, including what to monitor and how to connect to it. + // +optional // +kubebuilder:validation:MinItems=1 // +listType=atomic - Checks []CheckConfig `json:"checks"` + Checks []CheckConfig `json:"checks,omitempty"` } // PodSelector defines criteria for selecting pods by labels and annotations. @@ -73,40 +83,40 @@ type CheckConfig struct { Logs *apiextensionsv1.JSON `json:"logs,omitempty"` } -// DatadogPodCheckStatus defines the observed state of a DatadogPodCheck. +// DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig. // +k8s:openapi-gen=true -type DatadogPodCheckStatus struct { - // Conditions represents the latest available observations of the state of a DatadogPodCheck. +type DatadogWorkloadConfigStatus struct { + // Conditions represents the latest available observations of the state of a DatadogWorkloadConfig. // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty"` } -// DatadogPodCheck defines Datadog integration checks to run on pods that match -// the given selector. This enables monitoring without modifying pod annotations -// or restarting the Datadog Agent. +// DatadogWorkloadConfig defines Datadog features like integration checks to apply +// to the matching workload using the given selector. This enables dynamic configuration +// of monitoring without modifying workloads or restarting the Datadog Agent. // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:resource:path=datadogpodchecks,scope=Namespaced,shortName=ddpc +// +kubebuilder:resource:path=datadogworkloadconfigs,scope=Namespaced,shortName=ddwc // +kubebuilder:printcolumn:name="age",type="date",JSONPath=".metadata.creationTimestamp" // +k8s:openapi-gen=true // +genclient -type DatadogPodCheck struct { +type DatadogWorkloadConfig struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec DatadogPodCheckSpec `json:"spec,omitempty"` - Status DatadogPodCheckStatus `json:"status,omitempty"` + Spec DatadogWorkloadConfigSpec `json:"spec,omitempty"` + Status DatadogWorkloadConfigStatus `json:"status,omitempty"` } -// DatadogPodCheckList contains a list of DatadogPodCheck resources. +// DatadogWorkloadConfigList contains a list of DatadogWorkloadConfig resources. // +kubebuilder:object:root=true -type DatadogPodCheckList struct { +type DatadogWorkloadConfigList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []DatadogPodCheck `json:"items"` + Items []DatadogWorkloadConfig `json:"items"` } func init() { - SchemeBuilder.Register(&DatadogPodCheck{}, &DatadogPodCheckList{}) + SchemeBuilder.Register(&DatadogWorkloadConfig{}, &DatadogWorkloadConfigList{}) } diff --git a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go index 220632c2f..93198e011 100644 --- a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go @@ -1347,110 +1347,6 @@ func (in *DatadogPodAutoscalerSpec) DeepCopy() *DatadogPodAutoscalerSpec { return out } -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogPodCheck) DeepCopyInto(out *DatadogPodCheck) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheck. -func (in *DatadogPodCheck) DeepCopy() *DatadogPodCheck { - if in == nil { - return nil - } - out := new(DatadogPodCheck) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DatadogPodCheck) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogPodCheckList) DeepCopyInto(out *DatadogPodCheckList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]DatadogPodCheck, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheckList. -func (in *DatadogPodCheckList) DeepCopy() *DatadogPodCheckList { - if in == nil { - return nil - } - out := new(DatadogPodCheckList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DatadogPodCheckList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogPodCheckSpec) DeepCopyInto(out *DatadogPodCheckSpec) { - *out = *in - in.Selector.DeepCopyInto(&out.Selector) - if in.Checks != nil { - in, out := &in.Checks, &out.Checks - *out = make([]CheckConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheckSpec. -func (in *DatadogPodCheckSpec) DeepCopy() *DatadogPodCheckSpec { - if in == nil { - return nil - } - out := new(DatadogPodCheckSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogPodCheckStatus) DeepCopyInto(out *DatadogPodCheckStatus) { - *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogPodCheckStatus. -func (in *DatadogPodCheckStatus) DeepCopy() *DatadogPodCheckStatus { - if in == nil { - return nil - } - out := new(DatadogPodCheckStatus) - in.DeepCopyInto(out) - return out -} - // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DatadogSLO) DeepCopyInto(out *DatadogSLO) { *out = *in @@ -1626,6 +1522,104 @@ func (in *DatadogSLOStatus) DeepCopy() *DatadogSLOStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogWorkloadConfig) DeepCopyInto(out *DatadogWorkloadConfig) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfig. +func (in *DatadogWorkloadConfig) DeepCopy() *DatadogWorkloadConfig { + if in == nil { + return nil + } + out := new(DatadogWorkloadConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DatadogWorkloadConfig) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogWorkloadConfigList) DeepCopyInto(out *DatadogWorkloadConfigList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DatadogWorkloadConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfigList. +func (in *DatadogWorkloadConfigList) DeepCopy() *DatadogWorkloadConfigList { + if in == nil { + return nil + } + out := new(DatadogWorkloadConfigList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DatadogWorkloadConfigList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogWorkloadConfigSpec) DeepCopyInto(out *DatadogWorkloadConfigSpec) { + *out = *in + in.Selector.DeepCopyInto(&out.Selector) + in.Config.DeepCopyInto(&out.Config) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfigSpec. +func (in *DatadogWorkloadConfigSpec) DeepCopy() *DatadogWorkloadConfigSpec { + if in == nil { + return nil + } + out := new(DatadogWorkloadConfigSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogWorkloadConfigStatus) DeepCopyInto(out *DatadogWorkloadConfigStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfigStatus. +func (in *DatadogWorkloadConfigStatus) DeepCopy() *DatadogWorkloadConfigStatus { + if in == nil { + return nil + } + out := new(DatadogWorkloadConfigStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodSelector) DeepCopyInto(out *PodSelector) { *out = *in @@ -1676,3 +1670,25 @@ func (in *ProfileAffinity) DeepCopy() *ProfileAffinity { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WorkloadConfig) DeepCopyInto(out *WorkloadConfig) { + *out = *in + if in.Checks != nil { + in, out := &in.Checks, &out.Checks + *out = make([]CheckConfig, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadConfig. +func (in *WorkloadConfig) DeepCopy() *WorkloadConfig { + if in == nil { + return nil + } + out := new(WorkloadConfig) + in.DeepCopyInto(out) + return out +} diff --git a/api/datadoghq/v1alpha1/zz_generated.openapi.go b/api/datadoghq/v1alpha1/zz_generated.openapi.go index bf4c41b88..322707ff5 100644 --- a/api/datadoghq/v1alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v1alpha1/zz_generated.openapi.go @@ -48,15 +48,16 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitorSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorSpec(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitorStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorStatus(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitorTriggeredState": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorTriggeredState(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheck": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheck(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckStatus(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLO": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLO(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOControllerOptions": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOControllerOptions(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOQuery": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOQuery(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOSpec(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOStatus(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfig": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfig(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigSpec(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigStatus(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector": schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.WorkloadConfig": schema_datadog_operator_api_datadoghq_v1alpha1_WorkloadConfig(ref), } } @@ -1897,132 +1898,6 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitorTriggeredState } } -func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheck(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatadogPodCheck defines Datadog integration checks to run on pods that match the given selector. This enables monitoring without modifying pod annotations or restarting the Datadog Agent.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckSpec", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogPodCheckStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "selector": { - SchemaProps: spec.SchemaProps{ - Description: "Selector determines which pods this DatadogPodCheck applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected.", - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), - }, - }, - "checks": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Checks is the list of Datadog integration checks to run on the selected pods. Each entry defines one check, including what to monitor and how to connect to it.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), - }, - }, - }, - }, - }, - }, - Required: []string{"selector", "checks"}, - }, - }, - Dependencies: []string{ - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"}, - } -} - -func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogPodCheckStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatadogPodCheckStatus defines the observed state of a DatadogPodCheck.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "conditions": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-map-keys": []interface{}{ - "type", - }, - "x-kubernetes-list-type": "map", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Conditions represents the latest available observations of the state of a DatadogPodCheck.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, - } -} - func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLO(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2326,6 +2201,120 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOStatus(ref common. } } +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogWorkloadConfig defines Datadog features like integration checks to apply to the matching workload using the given selector. This enables dynamic configuration of monitoring without modifying workloads or restarting the Datadog Agent.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigSpec", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "selector": { + SchemaProps: spec.SchemaProps{ + Description: "Selector determines which pods this DatadogWorkloadConfig applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected.", + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), + }, + }, + "config": { + SchemaProps: spec.SchemaProps{ + Description: "Config holds the Datadog feature configurations to apply to the selected pods.", + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.WorkloadConfig"), + }, + }, + }, + Required: []string{"selector", "config"}, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.WorkloadConfig"}, + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "type", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Conditions represents the latest available observations of the state of a DatadogWorkloadConfig.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, + } +} + func schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2370,3 +2359,37 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref common.Refer }, } } + +func schema_datadog_operator_api_datadoghq_v1alpha1_WorkloadConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "WorkloadConfig holds the set of Datadog features to configure for the selected pods. Currently supports integration checks; APM instrumentation will be added in a future release.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "checks": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Checks is the list of Datadog integration checks to run on the selected pods. Each entry defines one check, including what to monitor and how to connect to it.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"}, + } +} diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml b/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs.yaml similarity index 58% rename from config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml rename to config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs.yaml index 3e915b8e0..75cc70ca0 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs.yaml @@ -4,16 +4,16 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.17.3 - name: datadogpodchecks.datadoghq.com + name: datadogworkloadconfigs.datadoghq.com spec: group: datadoghq.com names: - kind: DatadogPodCheck - listKind: DatadogPodCheckList - plural: datadogpodchecks + kind: DatadogWorkloadConfig + listKind: DatadogWorkloadConfigList + plural: datadogworkloadconfigs shortNames: - - ddpc - singular: datadogpodcheck + - ddwc + singular: datadogworkloadconfig scope: Namespaced versions: - additionalPrinterColumns: @@ -24,9 +24,9 @@ spec: schema: openAPIV3Schema: description: |- - DatadogPodCheck defines Datadog integration checks to run on pods that match - the given selector. This enables monitoring without modifying pod annotations - or restarting the Datadog Agent. + DatadogWorkloadConfig defines Datadog features like integration checks to apply + to the matching workload using the given selector. This enables dynamic configuration + of monitoring without modifying workloads or restarting the Datadog Agent. properties: apiVersion: description: |- @@ -46,62 +46,66 @@ spec: metadata: type: object spec: - description: DatadogPodCheckSpec defines the desired state of a DatadogPodCheck. + description: DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig. properties: - checks: - description: |- - Checks is the list of Datadog integration checks to run on the selected pods. - Each entry defines one check, including what to monitor and how to connect to it. - items: - description: CheckConfig defines a single Datadog integration check to run on matched pods. - properties: - containerImage: - description: |- - ContainerImage is a list of container image names (e.g. "nginx", "redis") - that the Datadog Agent uses to determine which container in a pod this - check should monitor. - items: - type: string - type: array - x-kubernetes-list-type: atomic - initConfig: - description: |- - InitConfig holds shared configuration that applies across all instances of - this check. This corresponds to the init_config section in a Datadog - integration YAML file. Most checks do not require this. - x-kubernetes-preserve-unknown-fields: true - instances: - description: |- - Instances defines how the Agent connects to and collects metrics from the - monitored service. Each entry represents one independent check execution. - Template variables such as %%host%% and %%port%% can be used and will be - resolved at runtime to the pod's IP and exposed port. - items: - x-kubernetes-preserve-unknown-fields: true - minItems: 1 - type: array - x-kubernetes-list-type: atomic - integration: - description: |- - Integration is the Datadog integration name (e.g. "nginx", "http_check", "redis"). - Must correspond to a valid Datadog integration. - type: string - logs: - description: |- - Logs configures log collection from containers matched by this check. - When set, the Datadog Agent will tail and forward logs according to - the provided rules (e.g. source, service, log processing pipelines). - x-kubernetes-preserve-unknown-fields: true - required: - - instances - - integration - type: object - minItems: 1 - type: array - x-kubernetes-list-type: atomic + config: + description: Config holds the Datadog feature configurations to apply to the selected pods. + properties: + checks: + description: |- + Checks is the list of Datadog integration checks to run on the selected pods. + Each entry defines one check, including what to monitor and how to connect to it. + items: + description: CheckConfig defines a single Datadog integration check to run on matched pods. + properties: + containerImage: + description: |- + ContainerImage is a list of container image names (e.g. "nginx", "redis") + that the Datadog Agent uses to determine which container in a pod this + check should monitor. + items: + type: string + type: array + x-kubernetes-list-type: atomic + initConfig: + description: |- + InitConfig holds shared configuration that applies across all instances of + this check. This corresponds to the init_config section in a Datadog + integration YAML file. Most checks do not require this. + x-kubernetes-preserve-unknown-fields: true + instances: + description: |- + Instances defines how the Agent connects to and collects metrics from the + monitored service. Each entry represents one independent check execution. + Template variables such as %%host%% and %%port%% can be used and will be + resolved at runtime to the pod's IP and exposed port. + items: + x-kubernetes-preserve-unknown-fields: true + minItems: 1 + type: array + x-kubernetes-list-type: atomic + integration: + description: |- + Integration is the Datadog integration name (e.g. "nginx", "http_check", "redis"). + Must correspond to a valid Datadog integration. + type: string + logs: + description: |- + Logs configures log collection from containers matched by this check. + When set, the Datadog Agent will tail and forward logs according to + the provided rules (e.g. source, service, log processing pipelines). + x-kubernetes-preserve-unknown-fields: true + required: + - instances + - integration + type: object + minItems: 1 + type: array + x-kubernetes-list-type: atomic + type: object selector: description: |- - Selector determines which pods this DatadogPodCheck applies to. + Selector determines which pods this DatadogWorkloadConfig applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected. properties: @@ -121,14 +125,14 @@ spec: type: object type: object required: - - checks + - config - selector type: object status: - description: DatadogPodCheckStatus defines the observed state of a DatadogPodCheck. + description: DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig. properties: conditions: - description: Conditions represents the latest available observations of the state of a DatadogPodCheck. + description: Conditions represents the latest available observations of the state of a DatadogWorkloadConfig. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: diff --git a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs_v1alpha1.json similarity index 57% rename from config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json rename to config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs_v1alpha1.json index 68962b91a..e43431fa3 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogpodchecks_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs_v1alpha1.json @@ -1,6 +1,6 @@ { "additionalProperties": false, - "description": "DatadogPodCheck defines Datadog integration checks to run on pods that match\nthe given selector. This enables monitoring without modifying pod annotations\nor restarting the Datadog Agent.", + "description": "DatadogWorkloadConfig defines Datadog features like integration checks to apply\nto the matching workload using the given selector. This enables dynamic configuration\nof monitoring without modifying workloads or restarting the Datadog Agent.", "properties": { "apiVersion": { "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", @@ -15,57 +15,64 @@ }, "spec": { "additionalProperties": false, - "description": "DatadogPodCheckSpec defines the desired state of a DatadogPodCheck.", + "description": "DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig.", "properties": { - "checks": { - "description": "Checks is the list of Datadog integration checks to run on the selected pods.\nEach entry defines one check, including what to monitor and how to connect to it.", - "items": { - "additionalProperties": false, - "description": "CheckConfig defines a single Datadog integration check to run on matched pods.", - "properties": { - "containerImage": { - "description": "ContainerImage is a list of container image names (e.g. \"nginx\", \"redis\")\nthat the Datadog Agent uses to determine which container in a pod this\ncheck should monitor.", - "items": { - "type": "string" - }, - "type": "array", - "x-kubernetes-list-type": "atomic" - }, - "initConfig": { - "description": "InitConfig holds shared configuration that applies across all instances of\nthis check. This corresponds to the init_config section in a Datadog\nintegration YAML file. Most checks do not require this.", - "x-kubernetes-preserve-unknown-fields": true - }, - "instances": { - "description": "Instances defines how the Agent connects to and collects metrics from the\nmonitored service. Each entry represents one independent check execution.\nTemplate variables such as %%host%% and %%port%% can be used and will be\nresolved at runtime to the pod's IP and exposed port.", - "items": { - "x-kubernetes-preserve-unknown-fields": true + "config": { + "additionalProperties": false, + "description": "Config holds the Datadog feature configurations to apply to the selected pods.", + "properties": { + "checks": { + "description": "Checks is the list of Datadog integration checks to run on the selected pods.\nEach entry defines one check, including what to monitor and how to connect to it.", + "items": { + "additionalProperties": false, + "description": "CheckConfig defines a single Datadog integration check to run on matched pods.", + "properties": { + "containerImage": { + "description": "ContainerImage is a list of container image names (e.g. \"nginx\", \"redis\")\nthat the Datadog Agent uses to determine which container in a pod this\ncheck should monitor.", + "items": { + "type": "string" + }, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "initConfig": { + "description": "InitConfig holds shared configuration that applies across all instances of\nthis check. This corresponds to the init_config section in a Datadog\nintegration YAML file. Most checks do not require this.", + "x-kubernetes-preserve-unknown-fields": true + }, + "instances": { + "description": "Instances defines how the Agent connects to and collects metrics from the\nmonitored service. Each entry represents one independent check execution.\nTemplate variables such as %%host%% and %%port%% can be used and will be\nresolved at runtime to the pod's IP and exposed port.", + "items": { + "x-kubernetes-preserve-unknown-fields": true + }, + "minItems": 1, + "type": "array", + "x-kubernetes-list-type": "atomic" + }, + "integration": { + "description": "Integration is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").\nMust correspond to a valid Datadog integration.", + "type": "string" + }, + "logs": { + "description": "Logs configures log collection from containers matched by this check.\nWhen set, the Datadog Agent will tail and forward logs according to\nthe provided rules (e.g. source, service, log processing pipelines).", + "x-kubernetes-preserve-unknown-fields": true + } }, - "minItems": 1, - "type": "array", - "x-kubernetes-list-type": "atomic" - }, - "integration": { - "description": "Integration is the Datadog integration name (e.g. \"nginx\", \"http_check\", \"redis\").\nMust correspond to a valid Datadog integration.", - "type": "string" + "required": [ + "instances", + "integration" + ], + "type": "object" }, - "logs": { - "description": "Logs configures log collection from containers matched by this check.\nWhen set, the Datadog Agent will tail and forward logs according to\nthe provided rules (e.g. source, service, log processing pipelines).", - "x-kubernetes-preserve-unknown-fields": true - } - }, - "required": [ - "instances", - "integration" - ], - "type": "object" + "minItems": 1, + "type": "array", + "x-kubernetes-list-type": "atomic" + } }, - "minItems": 1, - "type": "array", - "x-kubernetes-list-type": "atomic" + "type": "object" }, "selector": { "additionalProperties": false, - "description": "Selector determines which pods this DatadogPodCheck applies to.\nAt least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, a pod must match all criteria to be selected.", + "description": "Selector determines which pods this DatadogWorkloadConfig applies to.\nAt least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, a pod must match all criteria to be selected.", "properties": { "matchAnnotations": { "additionalProperties": { @@ -86,17 +93,17 @@ } }, "required": [ - "checks", + "config", "selector" ], "type": "object" }, "status": { "additionalProperties": false, - "description": "DatadogPodCheckStatus defines the observed state of a DatadogPodCheck.", + "description": "DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig.", "properties": { "conditions": { - "description": "Conditions represents the latest available observations of the state of a DatadogPodCheck.", + "description": "Conditions represents the latest available observations of the state of a DatadogWorkloadConfig.", "items": { "additionalProperties": false, "description": "Condition contains details for one aspect of the current state of this API Resource.", diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index cae274087..40fceb2cd 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -13,7 +13,7 @@ resources: - bases/v1/datadoghq.com_datadogdashboards.yaml - bases/v1/datadoghq.com_datadoggenericresources.yaml - bases/v1/datadoghq.com_datadogagentinternals.yaml -- bases/v1/datadoghq.com_datadogpodchecks.yaml +- bases/v1/datadoghq.com_datadogworkloadconfigs.yaml # +kubebuilder:scaffold:crdkustomizeresource #patches: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index f61166588..511400566 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -258,8 +258,8 @@ rules: - datadogdashboards/status - datadoggenericresources/status - datadogmonitors/status - - datadogpodchecks/status - datadogslos/status + - datadogworkloadconfigs/status verbs: - get - patch @@ -291,7 +291,7 @@ rules: - apiGroups: - datadoghq.com resources: - - datadogpodchecks + - datadogworkloadconfigs - extendeddaemonsetreplicasets - watermarkpodautoscalers verbs: diff --git a/internal/controller/datadogagent/controller.go b/internal/controller/datadogagent/controller.go index 69d3f6328..394b880c5 100644 --- a/internal/controller/datadogagent/controller.go +++ b/internal/controller/datadogagent/controller.go @@ -52,7 +52,6 @@ import ( _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/otelagentgateway" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/otelcollector" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/otlp" - _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/podcheck" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/privateactionrunner" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/processdiscovery" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/prometheusscrape" @@ -61,6 +60,7 @@ import ( _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/servicediscovery" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/tcpqueuelength" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/usm" + _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/workloadconfig" ) const ( diff --git a/internal/controller/datadogagent/feature/ids.go b/internal/controller/datadogagent/feature/ids.go index 95d6d6ef5..242af07de 100644 --- a/internal/controller/datadogagent/feature/ids.go +++ b/internal/controller/datadogagent/feature/ids.go @@ -85,6 +85,6 @@ const ( PrivateActionRunnerIDType = "private_action_runner" // DataPlaneIDType Data Plane feature. DataPlaneIDType = "data_plane" - // PodCheckIDType Pod Check feature. - PodCheckIDType = "pod_check" + // WorkloadConfigIDType Workload Config feature. + WorkloadConfigIDType = "workload_config" ) diff --git a/internal/controller/datadogagent/feature/podcheck/feature.go b/internal/controller/datadogagent/feature/workloadconfig/feature.go similarity index 64% rename from internal/controller/datadogagent/feature/podcheck/feature.go rename to internal/controller/datadogagent/feature/workloadconfig/feature.go index a97c19d99..be1fdbc77 100644 --- a/internal/controller/datadogagent/feature/podcheck/feature.go +++ b/internal/controller/datadogagent/feature/workloadconfig/feature.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -package podcheck +package workloadconfig import ( "fmt" @@ -24,37 +24,37 @@ import ( ) const ( - podCheckRBACPrefix = "pod-check" - podCheckVolumeName = "crd-check-conf" - crdConfigDirectory = "crd-conf.d" - podCheckConfigMapSuffix = "crd-check-conf" + workloadConfigRBACPrefix = "workload-config" + workloadConfigVolumeName = "crd-check-conf" + crdConfigDirectory = "crd-conf.d" + workloadConfigConfigMapSuffix = "crd-check-conf" ) func init() { - err := feature.Register(feature.PodCheckIDType, buildPodCheckFeature) + err := feature.Register(feature.WorkloadConfigIDType, buildWorkloadConfigFeature) if err != nil { panic(err) } } -func buildPodCheckFeature(_ *feature.Options) feature.Feature { - return &podCheckFeature{} +func buildWorkloadConfigFeature(_ *feature.Options) feature.Feature { + return &workloadConfigFeature{} } -type podCheckFeature struct { +type workloadConfigFeature struct { owner metav1.Object configMapName string serviceAccountName string rbacSuffix string } -func (f *podCheckFeature) ID() feature.IDType { - return feature.PodCheckIDType +func (f *workloadConfigFeature) ID() feature.IDType { + return feature.WorkloadConfigIDType } -func (f *podCheckFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) feature.RequiredComponents { +func (f *workloadConfigFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) feature.RequiredComponents { f.owner = dda - f.configMapName = fmt.Sprintf("%s-%s", dda.GetName(), podCheckConfigMapSuffix) + f.configMapName = fmt.Sprintf("%s-%s", dda.GetName(), workloadConfigConfigMapSuffix) f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) f.rbacSuffix = common.ClusterAgentSuffix @@ -70,7 +70,7 @@ func (f *podCheckFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.Datadog } } -func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, _ string) error { +func (f *workloadConfigFeature) ManageDependencies(managers feature.ResourceManagers, _ string) error { // Create the empty ConfigMap that the DCA will populate with check configs. cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ @@ -83,7 +83,7 @@ func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, return err } - // RBAC: allow the Cluster Agent to read DatadogPodCheck CRDs and update the ConfigMap. + // RBAC: allow the Cluster Agent to read DatadogWorkloadConfig CRDs and update the ConfigMap. rbacName := getRBACResourceName(f.owner, f.rbacSuffix) return managers.RBACManager().AddClusterPolicyRules( f.owner.GetNamespace(), @@ -93,14 +93,14 @@ func (f *podCheckFeature) ManageDependencies(managers feature.ResourceManagers, ) } -func (f *podCheckFeature) ManageClusterAgent(_ feature.PodTemplateManagers, _ string) error { +func (f *workloadConfigFeature) ManageClusterAgent(_ feature.PodTemplateManagers, _ string) error { return nil } -func (f *podCheckFeature) ManageNodeAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) +func (f *workloadConfigFeature) ManageNodeAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(f.configMapName, workloadConfigVolumeName) volMount := corev1.VolumeMount{ - Name: podCheckVolumeName, + Name: workloadConfigVolumeName, MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), ReadOnly: true, } @@ -110,10 +110,10 @@ func (f *podCheckFeature) ManageNodeAgent(managers feature.PodTemplateManagers, return nil } -func (f *podCheckFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(f.configMapName, podCheckVolumeName) +func (f *workloadConfigFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(f.configMapName, workloadConfigVolumeName) volMount := corev1.VolumeMount{ - Name: podCheckVolumeName, + Name: workloadConfigVolumeName, MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), ReadOnly: true, } @@ -123,23 +123,23 @@ func (f *podCheckFeature) ManageSingleContainerNodeAgent(managers feature.PodTem return nil } -func (f *podCheckFeature) ManageClusterChecksRunner(_ feature.PodTemplateManagers, _ string) error { +func (f *workloadConfigFeature) ManageClusterChecksRunner(_ feature.PodTemplateManagers, _ string) error { return nil } -func (f *podCheckFeature) ManageOtelAgentGateway(_ feature.PodTemplateManagers, _ string) error { +func (f *workloadConfigFeature) ManageOtelAgentGateway(_ feature.PodTemplateManagers, _ string) error { return nil } func getRBACResourceName(owner metav1.Object, suffix string) string { - return fmt.Sprintf("%s-%s-%s-%s", owner.GetNamespace(), owner.GetName(), podCheckRBACPrefix, suffix) + return fmt.Sprintf("%s-%s-%s-%s", owner.GetNamespace(), owner.GetName(), workloadConfigRBACPrefix, suffix) } func getPolicyRules(configMapName string) []rbacv1.PolicyRule { return []rbacv1.PolicyRule{ { APIGroups: []string{rbac.DatadogAPIGroup}, - Resources: []string{"datadogpodchecks"}, + Resources: []string{"datadogworkloadconfigs"}, Verbs: []string{"get", "list", "watch"}, }, { diff --git a/internal/controller/datadogagent_controller.go b/internal/controller/datadogagent_controller.go index 23993a099..166f111d6 100644 --- a/internal/controller/datadogagent_controller.go +++ b/internal/controller/datadogagent_controller.go @@ -93,9 +93,9 @@ type DatadogAgentReconciler struct { // +kubebuilder:rbac:groups=karpenter.sh,resources=*,verbs=get;list;watch;create;patch;update;delete // +kubebuilder:rbac:groups=karpenter.k8s.aws,resources=*,verbs=get;list -// Pod Check CRD -// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogpodchecks,verbs=get;list;watch -// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogpodchecks/status,verbs=get;update;patch +// WorkloadConfig CRD +// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogworkloadconfigs,verbs=get;list;watch +// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogworkloadconfigs/status,verbs=get;update;patch // Use ExtendedDaemonSet // +kubebuilder:rbac:groups=datadoghq.com,resources=extendeddaemonsets,verbs=get;list;watch;create;update;patch;delete From ee2eaeb66e95f043dcb4c3a5ee98d7922eed5cbc Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Wed, 11 Mar 2026 17:17:37 -0400 Subject: [PATCH 10/12] chore: standardize config map naming --- .../feature/workloadconfig/feature.go | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/internal/controller/datadogagent/feature/workloadconfig/feature.go b/internal/controller/datadogagent/feature/workloadconfig/feature.go index be1fdbc77..21da1e930 100644 --- a/internal/controller/datadogagent/feature/workloadconfig/feature.go +++ b/internal/controller/datadogagent/feature/workloadconfig/feature.go @@ -24,10 +24,10 @@ import ( ) const ( - workloadConfigRBACPrefix = "workload-config" - workloadConfigVolumeName = "crd-check-conf" - crdConfigDirectory = "crd-conf.d" - workloadConfigConfigMapSuffix = "crd-check-conf" + workloadConfigRBACPrefix = "workload-config" + workloadConfigVolumeName = "crd-check-conf" + crdConfigDirectory = "crd-conf.d" + workloadCheckConfigMapName = "datadog-crd-check-conf" ) func init() { @@ -43,7 +43,6 @@ func buildWorkloadConfigFeature(_ *feature.Options) feature.Feature { type workloadConfigFeature struct { owner metav1.Object - configMapName string serviceAccountName string rbacSuffix string } @@ -54,7 +53,6 @@ func (f *workloadConfigFeature) ID() feature.IDType { func (f *workloadConfigFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) feature.RequiredComponents { f.owner = dda - f.configMapName = fmt.Sprintf("%s-%s", dda.GetName(), workloadConfigConfigMapSuffix) f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) f.rbacSuffix = common.ClusterAgentSuffix @@ -74,7 +72,7 @@ func (f *workloadConfigFeature) ManageDependencies(managers feature.ResourceMana // Create the empty ConfigMap that the DCA will populate with check configs. cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: f.configMapName, + Name: workloadCheckConfigMapName, Namespace: f.owner.GetNamespace(), }, Data: map[string]string{}, @@ -89,7 +87,7 @@ func (f *workloadConfigFeature) ManageDependencies(managers feature.ResourceMana f.owner.GetNamespace(), rbacName, f.serviceAccountName, - getPolicyRules(f.configMapName), + getPolicyRules(workloadCheckConfigMapName), ) } @@ -98,7 +96,7 @@ func (f *workloadConfigFeature) ManageClusterAgent(_ feature.PodTemplateManagers } func (f *workloadConfigFeature) ManageNodeAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(f.configMapName, workloadConfigVolumeName) + vol := volume.GetBasicVolume(workloadCheckConfigMapName, workloadConfigVolumeName) volMount := corev1.VolumeMount{ Name: workloadConfigVolumeName, MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), @@ -111,7 +109,7 @@ func (f *workloadConfigFeature) ManageNodeAgent(managers feature.PodTemplateMana } func (f *workloadConfigFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(f.configMapName, workloadConfigVolumeName) + vol := volume.GetBasicVolume(workloadCheckConfigMapName, workloadConfigVolumeName) volMount := corev1.VolumeMount{ Name: workloadConfigVolumeName, MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), From 539d89ffd254fd5fc32c05e69290e3b3e3c6dc73 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 12 Mar 2026 11:55:15 -0400 Subject: [PATCH 11/12] chore: make update golang --- api/go.mod | 1 + api/go.sum | 1 + 2 files changed, 2 insertions(+) diff --git a/api/go.mod b/api/go.mod index e5e42604b..64e89aafc 100644 --- a/api/go.mod +++ b/api/go.mod @@ -9,6 +9,7 @@ require ( github.com/google/go-cmp v0.7.0 github.com/stretchr/testify v1.11.1 k8s.io/api v0.35.1 + k8s.io/apiextensions-apiserver v0.35.1 k8s.io/apimachinery v0.35.1 k8s.io/kube-openapi v0.0.0-20251125145642-4e65d59e963e sigs.k8s.io/controller-runtime v0.22.4 diff --git a/api/go.sum b/api/go.sum index c582a6ade..908249934 100644 --- a/api/go.sum +++ b/api/go.sum @@ -77,6 +77,7 @@ gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= k8s.io/api v0.35.1 h1:0PO/1FhlK/EQNVK5+txc4FuhQibV25VLSdLMmGpDE/Q= +k8s.io/apiextensions-apiserver v0.35.1 h1:p5vvALkknlOcAqARwjS20kJffgzHqwyQRM8vHLwgU7w= k8s.io/apimachinery v0.35.1 h1:yxO6gV555P1YV0SANtnTjXYfiivaTPvCTKX6w6qdDsU= k8s.io/klog/v2 v2.130.1 h1:n9Xl7H1Xvksem4KFG4PYbdQCQxqc/tTUyrgXaOhHSzk= k8s.io/klog/v2 v2.130.1/go.mod h1:3Jpz1GvMt720eyJH1ckRHK1EDfpxISzJ7I9OYgaDtPE= From 877d28ec5510653528773d6b62714002f400ce99 Mon Sep 17 00:00:00 2001 From: Mathew Estafanous Date: Thu, 12 Mar 2026 16:16:13 -0400 Subject: [PATCH 12/12] chore: rename to DatadogInstrumentation --- ...pes.go => datadoginstrumentation_types.go} | 40 +-- .../v1alpha1/zz_generated.deepcopy.go | 210 +++++++-------- .../v1alpha1/zz_generated.openapi.go | 250 +++++++++--------- ...atadoghq.com_datadoginstrumentations.yaml} | 26 +- ...com_datadoginstrumentations_v1alpha1.json} | 10 +- config/crd/kustomization.yaml | 2 +- config/rbac/role.yaml | 22 +- .../controller/datadogagent/controller.go | 2 +- .../controller/datadogagent/feature/ids.go | 4 +- .../feature.go | 54 ++-- .../controller/datadogagent_controller.go | 6 +- 11 files changed, 313 insertions(+), 313 deletions(-) rename api/datadoghq/v1alpha1/{datadogworkloadconfig_types.go => datadoginstrumentation_types.go} (75%) rename config/crd/bases/v1/{datadoghq.com_datadogworkloadconfigs.yaml => datadoghq.com_datadoginstrumentations.yaml} (91%) rename config/crd/bases/v1/{datadoghq.com_datadogworkloadconfigs_v1alpha1.json => datadoghq.com_datadoginstrumentations_v1alpha1.json} (91%) rename internal/controller/datadogagent/feature/{workloadconfig => instrumentation}/feature.go (63%) diff --git a/api/datadoghq/v1alpha1/datadogworkloadconfig_types.go b/api/datadoghq/v1alpha1/datadoginstrumentation_types.go similarity index 75% rename from api/datadoghq/v1alpha1/datadogworkloadconfig_types.go rename to api/datadoghq/v1alpha1/datadoginstrumentation_types.go index 93f8bcfe5..7c39067b8 100644 --- a/api/datadoghq/v1alpha1/datadogworkloadconfig_types.go +++ b/api/datadoghq/v1alpha1/datadoginstrumentation_types.go @@ -10,23 +10,23 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) -// DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig. +// DatadogInstrumentationSpec defines the desired state of a DatadogInstrumentation. // +k8s:openapi-gen=true -type DatadogWorkloadConfigSpec struct { - // Selector determines which pods this DatadogWorkloadConfig applies to. +type DatadogInstrumentationSpec struct { + // Selector determines which pods this DatadogInstrumentation applies to. // At least one of matchLabels or matchAnnotations must be set. // When both are specified, a pod must match all criteria to be selected. Selector PodSelector `json:"selector"` // Config holds the Datadog feature configurations to apply to the selected pods. - Config WorkloadConfig `json:"config"` + Config InstrumentationConfig `json:"config"` } -// WorkloadConfig holds the set of Datadog features to configure for the +// InstrumentationConfig holds the set of Datadog features to configure for the // selected pods. Currently supports integration checks; APM instrumentation // will be added in a future release. // +k8s:openapi-gen=true -type WorkloadConfig struct { +type InstrumentationConfig struct { // Checks is the list of Datadog integration checks to run on the selected pods. // Each entry defines one check, including what to monitor and how to connect to it. // +optional @@ -83,40 +83,40 @@ type CheckConfig struct { Logs *apiextensionsv1.JSON `json:"logs,omitempty"` } -// DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig. +// DatadogInstrumentationStatus defines the observed state of a DatadogInstrumentation. // +k8s:openapi-gen=true -type DatadogWorkloadConfigStatus struct { - // Conditions represents the latest available observations of the state of a DatadogWorkloadConfig. +type DatadogInstrumentationStatus struct { + // Conditions represents the latest available observations of the state of a DatadogInstrumentation. // +listType=map // +listMapKey=type Conditions []metav1.Condition `json:"conditions,omitempty"` } -// DatadogWorkloadConfig defines Datadog features like integration checks to apply -// to the matching workload using the given selector. This enables dynamic configuration -// of monitoring without modifying workloads or restarting the Datadog Agent. +// DatadogInstrumentation defines Datadog features such as integration checks and +// APM instrumentation to apply to pods that match the given selector. This enables +// monitoring without modifying pod annotations or restarting the Datadog Agent. // +kubebuilder:object:root=true // +kubebuilder:subresource:status -// +kubebuilder:resource:path=datadogworkloadconfigs,scope=Namespaced,shortName=ddwc +// +kubebuilder:resource:path=datadoginstrumentations,scope=Namespaced,shortName=ddi // +kubebuilder:printcolumn:name="age",type="date",JSONPath=".metadata.creationTimestamp" // +k8s:openapi-gen=true // +genclient -type DatadogWorkloadConfig struct { +type DatadogInstrumentation struct { metav1.TypeMeta `json:",inline"` metav1.ObjectMeta `json:"metadata,omitempty"` - Spec DatadogWorkloadConfigSpec `json:"spec,omitempty"` - Status DatadogWorkloadConfigStatus `json:"status,omitempty"` + Spec DatadogInstrumentationSpec `json:"spec,omitempty"` + Status DatadogInstrumentationStatus `json:"status,omitempty"` } -// DatadogWorkloadConfigList contains a list of DatadogWorkloadConfig resources. +// DatadogInstrumentationList contains a list of DatadogInstrumentation resources. // +kubebuilder:object:root=true -type DatadogWorkloadConfigList struct { +type DatadogInstrumentationList struct { metav1.TypeMeta `json:",inline"` metav1.ListMeta `json:"metadata,omitempty"` - Items []DatadogWorkloadConfig `json:"items"` + Items []DatadogInstrumentation `json:"items"` } func init() { - SchemeBuilder.Register(&DatadogWorkloadConfig{}, &DatadogWorkloadConfigList{}) + SchemeBuilder.Register(&DatadogInstrumentation{}, &DatadogInstrumentationList{}) } diff --git a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go index 93198e011..c65d73c51 100644 --- a/api/datadoghq/v1alpha1/zz_generated.deepcopy.go +++ b/api/datadoghq/v1alpha1/zz_generated.deepcopy.go @@ -619,6 +619,104 @@ func (in *DatadogGenericResourceStatus) DeepCopy() *DatadogGenericResourceStatus return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogInstrumentation) DeepCopyInto(out *DatadogInstrumentation) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogInstrumentation. +func (in *DatadogInstrumentation) DeepCopy() *DatadogInstrumentation { + if in == nil { + return nil + } + out := new(DatadogInstrumentation) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DatadogInstrumentation) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogInstrumentationList) DeepCopyInto(out *DatadogInstrumentationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]DatadogInstrumentation, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogInstrumentationList. +func (in *DatadogInstrumentationList) DeepCopy() *DatadogInstrumentationList { + if in == nil { + return nil + } + out := new(DatadogInstrumentationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *DatadogInstrumentationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogInstrumentationSpec) DeepCopyInto(out *DatadogInstrumentationSpec) { + *out = *in + in.Selector.DeepCopyInto(&out.Selector) + in.Config.DeepCopyInto(&out.Config) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogInstrumentationSpec. +func (in *DatadogInstrumentationSpec) DeepCopy() *DatadogInstrumentationSpec { + if in == nil { + return nil + } + out := new(DatadogInstrumentationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *DatadogInstrumentationStatus) DeepCopyInto(out *DatadogInstrumentationStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogInstrumentationStatus. +func (in *DatadogInstrumentationStatus) DeepCopy() *DatadogInstrumentationStatus { + if in == nil { + return nil + } + out := new(DatadogInstrumentationStatus) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *DatadogMetric) DeepCopyInto(out *DatadogMetric) { *out = *in @@ -1523,99 +1621,23 @@ func (in *DatadogSLOStatus) DeepCopy() *DatadogSLOStatus { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogWorkloadConfig) DeepCopyInto(out *DatadogWorkloadConfig) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - in.Spec.DeepCopyInto(&out.Spec) - in.Status.DeepCopyInto(&out.Status) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfig. -func (in *DatadogWorkloadConfig) DeepCopy() *DatadogWorkloadConfig { - if in == nil { - return nil - } - out := new(DatadogWorkloadConfig) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DatadogWorkloadConfig) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogWorkloadConfigList) DeepCopyInto(out *DatadogWorkloadConfigList) { - *out = *in - out.TypeMeta = in.TypeMeta - in.ListMeta.DeepCopyInto(&out.ListMeta) - if in.Items != nil { - in, out := &in.Items, &out.Items - *out = make([]DatadogWorkloadConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfigList. -func (in *DatadogWorkloadConfigList) DeepCopy() *DatadogWorkloadConfigList { - if in == nil { - return nil - } - out := new(DatadogWorkloadConfigList) - in.DeepCopyInto(out) - return out -} - -// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *DatadogWorkloadConfigList) DeepCopyObject() runtime.Object { - if c := in.DeepCopy(); c != nil { - return c - } - return nil -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogWorkloadConfigSpec) DeepCopyInto(out *DatadogWorkloadConfigSpec) { - *out = *in - in.Selector.DeepCopyInto(&out.Selector) - in.Config.DeepCopyInto(&out.Config) -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfigSpec. -func (in *DatadogWorkloadConfigSpec) DeepCopy() *DatadogWorkloadConfigSpec { - if in == nil { - return nil - } - out := new(DatadogWorkloadConfigSpec) - in.DeepCopyInto(out) - return out -} - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *DatadogWorkloadConfigStatus) DeepCopyInto(out *DatadogWorkloadConfigStatus) { +func (in *InstrumentationConfig) DeepCopyInto(out *InstrumentationConfig) { *out = *in - if in.Conditions != nil { - in, out := &in.Conditions, &out.Conditions - *out = make([]v1.Condition, len(*in)) + if in.Checks != nil { + in, out := &in.Checks, &out.Checks + *out = make([]CheckConfig, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new DatadogWorkloadConfigStatus. -func (in *DatadogWorkloadConfigStatus) DeepCopy() *DatadogWorkloadConfigStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new InstrumentationConfig. +func (in *InstrumentationConfig) DeepCopy() *InstrumentationConfig { if in == nil { return nil } - out := new(DatadogWorkloadConfigStatus) + out := new(InstrumentationConfig) in.DeepCopyInto(out) return out } @@ -1670,25 +1692,3 @@ func (in *ProfileAffinity) DeepCopy() *ProfileAffinity { in.DeepCopyInto(out) return out } - -// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *WorkloadConfig) DeepCopyInto(out *WorkloadConfig) { - *out = *in - if in.Checks != nil { - in, out := &in.Checks, &out.Checks - *out = make([]CheckConfig, len(*in)) - for i := range *in { - (*in)[i].DeepCopyInto(&(*out)[i]) - } - } -} - -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WorkloadConfig. -func (in *WorkloadConfig) DeepCopy() *WorkloadConfig { - if in == nil { - return nil - } - out := new(WorkloadConfig) - in.DeepCopyInto(out) - return out -} diff --git a/api/datadoghq/v1alpha1/zz_generated.openapi.go b/api/datadoghq/v1alpha1/zz_generated.openapi.go index 322707ff5..1820c3712 100644 --- a/api/datadoghq/v1alpha1/zz_generated.openapi.go +++ b/api/datadoghq/v1alpha1/zz_generated.openapi.go @@ -32,6 +32,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogGenericResource": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogGenericResource(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogGenericResourceSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogGenericResourceSpec(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogGenericResourceStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogGenericResourceStatus(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentation": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogInstrumentation(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentationSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogInstrumentationSpec(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentationStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogInstrumentationStatus(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMetric": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMetric(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMetricCondition": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMetricCondition(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogMonitor": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMonitor(ref), @@ -53,11 +56,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOQuery": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOQuery(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOSpec(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogSLOStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOStatus(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfig": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfig(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigSpec": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigSpec(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigStatus": schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigStatus(ref), + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.InstrumentationConfig": schema_datadog_operator_api_datadoghq_v1alpha1_InstrumentationConfig(ref), "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector": schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref), - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.WorkloadConfig": schema_datadog_operator_api_datadoghq_v1alpha1_WorkloadConfig(ref), } } @@ -980,6 +980,120 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogGenericResourceStatus } } +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogInstrumentation(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogInstrumentation defines Datadog features such as integration checks and APM instrumentation to apply to pods that match the given selector. This enables monitoring without modifying pod annotations or restarting the Datadog Agent.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentationSpec"), + }, + }, + "status": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentationStatus"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentationSpec", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogInstrumentationStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogInstrumentationSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogInstrumentationSpec defines the desired state of a DatadogInstrumentation.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "selector": { + SchemaProps: spec.SchemaProps{ + Description: "Selector determines which pods this DatadogInstrumentation applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected.", + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), + }, + }, + "config": { + SchemaProps: spec.SchemaProps{ + Description: "Config holds the Datadog feature configurations to apply to the selected pods.", + Default: map[string]interface{}{}, + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.InstrumentationConfig"), + }, + }, + }, + Required: []string{"selector", "config"}, + }, + }, + Dependencies: []string{ + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.InstrumentationConfig", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"}, + } +} + +func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogInstrumentationStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "DatadogInstrumentationStatus defines the observed state of a DatadogInstrumentation.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "conditions": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-map-keys": []interface{}{ + "type", + }, + "x-kubernetes-list-type": "map", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Conditions represents the latest available observations of the state of a DatadogInstrumentation.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, + } +} + func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogMetric(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2201,107 +2315,27 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogSLOStatus(ref common. } } -func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatadogWorkloadConfig defines Datadog features like integration checks to apply to the matching workload using the given selector. This enables dynamic configuration of monitoring without modifying workloads or restarting the Datadog Agent.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "kind": { - SchemaProps: spec.SchemaProps{ - Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", - Type: []string{"string"}, - Format: "", - }, - }, - "apiVersion": { - SchemaProps: spec.SchemaProps{ - Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", - Type: []string{"string"}, - Format: "", - }, - }, - "metadata": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), - }, - }, - "spec": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigSpec"), - }, - }, - "status": { - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigStatus"), - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigSpec", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.DatadogWorkloadConfigStatus", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, - } -} - -func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "selector": { - SchemaProps: spec.SchemaProps{ - Description: "Selector determines which pods this DatadogWorkloadConfig applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected.", - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector"), - }, - }, - "config": { - SchemaProps: spec.SchemaProps{ - Description: "Config holds the Datadog feature configurations to apply to the selected pods.", - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.WorkloadConfig"), - }, - }, - }, - Required: []string{"selector", "config"}, - }, - }, - Dependencies: []string{ - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.PodSelector", "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.WorkloadConfig"}, - } -} - -func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigStatus(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_datadog_operator_api_datadoghq_v1alpha1_InstrumentationConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig.", + Description: "InstrumentationConfig holds the set of Datadog features to configure for the selected pods. Currently supports integration checks; APM instrumentation will be added in a future release.", Type: []string{"object"}, Properties: map[string]spec.Schema{ - "conditions": { + "checks": { VendorExtensible: spec.VendorExtensible{ Extensions: spec.Extensions{ - "x-kubernetes-list-map-keys": []interface{}{ - "type", - }, - "x-kubernetes-list-type": "map", + "x-kubernetes-list-type": "atomic", }, }, SchemaProps: spec.SchemaProps{ - Description: "Conditions represents the latest available observations of the state of a DatadogWorkloadConfig.", + Description: "Checks is the list of Datadog integration checks to run on the selected pods. Each entry defines one check, including what to monitor and how to connect to it.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ SchemaProps: spec.SchemaProps{ Default: map[string]interface{}{}, - Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Condition"), + Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), }, }, }, @@ -2311,7 +2345,7 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_DatadogWorkloadConfigStatus( }, }, Dependencies: []string{ - "k8s.io/apimachinery/pkg/apis/meta/v1.Condition"}, + "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"}, } } @@ -2359,37 +2393,3 @@ func schema_datadog_operator_api_datadoghq_v1alpha1_PodSelector(ref common.Refer }, } } - -func schema_datadog_operator_api_datadoghq_v1alpha1_WorkloadConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { - return common.OpenAPIDefinition{ - Schema: spec.Schema{ - SchemaProps: spec.SchemaProps{ - Description: "WorkloadConfig holds the set of Datadog features to configure for the selected pods. Currently supports integration checks; APM instrumentation will be added in a future release.", - Type: []string{"object"}, - Properties: map[string]spec.Schema{ - "checks": { - VendorExtensible: spec.VendorExtensible{ - Extensions: spec.Extensions{ - "x-kubernetes-list-type": "atomic", - }, - }, - SchemaProps: spec.SchemaProps{ - Description: "Checks is the list of Datadog integration checks to run on the selected pods. Each entry defines one check, including what to monitor and how to connect to it.", - Type: []string{"array"}, - Items: &spec.SchemaOrArray{ - Schema: &spec.Schema{ - SchemaProps: spec.SchemaProps{ - Default: map[string]interface{}{}, - Ref: ref("github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"), - }, - }, - }, - }, - }, - }, - }, - }, - Dependencies: []string{ - "github.com/DataDog/datadog-operator/api/datadoghq/v1alpha1.CheckConfig"}, - } -} diff --git a/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs.yaml b/config/crd/bases/v1/datadoghq.com_datadoginstrumentations.yaml similarity index 91% rename from config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs.yaml rename to config/crd/bases/v1/datadoghq.com_datadoginstrumentations.yaml index 75cc70ca0..227adf32f 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs.yaml +++ b/config/crd/bases/v1/datadoghq.com_datadoginstrumentations.yaml @@ -4,16 +4,16 @@ kind: CustomResourceDefinition metadata: annotations: controller-gen.kubebuilder.io/version: v0.17.3 - name: datadogworkloadconfigs.datadoghq.com + name: datadoginstrumentations.datadoghq.com spec: group: datadoghq.com names: - kind: DatadogWorkloadConfig - listKind: DatadogWorkloadConfigList - plural: datadogworkloadconfigs + kind: DatadogInstrumentation + listKind: DatadogInstrumentationList + plural: datadoginstrumentations shortNames: - - ddwc - singular: datadogworkloadconfig + - ddi + singular: datadoginstrumentation scope: Namespaced versions: - additionalPrinterColumns: @@ -24,9 +24,9 @@ spec: schema: openAPIV3Schema: description: |- - DatadogWorkloadConfig defines Datadog features like integration checks to apply - to the matching workload using the given selector. This enables dynamic configuration - of monitoring without modifying workloads or restarting the Datadog Agent. + DatadogInstrumentation defines Datadog features such as integration checks and + APM instrumentation to apply to pods that match the given selector. This enables + monitoring without modifying pod annotations or restarting the Datadog Agent. properties: apiVersion: description: |- @@ -46,7 +46,7 @@ spec: metadata: type: object spec: - description: DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig. + description: DatadogInstrumentationSpec defines the desired state of a DatadogInstrumentation. properties: config: description: Config holds the Datadog feature configurations to apply to the selected pods. @@ -105,7 +105,7 @@ spec: type: object selector: description: |- - Selector determines which pods this DatadogWorkloadConfig applies to. + Selector determines which pods this DatadogInstrumentation applies to. At least one of matchLabels or matchAnnotations must be set. When both are specified, a pod must match all criteria to be selected. properties: @@ -129,10 +129,10 @@ spec: - selector type: object status: - description: DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig. + description: DatadogInstrumentationStatus defines the observed state of a DatadogInstrumentation. properties: conditions: - description: Conditions represents the latest available observations of the state of a DatadogWorkloadConfig. + description: Conditions represents the latest available observations of the state of a DatadogInstrumentation. items: description: Condition contains details for one aspect of the current state of this API Resource. properties: diff --git a/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs_v1alpha1.json b/config/crd/bases/v1/datadoghq.com_datadoginstrumentations_v1alpha1.json similarity index 91% rename from config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs_v1alpha1.json rename to config/crd/bases/v1/datadoghq.com_datadoginstrumentations_v1alpha1.json index e43431fa3..47e60cd8a 100644 --- a/config/crd/bases/v1/datadoghq.com_datadogworkloadconfigs_v1alpha1.json +++ b/config/crd/bases/v1/datadoghq.com_datadoginstrumentations_v1alpha1.json @@ -1,6 +1,6 @@ { "additionalProperties": false, - "description": "DatadogWorkloadConfig defines Datadog features like integration checks to apply\nto the matching workload using the given selector. This enables dynamic configuration\nof monitoring without modifying workloads or restarting the Datadog Agent.", + "description": "DatadogInstrumentation defines Datadog features such as integration checks and\nAPM instrumentation to apply to pods that match the given selector. This enables\nmonitoring without modifying pod annotations or restarting the Datadog Agent.", "properties": { "apiVersion": { "description": "APIVersion defines the versioned schema of this representation of an object.\nServers should convert recognized schemas to the latest internal value, and\nmay reject unrecognized values.\nMore info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", @@ -15,7 +15,7 @@ }, "spec": { "additionalProperties": false, - "description": "DatadogWorkloadConfigSpec defines the desired state of a DatadogWorkloadConfig.", + "description": "DatadogInstrumentationSpec defines the desired state of a DatadogInstrumentation.", "properties": { "config": { "additionalProperties": false, @@ -72,7 +72,7 @@ }, "selector": { "additionalProperties": false, - "description": "Selector determines which pods this DatadogWorkloadConfig applies to.\nAt least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, a pod must match all criteria to be selected.", + "description": "Selector determines which pods this DatadogInstrumentation applies to.\nAt least one of matchLabels or matchAnnotations must be set.\nWhen both are specified, a pod must match all criteria to be selected.", "properties": { "matchAnnotations": { "additionalProperties": { @@ -100,10 +100,10 @@ }, "status": { "additionalProperties": false, - "description": "DatadogWorkloadConfigStatus defines the observed state of a DatadogWorkloadConfig.", + "description": "DatadogInstrumentationStatus defines the observed state of a DatadogInstrumentation.", "properties": { "conditions": { - "description": "Conditions represents the latest available observations of the state of a DatadogWorkloadConfig.", + "description": "Conditions represents the latest available observations of the state of a DatadogInstrumentation.", "items": { "additionalProperties": false, "description": "Condition contains details for one aspect of the current state of this API Resource.", diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 40fceb2cd..3effdfb16 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -13,7 +13,7 @@ resources: - bases/v1/datadoghq.com_datadogdashboards.yaml - bases/v1/datadoghq.com_datadoggenericresources.yaml - bases/v1/datadoghq.com_datadogagentinternals.yaml -- bases/v1/datadoghq.com_datadogworkloadconfigs.yaml +- bases/v1/datadoghq.com_datadoginstrumentations.yaml # +kubebuilder:scaffold:crdkustomizeresource #patches: diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index 511400566..c59a399fe 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -257,9 +257,9 @@ rules: - datadogagents/status - datadogdashboards/status - datadoggenericresources/status + - datadoginstrumentations/status - datadogmonitors/status - datadogslos/status - - datadogworkloadconfigs/status verbs: - get - patch @@ -271,6 +271,16 @@ rules: - datadogmetrics/status verbs: - update +- apiGroups: + - datadoghq.com + resources: + - datadoginstrumentations + - extendeddaemonsetreplicasets + - watermarkpodautoscalers + verbs: + - get + - list + - watch - apiGroups: - datadoghq.com resources: @@ -288,16 +298,6 @@ rules: - datadogpodautoscalers/status verbs: - '*' -- apiGroups: - - datadoghq.com - resources: - - datadogworkloadconfigs - - extendeddaemonsetreplicasets - - watermarkpodautoscalers - verbs: - - get - - list - - watch - apiGroups: - datadoghq.com - karpenter.azure.com diff --git a/internal/controller/datadogagent/controller.go b/internal/controller/datadogagent/controller.go index 394b880c5..6277aa5b0 100644 --- a/internal/controller/datadogagent/controller.go +++ b/internal/controller/datadogagent/controller.go @@ -42,6 +42,7 @@ import ( _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/gpu" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/helmcheck" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/hostprofiler" + _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/instrumentation" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/kubernetesstatecore" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/livecontainer" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/liveprocess" @@ -60,7 +61,6 @@ import ( _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/servicediscovery" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/tcpqueuelength" _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/usm" - _ "github.com/DataDog/datadog-operator/internal/controller/datadogagent/feature/workloadconfig" ) const ( diff --git a/internal/controller/datadogagent/feature/ids.go b/internal/controller/datadogagent/feature/ids.go index 242af07de..2b22ac1ad 100644 --- a/internal/controller/datadogagent/feature/ids.go +++ b/internal/controller/datadogagent/feature/ids.go @@ -85,6 +85,6 @@ const ( PrivateActionRunnerIDType = "private_action_runner" // DataPlaneIDType Data Plane feature. DataPlaneIDType = "data_plane" - // WorkloadConfigIDType Workload Config feature. - WorkloadConfigIDType = "workload_config" + // InstrumentationIDType Instrumentation feature. + InstrumentationIDType = "instrumentation" ) diff --git a/internal/controller/datadogagent/feature/workloadconfig/feature.go b/internal/controller/datadogagent/feature/instrumentation/feature.go similarity index 63% rename from internal/controller/datadogagent/feature/workloadconfig/feature.go rename to internal/controller/datadogagent/feature/instrumentation/feature.go index 21da1e930..b0ab00018 100644 --- a/internal/controller/datadogagent/feature/workloadconfig/feature.go +++ b/internal/controller/datadogagent/feature/instrumentation/feature.go @@ -3,7 +3,7 @@ // This product includes software developed at Datadog (https://www.datadoghq.com/). // Copyright 2016-present Datadog, Inc. -package workloadconfig +package instrumentation import ( "fmt" @@ -24,34 +24,34 @@ import ( ) const ( - workloadConfigRBACPrefix = "workload-config" - workloadConfigVolumeName = "crd-check-conf" - crdConfigDirectory = "crd-conf.d" - workloadCheckConfigMapName = "datadog-crd-check-conf" + instrumentationRBACPrefix = "instrumentation" + instrumentationVolumeName = "crd-check-conf" + crdConfigDirectory = "crd-conf.d" + instrumentationConfigMapName = "datadog-crd-check-conf" ) func init() { - err := feature.Register(feature.WorkloadConfigIDType, buildWorkloadConfigFeature) + err := feature.Register(feature.InstrumentationIDType, buildInstrumentationFeature) if err != nil { panic(err) } } -func buildWorkloadConfigFeature(_ *feature.Options) feature.Feature { - return &workloadConfigFeature{} +func buildInstrumentationFeature(_ *feature.Options) feature.Feature { + return &instrumentationFeature{} } -type workloadConfigFeature struct { +type instrumentationFeature struct { owner metav1.Object serviceAccountName string rbacSuffix string } -func (f *workloadConfigFeature) ID() feature.IDType { - return feature.WorkloadConfigIDType +func (f *instrumentationFeature) ID() feature.IDType { + return feature.InstrumentationIDType } -func (f *workloadConfigFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) feature.RequiredComponents { +func (f *instrumentationFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgentSpec, _ *v2alpha1.RemoteConfigConfiguration) feature.RequiredComponents { f.owner = dda f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec) f.rbacSuffix = common.ClusterAgentSuffix @@ -68,11 +68,11 @@ func (f *workloadConfigFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.D } } -func (f *workloadConfigFeature) ManageDependencies(managers feature.ResourceManagers, _ string) error { +func (f *instrumentationFeature) ManageDependencies(managers feature.ResourceManagers, _ string) error { // Create the empty ConfigMap that the DCA will populate with check configs. cm := &corev1.ConfigMap{ ObjectMeta: metav1.ObjectMeta{ - Name: workloadCheckConfigMapName, + Name: instrumentationConfigMapName, Namespace: f.owner.GetNamespace(), }, Data: map[string]string{}, @@ -81,24 +81,24 @@ func (f *workloadConfigFeature) ManageDependencies(managers feature.ResourceMana return err } - // RBAC: allow the Cluster Agent to read DatadogWorkloadConfig CRDs and update the ConfigMap. + // RBAC: allow the Cluster Agent to read DatadogInstrumentation CRDs and update the ConfigMap. rbacName := getRBACResourceName(f.owner, f.rbacSuffix) return managers.RBACManager().AddClusterPolicyRules( f.owner.GetNamespace(), rbacName, f.serviceAccountName, - getPolicyRules(workloadCheckConfigMapName), + getPolicyRules(instrumentationConfigMapName), ) } -func (f *workloadConfigFeature) ManageClusterAgent(_ feature.PodTemplateManagers, _ string) error { +func (f *instrumentationFeature) ManageClusterAgent(_ feature.PodTemplateManagers, _ string) error { return nil } -func (f *workloadConfigFeature) ManageNodeAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(workloadCheckConfigMapName, workloadConfigVolumeName) +func (f *instrumentationFeature) ManageNodeAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(instrumentationConfigMapName, instrumentationVolumeName) volMount := corev1.VolumeMount{ - Name: workloadConfigVolumeName, + Name: instrumentationVolumeName, MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), ReadOnly: true, } @@ -108,10 +108,10 @@ func (f *workloadConfigFeature) ManageNodeAgent(managers feature.PodTemplateMana return nil } -func (f *workloadConfigFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplateManagers, _ string) error { - vol := volume.GetBasicVolume(workloadCheckConfigMapName, workloadConfigVolumeName) +func (f *instrumentationFeature) ManageSingleContainerNodeAgent(managers feature.PodTemplateManagers, _ string) error { + vol := volume.GetBasicVolume(instrumentationConfigMapName, instrumentationVolumeName) volMount := corev1.VolumeMount{ - Name: workloadConfigVolumeName, + Name: instrumentationVolumeName, MountPath: fmt.Sprintf("%s/%s", common.ConfigVolumePath, crdConfigDirectory), ReadOnly: true, } @@ -121,23 +121,23 @@ func (f *workloadConfigFeature) ManageSingleContainerNodeAgent(managers feature. return nil } -func (f *workloadConfigFeature) ManageClusterChecksRunner(_ feature.PodTemplateManagers, _ string) error { +func (f *instrumentationFeature) ManageClusterChecksRunner(_ feature.PodTemplateManagers, _ string) error { return nil } -func (f *workloadConfigFeature) ManageOtelAgentGateway(_ feature.PodTemplateManagers, _ string) error { +func (f *instrumentationFeature) ManageOtelAgentGateway(_ feature.PodTemplateManagers, _ string) error { return nil } func getRBACResourceName(owner metav1.Object, suffix string) string { - return fmt.Sprintf("%s-%s-%s-%s", owner.GetNamespace(), owner.GetName(), workloadConfigRBACPrefix, suffix) + return fmt.Sprintf("%s-%s-%s-%s", owner.GetNamespace(), owner.GetName(), instrumentationRBACPrefix, suffix) } func getPolicyRules(configMapName string) []rbacv1.PolicyRule { return []rbacv1.PolicyRule{ { APIGroups: []string{rbac.DatadogAPIGroup}, - Resources: []string{"datadogworkloadconfigs"}, + Resources: []string{"datadoginstrumentations"}, Verbs: []string{"get", "list", "watch"}, }, { diff --git a/internal/controller/datadogagent_controller.go b/internal/controller/datadogagent_controller.go index 166f111d6..9de51904f 100644 --- a/internal/controller/datadogagent_controller.go +++ b/internal/controller/datadogagent_controller.go @@ -93,9 +93,9 @@ type DatadogAgentReconciler struct { // +kubebuilder:rbac:groups=karpenter.sh,resources=*,verbs=get;list;watch;create;patch;update;delete // +kubebuilder:rbac:groups=karpenter.k8s.aws,resources=*,verbs=get;list -// WorkloadConfig CRD -// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogworkloadconfigs,verbs=get;list;watch -// +kubebuilder:rbac:groups=datadoghq.com,resources=datadogworkloadconfigs/status,verbs=get;update;patch +// Instrumentation CRD +// +kubebuilder:rbac:groups=datadoghq.com,resources=datadoginstrumentations,verbs=get;list;watch +// +kubebuilder:rbac:groups=datadoghq.com,resources=datadoginstrumentations/status,verbs=get;update;patch // Use ExtendedDaemonSet // +kubebuilder:rbac:groups=datadoghq.com,resources=extendeddaemonsets,verbs=get;list;watch;create;update;patch;delete