Skip to content

[pkg/stanza]: fix operator field config validation #40728

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

braydonk
Copy link
Contributor

Description

A few operators with entry.Field in their config were validating their configuration in their Build function via a comparison to entry.NewNilField. This was an inaccuracy; when a field is not provided during the unmarshal step, nothing ever gets run to actually construct the underlying struct field, meaning that the entry.Field was functionally set to entry.Field{}. This is not the same as entry.NewNilField which actually implements and supplies an interface value under the hood. This caused bad configs to pass validation and led to collector panic instead of nice failure messages.

This PR changed entry.NewNilField to actually produce the correct pattern for a "nil field", while leaving the original implementation intact in entry.NewNoopField in case it is useful elsewhere (though at the moment I only saw it used for nil comparisons, which as far as I can tell were either never useful or something got refactored without being caught). I also added functionality to
operatortest.ConfigUnmarshalTest to check for validation failures by expecting a particular error when calling the operator's Build method.

Link to tracking issue

Addresses a panic discovered by #40398.

Testing

Tests were added to each operator's config validation. I tested manually via a built collector by running the config from the linked issue and confirming that instead of panic I get an error message.

2025-06-15T01:53:10.582Z        info    service@v0.127.0/service.go:199 Setting up own telemetry...     {"resource": {}}
2025-06-15T01:53:10.582Z        info    builders/builders.go:26 Development component. May change in the future.        {"resource": {}, "otelcol.component.id": "debug", "otelcol.component.kind": "exporter", "otelcol.signal": "logs"}
Error: failed to build pipelines: failed to create "filelog/my-app-name" receiver for data type "logs": remove: field is empty
2025/06/15 01:53:10 collector server run finished with error: failed to build pipelines: failed to create "filelog/my-app-name" receiver for data type "logs": remove: field is empty

A few operators with `entry.Field` in their config were validating their
configuration in their `Build` function via a comparison to
`entry.NewNilField`. This was an inaccuracy; when a field is not
provided during the unmarshal step, nothing ever gets run to actually
construct the underlying struct field, meaning that the `entry.Field`
was functionally set to `entry.Field{}`. This is not the same as
`entry.NewNilField` which actually implements and supplies an interface
value under the hood. This caused bad configs to pass validation and led
to collector panic instead of nice failure messages.

This PR changed `entry.NewNilField` to actually produce the correct
pattern for a "nil field", while leaving the original implementation
intact in `entry.NewNoopField` in case it is useful elsewhere (though at
the moment I only saw it used for nil comparisons, which as far as I can
tell were either never useful or something got refactored without being
caught). I also added functionality to
`operatortest.ConfigUnmarshalTest` to check for validation failures by
expecting a particular error when calling the operator's `Build` method.
braydonk and others added 3 commits June 14, 2025 21:54
Turns out the construction of the `field` config is different in certain
scenarios where all resource or all attributes are intended to be
removed, meaning the original comparison didn't cover the case properly.
This is now added.

Also fixed copy operator test configs to use a prefix that is actually
recognized so the field is parsed.
@braydonk
Copy link
Contributor Author

Out of time to fix the new lint failures, will work on it tomorrow.

Copy link
Member

@andrzej-stencel andrzej-stencel left a comment

Choose a reason for hiding this comment

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

Thank you very much for this, this fix is much needed. Please let me know what you think about the proposed implementation without the Nil/NoopField type.

braydonk and others added 6 commits June 20, 2025 12:30
This commit changes to a `Field.IsEmpty` to allow the deletion of the
`NoopField` and `NilField` types. It also adds multiple error validation
to allow for friendlier validation error messages for the `copy` and
`move` operators. Finally, it fixes some tests that were revealed to be
broken by relying on the previously faulty `copy` operator config
validation.
@braydonk
Copy link
Contributor Author

@andrzej-stencel Implemented your suggestions. While doing so I found some tests that relied on the old broken validation so I've now fixed those as well. Should be ready for re-review.

Copy link
Member

@andrzej-stencel andrzej-stencel left a comment

Choose a reason for hiding this comment

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

Awesome! Please let me know what you think about the breaking change concern

Copy link
Member

@andrzej-stencel andrzej-stencel left a comment

Choose a reason for hiding this comment

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

Thank you 🚀 👏 🙏

@andrzej-stencel andrzej-stencel merged commit 265799d into open-telemetry:main Jul 9, 2025
177 checks passed
@github-actions github-actions bot added this to the next release milestone Jul 9, 2025
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.

3 participants