Skip to content

[CONTP-1504] Manage DatadogCSIDriver from DatadogAgent#2857

Merged
tbavelier merged 38 commits into
mainfrom
tbavelier/create-ddcsi-from-dda
Apr 27, 2026
Merged

[CONTP-1504] Manage DatadogCSIDriver from DatadogAgent#2857
tbavelier merged 38 commits into
mainfrom
tbavelier/create-ddcsi-from-dda

Conversation

@tbavelier

@tbavelier tbavelier commented Apr 2, 2026

Copy link
Copy Markdown
Member

What does this PR do?

When spec.global.csi.enabled=true, the DatadogAgent controller can now create and manage a DatadogCSIDriver custom resource on behalf of the DDA. The DatadogCSIDriver controller then reconciles it into the CSI DaemonSet and the cluster-scoped k8s.csi.datadoghq.com CSIDriver.

Controller-level opt-in. Management is gated on the existing operator flag --datadogCSIDriverEnabled (default false). With the flag off, csi.enabled=true keeps its long-standing semantics — the Agent uses a CSI driver that's installed by some other means (Helm chart, manual apply, GitOps) — and the operator doesn't touch anything. This preserves backward compatibility for existing clusters.

Defer to external installs. On the first-time create path (no DDA-owned CR yet), if a cluster-scoped k8s.csi.datadoghq.com CSIDriver is already present, the operator defers and skips creation. Avoids collisions with Helm/manual installs. Once the operator owns a CR, subsequent reconciles stay on the update path regardless of external CSIDriver presence.

Per-DDA opt-out for migrations. New field spec.global.csi.autoManage (*bool, default true). Flipping to false triggers cleanup of the operator-owned CR so users can hand ownership over to a DatadogCSIDriver they maintain themselves (useful when they need customizations not exposed via DDA spec) without having to toggle csi.enabled off/on.

Spec propagation from DDA. The created DatadogCSIDriver is built from:

  • Spec.APMSocketPathdda.Spec.Features.APM.UnixDomainSocketConfig.Path
  • Spec.DSDSocketPathdda.Spec.Features.Dogstatsd.UnixDomainSocketConfig.Path
  • Spec.Override.Tolerationsdda.Spec.Global.CSI.Tolerations
  • Spec.Override.NodeSelectordda.Spec.Global.CSI.NodeSelector
  • Spec.Override.Affinity.NodeAffinitydda.Spec.Global.CSI.NodeAffinity
  • Default operator-managed labels/annotations (app.kubernetes.io/managed-by=datadog-operator, etc.)
  • controllerutil.SetControllerReference → ownerRef for cascade delete

Scheduling fields (tolerations, nodeSelector, nodeAffinity) are set explicitly on spec.global.csi rather than being implicitly inherited from the node-agent component override. The Spec.Override struct is only populated when at least one scheduling field is set.

Update semantics. Spec-drift updates use a client.MergeFrom JSON merge patch (instead of UpdateFromObject), so only the fields we own (.spec, labels, annotations) appear in the wire payload. Finalizers added by the sibling DatadogCSIDriver controller (finalizer.datadoghq.com/csi-driver) and .status are not touched — prevents a class of bug where a spec-drift update would wipe the finalizer and a subsequent delete would leak the cluster-scoped CSIDriver.

Event-driven reconciles. The DDA controller now declares Owns(&v1alpha1.DatadogCSIDriver{}) (gated on DatadogCSIDriverEnabled to avoid startup crashes when the CRD is absent, matching the DatadogAgentInternal/ExtendedDaemonSet pattern). Drift on the operator-owned CR now self-heals within milliseconds via watch events rather than waiting for the 15s periodic requeue.

Motivation

Simplify CSI driver setup. Users can configure CSI on their DatadogAgent (and for cluster admins that want the operator to install the driver, flip --datadogCSIDriverEnabled at deployment time) without maintaining a separate DatadogCSIDriver by hand. For advanced users who need finer-grained control, autoManage=false offers a seamless migration path off "automatic" operator management based on DDA spec.

Additional Notes

  • The DatadogCSIDriver lifecycle is managed via direct API calls (get/patch/delete) rather than the dependency store, because the store only supports built-in Kubernetes types. Documented in code comments on reconcileDatadogCSIDriver.
  • RBAC is unchanged — the existing csidrivers rules (list/watch/create cluster-wide, get/update/patch/delete scoped to k8s.csi.datadoghq.com) cover the new external-check Get.

Minimum Agent Versions

N/A — this is an operator-level feature.

Describe your test plan

Unit tests in ddcsi_test.go cover:

  • Disabled — csi.enabled=false, no CR created
  • EnabledAndCreated — csi.enabled=true, flag on, CR created with owner ref and operator-managed labels
  • SpecFromDDA — APMSocketPath, DSDSocketPath, and tolerations (via spec.global.csi.tolerations) propagated from DDA
  • NodeSelectorPropagatedspec.global.csi.nodeSelector forwarded to Spec.Override.NodeSelector
  • NodeAffinityPropagatedspec.global.csi.nodeAffinity forwarded to Spec.Override.Affinity.NodeAffinity
  • NoOverrideWhenNoTolerations — override not set when no scheduling fields are configured
  • AutoManageDisabledCleansUpAndDoesNotRecreate — opt-out deletes the CR and stays out of the way
  • AutoManageDisabledSkipsForeignCR — opt-out honors IsControlledBy guard
  • ControllerDisabled — flag off is a no-op (no error, no CR)
  • DefersToExternalCSIDriver — pre-existing cluster-scoped CSIDriver blocks first-time create
  • ExternalAppearsAfterCRCreated — once owning a CR, external appearance doesn't abandon it
  • Idempotent — repeat reconciles are no-ops
  • CleanupOnDisable — owned resource deleted on toggle
  • CleanupSkipsNotOwned — manually-created CRs left alone
  • UpdateOnSpecDrift — drift reconciled back via merge patch
  • UpdatePreservesFinalizers — spec-drift update preserves externally-added finalizers (finalizer-wipe bug regression test)
  • CleanupCRDNotAvailable — no error when CRD isn't present

Checklist

  • PR has at least one valid label: bug, enhancement, refactoring, documentation, tooling, and/or dependencies
  • PR has a milestone or the qa/skip-qa label
  • All commits are signed (see: signing commits)

tbavelier and others added 9 commits April 2, 2026 14:03
Define the DatadogCSIDriver, DatadogCSIDriverSpec, DatadogCSIDriverOverride,
and DatadogCSIDriverStatus types in api/datadoghq/v1alpha1. The CRD enables
declarative management of the Datadog CSI Driver via the operator, replacing
the standalone Helm chart deployment.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Controller-runtime wiring for the DatadogCSIDriver reconciler. Watches the
primary CR with GenerationChangedPredicate, owned DaemonSets for all changes
(including status), and CSIDriver objects via label-based enqueue for drift
detection on the cluster-scoped resource.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Implements the reconciliation logic for the DatadogCSIDriver controller:
- Deferred SSA status patch with ObservedGeneration tracking
- CSIDriver object management with Get+DeepEqual+Update for full drift reversion
- DaemonSet management with the same pattern, including label enforcement
- Override system with merge-by-name semantics (env vars, volumes, mounts)
- Image resolution via pkg/images (supports tag-only overrides)
- Finalizer-based cleanup of the cluster-scoped CSIDriver on deletion
- Comprehensive unit tests covering creation, updates, drift, deletion, overrides

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Register the controller in setup.go with a feature flag and add the
-datadogCSIDriverEnabled flag (default: false) to cmd/main.go. Also
registers the storagev1 scheme required for CSIDriver object management.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
Treat the DatadogCSIDriver as a desired-state object like DDAI: if
someone modifies it externally, reconcile it back to the operator's
desired state on the next loop. Uses apiequality.Semantic.DeepEqual
to compare specs and kubernetes.UpdateFromObject to update.

Co-Authored-By: Claude Opus 4.6 (1M context) <[email protected]>
@codecov-commenter

codecov-commenter commented Apr 2, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 79.24528% with 22 lines in your changes missing coverage. Please review.
✅ Project coverage is 40.83%. Comparing base (039572f) to head (76ab54d).

Files with missing lines Patch % Lines
internal/controller/datadogagent/ddcsi.go 82.17% 9 Missing and 9 partials ⚠️
internal/controller/datadogagent/dependencies.go 0.00% 1 Missing and 1 partial ⚠️
internal/controller/datadogagent_controller.go 0.00% 1 Missing and 1 partial ⚠️

❌ Your patch status has failed because the patch coverage (79.24%) is below the target coverage (80.00%). You can increase the patch coverage or adjust the target coverage.

Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##             main    #2857      +/-   ##
==========================================
+ Coverage   40.69%   40.83%   +0.14%     
==========================================
  Files         321      322       +1     
  Lines       28413    28519     +106     
==========================================
+ Hits        11563    11647      +84     
- Misses      16015    16026      +11     
- Partials      835      846      +11     
Flag Coverage Δ
unittests 40.83% <79.24%> (+0.14%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
internal/controller/datadogagent/controller.go 92.85% <ø> (ø)
internal/controller/setup.go 36.64% <100.00%> (+0.33%) ⬆️
internal/controller/datadogagent/dependencies.go 60.86% <0.00%> (-2.77%) ⬇️
internal/controller/datadogagent_controller.go 58.64% <0.00%> (-0.90%) ⬇️
internal/controller/datadogagent/ddcsi.go 82.17% <82.17%> (ø)

Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 039572f...76ab54d. Read the comment docs.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Base automatically changed from tbavelier/csi-driver-standalone-v2 to main April 8, 2026 14:29
@tbavelier
tbavelier requested a review from a team April 20, 2026 11:58
@tbavelier
tbavelier requested a review from a team as a code owner April 20, 2026 11:58

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6b338d627f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/datadogagent/ddcsi.go Outdated
Comment thread internal/controller/datadogagent/ddcsi.go Outdated
Comment thread internal/controller/datadogagent/ddcsi.go Outdated
@tbavelier

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 99fc2f521a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/datadogagent/ddcsi.go
@tbavelier

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 231409b572

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/datadogagent/ddcsi.go
Comment thread internal/controller/datadogagent/ddcsi.go
@tbavelier

Copy link
Copy Markdown
Member Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 89b95fc985

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread internal/controller/datadogagent/ddcsi.go
@tbavelier
tbavelier requested a review from a team as a code owner April 23, 2026 13:47
@tbavelier tbavelier changed the title [CONTP-1504] Create DatadogCSIDriver from DDA when createDatadogCSIDriver=true [CONTP-1504] Manage DatadogCSIDriver from DatadogAgent Apr 23, 2026
Comment thread api/datadoghq/v2alpha1/datadogagent_types.go Outdated

@adel121 adel121 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM! Thank you 🙇
Approving with a minor nit.

@tbavelier
tbavelier merged commit e3f69bf into main Apr 27, 2026
37 of 38 checks passed
@tbavelier
tbavelier deleted the tbavelier/create-ddcsi-from-dda branch April 27, 2026 06:51
tbavelier added a commit that referenced this pull request Apr 27, 2026
* Add DatadogCSIDriver CRD types and generated manifests

Define the DatadogCSIDriver, DatadogCSIDriverSpec, DatadogCSIDriverOverride,
and DatadogCSIDriverStatus types in api/datadoghq/v1alpha1. The CRD enables
declarative management of the Datadog CSI Driver via the operator, replacing
the standalone Helm chart deployment.



* Add DatadogCSIDriver outer controller with RBAC markers

Controller-runtime wiring for the DatadogCSIDriver reconciler. Watches the
primary CR with GenerationChangedPredicate, owned DaemonSets for all changes
(including status), and CSIDriver objects via label-based enqueue for drift
detection on the cluster-scoped resource.



* Add DatadogCSIDriver reconciler, DaemonSet and CSIDriver builders

Implements the reconciliation logic for the DatadogCSIDriver controller:
- Deferred SSA status patch with ObservedGeneration tracking
- CSIDriver object management with Get+DeepEqual+Update for full drift reversion
- DaemonSet management with the same pattern, including label enforcement
- Override system with merge-by-name semantics (env vars, volumes, mounts)
- Image resolution via pkg/images (supports tag-only overrides)
- Finalizer-based cleanup of the cluster-scoped CSIDriver on deletion
- Comprehensive unit tests covering creation, updates, drift, deletion, overrides



* Wire DatadogCSIDriver controller into operator startup

Register the controller in setup.go with a feature flag and add the
-datadogCSIDriverEnabled flag (default: false) to cmd/main.go. Also
registers the storagev1 scheme required for CSIDriver object management.



* Add CreateDatadogCSIDriver field to CSIConfig



* Add reconcileDatadogCSIDriver for creating DatadogCSIDriver from DDA



* Wire reconcileDatadogCSIDriver into manageDDADependenciesWithDDAI



* Add tests for reconcileDatadogCSIDriver

* Add update logic to createOrUpdateDatadogCSIDriver

Treat the DatadogCSIDriver as a desired-state object like DDAI: if
someone modifies it externally, reconcile it back to the operator's
desired state on the next loop. Uses apiequality.Semantic.DeepEqual
to compare specs and kubernetes.UpdateFromObject to update.



* remove unnecessary variable declaration

* fix test after merging main

* Scope csidriver RBAC to Datadog driver

* Add comment why these were re-implemented but could be extracted for future work

* Move DD_APM_ENABLED to shared controller constants

* Move image tag and registries to proper package and delete defaults.go to consolide with const.go

* Remove useless variable after constant driver name

* Switch to context based logging

* Fix pointer use

* Always create DDCSIDriver unless existing CSIDriver with name and managed by Helm, remove CRD option

* Add labels on created DatadogCSIDriver

* Add tolerations + customize socket paths based on config on DatadogAgent

* Use JSON patch instead of UpdateFromObject to keep finalizer added by DatadogCSIDriver controller

* Do not create DatadogCSIDriver if controller not enabled and share info to DDA

* Do not crash existing CSIDrivers users, simply skip

* add debug logs

* add DDCSI to informer to reconcile instantly

* Add manageDatadogCSIDriver flag to allow smooth transitions to user-managed DDCSIs

* guard update on controllerref to avoid managing same namespace/name DDCSI

* Add tolerations, affinity, nodeselector to CRD field + remove automatic tolerations from DDA

* rename to autoManage

---------


(cherry picked from commit e3f69bf)

Co-authored-by: Timothée Bavelier <[email protected]>
Co-authored-by: Claude Opus 4.6 (1M context) <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants