Skip to content
Draft
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
19 changes: 19 additions & 0 deletions .chloggen/fix_yaml-string-preservation.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: bug_fix

# The name of the component, or a single word describing the area of concern, (e.g. collector, target allocator, auto-instrumentation, opamp, github action)
component: operator

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: "Fix string value preservation in YAML encoding to prevent automatic conversion of numeric-looking strings like \"0e12\" to float64"

# One or more tracking issues related to the change
issues: [4314]

# (Optional) One or more lines of additional information to render under the primary note.
# These lines will be padded with 2 spaces and then inserted directly into the document.
# Use pipe (|) for multiline entries.
subtext: |
Removed the go_yaml.AutoInt() option from YAML encoder that was causing string values
containing scientific notation patterns to be automatically converted to numeric types,
which resulted in type validation errors during collector creation.
2 changes: 1 addition & 1 deletion apis/v1beta1/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -390,7 +390,7 @@ func (c *Config) GetReadinessProbe(logger logr.Logger) (*corev1.Probe, error) {
// Yaml encodes the current object and returns it as a string.
func (c *Config) Yaml() (string, error) {
var buf bytes.Buffer
yamlEncoder := go_yaml.NewEncoder(&buf, go_yaml.IndentSequence(true), go_yaml.AutoInt())
yamlEncoder := go_yaml.NewEncoder(&buf, go_yaml.IndentSequence(true), go_yaml.UseSingleQuote(false))
if err := yamlEncoder.Encode(&c); err != nil {
return "", err
}
Expand Down
55 changes: 55 additions & 0 deletions apis/v1beta1/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,61 @@ service:
assert.Equal(t, expected, yamlCollector)
}

func TestConfigYamlStringPreservation(t *testing.T) {
// Test for issue https://github.com/open-telemetry/opentelemetry-operator/issues/4314
// Ensure that string values that look like numbers (e.g., "0e12") are preserved as strings
cfg := &Config{
Processors: &AnyConfig{
Object: map[string]interface{}{
"transform": map[string]interface{}{
"operations": []interface{}{
map[string]interface{}{
"new_value": "0e12", // This should remain a string, not be converted to float64
},
},
},
},
},
Receivers: AnyConfig{
Object: map[string]interface{}{
"otlp": map[string]interface{}{},
},
},
Exporters: AnyConfig{
Object: map[string]interface{}{
"debug": map[string]interface{}{},
},
},
Service: Service{
Pipelines: map[string]*Pipeline{
"traces": {
Receivers: []string{"otlp"},
Processors: []string{"transform"},
Exporters: []string{"debug"},
},
},
},
}

yamlOutput, err := cfg.Yaml()
require.NoError(t, err)

// Verify the string is not converted to a number by parsing back
var parsedConfig map[string]interface{}
err = go_yaml.Unmarshal([]byte(yamlOutput), &parsedConfig)
require.NoError(t, err)

processors := parsedConfig["processors"].(map[string]interface{})
transform := processors["transform"].(map[string]interface{})
operations := transform["operations"].([]interface{})
operation := operations[0].(map[string]interface{})
newValue := operation["new_value"]

// Ensure it's still a string, not a float64
assert.IsType(t, "", newValue)
assert.Equal(t, "0e12", newValue)
}

func TestGetTelemetryFromYAML(t *testing.T) {
collectorYaml, err := os.ReadFile("./testdata/otelcol-demo.yaml")
require.NoError(t, err)
Expand Down
Loading