diff --git a/apis/v1alpha2/config.go b/apis/v1alpha2/config.go index cd5832d787..740237b18e 100644 --- a/apis/v1alpha2/config.go +++ b/apis/v1alpha2/config.go @@ -23,7 +23,7 @@ import ( // AnyConfig represent parts of the config. type AnyConfig struct { - Object map[string]interface{} `json:"-"` + Object map[string]interface{} `json:"-" yaml:",inline"` } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. @@ -72,24 +72,24 @@ func (c *AnyConfig) MarshalJSON() ([]byte, error) { // Config encapsulates collector config. type Config struct { // +kubebuilder:pruning:PreserveUnknownFields - Receivers AnyConfig `json:"receivers"` + Receivers AnyConfig `json:"receivers" yaml:"receivers"` // +kubebuilder:pruning:PreserveUnknownFields - Exporters AnyConfig `json:"exporters"` + Exporters AnyConfig `json:"exporters" yaml:"exporters"` // +kubebuilder:pruning:PreserveUnknownFields - Processors *AnyConfig `json:"processors,omitempty"` + Processors *AnyConfig `json:"processors,omitempty" yaml:"processors,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields - Connectors *AnyConfig `json:"connectors,omitempty"` + Connectors *AnyConfig `json:"connectors,omitempty" yaml:"connectors,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields - Extensions *AnyConfig `json:"extensions,omitempty"` - Service Service `json:"service"` + Extensions *AnyConfig `json:"extensions,omitempty" yaml:"extensions,omitempty"` + Service Service `json:"service" yaml:"service"` } type Service struct { - Extensions *[]string `json:"extensions,omitempty"` + Extensions *[]string `json:"extensions,omitempty" yaml:"extensions,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields - Telemetry *AnyConfig `json:"telemetry,omitempty"` + Telemetry *AnyConfig `json:"telemetry,omitempty" yaml:"telemetry,omitempty"` // +kubebuilder:pruning:PreserveUnknownFields - Pipelines AnyConfig `json:"pipelines"` + Pipelines AnyConfig `json:"pipelines" yaml:"pipelines"` } // Returns null objects in the config. @@ -128,7 +128,11 @@ func hasNullValue(cfg map[string]interface{}) []string { nullKeys = append(nullKeys, fmt.Sprintf("%s:", k)) } if reflect.ValueOf(v).Kind() == reflect.Map { - nulls := hasNullValue(v.(map[string]interface{})) + var nulls []string + val, ok := v.(map[string]interface{}) + if ok { + nulls = hasNullValue(val) + } if len(nulls) > 0 { prefixed := addPrefix(k+".", nulls) nullKeys = append(nullKeys, prefixed...) diff --git a/apis/v1alpha2/config_test.go b/apis/v1alpha2/config_test.go index 079f6ba548..a672c4aa3f 100644 --- a/apis/v1alpha2/config_test.go +++ b/apis/v1alpha2/config_test.go @@ -23,6 +23,7 @@ import ( "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" + go_yaml "gopkg.in/yaml.v3" "sigs.k8s.io/yaml" ) @@ -71,3 +72,41 @@ func TestNullObjects(t *testing.T) { nullObjects := cfg.nullObjects() assert.Equal(t, []string{"connectors.spanmetrics:", "exporters.otlp.endpoint:", "extensions.health_check:", "processors.batch:", "receivers.otlp.protocols.grpc:", "receivers.otlp.protocols.http:"}, nullObjects) } + +func TestConfigFiles_go_yaml(t *testing.T) { + files, err := os.ReadDir("./testdata") + require.NoError(t, err) + + for _, file := range files { + if !strings.HasPrefix(file.Name(), "otelcol-") { + continue + } + + testFile := path.Join("./testdata", file.Name()) + t.Run(testFile, func(t *testing.T) { + collectorYaml, err := os.ReadFile(testFile) + require.NoError(t, err) + + cfg := &Config{} + err = go_yaml.Unmarshal(collectorYaml, cfg) + require.NoError(t, err) + yamlCfg, err := go_yaml.Marshal(cfg) + require.NoError(t, err) + + require.NoError(t, err) + assert.YAMLEq(t, string(collectorYaml), string(yamlCfg)) + }) + } +} + +func TestNullObjects_go_yaml(t *testing.T) { + collectorYaml, err := os.ReadFile("./testdata/otelcol-null-values.yaml") + require.NoError(t, err) + + cfg := &Config{} + err = go_yaml.Unmarshal(collectorYaml, cfg) + require.NoError(t, err) + + nullObjects := cfg.nullObjects() + assert.Equal(t, []string{"connectors.spanmetrics:", "exporters.otlp.endpoint:", "extensions.health_check:", "processors.batch:", "receivers.otlp.protocols.grpc:", "receivers.otlp.protocols.http:"}, nullObjects) +}