diff --git a/metrics-operator/controllers/common/providers/datadog/datadog.go b/metrics-operator/controllers/common/providers/datadog/datadog.go index 166c7c49e6d..617546502a7 100644 --- a/metrics-operator/controllers/common/providers/datadog/datadog.go +++ b/metrics-operator/controllers/common/providers/datadog/datadog.go @@ -2,8 +2,14 @@ package datadog import ( "context" + "fmt" + "github.com/DataDog/datadog-api-client-go/v2/api/datadog" + "github.com/DataDog/datadog-api-client-go/v2/api/datadogV1" "github.com/go-logr/logr" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha2" + "strconv" + "time" + //nolint:gci "net/http" //nolint:gci "sigs.k8s.io/controller-runtime/pkg/client" @@ -16,7 +22,48 @@ type KeptnDataDogProvider struct { } // EvaluateQuery fetches the SLI values from datadog provider -func (r *KeptnDataDogProvider) EvaluateQuery(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) (string, []byte, error) { - //TODO implement me - panic("implement me") +func (d *KeptnDataDogProvider) EvaluateQuery(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) (string, []byte, error) { + ctx, cancel := context.WithTimeout(ctx, 20*time.Second) + defer cancel() + + // TODO: get DD_API_KEY and DD_APP_KEY from kubernetes secret + // TODO: patch the context with the keys + // Ref: https://github.com/DataDog/datadog-api-client-go#getting-started + + ctx = context.WithValue( + ctx, + datadog.ContextAPIKeys, + map[string]datadog.APIKey{ + "apiKeyAuth": { + Key: "d34b12511dc0bab2566fcb46d7f8a9fa", + }, + "appKeyAuth": { + Key: "7d04a1176e70e7c256adc7c02df77b8ccf7b72d0", + }, + }, + ) + fromTime := time.Now().AddDate(0, 0, -1) + queryTime := time.Now() + + configuration := datadog.NewConfiguration() + apiClient := datadog.NewAPIClient(configuration) + api := datadogV1.NewMetricsApi(apiClient) + + resp, _, err := api.QueryMetrics( + ctx, + fromTime.Unix(), + queryTime.Unix(), + metric.Spec.Query, + ) + if err != nil { + d.Log.Error(err, "Error while creating request") + return "", nil, err + } + if len(resp.Series) == 0 { + d.Log.Info("No values in query result") + return "", nil, fmt.Errorf("no values in query result") + } + points := (resp.Series)[0].Pointlist + value := strconv.FormatFloat(*points[len(points)-1][1], 'g', 5, 64) + return value, []byte(value), nil } diff --git a/metrics-operator/controllers/common/providers/datadog/datadog_test.go b/metrics-operator/controllers/common/providers/datadog/datadog_test.go new file mode 100644 index 00000000000..92f052bb3d5 --- /dev/null +++ b/metrics-operator/controllers/common/providers/datadog/datadog_test.go @@ -0,0 +1,47 @@ +package datadog + +import ( + "context" + "net/http" + "testing" + + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha2" + "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + ctrl "sigs.k8s.io/controller-runtime" +) + +func Test_datadog(t *testing.T) { + + t.Run("datadog-test", func(t *testing.T) { + + fakeClient := fake.NewClient() + kpp := KeptnDataDogProvider{ + HttpClient: http.Client{}, + Log: ctrl.Log.WithName("testytest"), + K8sClient: fakeClient, + } + obj := metricsapi.KeptnMetric{ + Spec: metricsapi.KeptnMetricSpec{ + Query: "avg:system.cpu.user{*}", + }, + } + p := metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + SecretKeyRef: v1.SecretKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "dd-token", + }, + Key: "dd_client_app_key", + }, + TargetServer: "http://mockserver", + }, + } + r, raw, e := kpp.EvaluateQuery(context.TODO(), obj, p) + + require.Nil(t, e) + require.Equal(t, []byte(r), raw) + require.Equal(t, "", r) + }) +} diff --git a/metrics-operator/go.mod b/metrics-operator/go.mod index a6933406278..b53ef20747b 100644 --- a/metrics-operator/go.mod +++ b/metrics-operator/go.mod @@ -3,6 +3,7 @@ module github.com/keptn/lifecycle-toolkit/metrics-operator go 1.18 require ( + github.com/DataDog/datadog-api-client-go/v2 v2.9.0 github.com/benbjohnson/clock v1.3.0 github.com/go-logr/logr v1.2.3 github.com/gorilla/mux v1.8.0 @@ -27,6 +28,7 @@ require ( require ( cloud.google.com/go/compute/metadata v0.2.3 // indirect + github.com/DataDog/zstd v1.5.0 // indirect github.com/NYTimes/gziphandler v1.1.1 // indirect github.com/antlr/antlr4/runtime/Go/antlr v1.4.10 // indirect github.com/beorn7/perks v1.0.1 // indirect diff --git a/metrics-operator/go.sum b/metrics-operator/go.sum index 4a0cb559fde..28bc2fd63ab 100644 --- a/metrics-operator/go.sum +++ b/metrics-operator/go.sum @@ -43,6 +43,10 @@ dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7 github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/DataDog/datadog-api-client-go/v2 v2.9.0 h1:1Cz3mqj95iqnQPykEovq2p52rrU26XvLC2Fz6hPE+TU= +github.com/DataDog/datadog-api-client-go/v2 v2.9.0/go.mod h1:sHt3EuVMN8PSYJu065qwp3pZxCwR3RZP4sJnYwj/ZQY= +github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= +github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/NYTimes/gziphandler v1.1.1 h1:ZUDjpQae29j0ryrS0u/B8HZfJBtBQHjqw2rQ2cqUQ3I= github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU=