Skip to content

Commit

Permalink
[cmd/mdatagen]: Add feature gates support to metadata-schema.yaml
Browse files Browse the repository at this point in the history
  • Loading branch information
narcis96 committed Oct 17, 2024
1 parent a7d019f commit 05ec7bf
Show file tree
Hide file tree
Showing 2 changed files with 92 additions and 0 deletions.
75 changes: 75 additions & 0 deletions cmd/mdatagen/internal/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"fmt"
"os/exec"
"path/filepath"
"regexp"
"strings"

"go.opentelemetry.io/collector/component"
Expand All @@ -20,6 +21,20 @@ import (
"go.opentelemetry.io/collector/pdata/pcommon"
)

var (
// idRegexp is used to validate the ID of a Gate.
// IDs' characters must be alphanumeric or dots.
idRegexp = regexp.MustCompile(`^[0-9a-zA-Z\.]*$`)
versionRegexp = regexp.MustCompile(`^v(\d+)\.(\d+)\.(\d+)$`)
referenceURLRegexp = regexp.MustCompile(`^(https?:\/\/)?([a-zA-Z0-9-]+(\.[a-zA-Z0-9-]+)+)(\/[^\s]*)?$`)
validStages = map[string]bool{
"Alpha": true,
"Beta": true,
"Stable": true,
"Deprecated": true,
}
)

type MetricName string

func (mn MetricName) Render() (string, error) {
Expand All @@ -40,6 +55,16 @@ func (mn AttributeName) RenderUnexported() (string, error) {
return FormatIdentifier(string(mn), false)
}

type featureGateName string

func (mn featureGateName) Render() (string, error) {
return FormatIdentifier(string(mn), true)

Check warning on line 61 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L60-L61

Added lines #L60 - L61 were not covered by tests
}

func (mn featureGateName) RenderUnexported() (string, error) {
return FormatIdentifier(string(mn), false)

Check warning on line 65 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L64-L65

Added lines #L64 - L65 were not covered by tests
}

// ValueType defines an attribute value type.
type ValueType struct {
// ValueType is type of the attribute value.
Expand Down Expand Up @@ -159,6 +184,7 @@ func (m *Metric) Unmarshal(parser *confmap.Conf) error {
}
return parser.Unmarshal(m)
}

func (m Metric) Data() MetricData {
if m.Sum != nil {
return m.Sum
Expand Down Expand Up @@ -296,6 +322,8 @@ type Metadata struct {
ShortFolderName string `mapstructure:"-"`
// Tests is the set of tests generated with the component
Tests tests `mapstructure:"tests"`
// FeatureGates that can be used for the component.
FeatureGates map[featureGateName]featureGate `mapstructure:"feature_gates"`
}

func setAttributesFullName(attrs map[AttributeName]Attribute) {
Expand Down Expand Up @@ -373,3 +401,50 @@ func packageName() (string, error) {
}
return strings.TrimSpace(string(output)), nil
}

type featureGate struct {
// Required.
Id string `mapstructure:"id"`
// Description describes the purpose of the attribute.
Description string `mapstructure:"description"`
// Stage current stage at which the feature gate is in the development lifecyle
Stage string `mapstructure:"stage"`
// ReferenceURL can optionally give the url of the feature_gate
ReferenceURL string `mapstructure:"reference_url"`
// FromVersion optional field which gives the release version from which the gate has been given the current stage
FromVersion string `mapstructure:"from_version"`
// ToVersion optional field which gives the release version till which the gate the gate had the given lifecycle stage
ToVersion string `mapstructure:"to_version"`
// FeatureGateName name of the feature gate
FeatureGateName featureGateName `mapstructure:"-"`
}

func (f *featureGate) validate(parser *confmap.Conf) error {
if !parser.IsSet("id") {
return errors.New("missing required field: `id`")

Check warning on line 424 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L422-L424

Added lines #L422 - L424 were not covered by tests
}
var err []error
if !idRegexp.MatchString(fmt.Sprintf("%v", parser.Get("id"))) {
err = append(err, fmt.Errorf("invalid character(s) in ID"))

Check warning on line 428 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L426-L428

Added lines #L426 - L428 were not covered by tests
}
if !versionRegexp.MatchString(fmt.Sprintf("%v", parser.Get("from_version"))) {
err = append(err, fmt.Errorf("invalid character(s) in from_version"))

Check warning on line 431 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L430-L431

Added lines #L430 - L431 were not covered by tests
}
if !versionRegexp.MatchString(fmt.Sprintf("%v", parser.Get("to_version"))) {
err = append(err, fmt.Errorf("invalid character(s) in to_version"))

Check warning on line 434 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L433-L434

Added lines #L433 - L434 were not covered by tests
}
if !referenceURLRegexp.MatchString(fmt.Sprintf("%v", parser.Get("reference_url"))) {
err = append(err, fmt.Errorf("invalid character(s) in reference_url"))

Check warning on line 437 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L436-L437

Added lines #L436 - L437 were not covered by tests
}
if _, ok := validStages[fmt.Sprintf("%v", parser.Get("stage"))]; !ok {
err = append(err, fmt.Errorf("invalid stage"))

Check warning on line 440 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L439-L440

Added lines #L439 - L440 were not covered by tests
}
return errors.Join(err...)

Check warning on line 442 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L442

Added line #L442 was not covered by tests
}

func (f *featureGate) Unmarshal(parser *confmap.Conf) error {
if err := f.validate(parser); err != nil {
return err

Check warning on line 447 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L445-L447

Added lines #L445 - L447 were not covered by tests
}
return parser.Unmarshal(f)

Check warning on line 449 in cmd/mdatagen/internal/loader.go

View check run for this annotation

Codecov / codecov/patch

cmd/mdatagen/internal/loader.go#L449

Added line #L449 was not covered by tests
}
17 changes: 17 additions & 0 deletions cmd/mdatagen/metadata-schema.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,3 +175,20 @@ telemetry:
# Optional: array of attributes that were defined in the attributes section that are emitted by this metric.
# Note: Only the following attribute types are supported: <string|int|double|bool>
attributes: [string]

#Optional: Gate is an immutable object that is owned by the Registry and represents an individual feature that
# may be enabled or disabled based on the lifecycle state of the feature and CLI flags specified by the user.
feature_gates:
<feature_gate.name>:
#Required: id of the feature gate
id:
#Required: description of the gate
description:
#Required: current stage at which the feature gate is in the development lifecyle
stage:
#Optional: link to the issue where the gate has been discussed
reference_url:
#Optional: the release version from which the gate has been given the current stage
from_version:
#Optional: the release version till which the gate had the given lifecycle stage
to_version:

0 comments on commit 05ec7bf

Please sign in to comment.