Repository navigation
[OpenTelemetry] Resolve inline Secret placeholders in openTelemetryProperties - #40579
Conversation
There was a problem hiding this comment.
📋 Review Summary
This PR adds support for resolving Beam Secret placeholders (${type:<secret_type>;...}) in OpenTelemetry properties configured via SdkHarnessOptions. The implementation is clean, avoids mutating PipelineOptions (preventing secret leakage into serialized options), properly handles special regex characters and trailing whitespace, and includes comprehensive unit test coverage.
🔍 General Feedback
- The secret resolution logic in
SdkHarnessOptions.resolveOpenTelemetryPropertyValueis well-scoped to only match${type:...}placeholders, leaving other${...}expressions intact. - Good use of
Matcher.quoteReplacementand.trim()when substituting secret values into property strings. - Unit tests in
SdkHarnessOptionsTestthoroughly cover plain values, single and multiple secret placeholders, special characters, invalid secret types, and non-mutation ofPipelineOptions.
💡 Tip: Comment /gemini review on this pull request to trigger a new Gemini code review.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #40579 +/- ##
============================================
+ Coverage 56.16% 65.07% +8.90%
- Complexity 2288 13988 +11700
============================================
Files 1124 1729 +605
Lines 178336 108491 -69845
Branches 1489 11309 +9820
============================================
- Hits 100170 70603 -29567
+ Misses 75645 33680 -41965
- Partials 2521 4208 +1687
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
eca006b to
69ec99c
Compare
|
|
||
| class GlobalOpenTelemetryFactory implements DefaultValueFactory<OpenTelemetry> { | ||
| private static final Pattern SECRET_PLACEHOLDER_PATTERN = | ||
| Pattern.compile("\\$\\{(type:[^}]+)\\}"); |
There was a problem hiding this comment.
This pattern requires type: to be at the very beginning of the secret option string, but Secret.parseSecretOption doesn't actually enforce that restriction.
Have you considered making the regex more flexible to match the parser's behavior?
|
Assigning reviewers: R: @damccorm for label java. This pull request likely touches a core component ("core" label). Please review with scrutiny. Note: If you would like to opt out of this review, comment Available commands:
The PR bot will only process comments in the main thread (not review comments). |
69ec99c to
7b7344a
Compare
| * {@link Secret#parseSecretOption(String)}. | ||
| */ | ||
| @VisibleForTesting | ||
| static String resolveOpenTelemetryPropertyValue(String value) { |
There was a problem hiding this comment.
I wonder if this would be better as a generic function packaged in util alongside Secret? Right now, it is just used by OpenTelemetry, but I could imagine it being broadly useful, and it would be nice to make sure we do this consistently.
WDYT?
There was a problem hiding this comment.
Sorry, just missed mentioning this before the merge. It is fine to leave or move, I will defer to you
There was a problem hiding this comment.
I will move it in follow up pr, thanks for feedback
There was a problem hiding this comment.
Yes, I agree. Moving this logic to a generic utility alongside Secret would be a great way to ensure we handle this consistently across IOs that accept a map of configuration, like icebergIO and kafkaIO.
This PR also highlights that using an inline secret string format is much more user-friendly than attempting to parse nested JSON. However, I am afraid this will confuse users since in some places we support JSON secret spec and others support inline secret string.
Do you consider it as a problem @damccorm ?
There was a problem hiding this comment.
I think the UX here is not particularly problematic (it mostly puts some work on us to handle it correctly, which I think is fine)
Summary
Allows referencing secrets managed by Beam's
Secretframework (e.g.,GcpSecret/GoogleCloudSecretManager) inline inside--openTelemetryPropertiesvalues so sensitive tokens (such as OTLP exporter authentication headers) do not need to be passed in plaintext inPipelineOptions.Details
SdkHarnessOptions.configureOpenTelemetry(PipelineOptions)to resolve inline${...}placeholders (formatted as${type:<secret_type>;<secret_param>:<value>}) viaSecret.parseSecretOption(String)when populating JVM system properties on the worker, while preserving the unresolved placeholder inPipelineOptions.:(such as ARNs or URLs), but cannot contain;or}.$and\).SdkHarnessOptionsTestcovering plain strings, single and multiple${...}secret placeholders, parameter ordering, colons in parameter values, whitespace/newline trimming,$and\escaping, invalid secret specs / missingtypeparameter, andconfigureOpenTelemetrysystem property initialization.