feat(outputs.wavefront): Add more auth options and update SDK (#13857)

This commit is contained in:
Luke Winikates 2023-09-08 11:46:08 -07:00 committed by GitHub
parent 6e6c57154e
commit d807dd3c05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 272 additions and 105 deletions

3
go.mod
View File

@ -178,7 +178,7 @@ require (
github.com/vapourismo/knx-go v0.0.0-20220829185957-fb5458a5389d
github.com/vjeantet/grok v1.0.1
github.com/vmware/govmomi v0.28.1-0.20220921224932-b4b508abf208
github.com/wavefronthq/wavefront-sdk-go v0.13.0
github.com/wavefronthq/wavefront-sdk-go v0.14.0
github.com/wvanbergen/kafka v0.0.0-20171203153745-e2edea948ddf
github.com/x448/float16 v0.8.4
github.com/xdg/scram v1.0.5
@ -272,6 +272,7 @@ require (
github.com/bitly/go-hostpool v0.1.0 // indirect
github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869 // indirect
github.com/bufbuild/protocompile v0.4.0 // indirect
github.com/caio/go-tdigest/v4 v4.0.1 // indirect
github.com/cenkalti/backoff v2.2.1+incompatible // indirect
github.com/cenkalti/backoff/v4 v4.2.1 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect

6
go.sum
View File

@ -355,6 +355,8 @@ github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZ
github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8=
github.com/caio/go-tdigest v3.1.0+incompatible h1:uoVMJ3Q5lXmVLCCqaMGHLBWnbGoN6Lpu7OAUPR60cds=
github.com/caio/go-tdigest v3.1.0+incompatible/go.mod h1:sHQM/ubZStBUmF1WbB8FAm8q9GjDajLC5T7ydxE3JHI=
github.com/caio/go-tdigest/v4 v4.0.1 h1:sx4ZxjmIEcLROUPs2j1BGe2WhOtHD6VSe6NNbBdKYh4=
github.com/caio/go-tdigest/v4 v4.0.1/go.mod h1:Wsa+f0EZnV2gShdj1adgl0tQSoXRxtM0QioTgukFw8U=
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cenkalti/backoff/v4 v4.0.0/go.mod h1:eEew/i+1Q6OrCDZh3WiXYv3+nJwBASZ8Bog/87DQnVg=
@ -1500,8 +1502,8 @@ github.com/vjeantet/grok v1.0.1 h1:2rhIR7J4gThTgcZ1m2JY4TrJZNgjn985U28kT2wQrJ4=
github.com/vjeantet/grok v1.0.1/go.mod h1:ax1aAchzC6/QMXMcyzHQGZWaW1l195+uMYIkCWPCNIo=
github.com/vmware/govmomi v0.28.1-0.20220921224932-b4b508abf208 h1:IDVzGQ2aczmTEfTos4hzmFw20tGQ4zZsVnel9C6VEpA=
github.com/vmware/govmomi v0.28.1-0.20220921224932-b4b508abf208/go.mod h1:F7adsVewLNHsW/IIm7ziFURaXDaHEwcc+ym4r3INMdY=
github.com/wavefronthq/wavefront-sdk-go v0.13.0 h1:3s9maJmzI4orW+hiVBfCNp/SIu8ISXi6rtewmDGzheE=
github.com/wavefronthq/wavefront-sdk-go v0.13.0/go.mod h1:KA69ERADh+ePHNET6AqBCnna3W6lkHXwss/fTTZEFLg=
github.com/wavefronthq/wavefront-sdk-go v0.14.0 h1:Nq+yobFZrVw3bfXh+EsWmWDtwMHYRKLRVXgnB1S0j34=
github.com/wavefronthq/wavefront-sdk-go v0.14.0/go.mod h1:V72c8e+bXuLK8HpA6ioW0ll5mK9IPD+4IHNNDY75ksA=
github.com/wvanbergen/kafka v0.0.0-20171203153745-e2edea948ddf h1:TOV5PC6fIWwFOFra9xJfRXZcL2pLhMI8oNuDugNxg9Q=
github.com/wvanbergen/kafka v0.0.0-20171203153745-e2edea948ddf/go.mod h1:nxx7XRXbR9ykhnC8lXqQyJS0rfvJGxKyKw/sT1YOttg=
github.com/wvanbergen/kazoo-go v0.0.0-20180202103751-f72d8611297a h1:ILoU84rj4AQ3q6cjQvtb9jBjx4xzR/Riq/zYhmDQiOk=

View File

@ -24,57 +24,52 @@ to use them.
```toml @sample.conf
[[outputs.wavefront]]
## Url for Wavefront API or Wavefront Proxy instance.
## Url for Wavefront API or Wavefront proxy instance.
## Direct Ingestion via Wavefront API requires authentication. See below.
url = "https://metrics.wavefront.com"
## Authentication Token for Wavefront. Required if using Direct Ingestion. Not required if using a Wavefront Proxy.
#token = "DUMMY_TOKEN"
## Maximum number of metrics to send per HTTP request. This value should be higher than the `metric_batch_size`. Default is 10,000. Values higher than 40,000 are not recommended.
# http_maximum_batch_size = 10000
## Deprecated. DNS name of the Wavefront server or Wavefront Proxy. Use the `url` field instead.
#host = "wavefront.example.com"
## Deprecated. Wavefront proxy port. Use the `url` field instead.
#port = 2878
## prefix for metrics keys
#prefix = "my.specific.prefix."
# prefix = "my.specific.prefix."
## whether to use "value" for name of simple fields. default is false
#simple_fields = false
# simple_fields = false
## character to use between metric and field name. default is . (dot)
#metric_separator = "."
# metric_separator = "."
## Convert metric name paths to use metricSeparator character
## When true will convert all _ (underscore) characters in final metric name. default is true
#convert_paths = true
# convert_paths = true
## Use Strict rules to sanitize metric and tag names from invalid characters
## When enabled forward slash (/) and comma (,) will be accepted
#use_strict = false
# use_strict = false
## Use Regex to sanitize metric and tag names from invalid characters
## Regex is more thorough, but significantly slower. default is false
#use_regex = false
# use_regex = false
## point tags to use as the source name for Wavefront (if none found, host will be used)
#source_override = ["hostname", "address", "agent_host", "node_host"]
# source_override = ["hostname", "address", "agent_host", "node_host"]
## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true
#convert_bool = true
# convert_bool = true
## Truncate metric tags to a total of 254 characters for the tag name value. Wavefront will reject any
## data point exceeding this limit if not truncated. Defaults to 'false' to provide backwards compatibility.
#truncate_tags = false
# truncate_tags = false
## Flush the internal buffers after each batch. This effectively bypasses the background sending of metrics
## normally done by the Wavefront SDK. This can be used if you are experiencing buffer overruns. The sending
## of metrics will block for a longer time, but this will be handled gracefully by the internal buffering in
## Telegraf.
#immediate_flush = true
# immediate_flush = true
## Send internal metrics (starting with `~sdk.go`) for valid, invalid, and dropped metrics. default is true.
# send_internal_metrics = true
## Optional TLS Config
## Set to true/false to enforce TLS being enabled/disabled. If not set,
@ -92,7 +87,32 @@ to use them.
# insecure_skip_verify = false
## HTTP Timeout
#timeout="10s"
# timeout="10s"
## Authentication for Direct Ingestion.
## Direct Ingestion requires one of: `token`,`auth_csp_api_token`, or `auth_csp_client_credentials`
## See https://docs.wavefront.com/csp_getting_started.html to learn more about using CSP credentials with Wavefront.
## Not required if using a Wavefront proxy.
## Wavefront API Token Authentication. Ignored if using a Wavefront proxy.
## 1. Click the gear icon at the top right in the Wavefront UI.
## 2. Click your account name (usually your email)
## 3. Click *API access*.
# token = "YOUR_TOKEN"
## Optional. defaults to "https://console.cloud.vmware.com/"
## Ignored if using a Wavefront proxy or a Wavefront API token.
# auth_csp_base_url=https://console.cloud.vmware.com
## CSP API Token Authentication for Wavefront. Ignored if using a Wavefront proxy.
# auth_csp_api_token=CSP_API_TOKEN_HERE
## CSP Client Credentials Authentication Information for Wavefront. Ignored if using a Wavefront proxy.
## See also: https://docs.wavefront.com/csp_getting_started.html#whats-a-server-to-server-app
# [outputs.wavefront.auth_csp_client_credentials]
# app_id=CSP_APP_ID_HERE
# app_secret=CSP_APP_SECRET_HERE
# org_id=CSP_ORG_ID_HERE
```
### Convert Path & Metric Separator

View File

@ -1,55 +1,50 @@
[[outputs.wavefront]]
## Url for Wavefront API or Wavefront Proxy instance.
## Url for Wavefront API or Wavefront proxy instance.
## Direct Ingestion via Wavefront API requires authentication. See below.
url = "https://metrics.wavefront.com"
## Authentication Token for Wavefront. Required if using Direct Ingestion. Not required if using a Wavefront Proxy.
#token = "DUMMY_TOKEN"
## Maximum number of metrics to send per HTTP request. This value should be higher than the `metric_batch_size`. Default is 10,000. Values higher than 40,000 are not recommended.
# http_maximum_batch_size = 10000
## Deprecated. DNS name of the Wavefront server or Wavefront Proxy. Use the `url` field instead.
#host = "wavefront.example.com"
## Deprecated. Wavefront proxy port. Use the `url` field instead.
#port = 2878
## prefix for metrics keys
#prefix = "my.specific.prefix."
# prefix = "my.specific.prefix."
## whether to use "value" for name of simple fields. default is false
#simple_fields = false
# simple_fields = false
## character to use between metric and field name. default is . (dot)
#metric_separator = "."
# metric_separator = "."
## Convert metric name paths to use metricSeparator character
## When true will convert all _ (underscore) characters in final metric name. default is true
#convert_paths = true
# convert_paths = true
## Use Strict rules to sanitize metric and tag names from invalid characters
## When enabled forward slash (/) and comma (,) will be accepted
#use_strict = false
# use_strict = false
## Use Regex to sanitize metric and tag names from invalid characters
## Regex is more thorough, but significantly slower. default is false
#use_regex = false
# use_regex = false
## point tags to use as the source name for Wavefront (if none found, host will be used)
#source_override = ["hostname", "address", "agent_host", "node_host"]
# source_override = ["hostname", "address", "agent_host", "node_host"]
## whether to convert boolean values to numeric values, with false -> 0.0 and true -> 1.0. default is true
#convert_bool = true
# convert_bool = true
## Truncate metric tags to a total of 254 characters for the tag name value. Wavefront will reject any
## data point exceeding this limit if not truncated. Defaults to 'false' to provide backwards compatibility.
#truncate_tags = false
# truncate_tags = false
## Flush the internal buffers after each batch. This effectively bypasses the background sending of metrics
## normally done by the Wavefront SDK. This can be used if you are experiencing buffer overruns. The sending
## of metrics will block for a longer time, but this will be handled gracefully by the internal buffering in
## Telegraf.
#immediate_flush = true
# immediate_flush = true
## Send internal metrics (starting with `~sdk.go`) for valid, invalid, and dropped metrics. default is true.
# send_internal_metrics = true
## Optional TLS Config
## Set to true/false to enforce TLS being enabled/disabled. If not set,
@ -67,4 +62,29 @@
# insecure_skip_verify = false
## HTTP Timeout
#timeout="10s"
# timeout="10s"
## Authentication for Direct Ingestion.
## Direct Ingestion requires one of: `token`,`auth_csp_api_token`, or `auth_csp_client_credentials`
## See https://docs.wavefront.com/csp_getting_started.html to learn more about using CSP credentials with Wavefront.
## Not required if using a Wavefront proxy.
## Wavefront API Token Authentication. Ignored if using a Wavefront proxy.
## 1. Click the gear icon at the top right in the Wavefront UI.
## 2. Click your account name (usually your email)
## 3. Click *API access*.
# token = "YOUR_TOKEN"
## Optional. defaults to "https://console.cloud.vmware.com/"
## Ignored if using a Wavefront proxy or a Wavefront API token.
# auth_csp_base_url=https://console.cloud.vmware.com
## CSP API Token Authentication for Wavefront. Ignored if using a Wavefront proxy.
# auth_csp_api_token=CSP_API_TOKEN_HERE
## CSP Client Credentials Authentication Information for Wavefront. Ignored if using a Wavefront proxy.
## See also: https://docs.wavefront.com/csp_getting_started.html#whats-a-server-to-server-app
# [outputs.wavefront.auth_csp_client_credentials]
# app_id=CSP_APP_ID_HERE
# app_secret=CSP_APP_SECRET_HERE
# org_id=CSP_ORG_ID_HERE

View File

@ -2,7 +2,9 @@
package wavefront
import (
cryptoTls "crypto/tls"
_ "embed"
"errors"
"fmt"
"net/url"
"regexp"
@ -23,24 +25,34 @@ var sampleConfig string
const maxTagLength = 254
type authCSPClientCredentials struct {
AppID config.Secret `toml:"app_id"`
AppSecret config.Secret `toml:"app_secret"`
OrgID *string `toml:"org_id"`
}
type Wavefront struct {
URL string `toml:"url"`
Token config.Secret `toml:"token"`
Host string `toml:"host" deprecated:"2.4.0;use url instead"`
Port int `toml:"port" deprecated:"2.4.0;use url instead"`
Prefix string `toml:"prefix"`
SimpleFields bool `toml:"simple_fields"`
MetricSeparator string `toml:"metric_separator"`
ConvertPaths bool `toml:"convert_paths"`
ConvertBool bool `toml:"convert_bool"`
HTTPMaximumBatchSize int `toml:"http_maximum_batch_size"`
Timeout config.Duration `toml:"timeout"`
UseRegex bool `toml:"use_regex"`
UseStrict bool `toml:"use_strict"`
TruncateTags bool `toml:"truncate_tags"`
ImmediateFlush bool `toml:"immediate_flush"`
SourceOverride []string `toml:"source_override"`
StringToNumber map[string][]map[string]float64 `toml:"string_to_number" deprecated:"1.9.0;use the enum processor instead"`
URL string `toml:"url"`
Token config.Secret `toml:"token"`
CSPBaseURL string `toml:"auth_csp_base_url"`
AuthCSPAPIToken config.Secret `toml:"auth_csp_api_token"`
AuthCSPClientCredentials *authCSPClientCredentials `toml:"auth_csp_client_credentials"`
Host string `toml:"host" deprecated:"2.4.0;use url instead"`
Port int `toml:"port" deprecated:"2.4.0;use url instead"`
Prefix string `toml:"prefix"`
SimpleFields bool `toml:"simple_fields"`
MetricSeparator string `toml:"metric_separator"`
ConvertPaths bool `toml:"convert_paths"`
ConvertBool bool `toml:"convert_bool"`
HTTPMaximumBatchSize int `toml:"http_maximum_batch_size"`
Timeout config.Duration `toml:"timeout"`
UseRegex bool `toml:"use_regex"`
UseStrict bool `toml:"use_strict"`
TruncateTags bool `toml:"truncate_tags"`
ImmediateFlush bool `toml:"immediate_flush"`
SendInternalMetrics bool `toml:"send_internal_metrics"`
SourceOverride []string `toml:"source_override"`
StringToNumber map[string][]map[string]float64 `toml:"string_to_number" deprecated:"1.9.0;use the enum processor instead"`
tls.ClientConfig
sender wavefront.Sender
Log telegraf.Logger `toml:"-"`
@ -57,28 +69,41 @@ func (*Wavefront) SampleConfig() string {
return sampleConfig
}
func (w *Wavefront) senderURLFromURLAndToken() (string, error) {
newURL, err := url.Parse(w.URL)
func (w *Wavefront) parseConnectionURL() (string, error) {
if w.URL == "" {
if w.Host == "" || w.Port <= 0 {
return "", errors.New("no URL specified")
}
generatedURL := fmt.Sprintf("http://%s:%d", w.Host, w.Port)
w.Log.Warnf("translating host/port into url: %s\n", generatedURL)
return generatedURL, nil
}
u, err := url.ParseRequestURI(w.URL)
if err != nil {
return "", fmt.Errorf("could not parse the provided URL: %s", w.URL)
}
token := "DUMMY_TOKEN"
if !w.Token.Empty() {
b, err := w.Token.Get()
if err != nil {
return "", fmt.Errorf("getting token failed: %w", err)
}
token = string(b)
config.ReleaseSecret(b)
}
newURL.User = url.User(token)
return newURL.String(), nil
return u.String(), nil
}
func senderURLFromHostAndPort(host string, port int) string {
return fmt.Sprintf("http://%s:%d", host, port)
func (w *Wavefront) createSender(connectionURL string, flushSeconds int, tlsConfig *cryptoTls.Config) (wavefront.Sender, error) {
timeout := time.Duration(w.Timeout)
options := []wavefront.Option{
wavefront.BatchSize(w.HTTPMaximumBatchSize),
wavefront.FlushIntervalSeconds(flushSeconds),
wavefront.TLSConfigOptions(tlsConfig),
wavefront.Timeout(timeout),
wavefront.SendInternalMetrics(w.SendInternalMetrics),
}
authOptions, err := w.makeAuthOptions()
if err != nil {
return nil, err
}
options = append(options, authOptions...)
return wavefront.NewSender(connectionURL, options...)
}
func (w *Wavefront) Connect() error {
@ -86,18 +111,9 @@ func (w *Wavefront) Connect() error {
if w.ImmediateFlush {
flushSeconds = 86400 // Set a very long flush interval if we're flushing directly
}
var connectionURL string
if w.URL != "" {
w.Log.Debugf("Connecting over http/https using url: %s", w.URL)
connectionURLWithToken, err := w.senderURLFromURLAndToken()
if err != nil {
return err
}
connectionURL = connectionURLWithToken
} else {
w.Log.Warn("Configuration with host/port is deprecated. Please use url.")
w.Log.Debugf("Connecting over http using Host: %q and Port: %d", w.Host, w.Port)
connectionURL = senderURLFromHostAndPort(w.Host, w.Port)
connectionURL, err := w.parseConnectionURL()
if err != nil {
return err
}
tlsConfig, err := w.TLSConfig()
@ -105,12 +121,7 @@ func (w *Wavefront) Connect() error {
return err
}
sender, err := wavefront.NewSender(connectionURL,
wavefront.BatchSize(w.HTTPMaximumBatchSize),
wavefront.FlushIntervalSeconds(flushSeconds),
wavefront.TLSConfigOptions(tlsConfig),
wavefront.Timeout(time.Duration(w.Timeout)),
)
sender, err := w.createSender(connectionURL, flushSeconds, tlsConfig)
if err != nil {
return fmt.Errorf("could not create Wavefront Sender for the provided url")
@ -307,6 +318,62 @@ func (w *Wavefront) Close() error {
return nil
}
func (w *Wavefront) makeAuthOptions() ([]wavefront.Option, error) {
if !w.Token.Empty() {
b, err := w.Token.Get()
if err != nil {
return nil, fmt.Errorf("failed to parse token value: %w", err)
}
token := string(b)
config.ReleaseSecret(b)
return []wavefront.Option{
wavefront.APIToken(token),
}, nil
}
if !w.AuthCSPAPIToken.Empty() {
b, err := w.AuthCSPAPIToken.Get()
if err != nil {
return nil, fmt.Errorf("failed to CSP API token value: %w", err)
}
apiToken := string(b)
config.ReleaseSecret(b)
return []wavefront.Option{
wavefront.CSPAPIToken(apiToken, wavefront.CSPBaseURL(w.CSPBaseURL)),
}, nil
}
if w.AuthCSPClientCredentials != nil {
appIDBytes, err := w.AuthCSPClientCredentials.AppID.Get()
if err != nil {
return nil, fmt.Errorf("failed to parse Client Credentials App ID value: %w", err)
}
appID := string(appIDBytes)
config.ReleaseSecret(appIDBytes)
appSecretBytes, err := w.AuthCSPClientCredentials.AppSecret.Get()
if err != nil {
return nil, fmt.Errorf("failed to parse Client Credentials App Secret value: %w", err)
}
cspAppSecret := string(appSecretBytes)
config.ReleaseSecret(appSecretBytes)
options := []wavefront.CSPOption{
wavefront.CSPBaseURL(w.CSPBaseURL),
}
if w.AuthCSPClientCredentials.OrgID != nil {
options = append(options, wavefront.CSPOrgID(*w.AuthCSPClientCredentials.OrgID))
}
return []wavefront.Option{
wavefront.CSPClientCredentials(appID, cspAppSecret, options...),
}, nil
}
return nil, nil
}
func init() {
outputs.Add("wavefront", func() telegraf.Output {
return &Wavefront{
@ -315,8 +382,10 @@ func init() {
ConvertBool: true,
TruncateTags: false,
ImmediateFlush: true,
SendInternalMetrics: true,
HTTPMaximumBatchSize: 10000,
Timeout: config.Duration(10 * time.Second),
CSPBaseURL: "https://console.cloud.vmware.com",
}
})
}

View File

@ -365,19 +365,35 @@ func TestTagLimits(t *testing.T) {
require.Equal(t, longKey, tags[longKey])
}
func TestSenderURLFromHostAndPort(t *testing.T) {
require.Equal(t, "http://localhost:2878", senderURLFromHostAndPort("localhost", 2878))
}
func TestSenderURLFromURLAndToken(t *testing.T) {
func TestParseConnectionUrlReturnsAnErrorForInvalidUrls(t *testing.T) {
w := &Wavefront{
URL: "https://surf.wavefront.com",
Token: config.NewSecret([]byte("11111111-2222-3333-4444-555555555555")),
URL: "invalid url",
Log: testutil.Logger{},
}
_, err := w.parseConnectionURL()
require.EqualError(t, err, "could not parse the provided URL: invalid url")
}
func TestParseConnectionUrlReturnsAllowsTokensInUrl(t *testing.T) {
w := &Wavefront{
URL: "https://11111111-2222-3333-4444-555555555555@surf.wavefront.com",
Log: testutil.Logger{},
}
url, err := w.senderURLFromURLAndToken()
url, err := w.parseConnectionURL()
require.NoError(t, err)
require.Equal(t, "https://11111111-2222-3333-4444-555555555555@surf.wavefront.com", url)
require.Equalf(t, "https://11111111-2222-3333-4444-555555555555@surf.wavefront.com", url, "Token value should not overwrite the token embedded in url")
}
func TestParseConnectionUrlUsesHostAndPortWhenUrlIsOmitted(t *testing.T) {
w := &Wavefront{
Host: "surf.wavefront.com",
Port: 8080,
Log: testutil.Logger{},
}
url, err := w.parseConnectionURL()
require.NoError(t, err)
require.Equalf(t, "http://surf.wavefront.com:8080", url, "Should combine host and port into URI")
}
func TestDefaults(t *testing.T) {
@ -387,6 +403,45 @@ func TestDefaults(t *testing.T) {
require.Equal(t, "", defaultWavefront.TLSCA)
}
func TestMakeAuthOptions(t *testing.T) {
cspAPIWavefront := outputs.Outputs["wavefront"]().(*Wavefront)
cspAPIWavefront.AuthCSPAPIToken = config.NewSecret([]byte("fake-app-token"))
options, err := cspAPIWavefront.makeAuthOptions()
require.NoError(t, err)
require.Equal(t, 1, len(options))
cspClientCredsWavefront := outputs.Outputs["wavefront"]().(*Wavefront)
cspClientCredsWavefront.AuthCSPClientCredentials = &authCSPClientCredentials{
AppID: config.NewSecret([]byte("fake-app-id")),
AppSecret: config.NewSecret([]byte("fake-app-secret")),
}
options, err = cspClientCredsWavefront.makeAuthOptions()
require.NoError(t, err)
require.Equal(t, 1, len(options))
orgID := "org-id"
cspClientCredsWithOrgIDWavefront := outputs.Outputs["wavefront"]().(*Wavefront)
cspClientCredsWithOrgIDWavefront.AuthCSPClientCredentials = &authCSPClientCredentials{
AppID: config.NewSecret([]byte("fake-app-id")),
AppSecret: config.NewSecret([]byte("fake-app-secret")),
OrgID: &orgID,
}
options, err = cspClientCredsWithOrgIDWavefront.makeAuthOptions()
require.NoError(t, err)
require.Equal(t, 1, len(options))
apiTokenWavefront := outputs.Outputs["wavefront"]().(*Wavefront)
apiTokenWavefront.AuthCSPAPIToken = config.NewSecret([]byte("fake-wavefront-api-token"))
options, err = apiTokenWavefront.makeAuthOptions()
require.NoError(t, err)
require.Equal(t, 1, len(options))
noAuthOptionsWavefront := outputs.Outputs["wavefront"]().(*Wavefront)
options, err = noAuthOptionsWavefront.makeAuthOptions()
require.NoError(t, err)
require.Equal(t, 0, len(options))
}
// Benchmarks to test performance of string replacement via Regex and Sanitize
var testString = "this_is*my!test/string\\for=replacement"