Skip to content

[BYOCAPM-162] Add OPW local mode to DatadogObservabilityPipelinesWorker - #3651

Open
fpddog wants to merge 6 commits into
mainfrom
francisco.paulo/opw-local-mode
Open

fpddog wants to merge 6 commits into
mainfrom
francisco.paulo/opw-local-mode

Conversation

@fpddog

@fpddog fpddog commented Oct 22, 2026 •

Copy link
Copy Markdown
Collaborator

What does this PR do?

Adds a local mode to DatadogObservabilityPipelinesWorker: set spec.pipelineConfig to an Observability Pipelines pipeline in YAML and the Worker runs it instead of fetching pipelineID from Remote Config.

When pipelineConfig is set, the controller:

  • renders it into an owned ConfigMap <worker>-pipeline (key pipeline.yaml), mounted read-only at /etc/observability-pipelines-worker/pipeline;
  • runs run --pipeline-config=/etc/observability-pipelines-worker/pipeline/pipeline.yaml --skip-key-validation;
  • sets DD_OP_PIPELINE_ID to pipelineID if given, otherwise the Worker UID;
  • adds a checksum/pipeline pod annotation so editing the pipeline rolls the pods (OPW does not reload the file).

Switching back to Remote Config deletes the ConfigMap (only if the Worker controls it) and removes the args, volume, mount and annotation. Remote Config Workers render exactly as before, so they don't restart on operator upgrade.

API: pipelineID is now optional in the CRD schema (it lives on a struct shared with DatadogBYOCCluster components.pipelines[]). Validation moves to Go, no CEL: a Worker needs pipelineID or pipelineConfig; pipelineConfig must be a single, non-empty YAML mapping; every BYOC pipeline still needs pipelineID. In local mode, user volumes named pipeline-config and mounts overlapping the pipeline directory are rejected.

Motivation

BYOC APM ships Datadog-authored pipelines rather than Remote Config ones. This is the Worker half; a follow-up lets the DatadogBYOCCluster create a child Worker with the pipeline from its release (BYOCAPM-162, blocks BYOCAPM-163).

Additional Notes

  • Hidden OPW flag: local mode depends on OPW's --pipeline-config and --skip-key-validation. Without --skip-key-validation, startup validates the pipeline ID against Remote Config and fails. The flag also skips the API key check at startup. OPW team sign-off is pending.
  • Downgrade: remove local-mode Workers before downgrading the operator. Older operators dereference pipelineID and would panic on a Worker without one.
  • A pipeline that is a valid YAML mapping but not a valid OPW pipeline passes validation; the pods CrashLoop with Available=False until the spec is fixed.

Minimum Agent Versions

N/A (no Agent change).

Describe your test plan

  • Unit: builder tests diff the local-mode StatefulSet against the unchanged Remote Config fixture (only args, pipeline ID, checksum, volume and mount differ); ConfigMap and cleanup stubs; validation (pipeline source, YAML shape, multi-document, reserved names); BYOC pipelineID check.
  • Envtest: local Worker without pipelineID reaches Available with its UID as the pipeline ID; Remote Config → local → edit (checksum changes) → Remote Config (ConfigMap, args, volume, mount and annotation all gone); an unowned <worker>-pipeline ConfigMap reports Conflict and survives local mode being turned off.
  • make generate clean, make lint, go test ./... scope, make integration-tests pass.
  • Internal dev cluster (10-22), operator main + the first two commits of this PR, OPW 43d60b1e: a local-mode Worker without pipelineID reached Available; spans reached the BYOC cluster and the bridge check passed. Patching pipelineConfig changed the StatefulSet updateRevision and the rollout completed with all checks still passing.
  • The demo pipeline (OTLP traces with a sample processor) passes observability-pipelines-worker validate built from OPW 43d60b1e.

Checklist

  • PR has at least one valid label: enhancement
  • PR has a milestone or the qa/skip-qa label
  • All commits are signed

🤖 Generated with Claude Code

fpddog and others added 4 commits October 20, 2026 12:35
spec.pipelineConfig runs a YAML pipeline locally instead of fetching
pipelineID from Remote Config. The operator renders it into an owned
<worker>-pipeline ConfigMap, mounts it read-only, runs
`run --pipeline-config=... --skip-key-validation`, falls back to the
Worker UID for DD_OP_PIPELINE_ID, and rolls pods via a checksum/pipeline
annotation. Remote Config workers render unchanged.

pipelineID is now optional in the CRD schema; Go validation requires
pipelineID or pipelineConfig on the Worker, and pipelineID on every BYOC
pipeline.

Demo subset: cleanup of the ConfigMap when local mode is turned off,
reserved-name checks and envtest coverage follow.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Switching a Worker back to Remote Config now removes its
<worker>-pipeline ConfigMap if the Worker controls it. Envtest covers
Remote Config -> local -> edit -> Remote Config: the ConfigMap appears,
the checksum changes on edit, and switching back leaves no ConfigMap,
pipeline args, volume, mount or checksum annotation.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
In local mode, user volumes named pipeline-config and mounts at, under or
over /etc/observability-pipelines-worker/pipeline are rejected; Remote
Config Workers keep those names. Envtest adds a local Worker without a
pipelineID reaching Available with its UID as the pipeline ID, and an
unowned <worker>-pipeline ConfigMap causing a conflict and surviving
local mode being turned off.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fpddog
fpddog requested a review from a team October 22, 2026 15:44
@fpddog fpddog added enhancement New feature or request qa/skip-qa labels Oct 22, 2026
@fpddog
fpddog requested review from a team as code owners October 22, 2026 15:44
@fpddog
fpddog requested a review from shuheiktgw October 22, 2026 15:44
@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-22T15:48:11.731000Z 813bbac PR opened
ℹ️ 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" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@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: 813bbacde0

ℹ️ 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".

}
configPath := fieldPath.Child("pipelineConfig")
// sigs.k8s.io/yaml decodes only the first document, so later documents would be silently dropped.
if strings.Contains(*spec.PipelineConfig, "\n---") {

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Parse YAML documents instead of matching LF separators

For valid YAML streams using CR-only line endings, such as sources: {}\r---\rsinks: {}, this check does not detect the second document. The subsequent unmarshal accepts the first mapping while silently ignoring the remainder, so an invalid multi-document pipelineConfig passes reconciliation and may make the Worker run only part of the supplied configuration or fail at startup. Use a document-aware decoder and require EOF after the first non-empty mapping rather than searching for one separator spelling.

Useful? React with 👍 / 👎.

@datadog-prod-us1-5

datadog-prod-us1-5 Bot commented Oct 22, 2026 •

Copy link
Copy Markdown

Pipelines  Code Coverage

❌ Errors

Your PR has failed checks. Please review the issues below and take necessary action before merging.

🚦 1 Pipeline job failed

DataDog/datadog-operator | e2e_autoscaling

View more details · View in GitLab

ℹ️ Info

🎯 Code Coverage (details)
• Patch Coverage: 98.46%
• Overall Coverage: 55.91% (+0.07%)

Useful? React with 👍 / 👎

This comment will be updated automatically if new data arrives.
🔗 Commit SHA: 0da64d4 | Docs | View more details | Give us feedback!

fpddog and others added 2 commits October 23, 2026 22:34
The single-document check matched "\n---", so a stream using CR-only
line breaks (sources: {}\r---\rsinks: {}) passed and the second document
was silently dropped. Decode the first document with a stream decoder
and require EOF after it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

This branch has not been deployed

No deployments
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.

1 participant