Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[receiver/huaweicloudces] add implementation #36489

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
61 changes: 61 additions & 0 deletions receiver/huaweicloudcesreceiver/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,25 @@
package huaweicloudcesreceiver // import "github.com/open-telemetry/opentelemetry-collector-contrib/receiver/huaweicloudcesreceiver"

import (
"errors"
"fmt"
"slices"

"github.com/huaweicloud/huaweicloud-sdk-go-v3/services/ces/v1/model"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/config/confighttp"
"go.opentelemetry.io/collector/config/configopaque"
"go.opentelemetry.io/collector/config/configretry"
"go.opentelemetry.io/collector/receiver/scraperhelper"
"go.uber.org/multierr"
)

var (
// Predefined error responses for configuration validation failures
errInvalidCollectionInterval = errors.New(`invalid period; must be less than "collection_interval"`)
errMissingProjectID = errors.New(`"project_id" is not specified in config`)
errMissingRegionID = errors.New(`"region_id" is not specified in config`)
errInvalidProxy = errors.New(`"proxy_address" must be specified if "proxy_user" or "proxy_password" is set"`)
)

// Config represent a configuration for the CloudWatch logs exporter.
Expand Down Expand Up @@ -63,3 +78,49 @@ type huaweiSessionConfig struct {
ProxyUser string `mapstructure:"proxy_user"`
ProxyPassword string `mapstructure:"proxy_password"`
}

var _ component.Config = (*Config)(nil)

// These valid periods are defined by CES API constraints: https://support.huaweicloud.com/intl/en-us/api-ces/ces_03_0034.html#section3
var validPeriods = []int32{1, 300, 1200, 3600, 14400, 86400}

// These valid filters are defined by CES API constraints: https://support.huaweicloud.com/intl/en-us/api-ces/ces_03_0034.html#section3
var validFilters = map[string]model.ShowMetricDataRequestFilter{
"max": model.GetShowMetricDataRequestFilterEnum().MAX,
"min": model.GetShowMetricDataRequestFilterEnum().MIN,
"average": model.GetShowMetricDataRequestFilterEnum().AVERAGE,
"sum": model.GetShowMetricDataRequestFilterEnum().SUM,
"variance": model.GetShowMetricDataRequestFilterEnum().VARIANCE,
}

// Validate config
func (config *Config) Validate() error {
var err error
if config.RegionID == "" {
err = multierr.Append(err, errMissingRegionID)
}

if config.ProjectID == "" {
err = multierr.Append(err, errMissingProjectID)
}
if index := slices.Index(validPeriods, config.Period); index == -1 {
err = multierr.Append(err, fmt.Errorf("invalid period: got %d; must be one of %v", config.Period, validPeriods))
}
if _, ok := validFilters[config.Filter]; !ok {
var validFiltersSlice []string
for key := range validFilters {
validFiltersSlice = append(validFiltersSlice, key)
}
err = multierr.Append(err, fmt.Errorf("invalid filter: got %s; must be one of %v", config.Filter, validFiltersSlice))
}
if config.Period >= int32(config.CollectionInterval.Seconds()) {
err = multierr.Append(err, errInvalidCollectionInterval)
}

// Validate that ProxyAddress is provided if ProxyUser or ProxyPassword is set
if (config.ProxyUser != "" || config.ProxyPassword != "") && config.ProxyAddress == "" {
err = multierr.Append(err, errInvalidProxy)
}

return err
}
9 changes: 5 additions & 4 deletions receiver/huaweicloudcesreceiver/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,9 @@ func createDefaultConfig() component.Config {

func createMetricsReceiver(
_ context.Context,
_ receiver.Settings,
_ component.Config,
_ consumer.Metrics) (receiver.Metrics, error) {
return nil, nil
params receiver.Settings,
cfg component.Config,
next consumer.Metrics) (receiver.Metrics, error) {
return newHuaweiCloudCesReceiver(params, cfg.(*Config), next), nil

}
43 changes: 43 additions & 0 deletions receiver/huaweicloudcesreceiver/factory_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright The OpenTelemetry Authors
// SPDX-License-Identifier: Apache-2.0

package huaweicloudcesreceiver

import (
"context"
"testing"
"time"

"github.com/stretchr/testify/assert"
"go.opentelemetry.io/collector/component"
"go.opentelemetry.io/collector/component/componenttest"
"go.opentelemetry.io/collector/consumer/consumertest"
"go.opentelemetry.io/collector/receiver/receivertest"
)

func TestNewFactory(t *testing.T) {
factory := NewFactory()
assert.NotNil(t, factory)
assert.Equal(t, component.MustNewType("huaweicloudcesreceiver"), factory.Type())
}

func TestCreateDefaultConfig(t *testing.T) {
factory := NewFactory()
config := factory.CreateDefaultConfig()
assert.NotNil(t, config)
assert.NoError(t, componenttest.CheckConfigStruct(config))
}

func TestCreateMetricsReceiver(t *testing.T) {
factory := NewFactory()
config := factory.CreateDefaultConfig()

rConfig := config.(*Config)
rConfig.CollectionInterval = 60 * time.Second
rConfig.InitialDelay = time.Second

nextConsumer := new(consumertest.MetricsSink)
receiver, err := factory.CreateMetrics(context.Background(), receivertest.NewNopSettings(), config, nextConsumer)
assert.NoError(t, err)
assert.NotNil(t, receiver)
}
22 changes: 19 additions & 3 deletions receiver/huaweicloudcesreceiver/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,27 @@ go 1.22.7

require (
github.com/cenkalti/backoff/v4 v4.3.0
github.com/huaweicloud/huaweicloud-sdk-go-v3 v0.1.113
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/golden v0.114.0
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatatest v0.114.0
github.com/stretchr/testify v1.9.0
go.opentelemetry.io/collector/component v0.114.0
go.opentelemetry.io/collector/component/componenttest v0.114.0
go.opentelemetry.io/collector/config/confighttp v0.114.0
go.opentelemetry.io/collector/config/configopaque v1.20.0
go.opentelemetry.io/collector/config/configretry v1.20.0
go.opentelemetry.io/collector/consumer v0.114.0
go.opentelemetry.io/collector/consumer/consumertest v0.114.0
go.opentelemetry.io/collector/pdata v1.20.0
go.opentelemetry.io/collector/receiver v0.114.0
go.opentelemetry.io/collector/receiver/receivertest v0.114.0
go.uber.org/goleak v1.3.0
go.uber.org/multierr v1.11.0
go.uber.org/zap v1.27.0
)

require (
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/felixge/httpsnoop v1.0.4 // indirect
github.com/fsnotify/fsnotify v1.8.0 // indirect
Expand All @@ -28,32 +37,39 @@ require (
github.com/klauspost/compress v1.17.11 // indirect
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
github.com/modern-go/reflect2 v1.0.2 // indirect
github.com/open-telemetry/opentelemetry-collector-contrib/pkg/pdatautil v0.114.0 // indirect
github.com/pierrec/lz4/v4 v4.1.21 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rs/cors v1.11.1 // indirect
github.com/stretchr/objx v0.5.2 // indirect
github.com/tjfoc/gmsm v1.4.1 // indirect
go.mongodb.org/mongo-driver v1.12.0 // indirect
go.opentelemetry.io/collector/client v1.20.0 // indirect
go.opentelemetry.io/collector/config/configauth v0.114.0 // indirect
go.opentelemetry.io/collector/config/configcompression v1.20.0 // indirect
go.opentelemetry.io/collector/config/configtelemetry v0.114.0 // indirect
go.opentelemetry.io/collector/config/configtls v1.20.0 // indirect
go.opentelemetry.io/collector/config/internal v0.114.0 // indirect
go.opentelemetry.io/collector/consumer/consumererror v0.114.0 // indirect
go.opentelemetry.io/collector/consumer/consumerprofiles v0.114.0 // indirect
go.opentelemetry.io/collector/extension v0.114.0 // indirect
go.opentelemetry.io/collector/extension/auth v0.114.0 // indirect
go.opentelemetry.io/collector/pdata v1.20.0 // indirect
go.opentelemetry.io/collector/pdata/pprofile v0.114.0 // indirect
go.opentelemetry.io/collector/pipeline v0.114.0 // indirect
go.opentelemetry.io/collector/receiver/receiverprofiles v0.114.0 // indirect
go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.57.0 // indirect
go.opentelemetry.io/otel v1.32.0 // indirect
go.opentelemetry.io/otel/metric v1.32.0 // indirect
go.opentelemetry.io/otel/sdk v1.32.0 // indirect
go.opentelemetry.io/otel/sdk/metric v1.32.0 // indirect
go.opentelemetry.io/otel/trace v1.32.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/crypto v0.29.0 // indirect
golang.org/x/net v0.31.0 // indirect
golang.org/x/sys v0.27.0 // indirect
golang.org/x/text v0.20.0 // indirect
google.golang.org/genproto/googleapis/rpc v0.0.0-20241118233622-e639e219e697 // indirect
google.golang.org/grpc v1.68.0 // indirect
google.golang.org/protobuf v1.35.2 // indirect
gopkg.in/ini.v1 v1.67.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
Loading
Loading