Skip to content
Merged
25 changes: 25 additions & 0 deletions .chloggen/confmap-append-merge-components.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# Use this changelog template to create an entry for release notes.

# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
change_type: enhancement

# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
component: confmap

# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
note: Update the behavior of the confmap.enableMergeAppendOption feature gate to merge only component lists.

# One or more tracking issues or pull requests related to the change
issues: [12926]

# (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:

# Optional: The change log or logs in which this entry should be included.
# e.g. '[user]' or '[user, api]'
# Include 'user' if the change is relevant to end users.
# Include 'api' if there is a change to a library API.
# Default: '[user]'
change_logs: []
1 change: 1 addition & 0 deletions cmd/mdatagen/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ require (
github.com/go-logr/logr v1.4.2 // indirect
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions cmd/mdatagen/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions cmd/otelcorecol/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ require (
github.com/go-logr/stdr v1.2.2 // indirect
github.com/go-ole/go-ole v1.2.6 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/snappy v1.0.0 // indirect
github.com/google/go-tpm v0.9.3 // indirect
Expand Down
2 changes: 2 additions & 0 deletions cmd/otelcorecol/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions confmap/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ go 1.23.0

require (
github.com/go-viper/mapstructure/v2 v2.2.1
github.com/gobwas/glob v0.2.3
github.com/knadh/koanf/maps v0.1.2
github.com/knadh/koanf/providers/confmap v1.0.0
github.com/knadh/koanf/v2 v2.2.0
Expand Down
2 changes: 2 additions & 0 deletions confmap/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions confmap/internal/e2e/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions confmap/internal/e2e/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

69 changes: 46 additions & 23 deletions confmap/merge.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,47 +5,70 @@ package confmap // import "go.opentelemetry.io/collector/confmap"

import (
"reflect"

"github.com/gobwas/glob"
"github.com/knadh/koanf/maps"
)

func mergeAppend(src, dest map[string]any) error {
// mergeAppend recursively merges the src map into the dest map (left to right),
// modifying and expanding the dest map in the process.
// This function does not overwrite lists, and ensures that the final value is a name-aware
// copy of lists from src and dest.
// This function does not overwrite component lists, and ensures that the
// final value is a name-aware copy of lists from src and dest.

for sKey, sVal := range src {
dVal, dOk := dest[sKey]
if !dOk {
// key is not present in destination config. Hence, add it to destination map
dest[sKey] = sVal
continue
// Compile the globs once
patterns := []string{
"service::extensions",
"service::**::receivers",
"service::**::exporters",
}
var globs []glob.Glob
for _, p := range patterns {
if g, err := glob.Compile(p); err == nil {
globs = append(globs, g)
}
}

srcVal := reflect.ValueOf(sVal)
destVal := reflect.ValueOf(dVal)
// Flatten both source and destination maps
srcFlat, _ := maps.Flatten(src, []string{}, KeyDelimiter)
destFlat, _ := maps.Flatten(dest, []string{}, KeyDelimiter)

if destVal.Kind() != srcVal.Kind() {
// different kinds. Override the destination map
dest[sKey] = sVal
for sKey, sVal := range srcFlat {
if !isMatch(sKey, globs) {
continue
}

switch srcVal.Kind() {
case reflect.Array, reflect.Slice:
// both of them are array. Merge them
dest[sKey] = mergeSlice(srcVal, destVal)
case reflect.Map:
// both of them are maps. Recursively call the mergeAppend
_ = mergeAppend(sVal.(map[string]any), dVal.(map[string]any))
default:
// any other datatype. Override the destination map
dest[sKey] = sVal
dVal, dOk := destFlat[sKey]
if !dOk {
continue // Let maps.Merge handle missing keys
}

srcVal := reflect.ValueOf(sVal)
destVal := reflect.ValueOf(dVal)

// Only merge if the value is a slice or array; let maps.Merge handle other types
if srcVal.Kind() == reflect.Slice || srcVal.Kind() == reflect.Array {
srcFlat[sKey] = mergeSlice(srcVal, destVal)
}
}

// Unflatten and merge
mergedSrc := maps.Unflatten(srcFlat, KeyDelimiter)
maps.Merge(mergedSrc, dest)

return nil
}

// isMatch checks if a key matches any glob in the list
func isMatch(key string, globs []glob.Glob) bool {
for _, g := range globs {
if g.Match(key) {
return true
}
}
return false
}

func mergeSlice(src, dest reflect.Value) any {
slice := reflect.MakeSlice(src.Type(), 0, src.Cap()+dest.Cap())
for i := 0; i < dest.Len(); i++ {
Expand Down
1 change: 1 addition & 0 deletions confmap/provider/envprovider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions confmap/provider/envprovider/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions confmap/provider/fileprovider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions confmap/provider/fileprovider/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions confmap/provider/httpprovider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions confmap/provider/httpprovider/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions confmap/provider/httpsprovider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions confmap/provider/httpsprovider/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions confmap/provider/yamlprovider/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ require (
require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-viper/mapstructure/v2 v2.2.1 // indirect
github.com/gobwas/glob v0.2.3 // indirect
github.com/hashicorp/go-version v1.7.0 // indirect
github.com/knadh/koanf/maps v0.1.2 // indirect
github.com/knadh/koanf/providers/confmap v1.0.0 // indirect
Expand Down
2 changes: 2 additions & 0 deletions confmap/provider/yamlprovider/go.sum

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 7 additions & 0 deletions confmap/testdata/config2.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
service:
extensions: [nop2]
pipelines:
traces:
receivers: [nop2]
processors: [nop]
exporters: [nop2]
Loading
Loading