diff --git a/pkg/collector/corechecks/snmp/internal/profile/profile_resolver.go b/pkg/collector/corechecks/snmp/internal/profile/profile_resolver.go index c90d99e658662..19f758c8758d2 100644 --- a/pkg/collector/corechecks/snmp/internal/profile/profile_resolver.go +++ b/pkg/collector/corechecks/snmp/internal/profile/profile_resolver.go @@ -8,6 +8,7 @@ package profile import ( "expvar" "fmt" + "reflect" "strings" "github.com/DataDog/datadog-agent/pkg/util/log" @@ -108,28 +109,32 @@ func mergeProfileDefinition(targetDefinition *profiledefinition.ProfileDefinitio targetDefinition.Metrics = append(targetDefinition.Metrics, baseDefinition.Metrics...) targetDefinition.MetricTags = append(targetDefinition.MetricTags, baseDefinition.MetricTags...) targetDefinition.StaticTags = append(targetDefinition.StaticTags, baseDefinition.StaticTags...) - if targetDefinition.Metadata == nil { - targetDefinition.Metadata = make(profiledefinition.MetadataConfig) - } - for baseResName, baseResource := range baseDefinition.Metadata { - if _, ok := targetDefinition.Metadata[baseResName]; !ok { - targetDefinition.Metadata[baseResName] = profiledefinition.NewMetadataResourceConfig() + // we only have two types of resources: Device and Interface + // merge Device Metadata Fields + baseProfileDeviceMetadataFields := reflect.ValueOf(baseDefinition.Metadata.Device.Fields).Elem() + targetProfileDeviceMetadataFields := reflect.ValueOf(targetDefinition.Metadata.Device.Fields).Elem() + for i := 0; i < targetProfileDeviceMetadataFields.NumField(); i++ { + targetField := targetProfileDeviceMetadataFields.Field(i) + baseField := baseProfileDeviceMetadataFields.Field(i) + + if isEmpty(targetField) { + targetField.Set(baseField) } - if resource, ok := targetDefinition.Metadata[baseResName]; ok { - for _, tagConfig := range baseResource.IDTags { - resource.IDTags = append(targetDefinition.Metadata[baseResName].IDTags, tagConfig) - } - - if resource.Fields == nil { - resource.Fields = make(map[string]profiledefinition.MetadataField, len(baseResource.Fields)) - } - for field, symbol := range baseResource.Fields { - if _, ok := resource.Fields[field]; !ok { - resource.Fields[field] = symbol - } - } - - targetDefinition.Metadata[baseResName] = resource + } + m + // merge Interface Metadata Fields + baseProfileInterfaceMetadataFields := reflect.ValueOf(baseDefinition.Metadata.Interface.Fields).Elem() + targetProfileInterfaceMetadataFields := reflect.ValueOf(targetDefinition.Metadata.Interface.Fields).Elem() + for i := 0; i < targetProfileInterfaceMetadataFields.NumField(); i++ { + targetField := targetProfileInterfaceMetadataFields.Field(i) + baseField := baseProfileInterfaceMetadataFields.Field(i) + + if isEmpty(targetField) { + targetField.Set(baseField) } } + // merge Interface Metadata IDTags + for _, tagConfig := range baseDefinition.Metadata.Interface.IDTags { + targetDefinition.Metadata.Interface.IDTags = append(targetDefinition.Metadata.Interface.IDTags, tagConfig) + } } diff --git a/pkg/collector/corechecks/snmp/internal/profile/utils.go b/pkg/collector/corechecks/snmp/internal/profile/utils.go index 0ac5e1d8508d8..303e5ff1ca833 100644 --- a/pkg/collector/corechecks/snmp/internal/profile/utils.go +++ b/pkg/collector/corechecks/snmp/internal/profile/utils.go @@ -7,6 +7,7 @@ package profile import ( "os" + "reflect" "github.com/mohae/deepcopy" ) @@ -29,3 +30,35 @@ func pathExists(path string) bool { _, err := os.Stat(path) return !os.IsNotExist(err) } + +// isStructEmpty returns true if the given struct is empty +func isStructEmpty(s interface{}) bool { + v := reflect.ValueOf(s) + if v.Kind() == reflect.Ptr { + v = v.Elem() + } + if v.Kind() != reflect.Struct { + return false + } + for i := 0; i < v.NumField(); i++ { + if !reflect.DeepEqual(v.Field(i).Interface(), reflect.Zero(v.Field(i).Type()).Interface()) { + return false + } + } + return true +} + +// isEmpty returns true if the given field is empty +func isEmpty(field reflect.Value) bool { + switch field.Kind() { + case reflect.String: + return field.String() == "" + case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: + return field.Int() == 0 + case reflect.Bool: + return !field.Bool() + // Add other types as needed + default: + return false + } +}