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

[exporter/datadog] Add api.fail_on_invalid_key to fail fast if API Key is invalid #9426

Merged
merged 11 commits into from
May 5, 2022
Prev Previous commit
Next Next commit
utils.ValidateAPI() returns error
  • Loading branch information
keisku committed Apr 27, 2022
commit 624b4a1398d8516ab25033c8cfbc397cd11da035
6 changes: 5 additions & 1 deletion exporter/datadogexporter/factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -214,7 +214,11 @@ func (f *factory) createTracesExporter(
return nil
}
} else {
pushTracesFn = newTracesExporter(ctx, set, cfg, &f.onceMetadata).pushTraceDataScrubbed
exporter, err := newTracesExporter(ctx, set, cfg, &f.onceMetadata)
if err != nil {
return nil, err
}
pushTracesFn = exporter.pushTraceDataScrubbed
}

return exporterhelper.NewTracesExporter(
Expand Down
22 changes: 13 additions & 9 deletions exporter/datadogexporter/internal/utils/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@
package utils // import "github.com/open-telemetry/opentelemetry-collector-contrib/exporter/datadogexporter/internal/utils"

import (
"errors"
"fmt"

"go.uber.org/zap"
"gopkg.in/zorkian/go-datadog-api.v2"
)
Expand All @@ -27,20 +30,21 @@ func CreateClient(APIKey string, endpoint string) *datadog.Client {
return client
}

var ErrInvalidAPI = errors.New("API Key validation failed")

// ValidateAPIKey checks that the provided client was given a correct API key.
func ValidateAPIKey(logger *zap.Logger, client *datadog.Client, failOnInvalidKey bool) {
func ValidateAPIKey(logger *zap.Logger, client *datadog.Client) error {
logger.Info("Validating API key.")
valid, err := client.Validate()
if err == nil && valid {
logger.Info("API key validation successful.")
return
return nil
}
switch {
case err != nil:
logger.Warn("Error while validating API key.", zap.Error(err))
case !valid && failOnInvalidKey:
logger.Fatal("API Key validation failed.")
case !valid && !failOnInvalidKey:
logger.Warn("API Key validation failed.")
if err != nil {
msg := "Error while validating API key"
logger.Warn(msg, zap.Error(err))
return fmt.Errorf("%s: %w", msg, err)
mx-psi marked this conversation as resolved.
Show resolved Hide resolved
}
logger.Warn(ErrInvalidAPI.Error())
return ErrInvalidAPI
}
4 changes: 3 additions & 1 deletion exporter/datadogexporter/metrics_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,9 @@ func newMetricsExporter(ctx context.Context, params component.ExporterCreateSett
client.ExtraHeader["User-Agent"] = utils.UserAgent(params.BuildInfo)
client.HttpClient = utils.NewHTTPClient(cfg.TimeoutSettings, cfg.LimitedHTTPClientSettings.TLSSetting.InsecureSkipVerify)

utils.ValidateAPIKey(params.Logger, client, cfg.API.FailOnInvalidKey)
if err := utils.ValidateAPIKey(params.Logger, client); err != nil && cfg.API.FailOnInvalidKey {
return nil, err
}

tr, err := translatorFromConfig(params.Logger, cfg)
if err != nil {
Expand Down
8 changes: 5 additions & 3 deletions exporter/datadogexporter/traces_exporter.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,10 +65,12 @@ var (
}
)

func newTracesExporter(ctx context.Context, params component.ExporterCreateSettings, cfg *config.Config, onceMetadata *sync.Once) *traceExporter {
func newTracesExporter(ctx context.Context, params component.ExporterCreateSettings, cfg *config.Config, onceMetadata *sync.Once) (*traceExporter, error) {
// client to send running metric to the backend & perform API key validation
client := utils.CreateClient(cfg.API.Key, cfg.Metrics.TCPAddr.Endpoint)
utils.ValidateAPIKey(params.Logger, client, cfg.API.FailOnInvalidKey)
if err := utils.ValidateAPIKey(params.Logger, client); err != nil && cfg.API.FailOnInvalidKey {
return nil, err
}

// removes potentially sensitive info and PII, approach taken from serverless approach
// https://github.com/DataDog/datadog-serverless-functions/blob/11f170eac105d66be30f18eda09eca791bc0d31b/aws/logs_monitoring/trace_forwarder/cmd/trace/main.go#L43
Expand All @@ -89,7 +91,7 @@ func newTracesExporter(ctx context.Context, params component.ExporterCreateSetti
onceMetadata: onceMetadata,
}

return exporter
return exporter, nil
}

// TODO: when component.Host exposes a way to retrieve processors, check for batch processors
Expand Down