Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,13 @@ rules:
- deletecollection
- list
- watch
- apiGroups:
- apps
resources:
- controllerrevisions
verbs:
- list
- watch
- apiGroups:
- apps
resources:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,10 @@ instances:
config.WriteString(" - apiservices\n")
}

if collectorOpts.enableControllerRevisions {
config.WriteString(" - controllerrevisions\n")
}

if collectorOpts.enableCRD {
config.WriteString(" - customresourcedefinitions\n")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ instances:
optionsWithVPA := collectorOptions{enableVPA: true}
optionsWithCRD := collectorOptions{enableCRD: true}
optionsWithAPIService := collectorOptions{enableAPIService: true}
optionsWithControllerRevisions := collectorOptions{enableControllerRevisions: true}

// Test custom resources
optionsWithCustomResources := collectorOptions{
Expand Down Expand Up @@ -159,6 +160,17 @@ instances:
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithAPIService)),
},
{
name: "with ControllerRevisions",
fields: fields{
owner: owner,
enable: true,
runInClusterChecksRunner: true,
configConfigMapName: defaultKubeStateMetricsCoreConf,
collectorOpts: optionsWithControllerRevisions,
},
want: buildDefaultConfigMap(owner.GetNamespace(), defaultKubeStateMetricsCoreConf, ksmCheckConfig(true, optionsWithControllerRevisions)),
},
{
name: "with custom resources",
fields: fields{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import (
"github.com/DataDog/datadog-operator/internal/controller/datadogagent/object/volume"
"github.com/DataDog/datadog-operator/pkg/constants"
"github.com/DataDog/datadog-operator/pkg/controller/utils/comparison"
"github.com/DataDog/datadog-operator/pkg/images"
"github.com/DataDog/datadog-operator/pkg/kubernetes"
"github.com/DataDog/datadog-operator/pkg/utils"
)
Expand All @@ -46,10 +47,11 @@ func buildKSMFeature(options *feature.Options) feature.Feature {
}

type ksmFeature struct {
runInClusterChecksRunner bool
collectCRDMetrics bool
collectCrMetrics []v2alpha1.Resource
collectAPIServiceMetrics bool
runInClusterChecksRunner bool
collectCRDMetrics bool
collectCrMetrics []v2alpha1.Resource
collectAPIServiceMetrics bool
collectControllerRevisions bool

rbacSuffix string
serviceAccountName string
Expand All @@ -63,9 +65,14 @@ type ksmFeature struct {
logger logr.Logger
}

// Minimum agent version that supports collection of CRD and APIService data
// Add "-0" so that prerelase versions are considered sufficient. https://github.com/Masterminds/semver#working-with-prerelease-versions
const crdAPIServiceCollectionMinVersion = "7.46.0-0"
const (
// Minimum agent version that supports collection of CRD and APIService data
// Add "-0" so that prerelase versions are considered sufficient. https://github.com/Masterminds/semver#working-with-prerelease-versions
crdAPIServiceCollectionMinVersion = "7.46.0-0"

// Minimum agent version that supports collection of controllerrevisions
controllerRevisionsCollectionMinVersion = "7.72.0-0"
)

// ID returns the ID of the Feature
func (f *ksmFeature) ID() feature.IDType {
Expand All @@ -88,6 +95,10 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent
f.collectCrMetrics = ddaSpec.Features.KubeStateMetricsCore.CollectCrMetrics
f.serviceAccountName = constants.GetClusterAgentServiceAccount(dda.GetName(), ddaSpec)

// Determine CollectControllerRevisions setting
// Default to false, then check version requirements
f.collectControllerRevisions = false

// This check will only run in the Cluster Checks Runners or Cluster Agent (not the Node Agent)
if ddaSpec.Features.ClusterChecks != nil && apiutils.BoolValue(ddaSpec.Features.ClusterChecks.Enabled) && apiutils.BoolValue(ddaSpec.Features.ClusterChecks.UseClusterChecksRunners) {
f.runInClusterChecksRunner = true
Expand All @@ -97,17 +108,53 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent
output.ClusterChecksRunner.Containers = []apicommon.AgentContainerName{apicommon.CoreAgentContainerName}

if ccrOverride, ok := ddaSpec.Override[v2alpha1.ClusterChecksRunnerComponentName]; ok {
if ccrOverride.Image != nil && !utils.IsAboveMinVersion(common.GetAgentVersionFromImage(*ccrOverride.Image), crdAPIServiceCollectionMinVersion) {
// Disable if image is overridden to an unsupported version
f.collectAPIServiceMetrics = false
f.collectCRDMetrics = false
if ccrOverride.Image != nil {
agentVersion := common.GetAgentVersionFromImage(*ccrOverride.Image)

// CRD and APIService version checks
if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) {
f.collectAPIServiceMetrics = false
f.collectCRDMetrics = false
}

// ControllerRevisions version check - enable if version supports it
if utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) {
f.collectControllerRevisions = true
}
}
}
} else if clusterAgentOverride, ok := ddaSpec.Override[v2alpha1.ClusterAgentComponentName]; ok {
if clusterAgentOverride.Image != nil && !utils.IsAboveMinVersion(common.GetAgentVersionFromImage(*clusterAgentOverride.Image), crdAPIServiceCollectionMinVersion) {
// Disable if image is overridden to an unsupported version
f.collectAPIServiceMetrics = false
f.collectCRDMetrics = false
} else {
if clusterAgentOverride, ok := ddaSpec.Override[v2alpha1.ClusterAgentComponentName]; ok {
if clusterAgentOverride.Image != nil {
agentVersion := common.GetAgentVersionFromImage(*clusterAgentOverride.Image)

// CRD and APIService version checks
if !utils.IsAboveMinVersion(agentVersion, crdAPIServiceCollectionMinVersion) {
f.collectAPIServiceMetrics = false
f.collectCRDMetrics = false
}

// ControllerRevisions version check - enable if version supports it
if utils.IsAboveMinVersionWithFallback(agentVersion, controllerRevisionsCollectionMinVersion) {
f.collectControllerRevisions = true
}
}
}
}

// If no override was found, check default version based on deployment mode
if !f.collectControllerRevisions {
// Determine which default version to check based on deployment mode
var defaultVersion string
if f.runInClusterChecksRunner {
defaultVersion = images.AgentLatestVersion
} else {
defaultVersion = images.ClusterAgentLatestVersion
}

// Check if default version supports controllerrevisions
if utils.IsAboveMinVersionWithFallback(defaultVersion, controllerRevisionsCollectionMinVersion) {
f.collectControllerRevisions = true
}
}

Expand All @@ -124,16 +171,18 @@ func (f *ksmFeature) Configure(dda metav1.Object, ddaSpec *v2alpha1.DatadogAgent
}

f.configConfigMapName = constants.GetConfName(dda, f.customConfig, defaultKubeStateMetricsCoreConf)

}

return output
}

type collectorOptions struct {
enableVPA bool
enableAPIService bool
enableCRD bool
customResources []v2alpha1.Resource
enableVPA bool
enableAPIService bool
enableCRD bool
enableControllerRevisions bool
customResources []v2alpha1.Resource
}

// ManageDependencies allows a feature to manage its dependencies.
Expand All @@ -143,10 +192,11 @@ func (f *ksmFeature) ManageDependencies(managers feature.ResourceManagers, provi
// OR if the default configMap is needed.
pInfo := managers.Store().GetPlatformInfo()
collectorOpts := collectorOptions{
enableVPA: pInfo.IsResourceSupported("VerticalPodAutoscaler"),
enableAPIService: f.collectAPIServiceMetrics,
enableCRD: f.collectCRDMetrics,
customResources: f.collectCrMetrics,
enableVPA: pInfo.IsResourceSupported("VerticalPodAutoscaler"),
enableAPIService: f.collectAPIServiceMetrics,
enableCRD: f.collectCRDMetrics,
enableControllerRevisions: f.collectControllerRevisions,
customResources: f.collectCrMetrics,
}
configCM, err := f.buildKSMCoreConfigMap(collectorOpts)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,50 @@ func Test_ksmFeature_Configure(t *testing.T) {
ClusterAgent: ksmClusterAgentWantFunc(true),
Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentSingleAgentWantFunc),
},
{
Name: "ksm-core enabled, cluster agent with image >= 7.72.0",
DDA: testutils.NewDatadogAgentBuilder().
WithKSMEnabled(true).
WithClusterAgentImage("gcr.io/datadoghq/agent:7.72.0").
Build(),
WantConfigure: true,
ClusterAgent: ksmClusterAgentWantFunc(false),
Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc),
},
{
Name: "ksm-core enabled, cluster agent with image < 7.72.0",
DDA: testutils.NewDatadogAgentBuilder().
WithKSMEnabled(true).
WithClusterAgentImage("gcr.io/datadoghq/agent:7.71.0").
Build(),
WantConfigure: true,
ClusterAgent: ksmClusterAgentWantFunc(false),
Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc),
},
{
Name: "ksm-core enabled, cluster checks runner with image >= 7.72.0",
DDA: testutils.NewDatadogAgentBuilder().
WithKSMEnabled(true).
WithClusterChecks(true, true).
WithClusterChecksRunnerImage("gcr.io/datadoghq/agent:7.72.0").
Build(),
WantConfigure: true,
Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc),
ClusterAgent: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}),
ClusterChecksRunner: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}),
},
{
Name: "ksm-core enabled, cluster checks runner with image < 7.72.0",
DDA: testutils.NewDatadogAgentBuilder().
WithKSMEnabled(true).
WithClusterChecks(true, true).
WithClusterChecksRunnerImage("gcr.io/datadoghq/agent:7.71.0").
Build(),
WantConfigure: true,
Agent: test.NewDefaultComponentTest().WithWantFunc(ksmAgentNodeWantFunc),
ClusterAgent: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}),
ClusterChecksRunner: test.NewDefaultComponentTest().WithWantFunc(func(t testing.TB, mgrInterface feature.PodTemplateManagers) {}),
},
}

tests.Run(t, buildKSMFeature)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ func getRBACPolicyRules(collectorOpts collectorOptions) []rbacv1.PolicyRule {
rbac.DeploymentsResource,
rbac.ReplicasetsResource,
rbac.StatefulsetsResource,
rbac.ControllerRevisionsResource,
},
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -288,4 +288,3 @@ func TestGetRBACPolicyRules(t *testing.T) {
})
}
}

1 change: 1 addition & 0 deletions internal/controller/datadogagent_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,7 @@ type DatadogAgentReconciler struct {
// +kubebuilder:rbac:groups=apps,resources=replicasets,verbs=list;watch
// +kubebuilder:rbac:groups="",resources=replicationcontrollers,verbs=get;list;watch
// +kubebuilder:rbac:groups=apps,resources=statefulsets,verbs=list;watch
// +kubebuilder:rbac:groups=apps,resources=controllerrevisions,verbs=list;watch
// +kubebuilder:rbac:groups=autoscaling,resources=horizontalpodautoscalers,verbs=list;watch
// +kubebuilder:rbac:groups=batch,resources=cronjobs,verbs=list;watch
// +kubebuilder:rbac:groups=batch,resources=jobs,verbs=list;watch
Expand Down
1 change: 1 addition & 0 deletions pkg/kubernetes/rbac/const.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ const (
ClusterRoleBindingResource = "clusterrolebindings"
ClusterRoleResource = "clusterroles"
ComponentStatusesResource = "componentstatuses"
ControllerRevisionsResource = "controllerrevisions"
ConfigMapsResource = "configmaps"
CronjobsResource = "cronjobs"
CustomResourceDefinitionsResource = "customresourcedefinitions"
Expand Down
37 changes: 37 additions & 0 deletions pkg/testutils/builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -646,6 +646,13 @@ func (builder *DatadogAgentBuilder) WithClusterChecksUseCLCEnabled(enabled bool)
return builder
}

func (builder *DatadogAgentBuilder) WithClusterChecks(enabled bool, useRunners bool) *DatadogAgentBuilder {
builder.initCC()
builder.datadogAgent.Spec.Features.ClusterChecks.Enabled = apiutils.NewBoolPointer(enabled)
builder.datadogAgent.Spec.Features.ClusterChecks.UseClusterChecksRunners = apiutils.NewBoolPointer(useRunners)
return builder
}

// Prometheus Scrape

func (builder *DatadogAgentBuilder) initPrometheusScrape() {
Expand Down Expand Up @@ -1045,6 +1052,36 @@ func (builder *DatadogAgentBuilder) WithComponentOverride(componentName v2alpha1
return builder
}

func (builder *DatadogAgentBuilder) WithClusterAgentImage(image string) *DatadogAgentBuilder {
if builder.datadogAgent.Spec.Override == nil {
builder.datadogAgent.Spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{}
}

if builder.datadogAgent.Spec.Override[v2alpha1.ClusterAgentComponentName] == nil {
builder.datadogAgent.Spec.Override[v2alpha1.ClusterAgentComponentName] = &v2alpha1.DatadogAgentComponentOverride{}
}

builder.datadogAgent.Spec.Override[v2alpha1.ClusterAgentComponentName].Image = &v2alpha1.AgentImageConfig{
Name: image,
}
return builder
}

func (builder *DatadogAgentBuilder) WithClusterChecksRunnerImage(image string) *DatadogAgentBuilder {
if builder.datadogAgent.Spec.Override == nil {
builder.datadogAgent.Spec.Override = map[v2alpha1.ComponentName]*v2alpha1.DatadogAgentComponentOverride{}
}

if builder.datadogAgent.Spec.Override[v2alpha1.ClusterChecksRunnerComponentName] == nil {
builder.datadogAgent.Spec.Override[v2alpha1.ClusterChecksRunnerComponentName] = &v2alpha1.DatadogAgentComponentOverride{}
}

builder.datadogAgent.Spec.Override[v2alpha1.ClusterChecksRunnerComponentName].Image = &v2alpha1.AgentImageConfig{
Name: image,
}
return builder
}

// FIPS

func (builder *DatadogAgentBuilder) WithUseFIPSAgent() *DatadogAgentBuilder {
Expand Down
Loading
Loading