Skip to content

Commit 04bb6d9

Browse files
committed
[mdatagen] Improve validation for attribute enabled field
Resource attributes now require an explicit `enabled` field in metadata.yaml files, while regular attributes are prohibited from having this field. This improves validation and prevents configuration errors.
1 parent 4670870 commit 04bb6d9

File tree

3 files changed

+59
-10
lines changed

3 files changed

+59
-10
lines changed
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Use this changelog template to create an entry for release notes.
2+
3+
# One of 'breaking', 'deprecation', 'new_component', 'enhancement', 'bug_fix'
4+
change_type: enhancement
5+
6+
# The name of the component, or a single word describing the area of concern, (e.g. otlpreceiver)
7+
component: mdatagen
8+
9+
# A brief description of the change. Surround your text with quotes ("") if it needs to start with a backtick (`).
10+
note: Improve validation for resource attribute `enabled` field in metadata files
11+
12+
# One or more tracking issues or pull requests related to the change
13+
issues: [12722]
14+
15+
# (Optional) One or more lines of additional information to render under the primary note.
16+
# These lines will be padded with 2 spaces and then inserted directly into the document.
17+
# Use pipe (|) for multiline entries.
18+
subtext: |
19+
Resource attributes now require an explicit `enabled` field in metadata.yaml files, while regular attributes
20+
are prohibited from having this field. This improves validation and prevents configuration errors.
21+
22+
# Optional: The change log or logs in which this entry should be included.
23+
# e.g. '[user]' or '[user, api]'
24+
# Include 'user' if the change is relevant to end users.
25+
# Include 'api' if there is a change to a library API.
26+
# Default: '[user]'
27+
change_logs: [user]

cmd/mdatagen/internal/loader_test.go

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ import (
1515
"go.opentelemetry.io/collector/pdata/pmetric"
1616
)
1717

18+
func boolPtr(b bool) *bool {
19+
return &b
20+
}
21+
1822
func TestTwoPackagesInDirectory(t *testing.T) {
1923
contents, err := os.ReadFile("testdata/twopackages.yaml")
2024
require.NoError(t, err)
@@ -70,15 +74,15 @@ func TestLoadMetadata(t *testing.T) {
7074
ResourceAttributes: map[AttributeName]Attribute{
7175
"string.resource.attr": {
7276
Description: "Resource attribute with any string value.",
73-
Enabled: true,
77+
EnabledPtr: boolPtr(true),
7478
Type: ValueType{
7579
ValueType: pcommon.ValueTypeStr,
7680
},
7781
FullName: "string.resource.attr",
7882
},
7983
"string.enum.resource.attr": {
8084
Description: "Resource attribute with a known set of string values.",
81-
Enabled: true,
85+
EnabledPtr: boolPtr(true),
8286
Enum: []string{"one", "two"},
8387
Type: ValueType{
8488
ValueType: pcommon.ValueTypeStr,
@@ -87,23 +91,23 @@ func TestLoadMetadata(t *testing.T) {
8791
},
8892
"optional.resource.attr": {
8993
Description: "Explicitly disabled ResourceAttribute.",
90-
Enabled: false,
94+
EnabledPtr: boolPtr(false),
9195
Type: ValueType{
9296
ValueType: pcommon.ValueTypeStr,
9397
},
9498
FullName: "optional.resource.attr",
9599
},
96100
"slice.resource.attr": {
97101
Description: "Resource attribute with a slice value.",
98-
Enabled: true,
102+
EnabledPtr: boolPtr(true),
99103
Type: ValueType{
100104
ValueType: pcommon.ValueTypeSlice,
101105
},
102106
FullName: "slice.resource.attr",
103107
},
104108
"map.resource.attr": {
105109
Description: "Resource attribute with a map value.",
106-
Enabled: true,
110+
EnabledPtr: boolPtr(true),
107111
Type: ValueType{
108112
ValueType: pcommon.ValueTypeMap,
109113
},
@@ -114,7 +118,7 @@ func TestLoadMetadata(t *testing.T) {
114118
Warnings: Warnings{
115119
IfEnabledNotSet: "This resource_attribute will be disabled by default soon.",
116120
},
117-
Enabled: true,
121+
EnabledPtr: boolPtr(true),
118122
Type: ValueType{
119123
ValueType: pcommon.ValueTypeStr,
120124
},
@@ -125,7 +129,7 @@ func TestLoadMetadata(t *testing.T) {
125129
Warnings: Warnings{
126130
IfConfigured: "This resource_attribute is deprecated and will be removed soon.",
127131
},
128-
Enabled: false,
132+
EnabledPtr: boolPtr(false),
129133
Type: ValueType{
130134
ValueType: pcommon.ValueTypeStr,
131135
},
@@ -136,7 +140,7 @@ func TestLoadMetadata(t *testing.T) {
136140
Warnings: Warnings{
137141
IfEnabled: "This resource_attribute is deprecated and will be removed soon.",
138142
},
139-
Enabled: true,
143+
EnabledPtr: boolPtr(true),
140144
Type: ValueType{
141145
ValueType: pcommon.ValueTypeStr,
142146
},

cmd/mdatagen/internal/metadata.go

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,9 @@ func (md *Metadata) validateResourceAttributes() error {
114114
if attr.Type == empty {
115115
errs = errors.Join(errs, fmt.Errorf("empty type for resource attribute: %v", name))
116116
}
117+
if attr.EnabledPtr == nil {
118+
errs = errors.Join(errs, fmt.Errorf("enabled field is required for resource attribute: %v", name))
119+
}
117120
}
118121
return errs
119122
}
@@ -140,6 +143,9 @@ func (md *Metadata) validateAttributes(usedAttrs map[AttributeName]bool) error {
140143
if attr.Type == empty {
141144
errs = errors.Join(errs, fmt.Errorf("empty type for attribute: %v", attrName))
142145
}
146+
if attr.EnabledPtr != nil {
147+
errs = errors.Join(errs, fmt.Errorf("enabled field is not allowed for regular attribute: %v", attrName))
148+
}
143149
if !usedAttrs[attrName] {
144150
unusedAttrs = append(unusedAttrs, attrName)
145151
}
@@ -292,8 +298,8 @@ type Attribute struct {
292298
Description string `mapstructure:"description"`
293299
// NameOverride can be used to override the attribute name.
294300
NameOverride string `mapstructure:"name_override"`
295-
// Enabled defines whether the attribute is enabled by default.
296-
Enabled bool `mapstructure:"enabled"`
301+
// EnabledPtr defines whether the attribute is enabled by default.
302+
EnabledPtr *bool `mapstructure:"enabled"`
297303
// Include can be used to filter attributes.
298304
Include []filter.Config `mapstructure:"include"`
299305
// Include can be used to filter attributes.
@@ -310,6 +316,18 @@ type Attribute struct {
310316
Optional bool `mapstructure:"optional"`
311317
}
312318

319+
// Enabled returns the boolean value of EnabledPtr.
320+
// This method is needed to differentiate between different types of attributes:
321+
// - Resource attributes: EnabledPtr is always set (non-nil) due to validation
322+
// - Regular attributes: EnabledPtr is always nil due to validation
323+
// Panics if EnabledPtr is nil, indicating incorrect template usage.
324+
func (a Attribute) Enabled() bool {
325+
if a.EnabledPtr == nil {
326+
panic("Enabled() must not be called on regular attributes, only on resource attributes")
327+
}
328+
return *a.EnabledPtr
329+
}
330+
313331
// Name returns actual name of the attribute that is set on the metric after applying NameOverride.
314332
func (a Attribute) Name() AttributeName {
315333
if a.NameOverride != "" {

0 commit comments

Comments
 (0)