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
add tests
  • Loading branch information
keisku committed Apr 27, 2022
commit e3c8cf26cdf2578f41f609e2b809f48768b0ff89
111 changes: 101 additions & 10 deletions exporter/datadogexporter/factory_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,9 @@ func TestCreateDefaultConfig(t *testing.T) {
QueueSettings: exporterhelper.NewDefaultQueueSettings(),

API: ddconfig.APIConfig{
Key: "API_KEY",
Site: "SITE",
Key: "API_KEY",
Site: "SITE",
FailOnInvalidKey: false,
},

Metrics: ddconfig.MetricsConfig{
Expand Down Expand Up @@ -151,8 +152,9 @@ func TestLoadConfig(t *testing.T) {
Tags: []string{"example:tag"},
}, apiConfig.TagsConfig)
assert.Equal(t, ddconfig.APIConfig{
Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Site: "datadoghq.eu",
Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Site: "datadoghq.eu",
FailOnInvalidKey: true,
}, apiConfig.API)
assert.Equal(t, ddconfig.MetricsConfig{
TCPAddr: confignet.TCPAddr{
Expand Down Expand Up @@ -202,8 +204,9 @@ func TestLoadConfig(t *testing.T) {
},

API: ddconfig.APIConfig{
Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Site: "datadoghq.com",
Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Site: "datadoghq.com",
FailOnInvalidKey: false,
},

Metrics: ddconfig.MetricsConfig{
Expand Down Expand Up @@ -303,8 +306,9 @@ func TestLoadConfigEnvVariables(t *testing.T) {
}, apiConfig.TagsConfig)
assert.Equal(t,
ddconfig.APIConfig{
Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Site: "datadoghq.eu",
Key: "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
Site: "datadoghq.eu",
FailOnInvalidKey: false,
}, apiConfig.API)
assert.Equal(t,
ddconfig.MetricsConfig{
Expand Down Expand Up @@ -357,8 +361,9 @@ func TestLoadConfigEnvVariables(t *testing.T) {
EnvVarTags: "envexample:tag envexample2:tag",
}, defaultConfig.TagsConfig)
assert.Equal(t, ddconfig.APIConfig{
Key: "replacedapikey",
Site: "datadoghq.test",
Key: "replacedapikey",
Site: "datadoghq.test",
FailOnInvalidKey: false,
}, defaultConfig.API)
assert.Equal(t, ddconfig.MetricsConfig{
TCPAddr: confignet.TCPAddr{
Expand Down Expand Up @@ -417,6 +422,49 @@ func TestCreateAPIMetricsExporter(t *testing.T) {
assert.NotNil(t, exp)
}

func TestCreateAPIMetricsExporterFailOnInvalidkey(t *testing.T) {
server := testutils.DatadogServerMock(testutils.ValidateAPIKeyEndpointInvalid)
defer server.Close()

factories, err := componenttest.NopFactories()
require.NoError(t, err)

factory := NewFactory()
factories.Exporters[typeStr] = factory
cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config.yaml"), factories)

require.NoError(t, err)
require.NotNil(t, cfg)

// Use the mock server for API key validation
c := (cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")]).(*ddconfig.Config)
c.Metrics.TCPAddr.Endpoint = server.URL
c.HostMetadata.Enabled = false

t.Run("failed_on_invalid_key is true", func(t *testing.T) {
c.API.FailOnInvalidKey = true
ctx := context.Background()
exp, err := factory.CreateMetricsExporter(
ctx,
componenttest.NewNopExporterCreateSettings(),
cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")],
)
assert.EqualError(t, err, "API Key validation failed")
assert.Nil(t, exp)
})
t.Run("failed_on_invalid_key is false", func(t *testing.T) {
c.API.FailOnInvalidKey = false
ctx := context.Background()
exp, err := factory.CreateMetricsExporter(
ctx,
componenttest.NewNopExporterCreateSettings(),
cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")],
)
assert.Nil(t, err)
assert.NotNil(t, exp)
})
}

func TestCreateAPITracesExporter(t *testing.T) {
server := testutils.DatadogServerMock()
defer server.Close()
Expand Down Expand Up @@ -447,6 +495,49 @@ func TestCreateAPITracesExporter(t *testing.T) {
assert.NotNil(t, exp)
}

func TestCreateAPITracesExporterFailOnInvalidkey(t *testing.T) {
server := testutils.DatadogServerMock(testutils.ValidateAPIKeyEndpointInvalid)
defer server.Close()

factories, err := componenttest.NopFactories()
require.NoError(t, err)

factory := NewFactory()
factories.Exporters[typeStr] = factory
cfg, err := servicetest.LoadConfigAndValidate(filepath.Join("testdata", "config.yaml"), factories)

require.NoError(t, err)
require.NotNil(t, cfg)

// Use the mock server for API key validation
c := (cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")]).(*ddconfig.Config)
c.Metrics.TCPAddr.Endpoint = server.URL
c.HostMetadata.Enabled = false

t.Run("failed_on_invalid_key is true", func(t *testing.T) {
keisku marked this conversation as resolved.
Show resolved Hide resolved
c.API.FailOnInvalidKey = true
ctx := context.Background()
exp, err := factory.CreateTracesExporter(
ctx,
componenttest.NewNopExporterCreateSettings(),
cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")],
)
assert.EqualError(t, err, "API Key validation failed")
assert.Nil(t, exp)
})
t.Run("failed_on_invalid_key is false", func(t *testing.T) {
keisku marked this conversation as resolved.
Show resolved Hide resolved
c.API.FailOnInvalidKey = false
ctx := context.Background()
exp, err := factory.CreateTracesExporter(
ctx,
componenttest.NewNopExporterCreateSettings(),
cfg.Exporters[config.NewComponentIDWithName(typeStr, "api")],
)
assert.Nil(t, err)
assert.NotNil(t, exp)
})
}

func TestOnlyMetadata(t *testing.T) {
server := testutils.DatadogServerMock()
defer server.Close()
Expand Down
40 changes: 33 additions & 7 deletions exporter/datadogexporter/internal/testutils/test_utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,40 @@ type DatadogServer struct {
}

// DatadogServerMock mocks a Datadog backend server
func DatadogServerMock() *DatadogServer {
func DatadogServerMock(overwriteHandlerFuncs ...OverwriteHandleFunc) *DatadogServer {
metadataChan := make(chan []byte)
handler := http.NewServeMux()
handler.HandleFunc("/api/v1/validate", validateAPIKeyEndpoint)
handler.HandleFunc("/api/v1/series", metricsEndpoint)
handler.HandleFunc("/intake", newMetadataEndpoint(metadataChan))
handler.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {})
mux := http.NewServeMux()

srv := httptest.NewServer(handler)
handlers := map[string]http.HandlerFunc{
"/api/v1/validate": validateAPIKeyEndpoint,
"/api/v1/series": metricsEndpoint,
"/intake": newMetadataEndpoint(metadataChan),
"/": func(w http.ResponseWriter, r *http.Request) {},
}
for _, f := range overwriteHandlerFuncs {
p, hf := f()
handlers[p] = hf
}
for pattern, handler := range handlers {
mux.HandleFunc(pattern, handler)
}

srv := httptest.NewServer(mux)

return &DatadogServer{
srv,
metadataChan,
}
}

// OverwriteHandleFuncs allows to overwrite the default handler functions
type OverwriteHandleFunc func() (string, http.HandlerFunc)

// ValidateAPIKeyEndpointInvalid returns a handler function that returns an invalid API key response
func ValidateAPIKeyEndpointInvalid() (string, http.HandlerFunc) {
return "/api/v1/validate", validateAPIKeyEndpointInvalid
}

type validateAPIKeyResponse struct {
Valid bool `json:"valid"`
}
Expand All @@ -67,6 +85,14 @@ func validateAPIKeyEndpoint(w http.ResponseWriter, r *http.Request) {
w.Write(resJSON)
}

func validateAPIKeyEndpointInvalid(w http.ResponseWriter, r *http.Request) {
res := validateAPIKeyResponse{Valid: false}
resJSON, _ := json.Marshal(res)

w.Header().Set("Content-Type", "application/json")
w.Write(resJSON)
}

type metricsResponse struct {
Status string `json:"status"`
}
Expand Down
3 changes: 2 additions & 1 deletion exporter/datadogexporter/testdata/config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ exporters:
api:
key: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
site: datadoghq.eu
fail_on_invalid_key: true

traces:
sample_rate: 1
Expand Down Expand Up @@ -63,7 +64,7 @@ exporters:
datadog/invalid:
metrics:
endpoint: "invalid:"

traces:
endpoint: "invalid:"

Expand Down