From 7642e7c024f61a01d19a17677d45ce2609d03438 Mon Sep 17 00:00:00 2001 From: realanna Date: Thu, 21 Sep 2023 12:59:34 +0200 Subject: [PATCH 01/27] feat(metrics-operator): first iteration on prometheus auth Signed-off-by: realanna --- .../common/providers/datadog/common.go | 14 +-- .../common/providers/prometheus/common.go | 42 +++++++ .../providers/prometheus/common_test.go | 116 ++++++++++++++++++ .../common/providers/prometheus/prometheus.go | 37 +++++- .../providers/prometheus/prometheus_test.go | 13 +- .../controllers/common/providers/provider.go | 4 +- 6 files changed, 200 insertions(+), 26 deletions(-) create mode 100644 metrics-operator/controllers/common/providers/prometheus/common.go create mode 100644 metrics-operator/controllers/common/providers/prometheus/common_test.go diff --git a/metrics-operator/controllers/common/providers/datadog/common.go b/metrics-operator/controllers/common/providers/datadog/common.go index 377129a038..e1f0be1eaa 100644 --- a/metrics-operator/controllers/common/providers/datadog/common.go +++ b/metrics-operator/controllers/common/providers/datadog/common.go @@ -4,8 +4,6 @@ import ( "context" "errors" "fmt" - "strings" - metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" @@ -16,18 +14,8 @@ const apiKey, appKey = "DD_CLIENT_API_KEY", "DD_CLIENT_APP_KEY" var ErrSecretKeyRefNotDefined = errors.New("the SecretKeyRef property with the DataDog API Key is missing") -func hasDDSecretDefined(spec metricsapi.KeptnMetricsProviderSpec) bool { - if spec.SecretKeyRef == (corev1.SecretKeySelector{}) { - return false - } - if strings.TrimSpace(spec.SecretKeyRef.Name) == "" { - return false - } - return true -} - func getDDSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (string, string, error) { - if !hasDDSecretDefined(provider.Spec) { + if !provider.HasSecretDefined() { return "", "", ErrSecretKeyRefNotDefined } ddCredsSecret := &corev1.Secret{} diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go new file mode 100644 index 0000000000..e7647b8d16 --- /dev/null +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -0,0 +1,42 @@ +package prometheus + +import ( + "context" + "errors" + "fmt" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/types" + "net/http" + "sigs.k8s.io/controller-runtime/pkg/client" +) + +const apiKey = "ACCESS_TOKEN" + +var ErrSecretKeyRefNotDefined = errors.New("the SecretKeyRef property with the Prometheus API Key is missing") + +type transport struct { + underlyingTransport http.RoundTripper + apiToken string +} + +func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { + req.Header.Add("Authorization:Bearer", t.apiToken) + return t.underlyingTransport.RoundTrip(req) +} + +func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (string, error) { + if !provider.HasSecretDefined() { + return "", ErrSecretKeyRefNotDefined + } + secret := &corev1.Secret{} + if err := k8sClient.Get(ctx, types.NamespacedName{Name: provider.Spec.SecretKeyRef.Name, Namespace: provider.Namespace}, secret); err != nil { + return "", err + } + + apiKeyVal := secret.Data[provider.Spec.SecretKeyRef.Key] + if len(apiKeyVal) == 0 { + return "", fmt.Errorf("secret does not contain %s", apiKey) + } + return string(apiKeyVal), nil +} diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go new file mode 100644 index 0000000000..1c36abfcf9 --- /dev/null +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -0,0 +1,116 @@ +package prometheus + +import ( + "context" + "net/http" + "net/http/httptest" + "strings" + "testing" + + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" + "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +const prometheusPayload = "test" + +func TestGetSecret_NoKeyDefined(t *testing.T) { + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte(prometheusPayload)) + require.Nil(t, err) + })) + defer svr.Close() + fakeClient := fake.NewClient() + + p := metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + TargetServer: svr.URL, + }, + } + r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) + require.NotNil(t, e) + require.ErrorIs(t, e, ErrSecretKeyRefNotDefined) + require.Empty(t, r1) + +} + +func TestGetSecret_NoSecretDefined(t *testing.T) { + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte(prometheusPayload)) + require.Nil(t, err) + })) + defer svr.Close() + + secretName := "datadogSecret" + apiKey, apiKeyValue := "DD_CLIENT_API_KEY", "fake-api-key" + appKey, appKeyValue := "DD_CLIENT_APP_KEY", "fake-app-key" + apiToken := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "garbage", + Namespace: "", + }, + Data: map[string][]byte{ + apiKey: []byte(apiKeyValue), + appKey: []byte(appKeyValue), + }, + } + fakeClient := fake.NewClient(apiToken) + + b := true + p := metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + SecretKeyRef: v1.SecretKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: secretName, + }, + Optional: &b, + }, + TargetServer: svr.URL, + }, + } + r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) + require.NotNil(t, e) + require.True(t, strings.Contains(e.Error(), "secrets \""+secretName+"\" not found")) + require.Empty(t, r1) + +} + +func TestGetSecret_HappyPath(t *testing.T) { + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + _, err := w.Write([]byte(prometheusPayload)) + require.Nil(t, err) + })) + defer svr.Close() + + secretName := "datadogSecret" + apiToken := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: "", + }, + Data: map[string][]byte{ + apiKey: []byte(apiKey), + }, + } + fakeClient := fake.NewClient(apiToken) + + b := true + p := metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + SecretKeyRef: v1.SecretKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: secretName, + }, + Optional: &b, + }, + TargetServer: svr.URL, + }, + } + r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) + require.Nil(t, e) + require.Equal(t, apiKey, r1) + +} diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index 79de2f955f..eb4fbb5162 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -5,6 +5,7 @@ import ( "encoding/json" "fmt" //nolint:gci "net/http" //nolint:gci + "sigs.k8s.io/controller-runtime/pkg/client" "time" "github.com/go-logr/logr" @@ -19,18 +20,34 @@ var errNoValues = fmt.Errorf("no values in query result") var errTooManyValues = fmt.Errorf("too many values in query result") type KeptnPrometheusProvider struct { - Log logr.Logger - HttpClient http.Client + Log logr.Logger + K8sClient client.Client +} + +func (r *KeptnPrometheusProvider) NewHttpClient(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (*http.Client, error) { + + token, err := getPrometheusSecret(ctx, provider, r.K8sClient) + if err != nil { + return nil, err + } + + return &http.Client{Transport: &transport{underlyingTransport: http.DefaultTransport, apiToken: token}}, nil } func (r *KeptnPrometheusProvider) FetchAnalysisValue(ctx context.Context, query string, analysis metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: &r.HttpClient}) + c, err := r.NewHttpClient(ctx, *provider) + if err != nil { + return "", err + } + + client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: c}) if err != nil { return "", err } + api := prometheus.NewAPI(client) r.Log.Info(fmt.Sprintf( "Running query: /api/v1/query_range?query=%s&start=%d&end=%d", @@ -64,7 +81,11 @@ func (r *KeptnPrometheusProvider) EvaluateQuery(ctx context.Context, metric metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: &r.HttpClient}) + c, err := r.NewHttpClient(ctx, provider) + if err != nil { + return "", nil, err + } + client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: c}) if err != nil { return "", nil, err } @@ -96,12 +117,18 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: &r.HttpClient}) + c, err := r.NewHttpClient(ctx, provider) + if err != nil { + return nil, nil, err + } + + client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: c}) if err != nil { return nil, nil, err } api := prometheus.NewAPI(client) + result, warnings, err := evaluateQueryWithRange(ctx, metric, r, api) if err != nil { return nil, nil, err diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index 4c673d7c2b..b5fc8582a3 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -2,6 +2,7 @@ package prometheus import ( "context" + "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" "net/http" "net/http/httptest" "testing" @@ -180,10 +181,10 @@ func Test_prometheus(t *testing.T) { require.Nil(t, err) })) defer svr.Close() - + fclient := fake.NewClient() kpp := KeptnPrometheusProvider{ - HttpClient: http.Client{}, - Log: ctrl.Log.WithName("testytest"), + K8sClient: fclient, + Log: ctrl.Log.WithName("testytest"), } p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ @@ -337,11 +338,11 @@ func TestFetchAnalysisValue(t *testing.T) { TargetServer: svr.URL, }, } - + fclient := fake.NewClient() // Create your KeptnPrometheusProvider instance provider := KeptnPrometheusProvider{ - HttpClient: http.Client{}, - Log: ctrl.Log.WithName("testytest"), + K8sClient: fclient, + Log: ctrl.Log.WithName("testytest"), } // Prepare the analysis spec diff --git a/metrics-operator/controllers/common/providers/provider.go b/metrics-operator/controllers/common/providers/provider.go index b05289f50f..a3fd755af0 100644 --- a/metrics-operator/controllers/common/providers/provider.go +++ b/metrics-operator/controllers/common/providers/provider.go @@ -31,8 +31,8 @@ func NewProvider(providerType string, log logr.Logger, k8sClient client.Client) switch strings.ToLower(providerType) { case PrometheusProviderType: return &prometheus.KeptnPrometheusProvider{ - HttpClient: http.Client{}, - Log: log, + K8sClient: k8sClient, + Log: log, }, nil case DynatraceProviderType: return &dynatrace.KeptnDynatraceProvider{ From 90d56f56c56dec94fb71c5d026e9b0968f085e34 Mon Sep 17 00:00:00 2001 From: realanna Date: Thu, 21 Sep 2023 13:55:14 +0200 Subject: [PATCH 02/27] feat(metrics-operator): add unit tests Signed-off-by: realanna --- .../common/providers/prometheus/common.go | 6 ++-- .../providers/prometheus/common_test.go | 33 +++++++------------ .../common/providers/prometheus/prometheus.go | 9 +++-- .../providers/prometheus/prometheus_test.go | 20 ++++++----- 4 files changed, 35 insertions(+), 33 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index e7647b8d16..28bfb65c46 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -9,6 +9,7 @@ import ( "k8s.io/apimachinery/pkg/types" "net/http" "sigs.k8s.io/controller-runtime/pkg/client" + "strings" ) const apiKey = "ACCESS_TOKEN" @@ -21,7 +22,8 @@ type transport struct { } func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { - req.Header.Add("Authorization:Bearer", t.apiToken) + bearer := "Bearer " + t.apiToken + req.Header.Add("Authorization", bearer) return t.underlyingTransport.RoundTrip(req) } @@ -38,5 +40,5 @@ func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsPr if len(apiKeyVal) == 0 { return "", fmt.Errorf("secret does not contain %s", apiKey) } - return string(apiKeyVal), nil + return strings.Trim(string(apiKeyVal), "\n"), nil } diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index 1c36abfcf9..adf5edb599 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -44,25 +44,15 @@ func TestGetSecret_NoSecretDefined(t *testing.T) { })) defer svr.Close() - secretName := "datadogSecret" - apiKey, apiKeyValue := "DD_CLIENT_API_KEY", "fake-api-key" - appKey, appKeyValue := "DD_CLIENT_APP_KEY", "fake-app-key" - apiToken := &corev1.Secret{ - ObjectMeta: metav1.ObjectMeta{ - Name: "garbage", - Namespace: "", - }, - Data: map[string][]byte{ - apiKey: []byte(apiKeyValue), - appKey: []byte(appKeyValue), - }, - } - fakeClient := fake.NewClient(apiToken) + secretName := "testSecret" + + fakeClient := fake.NewClient() b := true p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ SecretKeyRef: v1.SecretKeySelector{ + Key: apiKey, LocalObjectReference: v1.LocalObjectReference{ Name: secretName, }, @@ -73,7 +63,8 @@ func TestGetSecret_NoSecretDefined(t *testing.T) { } r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.NotNil(t, e) - require.True(t, strings.Contains(e.Error(), "secrets \""+secretName+"\" not found")) + t.Log(e.Error()) + require.True(t, strings.Contains(e.Error(), "the SecretKeyRef property with the Prometheus API Key is missing")) require.Empty(t, r1) } @@ -85,32 +76,32 @@ func TestGetSecret_HappyPath(t *testing.T) { })) defer svr.Close() - secretName := "datadogSecret" + secretName := "mySecret" apiToken := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: secretName, - Namespace: "", + Namespace: "default", }, Data: map[string][]byte{ - apiKey: []byte(apiKey), + apiKey: []byte("mytoken"), }, } fakeClient := fake.NewClient(apiToken) - b := true p := metricsapi.KeptnMetricsProvider{ + ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: metricsapi.KeptnMetricsProviderSpec{ SecretKeyRef: v1.SecretKeySelector{ + Key: apiKey, LocalObjectReference: v1.LocalObjectReference{ Name: secretName, }, - Optional: &b, }, TargetServer: svr.URL, }, } r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.Nil(t, e) - require.Equal(t, apiKey, r1) + require.Equal(t, "mytoken", r1) } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index eb4fbb5162..65fe3c21fe 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -3,7 +3,8 @@ package prometheus import ( "context" "encoding/json" - "fmt" //nolint:gci + "fmt" //nolint:gci + "github.com/pkg/errors" "net/http" //nolint:gci "sigs.k8s.io/controller-runtime/pkg/client" "time" @@ -27,10 +28,14 @@ type KeptnPrometheusProvider struct { func (r *KeptnPrometheusProvider) NewHttpClient(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (*http.Client, error) { token, err := getPrometheusSecret(ctx, provider, r.K8sClient) + if err != nil { + if errors.Is(err, ErrSecretKeyRefNotDefined) { + //if no secret is registered the provider will attempt to connect without authentication + return &http.Client{}, nil + } return nil, err } - return &http.Client{Transport: &transport{underlyingTransport: http.DefaultTransport, apiToken: token}}, nil } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index b5fc8582a3..2524716f9a 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -181,6 +181,7 @@ func Test_prometheus(t *testing.T) { require.Nil(t, err) })) defer svr.Close() + fclient := fake.NewClient() kpp := KeptnPrometheusProvider{ K8sClient: fclient, @@ -188,12 +189,6 @@ func Test_prometheus(t *testing.T) { } p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ - SecretKeyRef: v1.SecretKeySelector{ - LocalObjectReference: v1.LocalObjectReference{ - Name: "myapitoken", - }, - Key: "mykey", - }, TargetServer: svr.URL, }, } @@ -333,12 +328,21 @@ func TestFetchAnalysisValue(t *testing.T) { LocalObjectReference: v1.LocalObjectReference{ Name: "myapitoken", }, - Key: "mykey", + Key: apiKey, }, TargetServer: svr.URL, }, } - fclient := fake.NewClient() + secret := v1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "myapitoken", + Namespace: "", + }, + Data: map[string][]byte{ + apiKey: []byte("secretValue"), + }, + } + fclient := fake.NewClient(&secret) // Create your KeptnPrometheusProvider instance provider := KeptnPrometheusProvider{ K8sClient: fclient, From d57d5d736cb2bd59275f1c897cfb98ff10b0e173 Mon Sep 17 00:00:00 2001 From: realanna Date: Thu, 21 Sep 2023 14:01:24 +0200 Subject: [PATCH 03/27] feat(metrics-operator): add test of header Signed-off-by: realanna --- .../common/providers/prometheus/prometheus_test.go | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index 2524716f9a..b134c58dc6 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -5,6 +5,7 @@ import ( "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" "net/http" "net/http/httptest" + "strings" "testing" "time" @@ -313,11 +314,18 @@ func Test_resultsForMatrix(t *testing.T) { } } -func TestFetchAnalysisValue(t *testing.T) { +func TestFetchAnalysisValueWithAuth(t *testing.T) { svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(promPayloadWithRangeAndStep)) - require.Nil(t, err) + header := r.Header.Get("Authorization") + t.Log(header) + if strings.Contains(header, "Bearer secretValue") { + _, err := w.Write([]byte(promPayloadWithRangeAndStep)) + require.Nil(t, err) + } else { + _, err := w.Write([]byte("Unauthorized")) + require.Nil(t, err) + } })) defer svr.Close() From 4a72956e4ae805108d1e2976bfca17b36478ca78 Mon Sep 17 00:00:00 2001 From: realanna Date: Fri, 22 Sep 2023 12:43:15 +0200 Subject: [PATCH 04/27] feat(metrics-operator): use roundtripper from prometheus api Signed-off-by: realanna --- .../common/providers/prometheus/common.go | 50 ++++++++++------ .../providers/prometheus/common_test.go | 14 +++-- .../common/providers/prometheus/prometheus.go | 59 ++++++------------- .../providers/prometheus/prometheus_test.go | 16 +++-- 4 files changed, 72 insertions(+), 67 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index 28bfb65c46..74cfe9f91b 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -3,42 +3,58 @@ package prometheus import ( "context" "errors" - "fmt" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" + promapi "github.com/prometheus/client_golang/api" + "github.com/prometheus/common/config" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" + "k8s.io/apimachinery/pkg/util/json" "net/http" "sigs.k8s.io/controller-runtime/pkg/client" - "strings" ) -const apiKey = "ACCESS_TOKEN" +const userName = "user" +const password = "password" var ErrSecretKeyRefNotDefined = errors.New("the SecretKeyRef property with the Prometheus API Key is missing") +var ErrInvalidSecretFormat = errors.New("secret key does not contain user and password") -type transport struct { - underlyingTransport http.RoundTripper - apiToken string +type SecretData struct { + User string `json:"user"` + Password config.Secret `json:"password"` } -func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) { - bearer := "Bearer " + t.apiToken - req.Header.Add("Authorization", bearer) - return t.underlyingTransport.RoundTrip(req) +func getRoundtripper(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + secret, err := getPrometheusSecret(ctx, provider, k8sClient) + if err != nil { + if errors.Is(err, ErrSecretKeyRefNotDefined) { + return promapi.DefaultRoundTripper, nil + } + return nil, err + } + return config.NewBasicAuthRoundTripper(secret.User, secret.Password, "", promapi.DefaultRoundTripper), nil + } -func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (string, error) { +func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (*SecretData, error) { if !provider.HasSecretDefined() { - return "", ErrSecretKeyRefNotDefined + return nil, ErrSecretKeyRefNotDefined } secret := &corev1.Secret{} if err := k8sClient.Get(ctx, types.NamespacedName{Name: provider.Spec.SecretKeyRef.Name, Namespace: provider.Namespace}, secret); err != nil { - return "", err + return nil, err } - apiKeyVal := secret.Data[provider.Spec.SecretKeyRef.Key] - if len(apiKeyVal) == 0 { - return "", fmt.Errorf("secret does not contain %s", apiKey) + var secretData SecretData + if data, ok := secret.Data[provider.Spec.SecretKeyRef.Key]; ok { + // Unmarshal the JSON data into the SecretData struct + if err := json.Unmarshal(data, &secretData); err != nil { + return nil, ErrInvalidSecretFormat + } + } else if _, ok := secret.Data[userName]; !ok { + return nil, ErrInvalidSecretFormat } - return strings.Trim(string(apiKeyVal), "\n"), nil + secretData.User = string(secret.Data[userName]) + secretData.Password = config.Secret(secret.Data[password]) + return &secretData, nil } diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index adf5edb599..fa463d3342 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -2,9 +2,9 @@ package prometheus import ( "context" + "github.com/pkg/errors" "net/http" "net/http/httptest" - "strings" "testing" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" @@ -52,7 +52,7 @@ func TestGetSecret_NoSecretDefined(t *testing.T) { p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ SecretKeyRef: v1.SecretKeySelector{ - Key: apiKey, + Key: "apiKey", LocalObjectReference: v1.LocalObjectReference{ Name: secretName, }, @@ -64,7 +64,7 @@ func TestGetSecret_NoSecretDefined(t *testing.T) { r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.NotNil(t, e) t.Log(e.Error()) - require.True(t, strings.Contains(e.Error(), "the SecretKeyRef property with the Prometheus API Key is missing")) + require.True(t, errors.Is(e, ErrSecretKeyRefNotDefined)) require.Empty(t, r1) } @@ -83,7 +83,8 @@ func TestGetSecret_HappyPath(t *testing.T) { Namespace: "default", }, Data: map[string][]byte{ - apiKey: []byte("mytoken"), + "user": []byte("myuser"), + "password": []byte("mytoken"), }, } fakeClient := fake.NewClient(apiToken) @@ -92,7 +93,7 @@ func TestGetSecret_HappyPath(t *testing.T) { ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: metricsapi.KeptnMetricsProviderSpec{ SecretKeyRef: v1.SecretKeySelector{ - Key: apiKey, + Key: "login", LocalObjectReference: v1.LocalObjectReference{ Name: secretName, }, @@ -102,6 +103,7 @@ func TestGetSecret_HappyPath(t *testing.T) { } r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.Nil(t, e) - require.Equal(t, "mytoken", r1) + require.Equal(t, "myuser", r1.User) + require.Equal(t, "mytoken", r1.Password) } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index 65fe3c21fe..beba6c0c42 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -3,10 +3,7 @@ package prometheus import ( "context" "encoding/json" - "fmt" //nolint:gci - "github.com/pkg/errors" - "net/http" //nolint:gci - "sigs.k8s.io/controller-runtime/pkg/client" + "fmt" "time" "github.com/go-logr/logr" @@ -14,6 +11,7 @@ import ( promapi "github.com/prometheus/client_golang/api" prometheus "github.com/prometheus/client_golang/api/prometheus/v1" "github.com/prometheus/common/model" + "sigs.k8s.io/controller-runtime/pkg/client" ) var errCouldNotCast = fmt.Errorf("could not cast result") @@ -25,35 +23,14 @@ type KeptnPrometheusProvider struct { K8sClient client.Client } -func (r *KeptnPrometheusProvider) NewHttpClient(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (*http.Client, error) { - - token, err := getPrometheusSecret(ctx, provider, r.K8sClient) - - if err != nil { - if errors.Is(err, ErrSecretKeyRefNotDefined) { - //if no secret is registered the provider will attempt to connect without authentication - return &http.Client{}, nil - } - return nil, err - } - return &http.Client{Transport: &transport{underlyingTransport: http.DefaultTransport, apiToken: token}}, nil -} - func (r *KeptnPrometheusProvider) FetchAnalysisValue(ctx context.Context, query string, analysis metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - - c, err := r.NewHttpClient(ctx, *provider) - if err != nil { - return "", err - } - - client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: c}) + api, err := r.setupApi(ctx, *provider) if err != nil { return "", err } - api := prometheus.NewAPI(client) r.Log.Info(fmt.Sprintf( "Running query: /api/v1/query_range?query=%s&start=%d&end=%d", query, @@ -86,16 +63,12 @@ func (r *KeptnPrometheusProvider) EvaluateQuery(ctx context.Context, metric metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - c, err := r.NewHttpClient(ctx, provider) - if err != nil { - return "", nil, err - } - client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: c}) + api, err := r.setupApi(ctx, provider) + if err != nil { return "", nil, err } - api := prometheus.NewAPI(client) if metric.Spec.Range != nil { result, warnings, err := evaluateQueryWithRange(ctx, metric, r, api) if err != nil { @@ -122,18 +95,11 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - c, err := r.NewHttpClient(ctx, provider) - if err != nil { - return nil, nil, err - } - - client, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, Client: c}) + api, err := r.setupApi(ctx, provider) if err != nil { return nil, nil, err } - api := prometheus.NewAPI(client) - result, warnings, err := evaluateQueryWithRange(ctx, metric, r, api) if err != nil { return nil, nil, err @@ -144,6 +110,19 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr return getResultForStepMatrix(result) } +func (r *KeptnPrometheusProvider) setupApi(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (prometheus.API, error) { + rt, err := getRoundtripper(ctx, provider, r.K8sClient) + if err != nil { + return nil, err + } + + pClient, err := promapi.NewClient(promapi.Config{Address: provider.Spec.TargetServer, RoundTripper: rt}) + if err != nil { + return nil, err + } + return prometheus.NewAPI(pClient), nil +} + func evaluateQueryWithRange(ctx context.Context, metric metricsapi.KeptnMetric, r *KeptnPrometheusProvider, api prometheus.API) (model.Value, prometheus.Warnings, error) { queryTime := time.Now().UTC() // Get the duration diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index b134c58dc6..5300a69f59 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -2,13 +2,15 @@ package prometheus import ( "context" - "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + "encoding/json" "net/http" "net/http/httptest" "strings" "testing" "time" + "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" @@ -319,7 +321,7 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { header := r.Header.Get("Authorization") t.Log(header) - if strings.Contains(header, "Bearer secretValue") { + if strings.Contains(header, "Basic user:password") { _, err := w.Write([]byte(promPayloadWithRangeAndStep)) require.Nil(t, err) } else { @@ -336,18 +338,24 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { LocalObjectReference: v1.LocalObjectReference{ Name: "myapitoken", }, - Key: apiKey, + Key: "defaultuser", }, TargetServer: svr.URL, }, } + + secValue := SecretData{Password: password, User: userName} + secByte, err := json.Marshal(secValue) + + require.Nil(t, err) + secret := v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "myapitoken", Namespace: "", }, Data: map[string][]byte{ - apiKey: []byte("secretValue"), + "defaultuser": secByte, }, } fclient := fake.NewClient(&secret) From 7e2ca7ef38c5c84a2c12121dbc7aa483333a77f0 Mon Sep 17 00:00:00 2001 From: realanna Date: Fri, 22 Sep 2023 13:56:00 +0200 Subject: [PATCH 05/27] feat(metrics-operator): fixed test Signed-off-by: realanna --- .../common/providers/prometheus/common.go | 14 +++++--------- .../common/providers/prometheus/common_test.go | 9 +++++---- .../common/providers/prometheus/prometheus_test.go | 14 ++++++-------- metrics-operator/go.mod | 2 ++ metrics-operator/go.sum | 2 ++ 5 files changed, 20 insertions(+), 21 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index 74cfe9f91b..8da20ed1ca 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -8,7 +8,6 @@ import ( "github.com/prometheus/common/config" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - "k8s.io/apimachinery/pkg/util/json" "net/http" "sigs.k8s.io/controller-runtime/pkg/client" ) @@ -46,15 +45,12 @@ func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsPr } var secretData SecretData - if data, ok := secret.Data[provider.Spec.SecretKeyRef.Key]; ok { - // Unmarshal the JSON data into the SecretData struct - if err := json.Unmarshal(data, &secretData); err != nil { - return nil, ErrInvalidSecretFormat - } - } else if _, ok := secret.Data[userName]; !ok { + user, ok := secret.Data[userName] + pw, yes := secret.Data[password] + if !ok || !yes { return nil, ErrInvalidSecretFormat } - secretData.User = string(secret.Data[userName]) - secretData.Password = config.Secret(secret.Data[password]) + secretData.User = string(user) + secretData.Password = config.Secret(pw) return &secretData, nil } diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index fa463d3342..a4435c608d 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -2,7 +2,7 @@ package prometheus import ( "context" - "github.com/pkg/errors" + "github.com/prometheus/common/config" "net/http" "net/http/httptest" "testing" @@ -12,6 +12,7 @@ import ( "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" + k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -32,7 +33,7 @@ func TestGetSecret_NoKeyDefined(t *testing.T) { } r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.NotNil(t, e) - require.ErrorIs(t, e, ErrSecretKeyRefNotDefined) + require.ErrorIs(t, ErrSecretKeyRefNotDefined, e) require.Empty(t, r1) } @@ -64,7 +65,7 @@ func TestGetSecret_NoSecretDefined(t *testing.T) { r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.NotNil(t, e) t.Log(e.Error()) - require.True(t, errors.Is(e, ErrSecretKeyRefNotDefined)) + require.True(t, k8serrors.IsNotFound(e)) require.Empty(t, r1) } @@ -104,6 +105,6 @@ func TestGetSecret_HappyPath(t *testing.T) { r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) require.Nil(t, e) require.Equal(t, "myuser", r1.User) - require.Equal(t, "mytoken", r1.Password) + require.Equal(t, config.Secret("mytoken"), r1.Password) } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index 5300a69f59..c3093449ec 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -2,7 +2,7 @@ package prometheus import ( "context" - "encoding/json" + "encoding/base64" "net/http" "net/http/httptest" "strings" @@ -320,8 +320,10 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { header := r.Header.Get("Authorization") + //prometheus encodes basic user password in header t.Log(header) - if strings.Contains(header, "Basic user:password") { + encoded := "Basic " + base64.StdEncoding.EncodeToString([]byte("user:password")) + if strings.Contains(header, encoded) { _, err := w.Write([]byte(promPayloadWithRangeAndStep)) require.Nil(t, err) } else { @@ -344,18 +346,14 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { }, } - secValue := SecretData{Password: password, User: userName} - secByte, err := json.Marshal(secValue) - - require.Nil(t, err) - secret := v1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "myapitoken", Namespace: "", }, Data: map[string][]byte{ - "defaultuser": secByte, + userName: []byte(userName), + password: []byte(password), }, } fclient := fake.NewClient(&secret) diff --git a/metrics-operator/go.mod b/metrics-operator/go.mod index da9fe3afc7..fd173043d5 100644 --- a/metrics-operator/go.mod +++ b/metrics-operator/go.mod @@ -67,12 +67,14 @@ require ( github.com/imdario/mergo v0.3.13 // indirect github.com/inconshreveable/mousetrap v1.1.0 // indirect github.com/josharian/intern v1.0.0 // indirect + github.com/jpillora/backoff v1.0.0 // indirect github.com/json-iterator/go v1.1.12 // indirect github.com/mailru/easyjson v0.7.7 // indirect github.com/matttproud/golang_protobuf_extensions v1.0.4 // indirect github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect github.com/modern-go/reflect2 v1.0.2 // indirect github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect + github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect github.com/spf13/afero v1.10.0 // indirect diff --git a/metrics-operator/go.sum b/metrics-operator/go.sum index 15135711cf..55cbd525d8 100644 --- a/metrics-operator/go.sum +++ b/metrics-operator/go.sum @@ -233,6 +233,7 @@ github.com/jonboulle/clockwork v0.2.2 h1:UOGuzwb1PwsrDAObMuhUnj0p5ULPj8V/xJ7Kx9q github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0 h1:uvFg412JmmHBHw7iwprIxkPMI+sGQ4kzOWsMeHnm2EA= +github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.12 h1:PV8peI4a0ysnczrg+LtxykD8LfKY9ML6u2jnxaEnrnM= github.com/json-iterator/go v1.1.12/go.mod h1:e30LSqwooZae/UwlEbR2852Gd8hjQvJoHmT4TnhNGBo= github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU= @@ -263,6 +264,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f h1:KUppIJq7/+SVif2QVs3tOP0zanoHgBEVAwHxUSIzRqU= +github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/onsi/ginkgo/v2 v2.11.0 h1:WgqUCUt/lT6yXoQ8Wef0fsNn5cAuMK7+KT9UFRz2tcU= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/open-feature/go-sdk v1.7.0 h1:g6o/sf5xaED7xawXwZ0LqE7RS9co7HZJMClXCXmIbgw= From 34fcf45768e44d8b8fc4fbc7819369e66ab7141f Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 08:28:12 +0200 Subject: [PATCH 06/27] feat(metrics-operator): revert change to ddprovider Signed-off-by: realanna --- .../controllers/common/providers/datadog/common.go | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/metrics-operator/controllers/common/providers/datadog/common.go b/metrics-operator/controllers/common/providers/datadog/common.go index e1f0be1eaa..097e0f191d 100644 --- a/metrics-operator/controllers/common/providers/datadog/common.go +++ b/metrics-operator/controllers/common/providers/datadog/common.go @@ -8,14 +8,25 @@ import ( corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" + "strings" ) const apiKey, appKey = "DD_CLIENT_API_KEY", "DD_CLIENT_APP_KEY" var ErrSecretKeyRefNotDefined = errors.New("the SecretKeyRef property with the DataDog API Key is missing") +func hasDDSecretDefined(spec metricsapi.KeptnMetricsProviderSpec) bool { + if spec.SecretKeyRef == (corev1.SecretKeySelector{}) { + return false + } + if strings.TrimSpace(spec.SecretKeyRef.Name) == "" { + return false + } + return true +} + func getDDSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (string, string, error) { - if !provider.HasSecretDefined() { + if !hasDDSecretDefined(provider.Spec) { return "", "", ErrSecretKeyRefNotDefined } ddCredsSecret := &corev1.Secret{} From dc17e310b38e647927364d20a08968238f92ffba Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 08:31:55 +0200 Subject: [PATCH 07/27] feat(metrics-operator): lint Signed-off-by: realanna --- .../controllers/common/providers/datadog/common.go | 3 ++- .../controllers/common/providers/prometheus/common.go | 3 ++- .../controllers/common/providers/prometheus/prometheus_test.go | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/metrics-operator/controllers/common/providers/datadog/common.go b/metrics-operator/controllers/common/providers/datadog/common.go index 097e0f191d..377129a038 100644 --- a/metrics-operator/controllers/common/providers/datadog/common.go +++ b/metrics-operator/controllers/common/providers/datadog/common.go @@ -4,11 +4,12 @@ import ( "context" "errors" "fmt" + "strings" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" "sigs.k8s.io/controller-runtime/pkg/client" - "strings" ) const apiKey, appKey = "DD_CLIENT_API_KEY", "DD_CLIENT_APP_KEY" diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index 8da20ed1ca..cd1c1b81f8 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -3,12 +3,13 @@ package prometheus import ( "context" "errors" + "net/http" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" promapi "github.com/prometheus/client_golang/api" "github.com/prometheus/common/config" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/types" - "net/http" "sigs.k8s.io/controller-runtime/pkg/client" ) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index c3093449ec..e5f86934f1 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -12,6 +12,7 @@ import ( "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" + "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" From 204a01aaaca585bf43546494eacbd275ea0d6245 Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 10:47:28 +0200 Subject: [PATCH 08/27] feat(metrics-operator): lint Signed-off-by: realanna --- .../controllers/common/providers/prometheus/common_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index a4435c608d..9ad8bde245 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -2,13 +2,13 @@ package prometheus import ( "context" - "github.com/prometheus/common/config" "net/http" "net/http/httptest" "testing" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + "github.com/prometheus/common/config" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" From 84933625485029a1db5d851dbab8e6c75fb4e0ff Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 10:54:54 +0200 Subject: [PATCH 09/27] feat(metrics-operator): add integration test Signed-off-by: realanna --- .../prometheus-operator-serviceMonitor.yaml | 13 +++++++------ test/prometheus/secret.yaml | 8 ++++++++ 2 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 test/prometheus/secret.yaml diff --git a/test/prometheus/prometheus-operator-serviceMonitor.yaml b/test/prometheus/prometheus-operator-serviceMonitor.yaml index b68a98b010..293f795411 100644 --- a/test/prometheus/prometheus-operator-serviceMonitor.yaml +++ b/test/prometheus/prometheus-operator-serviceMonitor.yaml @@ -10,12 +10,13 @@ metadata: namespace: monitoring spec: endpoints: - - bearerTokenFile: /var/run/secrets/kubernetes.io/serviceaccount/token - honorLabels: true - port: https - scheme: https - tlsConfig: - insecureSkipVerify: true + - basicAuth: + password: + name: basic-auth + key: password + username: + name: basic-auth + key: user selector: matchLabels: app.kubernetes.io/component: controller diff --git a/test/prometheus/secret.yaml b/test/prometheus/secret.yaml new file mode 100644 index 0000000000..fa0dd897c0 --- /dev/null +++ b/test/prometheus/secret.yaml @@ -0,0 +1,8 @@ +apiVersion: v1 +kind: Secret +metadata: + name: basic-auth +data: + password: dG9vcg== # toor + user: YWRtaW4= # admin +type: Opaque \ No newline at end of file From c3982e72adc0ee626001068b75127686da00f0fa Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 11:45:31 +0200 Subject: [PATCH 10/27] feat(metrics-operator): add unit test Signed-off-by: realanna --- .../common/providers/prometheus/prometheus.go | 13 ++-- .../providers/prometheus/prometheus_test.go | 64 +++++++++++++++++++ 2 files changed, 72 insertions(+), 5 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index beba6c0c42..d9e1f94a73 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "fmt" + "net/http" "time" "github.com/go-logr/logr" @@ -18,6 +19,8 @@ var errCouldNotCast = fmt.Errorf("could not cast result") var errNoValues = fmt.Errorf("no values in query result") var errTooManyValues = fmt.Errorf("too many values in query result") +type RountripGetter func(context.Context, metricsapi.KeptnMetricsProvider, client.Client) (http.RoundTripper, error) + type KeptnPrometheusProvider struct { Log logr.Logger K8sClient client.Client @@ -26,7 +29,7 @@ type KeptnPrometheusProvider struct { func (r *KeptnPrometheusProvider) FetchAnalysisValue(ctx context.Context, query string, analysis metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - api, err := r.setupApi(ctx, *provider) + api, err := r.setupApi(ctx, *provider, getRoundtripper) if err != nil { return "", err } @@ -63,7 +66,7 @@ func (r *KeptnPrometheusProvider) EvaluateQuery(ctx context.Context, metric metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - api, err := r.setupApi(ctx, provider) + api, err := r.setupApi(ctx, provider, getRoundtripper) if err != nil { return "", nil, err @@ -95,7 +98,7 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - api, err := r.setupApi(ctx, provider) + api, err := r.setupApi(ctx, provider, getRoundtripper) if err != nil { return nil, nil, err } @@ -110,8 +113,8 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr return getResultForStepMatrix(result) } -func (r *KeptnPrometheusProvider) setupApi(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (prometheus.API, error) { - rt, err := getRoundtripper(ctx, provider, r.K8sClient) +func (r *KeptnPrometheusProvider) setupApi(ctx context.Context, provider metricsapi.KeptnMetricsProvider, getter RountripGetter) (prometheus.API, error) { + rt, err := getter(ctx, provider, r.K8sClient) if err != nil { return nil, err } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index e5f86934f1..eb9e32ca79 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -3,6 +3,7 @@ package prometheus import ( "context" "encoding/base64" + "errors" "net/http" "net/http/httptest" "strings" @@ -13,11 +14,13 @@ import ( metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + promapi "github.com/prometheus/client_golang/api" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" v1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ctrl "sigs.k8s.io/controller-runtime" + "sigs.k8s.io/controller-runtime/pkg/client" ) const promWarnPayloadWithNoRange = "{\"status\":\"success\",\"warnings\":[\"awarning\"],\"data\":{\"resultType\":\"vector\",\"result\":[{\"metric\":{\"__name__\":\"kube_pod_info\",\"container\":\"kube-rbac-proxy-main\",\"created_by_kind\":\"DaemonSet\",\"created_by_name\":\"kindnet\",\"host_ip\":\"172.18.0.2\",\"host_network\":\"true\",\"instance\":\"10.244.0.24:8443\",\"job\":\"kube-state-metrics\",\"namespace\":\"kube-system\",\"node\":\"kind-control-plane\",\"pod\":\"kindnet-llt85\",\"pod_ip\":\"172.18.0.2\",\"uid\":\"0bb9d9db-2658-439f-aed9-ab3e8502397d\"},\"value\":[1669714193.275,\"1\"]}]}}" @@ -388,3 +391,64 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { require.NoError(t, err) require.Equal(t, expectedResult, result) } + +func TestKeptnPrometheusProvider_setupApi(t *testing.T) { + var b byte + b = 0x7f + tests := []struct { + name string + getter RountripGetter + provider metricsapi.KeptnMetricsProvider + expectedError string + }{ + { + name: "Successful setup", + getter: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + return promapi.DefaultRoundTripper, nil + }, + provider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + TargetServer: "http://example.com", + }, + }, + expectedError: "", + }, + { + name: "Error in getter", + getter: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + return nil, errors.New("bad") + }, + provider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + TargetServer: "http://example.com", + }, + }, + expectedError: "bad", + }, + { + name: "Error in NewClient", + getter: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + return promapi.DefaultRoundTripper, nil + }, + provider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + TargetServer: string(b), + }, + }, + expectedError: "parse", + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + r := &KeptnPrometheusProvider{ + K8sClient: fake.NewClient(), // Initialize with your K8s client + } + _, err := r.setupApi(context.Background(), tc.provider, tc.getter) + if tc.expectedError == "" { + require.Nil(t, err) + } else { + require.Contains(t, err.Error(), tc.expectedError) + } + }) + } +} From 3eeb2fef15105ec8bbc131309f01ab4b8582f804 Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 11:48:03 +0200 Subject: [PATCH 11/27] feat(metrics-operator): add unit test Signed-off-by: realanna --- .../controllers/common/providers/prometheus/prometheus_test.go | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index eb9e32ca79..4e25e016ff 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -393,8 +393,7 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { } func TestKeptnPrometheusProvider_setupApi(t *testing.T) { - var b byte - b = 0x7f + var b byte = 0x7f tests := []struct { name string getter RountripGetter From 906a528c6b96558b16d4ab949639cffea59569b9 Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 14:21:35 +0200 Subject: [PATCH 12/27] fix: useless test setup Signed-off-by: realanna --- .../api/v1alpha3/keptnmetricsprovider_types.go | 3 ++- .../common/providers/dynatrace/common_test.go | 15 +++------------ .../common/providers/prometheus/common_test.go | 15 +++------------ 3 files changed, 8 insertions(+), 25 deletions(-) diff --git a/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go b/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go index f60e6749ef..db9f84a842 100644 --- a/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go +++ b/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go @@ -68,7 +68,8 @@ func (p *KeptnMetricsProvider) HasSecretDefined() bool { if p.Spec.SecretKeyRef == (corev1.SecretKeySelector{}) { return false } - if strings.TrimSpace(p.Spec.SecretKeyRef.Name) == "" || strings.TrimSpace(p.Spec.SecretKeyRef.Key) == "" { + //if the secret name exists the secret is defined + if strings.TrimSpace(p.Spec.SecretKeyRef.Name) == "" { return false } return true diff --git a/metrics-operator/controllers/common/providers/dynatrace/common_test.go b/metrics-operator/controllers/common/providers/dynatrace/common_test.go index 04fa73f910..78f6ec7096 100644 --- a/metrics-operator/controllers/common/providers/dynatrace/common_test.go +++ b/metrics-operator/controllers/common/providers/dynatrace/common_test.go @@ -12,16 +12,12 @@ import ( ) func TestGetSecret_NoKeyDefined(t *testing.T) { - svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(dtpayload)) - require.Nil(t, err) - })) - defer svr.Close() + fakeClient := fake.NewClient() p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ - TargetServer: svr.URL, + TargetServer: "svr.URL", }, } r, e := getDTSecret(context.TODO(), p, fakeClient) @@ -31,16 +27,11 @@ func TestGetSecret_NoKeyDefined(t *testing.T) { } func TestGetSecret_NoSecret(t *testing.T) { - svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(dtpayload)) - require.Nil(t, err) - })) - defer svr.Close() fakeClient := fake.NewClient() p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ - TargetServer: svr.URL, + TargetServer: "svr.URL", }, } r, e := getDTSecret(context.TODO(), p, fakeClient) diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index 9ad8bde245..a7a1a9ca8e 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -19,16 +19,12 @@ import ( const prometheusPayload = "test" func TestGetSecret_NoKeyDefined(t *testing.T) { - svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(prometheusPayload)) - require.Nil(t, err) - })) - defer svr.Close() + fakeClient := fake.NewClient() p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ - TargetServer: svr.URL, + TargetServer: "svr.URL", }, } r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) @@ -39,11 +35,6 @@ func TestGetSecret_NoKeyDefined(t *testing.T) { } func TestGetSecret_NoSecretDefined(t *testing.T) { - svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - _, err := w.Write([]byte(prometheusPayload)) - require.Nil(t, err) - })) - defer svr.Close() secretName := "testSecret" @@ -59,7 +50,7 @@ func TestGetSecret_NoSecretDefined(t *testing.T) { }, Optional: &b, }, - TargetServer: svr.URL, + TargetServer: "svr", }, } r1, e := getPrometheusSecret(context.TODO(), p, fakeClient) From 198f7ded0e7b787932e1f22b9f5ca1cddb78a6bd Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 14:47:00 +0200 Subject: [PATCH 13/27] fix: removed dd special func for secrets Signed-off-by: realanna --- .../controllers/common/providers/datadog/common.go | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/metrics-operator/controllers/common/providers/datadog/common.go b/metrics-operator/controllers/common/providers/datadog/common.go index 377129a038..8fe4b68b8f 100644 --- a/metrics-operator/controllers/common/providers/datadog/common.go +++ b/metrics-operator/controllers/common/providers/datadog/common.go @@ -4,7 +4,6 @@ import ( "context" "errors" "fmt" - "strings" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" corev1 "k8s.io/api/core/v1" @@ -16,18 +15,8 @@ const apiKey, appKey = "DD_CLIENT_API_KEY", "DD_CLIENT_APP_KEY" var ErrSecretKeyRefNotDefined = errors.New("the SecretKeyRef property with the DataDog API Key is missing") -func hasDDSecretDefined(spec metricsapi.KeptnMetricsProviderSpec) bool { - if spec.SecretKeyRef == (corev1.SecretKeySelector{}) { - return false - } - if strings.TrimSpace(spec.SecretKeyRef.Name) == "" { - return false - } - return true -} - func getDDSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (string, string, error) { - if !hasDDSecretDefined(provider.Spec) { + if !provider.HasSecretDefined() { return "", "", ErrSecretKeyRefNotDefined } ddCredsSecret := &corev1.Secret{} From bc72d94ea94c51fbd52d7bdfe8b23e2f0134602d Mon Sep 17 00:00:00 2001 From: realanna Date: Mon, 25 Sep 2023 16:29:33 +0200 Subject: [PATCH 14/27] fix: add unit test to make ondrej happy Signed-off-by: realanna --- .../providers/prometheus/common_test.go | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index a7a1a9ca8e..9172e87255 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -4,16 +4,20 @@ import ( "context" "net/http" "net/http/httptest" + "reflect" + "strings" "testing" metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + promapi "github.com/prometheus/client_golang/api" "github.com/prometheus/common/config" "github.com/stretchr/testify/require" corev1 "k8s.io/api/core/v1" v1 "k8s.io/api/core/v1" k8serrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "sigs.k8s.io/controller-runtime/pkg/client" ) const prometheusPayload = "test" @@ -99,3 +103,90 @@ func TestGetSecret_HappyPath(t *testing.T) { require.Equal(t, config.Secret("mytoken"), r1.Password) } + +func Test_getRoundtripper(t *testing.T) { + goodsecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test", + Namespace: "default", + }, + Data: map[string][]byte{ + "user": []byte("myuser"), + "password": []byte("mytoken"), + }, + } + tests := []struct { + name string + provider metricsapi.KeptnMetricsProvider + k8sClient client.Client + want http.RoundTripper + wantErr bool + errorStr string + }{ + { + name: "TestSuccess", + provider: metricsapi.KeptnMetricsProvider{ + ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: "", + TargetServer: "", + SecretKeyRef: v1.SecretKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "test", + }, + Key: "", + Optional: nil, + }, + }, + }, + k8sClient: fake.NewClient(goodsecret), + want: config.NewBasicAuthRoundTripper("myuser", "mytoken", "", promapi.DefaultRoundTripper), + wantErr: false, + }, + { + name: "TestSecretNotDefined", + provider: metricsapi.KeptnMetricsProvider{}, + k8sClient: fake.NewClient(), + want: promapi.DefaultRoundTripper, + wantErr: false, + }, + { + name: "TestErrorFromGetPrometheusSecretNotExists", + provider: metricsapi.KeptnMetricsProvider{ + ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: "", + TargetServer: "", + SecretKeyRef: v1.SecretKeySelector{ + LocalObjectReference: v1.LocalObjectReference{ + Name: "test", + }, + Key: "", + Optional: nil, + }, + }, + }, + k8sClient: fake.NewClient(), + want: nil, + wantErr: true, + errorStr: "not found", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, err := getRoundtripper(context.TODO(), tt.provider, tt.k8sClient) + t.Log(err) + if (err != nil) != tt.wantErr { + t.Errorf("getRoundtripper() error = %v, wantErr %v", err, tt.wantErr) + return + } + if tt.errorStr != "" && !strings.Contains(err.Error(), tt.errorStr) { + t.Errorf("getRoundtripper() error = %s, wantErr %s", err.Error(), tt.errorStr) + return + } + if !reflect.DeepEqual(got, tt.want) { + t.Errorf("getRoundtripper() got = %v, want %v", got, tt.want) + } + }) + } +} From 72a6ba0d29877d0941663563c64cd247680340c8 Mon Sep 17 00:00:00 2001 From: RealAnna <89971034+RealAnna@users.noreply.github.com> Date: Tue, 26 Sep 2023 08:46:15 +0200 Subject: [PATCH 15/27] Update metrics-operator/controllers/common/providers/prometheus/prometheus.go Co-authored-by: odubajDT <93584209+odubajDT@users.noreply.github.com> Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> --- .../controllers/common/providers/prometheus/prometheus.go | 1 + 1 file changed, 1 insertion(+) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index d9e1f94a73..044cd54fa6 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -24,6 +24,7 @@ type RountripGetter func(context.Context, metricsapi.KeptnMetricsProvider, clien type KeptnPrometheusProvider struct { Log logr.Logger K8sClient client.Client + getter RountripGetter } func (r *KeptnPrometheusProvider) FetchAnalysisValue(ctx context.Context, query string, analysis metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { From febbd21403471f54c2469c7cbc1cb3ce3ec3f446 Mon Sep 17 00:00:00 2001 From: realanna Date: Tue, 26 Sep 2023 08:57:51 +0200 Subject: [PATCH 16/27] fix: embed getter in the struct Signed-off-by: realanna --- .../common/providers/prometheus/common.go | 2 +- .../common/providers/prometheus/common_test.go | 4 ++-- .../common/providers/prometheus/prometheus.go | 12 ++++++------ .../common/providers/prometheus/prometheus_test.go | 5 ++++- .../controllers/common/providers/provider.go | 1 + 5 files changed, 14 insertions(+), 10 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index cd1c1b81f8..42f4fa1f6b 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -24,7 +24,7 @@ type SecretData struct { Password config.Secret `json:"password"` } -func getRoundtripper(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { +func GetRoundtripper(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { secret, err := getPrometheusSecret(ctx, provider, k8sClient) if err != nil { if errors.Is(err, ErrSecretKeyRefNotDefined) { diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index 9172e87255..9041ffa10f 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -104,7 +104,7 @@ func TestGetSecret_HappyPath(t *testing.T) { } -func Test_getRoundtripper(t *testing.T) { +func Test_GetRoundtripper(t *testing.T) { goodsecret := &corev1.Secret{ ObjectMeta: metav1.ObjectMeta{ Name: "test", @@ -174,7 +174,7 @@ func Test_getRoundtripper(t *testing.T) { } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := getRoundtripper(context.TODO(), tt.provider, tt.k8sClient) + got, err := GetRoundtripper(context.TODO(), tt.provider, tt.k8sClient) t.Log(err) if (err != nil) != tt.wantErr { t.Errorf("getRoundtripper() error = %v, wantErr %v", err, tt.wantErr) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index 044cd54fa6..911567e7df 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -24,13 +24,13 @@ type RountripGetter func(context.Context, metricsapi.KeptnMetricsProvider, clien type KeptnPrometheusProvider struct { Log logr.Logger K8sClient client.Client - getter RountripGetter + Getter RountripGetter } func (r *KeptnPrometheusProvider) FetchAnalysisValue(ctx context.Context, query string, analysis metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - api, err := r.setupApi(ctx, *provider, getRoundtripper) + api, err := r.setupApi(ctx, *provider) if err != nil { return "", err } @@ -67,7 +67,7 @@ func (r *KeptnPrometheusProvider) EvaluateQuery(ctx context.Context, metric metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - api, err := r.setupApi(ctx, provider, getRoundtripper) + api, err := r.setupApi(ctx, provider) if err != nil { return "", nil, err @@ -99,7 +99,7 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr ctx, cancel := context.WithTimeout(ctx, 20*time.Second) defer cancel() - api, err := r.setupApi(ctx, provider, getRoundtripper) + api, err := r.setupApi(ctx, provider) if err != nil { return nil, nil, err } @@ -114,8 +114,8 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr return getResultForStepMatrix(result) } -func (r *KeptnPrometheusProvider) setupApi(ctx context.Context, provider metricsapi.KeptnMetricsProvider, getter RountripGetter) (prometheus.API, error) { - rt, err := getter(ctx, provider, r.K8sClient) +func (r *KeptnPrometheusProvider) setupApi(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (prometheus.API, error) { + rt, err := r.Getter(ctx, provider, r.K8sClient) if err != nil { return nil, err } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index 4e25e016ff..93732c4aec 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -193,6 +193,7 @@ func Test_prometheus(t *testing.T) { kpp := KeptnPrometheusProvider{ K8sClient: fclient, Log: ctrl.Log.WithName("testytest"), + Getter: GetRoundtripper, } p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ @@ -365,6 +366,7 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { provider := KeptnPrometheusProvider{ K8sClient: fclient, Log: ctrl.Log.WithName("testytest"), + Getter: GetRoundtripper, } // Prepare the analysis spec @@ -441,8 +443,9 @@ func TestKeptnPrometheusProvider_setupApi(t *testing.T) { t.Run(tc.name, func(t *testing.T) { r := &KeptnPrometheusProvider{ K8sClient: fake.NewClient(), // Initialize with your K8s client + Getter: tc.getter, } - _, err := r.setupApi(context.Background(), tc.provider, tc.getter) + _, err := r.setupApi(context.Background(), tc.provider) if tc.expectedError == "" { require.Nil(t, err) } else { diff --git a/metrics-operator/controllers/common/providers/provider.go b/metrics-operator/controllers/common/providers/provider.go index a3fd755af0..69af3741a2 100644 --- a/metrics-operator/controllers/common/providers/provider.go +++ b/metrics-operator/controllers/common/providers/provider.go @@ -33,6 +33,7 @@ func NewProvider(providerType string, log logr.Logger, k8sClient client.Client) return &prometheus.KeptnPrometheusProvider{ K8sClient: k8sClient, Log: log, + Getter: prometheus.GetRoundtripper, }, nil case DynatraceProviderType: return &dynatrace.KeptnDynatraceProvider{ From b940271938fa212442287bda1d27ad5e5dab632a Mon Sep 17 00:00:00 2001 From: RealAnna <89971034+RealAnna@users.noreply.github.com> Date: Tue, 26 Sep 2023 12:30:07 +0200 Subject: [PATCH 17/27] Update metrics-operator/controllers/common/providers/prometheus/common.go Co-authored-by: Florian Bacher Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> --- .../controllers/common/providers/prometheus/common.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index 42f4fa1f6b..9a01625d11 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -13,8 +13,8 @@ import ( "sigs.k8s.io/controller-runtime/pkg/client" ) -const userName = "user" -const password = "password" +const secretKeyUserName = "user" +const secretKeyPassword = "password" var ErrSecretKeyRefNotDefined = errors.New("the SecretKeyRef property with the Prometheus API Key is missing") var ErrInvalidSecretFormat = errors.New("secret key does not contain user and password") From 48020611bca53bfb31a5939d687342590d76006b Mon Sep 17 00:00:00 2001 From: RealAnna <89971034+RealAnna@users.noreply.github.com> Date: Tue, 26 Sep 2023 12:30:16 +0200 Subject: [PATCH 18/27] Update metrics-operator/controllers/common/providers/prometheus/prometheus.go Co-authored-by: Florian Bacher Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> --- .../controllers/common/providers/prometheus/prometheus.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index 911567e7df..2647ae459b 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -19,7 +19,7 @@ var errCouldNotCast = fmt.Errorf("could not cast result") var errNoValues = fmt.Errorf("no values in query result") var errTooManyValues = fmt.Errorf("too many values in query result") -type RountripGetter func(context.Context, metricsapi.KeptnMetricsProvider, client.Client) (http.RoundTripper, error) +type RoundtripGetter func(context.Context, metricsapi.KeptnMetricsProvider, client.Client) (http.RoundTripper, error) type KeptnPrometheusProvider struct { Log logr.Logger From 19073cd0342d70d3d1e5c2bf92bfb472a5c964ea Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 22 Sep 2023 12:30:39 +0200 Subject: [PATCH 19/27] deps: update github.com/keptn/lifecycle-toolkit/klt-cert-manager digest to 6566e7d (#2143) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- lifecycle-operator/go.mod | 8 ++++---- lifecycle-operator/go.sum | 16 ++++++++-------- metrics-operator/go.mod | 4 ++-- metrics-operator/go.sum | 8 ++++---- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/lifecycle-operator/go.mod b/lifecycle-operator/go.mod index d4991cc604..bbff9470de 100644 --- a/lifecycle-operator/go.mod +++ b/lifecycle-operator/go.mod @@ -9,9 +9,9 @@ require ( github.com/cloudevents/sdk-go/v2 v2.14.0 github.com/go-logr/logr v1.2.4 github.com/kelseyhightower/envconfig v1.4.0 - github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 + github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a github.com/magiconair/properties v1.8.7 - github.com/onsi/ginkgo/v2 v2.12.1 + github.com/onsi/ginkgo/v2 v2.12.0 github.com/onsi/gomega v1.27.10 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 @@ -25,7 +25,7 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.41.0 go.opentelemetry.io/otel/trace v1.18.0 golang.org/x/net v0.15.0 - google.golang.org/grpc v1.58.2 + google.golang.org/grpc v1.58.1 k8s.io/api v0.28.2 k8s.io/apiextensions-apiserver v0.28.2 k8s.io/apimachinery v0.28.2 @@ -70,7 +70,7 @@ require ( github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/afero v1.10.0 // indirect + github.com/spf13/afero v1.9.5 // indirect github.com/spf13/pflag v1.0.5 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.18.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect diff --git a/lifecycle-operator/go.sum b/lifecycle-operator/go.sum index 9b063ccfb2..9c9bd2f2a7 100644 --- a/lifecycle-operator/go.sum +++ b/lifecycle-operator/go.sum @@ -189,8 +189,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 h1:wytmV4pUahfCvjNfsYTpHAjRentNjMOwaOpcAz/6qbc= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273/go.mod h1:GjJFB+g1DuBYrOXSgF4kzR9Phb+W5t3obFt4UHqz9OM= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a h1:lwPbbcRNWJmQWvpWoVVBXxpMv0C3YLX5O6P3yJo0b+A= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a/go.mod h1:IMs51ScEWzHa5k0L7leYRNc0C/TghTHNRp+Go7o58Ko= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -214,8 +214,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= -github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= +github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= +github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -235,8 +235,8 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -566,8 +566,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= -google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= +google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/metrics-operator/go.mod b/metrics-operator/go.mod index fd173043d5..47c53877b3 100644 --- a/metrics-operator/go.mod +++ b/metrics-operator/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-logr/logr v1.2.4 github.com/gorilla/mux v1.8.0 github.com/kelseyhightower/envconfig v1.4.0 - github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 + github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a github.com/open-feature/go-sdk v1.7.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 @@ -77,7 +77,7 @@ require ( github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/afero v1.10.0 // indirect + github.com/spf13/afero v1.9.5 // indirect github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect diff --git a/metrics-operator/go.sum b/metrics-operator/go.sum index 55cbd525d8..0e60d42f55 100644 --- a/metrics-operator/go.sum +++ b/metrics-operator/go.sum @@ -240,8 +240,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 h1:wytmV4pUahfCvjNfsYTpHAjRentNjMOwaOpcAz/6qbc= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273/go.mod h1:GjJFB+g1DuBYrOXSgF4kzR9Phb+W5t3obFt4UHqz9OM= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a h1:lwPbbcRNWJmQWvpWoVVBXxpMv0C3YLX5O6P3yJo0b+A= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a/go.mod h1:IMs51ScEWzHa5k0L7leYRNc0C/TghTHNRp+Go7o58Ko= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -291,8 +291,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= -github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= +github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= From 75c51c131954f8e2a53862b77b09e9cd06d2959e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 26 Sep 2023 13:28:16 +0200 Subject: [PATCH 20/27] deps: update github.com/keptn/lifecycle-toolkit/klt-cert-manager digest to 099a457 (#2169) Signed-off-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- lifecycle-operator/go.mod | 10 +++++----- lifecycle-operator/go.sum | 16 ++++++++-------- metrics-operator/go.mod | 4 ++-- metrics-operator/go.sum | 8 ++++---- 4 files changed, 19 insertions(+), 19 deletions(-) diff --git a/lifecycle-operator/go.mod b/lifecycle-operator/go.mod index bbff9470de..a45ca58a89 100644 --- a/lifecycle-operator/go.mod +++ b/lifecycle-operator/go.mod @@ -9,9 +9,9 @@ require ( github.com/cloudevents/sdk-go/v2 v2.14.0 github.com/go-logr/logr v1.2.4 github.com/kelseyhightower/envconfig v1.4.0 - github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a + github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 github.com/magiconair/properties v1.8.7 - github.com/onsi/ginkgo/v2 v2.12.0 + github.com/onsi/ginkgo/v2 v2.12.1 github.com/onsi/gomega v1.27.10 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 @@ -25,7 +25,8 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.41.0 go.opentelemetry.io/otel/trace v1.18.0 golang.org/x/net v0.15.0 - google.golang.org/grpc v1.58.1 + gomodules.xyz/jsonpatch/v2 v2.4.0 + google.golang.org/grpc v1.58.2 k8s.io/api v0.28.2 k8s.io/apiextensions-apiserver v0.28.2 k8s.io/apimachinery v0.28.2 @@ -70,7 +71,7 @@ require ( github.com/prometheus/client_model v0.4.0 // indirect github.com/prometheus/common v0.44.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/afero v1.10.0 // indirect github.com/spf13/pflag v1.0.5 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.18.0 // indirect go.opentelemetry.io/proto/otlp v1.0.0 // indirect @@ -83,7 +84,6 @@ require ( golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.12.0 // indirect - gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect diff --git a/lifecycle-operator/go.sum b/lifecycle-operator/go.sum index 9c9bd2f2a7..9b063ccfb2 100644 --- a/lifecycle-operator/go.sum +++ b/lifecycle-operator/go.sum @@ -189,8 +189,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a h1:lwPbbcRNWJmQWvpWoVVBXxpMv0C3YLX5O6P3yJo0b+A= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a/go.mod h1:IMs51ScEWzHa5k0L7leYRNc0C/TghTHNRp+Go7o58Ko= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 h1:wytmV4pUahfCvjNfsYTpHAjRentNjMOwaOpcAz/6qbc= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273/go.mod h1:GjJFB+g1DuBYrOXSgF4kzR9Phb+W5t3obFt4UHqz9OM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -214,8 +214,8 @@ github.com/modern-go/reflect2 v1.0.2 h1:xBagoLtFs94CBntxluKeaWgTMpvLxC4ur3nMaC9G github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjYzDa0/r8luk= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 h1:C3w9PqII01/Oq1c1nUAm88MOHcQC9l5mIlSMApZMrHA= github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= -github.com/onsi/ginkgo/v2 v2.12.0 h1:UIVDowFPwpg6yMUpPjGkYvf06K3RAiJXUhCxEwQVHRI= -github.com/onsi/ginkgo/v2 v2.12.0/go.mod h1:ZNEzXISYlqpb8S36iN71ifqLi3vVD1rVJGvWRCJOUpQ= +github.com/onsi/ginkgo/v2 v2.12.1 h1:uHNEO1RP2SpuZApSkel9nEh1/Mu+hmQe7Q+Pepg5OYA= +github.com/onsi/ginkgo/v2 v2.12.1/go.mod h1:TE309ZR8s5FsKKpuB1YAQYBzCaAfUgatB/xlT/ETL/o= github.com/onsi/gomega v1.27.10 h1:naR28SdDFlqrG6kScpT8VWpu1xWY5nJRCF3XaYyBjhI= github.com/onsi/gomega v1.27.10/go.mod h1:RsS8tutOdbdgzbPtzzATp12yT7kM5I5aElG3evPbQ0M= github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= @@ -235,8 +235,8 @@ github.com/prometheus/procfs v0.10.1 h1:kYK1Va/YMlutzCGazswoHKo//tZVlFpKYh+Pymzi github.com/prometheus/procfs v0.10.1/go.mod h1:nwNm2aOCAYw8uTR/9bWRREkZFxAUcWzPHWJq+XBB/FM= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -566,8 +566,8 @@ google.golang.org/grpc v1.31.1/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= google.golang.org/grpc v1.34.0/go.mod h1:WotjhfgOW/POjDeRt8vscBtXq+2VjORFy659qA51WJ8= google.golang.org/grpc v1.35.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= -google.golang.org/grpc v1.58.1 h1:OL+Vz23DTtrrldqHK49FUOPHyY75rvFqJfXC84NYW58= -google.golang.org/grpc v1.58.1/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= +google.golang.org/grpc v1.58.2 h1:SXUpjxeVF3FKrTYQI4f4KvbGD5u2xccdYdurwowix5I= +google.golang.org/grpc v1.58.2/go.mod h1:tgX3ZQDlNJGU96V6yHh1T/JeoBQ2TXdr43YbYSsCJk0= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= diff --git a/metrics-operator/go.mod b/metrics-operator/go.mod index 47c53877b3..fd173043d5 100644 --- a/metrics-operator/go.mod +++ b/metrics-operator/go.mod @@ -8,7 +8,7 @@ require ( github.com/go-logr/logr v1.2.4 github.com/gorilla/mux v1.8.0 github.com/kelseyhightower/envconfig v1.4.0 - github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a + github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 github.com/open-feature/go-sdk v1.7.0 github.com/pkg/errors v0.9.1 github.com/prometheus/client_golang v1.16.0 @@ -77,7 +77,7 @@ require ( github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/prometheus/procfs v0.10.1 // indirect - github.com/spf13/afero v1.9.5 // indirect + github.com/spf13/afero v1.10.0 // indirect github.com/spf13/cobra v1.7.0 // indirect github.com/spf13/pflag v1.0.5 // indirect github.com/stoewer/go-strcase v1.2.0 // indirect diff --git a/metrics-operator/go.sum b/metrics-operator/go.sum index 0e60d42f55..55cbd525d8 100644 --- a/metrics-operator/go.sum +++ b/metrics-operator/go.sum @@ -240,8 +240,8 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk= github.com/kelseyhightower/envconfig v1.4.0 h1:Im6hONhd3pLkfDFsbRgu68RDNkGF1r3dvMUtDTo2cv8= github.com/kelseyhightower/envconfig v1.4.0/go.mod h1:cccZRl6mQpaq41TPp5QxidR+Sa3axMbJDNb//FQX6Gg= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a h1:lwPbbcRNWJmQWvpWoVVBXxpMv0C3YLX5O6P3yJo0b+A= -github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230922075626-6566e7dbac9a/go.mod h1:IMs51ScEWzHa5k0L7leYRNc0C/TghTHNRp+Go7o58Ko= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273 h1:wytmV4pUahfCvjNfsYTpHAjRentNjMOwaOpcAz/6qbc= +github.com/keptn/lifecycle-toolkit/klt-cert-manager v0.0.0-20230926092913-099a4573b273/go.mod h1:GjJFB+g1DuBYrOXSgF4kzR9Phb+W5t3obFt4UHqz9OM= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg= @@ -291,8 +291,8 @@ github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQD github.com/sirupsen/logrus v1.9.0 h1:trlNQbNUG3OdDrDil03MCb1H2o9nJ1x4/5LYw7byDE0= github.com/soheilhy/cmux v0.1.5 h1:jjzc5WVemNEDTLwv9tlmemhC73tI08BNOIGwBOo10Js= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spf13/afero v1.9.5 h1:stMpOSZFs//0Lv29HduCmli3GUfpFoF3Y1Q/aXj/wVM= -github.com/spf13/afero v1.9.5/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= +github.com/spf13/afero v1.10.0 h1:EaGW2JJh15aKOejeuJ+wpFSHnbd7GE6Wvp3TsNhb6LY= +github.com/spf13/afero v1.10.0/go.mod h1:UBogFpq8E9Hx+xc5CNTTEpTnuHVmXDwZcZcE1eb/UhQ= github.com/spf13/cobra v1.7.0 h1:hyqWnYt1ZQShIddO5kBpj3vu05/++x6tJ6dg8EC572I= github.com/spf13/cobra v1.7.0/go.mod h1:uLxZILRyS/50WlhOIKD7W6V5bgeIt+4sICxh6uRMrb0= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= From 1ca1af02806aec3e3176e144a2ee568c6cece614 Mon Sep 17 00:00:00 2001 From: Florian Bacher Date: Wed, 27 Sep 2023 12:46:46 +0200 Subject: [PATCH 21/27] feat(metrics-operator): add support for user-friendly duration string for specifying time frame (#2147) Signed-off-by: Florian Bacher --- .../invalid-analysis-1.yaml~merged | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged diff --git a/test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged b/test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged new file mode 100644 index 0000000000..c4ee6eb537 --- /dev/null +++ b/test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged @@ -0,0 +1,24 @@ +apiVersion: metrics.keptn.sh/v1alpha3 +kind: Analysis +metadata: + name: invalid-analysis-1 +spec: + timeframe: + # using 'recent' and 'from'/'to' at the same time + recent: 5m + from: 2023-05-05T05:05:05Z + to: 2023-05-05T10:10:10Z + args: + project: my-project + stage: dev + service: svc1 +<<<<<<< HEAD + foo: bar # can be any key/value pair; NOT only project/stage/service + analysisDefinition: + name: ed-my-proj-dev-svc1 +======= + nodename: test # can be any key/value pair; NOT only project/stage/service + analysisDefinition: + name: ed-my-proj-dev-svc1 + namespace: keptn-lifecycle-toolkit-system +>>>>>>> feat(metrics-operator): add support for user-friendly duration string for specifying time frame (#2147) From e1b89a3d3ef51b6988da557d119af4bcda0f7d62 Mon Sep 17 00:00:00 2001 From: realanna Date: Thu, 21 Sep 2023 12:59:34 +0200 Subject: [PATCH 22/27] feat: add interface Signed-off-by: realanna fix: link Signed-off-by: realanna Update metrics-operator/controllers/common/providers/prometheus/prometheus.go Co-authored-by: Florian Bacher Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> Update metrics-operator/controllers/common/providers/prometheus/common.go Co-authored-by: Florian Bacher Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> fix: embed getter in the struct Signed-off-by: realanna Update metrics-operator/controllers/common/providers/prometheus/prometheus.go Co-authored-by: odubajDT <93584209+odubajDT@users.noreply.github.com> Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> fix: add unit test to make ondrej happy Signed-off-by: realanna fix: removed skip lint Signed-off-by: realanna fix: removed dd special func for secrets Signed-off-by: realanna fix: useless test setup Signed-off-by: realanna feat(metrics-operator): add unit test Signed-off-by: realanna feat(metrics-operator): add unit test Signed-off-by: realanna feat(metrics-operator): add integration test Signed-off-by: realanna feat(metrics-operator): lint Signed-off-by: realanna feat(metrics-operator): lint Signed-off-by: realanna feat(metrics-operator): revert change to ddprovider Signed-off-by: realanna feat(metrics-operator): fixed test Signed-off-by: realanna feat(metrics-operator): use roundtripper from prometheus api Signed-off-by: realanna feat(metrics-operator): add test of header Signed-off-by: realanna feat(metrics-operator): add unit tests Signed-off-by: realanna feat(metrics-operator): first iteration on prometheus auth Signed-off-by: realanna --- .../common/providers/prometheus/common.go | 15 +++- .../providers/prometheus/common_test.go | 3 +- .../prometheus/fake/roundtripper_mock.go | 86 +++++++++++++++++++ .../common/providers/prometheus/prometheus.go | 15 ++-- .../providers/prometheus/prometheus_test.go | 30 ++++--- .../controllers/common/providers/provider.go | 6 +- 6 files changed, 129 insertions(+), 26 deletions(-) create mode 100644 metrics-operator/controllers/common/providers/prometheus/fake/roundtripper_mock.go diff --git a/metrics-operator/controllers/common/providers/prometheus/common.go b/metrics-operator/controllers/common/providers/prometheus/common.go index 9a01625d11..22c32cdd8b 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common.go +++ b/metrics-operator/controllers/common/providers/prometheus/common.go @@ -24,7 +24,15 @@ type SecretData struct { Password config.Secret `json:"password"` } -func GetRoundtripper(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { +//go:generate moq -pkg fake -skip-ensure -out ./fake/roundtripper_mock.go . IRoundTripper +type IRoundTripper interface { + GetRoundTripper(context.Context, metricsapi.KeptnMetricsProvider, client.Client) (http.RoundTripper, error) +} + +type RoundTripperRetriever struct { +} + +func (r RoundTripperRetriever) GetRoundTripper(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { secret, err := getPrometheusSecret(ctx, provider, k8sClient) if err != nil { if errors.Is(err, ErrSecretKeyRefNotDefined) { @@ -33,7 +41,6 @@ func GetRoundtripper(ctx context.Context, provider metricsapi.KeptnMetricsProvid return nil, err } return config.NewBasicAuthRoundTripper(secret.User, secret.Password, "", promapi.DefaultRoundTripper), nil - } func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (*SecretData, error) { @@ -46,8 +53,8 @@ func getPrometheusSecret(ctx context.Context, provider metricsapi.KeptnMetricsPr } var secretData SecretData - user, ok := secret.Data[userName] - pw, yes := secret.Data[password] + user, ok := secret.Data[secretKeyUserName] + pw, yes := secret.Data[secretKeyPassword] if !ok || !yes { return nil, ErrInvalidSecretFormat } diff --git a/metrics-operator/controllers/common/providers/prometheus/common_test.go b/metrics-operator/controllers/common/providers/prometheus/common_test.go index 9041ffa10f..9eeacdfbed 100644 --- a/metrics-operator/controllers/common/providers/prometheus/common_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/common_test.go @@ -172,9 +172,10 @@ func Test_GetRoundtripper(t *testing.T) { errorStr: "not found", }, } + for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - got, err := GetRoundtripper(context.TODO(), tt.provider, tt.k8sClient) + got, err := RoundTripperRetriever{}.GetRoundTripper(context.TODO(), tt.provider, tt.k8sClient) t.Log(err) if (err != nil) != tt.wantErr { t.Errorf("getRoundtripper() error = %v, wantErr %v", err, tt.wantErr) diff --git a/metrics-operator/controllers/common/providers/prometheus/fake/roundtripper_mock.go b/metrics-operator/controllers/common/providers/prometheus/fake/roundtripper_mock.go new file mode 100644 index 0000000000..3fb5251052 --- /dev/null +++ b/metrics-operator/controllers/common/providers/prometheus/fake/roundtripper_mock.go @@ -0,0 +1,86 @@ +// Code generated by moq; DO NOT EDIT. +// github.com/matryer/moq + +package fake + +import ( + "context" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" + "net/http" + "sigs.k8s.io/controller-runtime/pkg/client" + "sync" +) + +// IRoundTripperMock is a mock implementation of prometheus.IRoundTripper. +// +// func TestSomethingThatUsesIRoundTripper(t *testing.T) { +// +// // make and configure a mocked prometheus.IRoundTripper +// mockedIRoundTripper := &IRoundTripperMock{ +// GetRoundTripperFunc: func(contextMoqParam context.Context, keptnMetricsProvider metricsapi.KeptnMetricsProvider, clientMoqParam client.Client) (http.RoundTripper, error) { +// panic("mock out the GetRoundTripper method") +// }, +// } +// +// // use mockedIRoundTripper in code that requires prometheus.IRoundTripper +// // and then make assertions. +// +// } +type IRoundTripperMock struct { + // GetRoundTripperFunc mocks the GetRoundTripper method. + GetRoundTripperFunc func(contextMoqParam context.Context, keptnMetricsProvider metricsapi.KeptnMetricsProvider, clientMoqParam client.Client) (http.RoundTripper, error) + + // calls tracks calls to the methods. + calls struct { + // GetRoundTripper holds details about calls to the GetRoundTripper method. + GetRoundTripper []struct { + // ContextMoqParam is the contextMoqParam argument value. + ContextMoqParam context.Context + // KeptnMetricsProvider is the keptnMetricsProvider argument value. + KeptnMetricsProvider metricsapi.KeptnMetricsProvider + // ClientMoqParam is the clientMoqParam argument value. + ClientMoqParam client.Client + } + } + lockGetRoundTripper sync.RWMutex +} + +// GetRoundTripper calls GetRoundTripperFunc. +func (mock *IRoundTripperMock) GetRoundTripper(contextMoqParam context.Context, keptnMetricsProvider metricsapi.KeptnMetricsProvider, clientMoqParam client.Client) (http.RoundTripper, error) { + if mock.GetRoundTripperFunc == nil { + panic("IRoundTripperMock.GetRoundTripperFunc: method is nil but IRoundTripper.GetRoundTripper was just called") + } + callInfo := struct { + ContextMoqParam context.Context + KeptnMetricsProvider metricsapi.KeptnMetricsProvider + ClientMoqParam client.Client + }{ + ContextMoqParam: contextMoqParam, + KeptnMetricsProvider: keptnMetricsProvider, + ClientMoqParam: clientMoqParam, + } + mock.lockGetRoundTripper.Lock() + mock.calls.GetRoundTripper = append(mock.calls.GetRoundTripper, callInfo) + mock.lockGetRoundTripper.Unlock() + return mock.GetRoundTripperFunc(contextMoqParam, keptnMetricsProvider, clientMoqParam) +} + +// GetRoundTripperCalls gets all the calls that were made to GetRoundTripper. +// Check the length with: +// +// len(mockedIRoundTripper.GetRoundTripperCalls()) +func (mock *IRoundTripperMock) GetRoundTripperCalls() []struct { + ContextMoqParam context.Context + KeptnMetricsProvider metricsapi.KeptnMetricsProvider + ClientMoqParam client.Client +} { + var calls []struct { + ContextMoqParam context.Context + KeptnMetricsProvider metricsapi.KeptnMetricsProvider + ClientMoqParam client.Client + } + mock.lockGetRoundTripper.RLock() + calls = mock.calls.GetRoundTripper + mock.lockGetRoundTripper.RUnlock() + return calls +} diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus.go b/metrics-operator/controllers/common/providers/prometheus/prometheus.go index 2647ae459b..3639b3690e 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus.go @@ -4,7 +4,6 @@ import ( "context" "encoding/json" "fmt" - "net/http" "time" "github.com/go-logr/logr" @@ -19,12 +18,18 @@ var errCouldNotCast = fmt.Errorf("could not cast result") var errNoValues = fmt.Errorf("no values in query result") var errTooManyValues = fmt.Errorf("too many values in query result") -type RoundtripGetter func(context.Context, metricsapi.KeptnMetricsProvider, client.Client) (http.RoundTripper, error) - type KeptnPrometheusProvider struct { Log logr.Logger K8sClient client.Client - Getter RountripGetter + Getter IRoundTripper +} + +func NewPrometheusProvider(log logr.Logger, k8sClient client.Client) *KeptnPrometheusProvider { + return &KeptnPrometheusProvider{ + K8sClient: k8sClient, + Log: log, + Getter: RoundTripperRetriever{}, + } } func (r *KeptnPrometheusProvider) FetchAnalysisValue(ctx context.Context, query string, analysis metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { @@ -115,7 +120,7 @@ func (r *KeptnPrometheusProvider) EvaluateQueryForStep(ctx context.Context, metr } func (r *KeptnPrometheusProvider) setupApi(ctx context.Context, provider metricsapi.KeptnMetricsProvider) (prometheus.API, error) { - rt, err := r.Getter(ctx, provider, r.K8sClient) + rt, err := r.Getter.GetRoundTripper(ctx, provider, r.K8sClient) if err != nil { return nil, err } diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index 93732c4aec..efb87bd6b6 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -14,6 +14,7 @@ import ( metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" + fakeprom "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/providers/prometheus/fake" promapi "github.com/prometheus/client_golang/api" "github.com/prometheus/common/model" "github.com/stretchr/testify/require" @@ -193,7 +194,7 @@ func Test_prometheus(t *testing.T) { kpp := KeptnPrometheusProvider{ K8sClient: fclient, Log: ctrl.Log.WithName("testytest"), - Getter: GetRoundtripper, + Getter: RoundTripperRetriever{}, } p := metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ @@ -357,8 +358,8 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { Namespace: "", }, Data: map[string][]byte{ - userName: []byte(userName), - password: []byte(password), + secretKeyUserName: []byte(secretKeyUserName), + secretKeyPassword: []byte(secretKeyPassword), }, } fclient := fake.NewClient(&secret) @@ -366,7 +367,7 @@ func TestFetchAnalysisValueWithAuth(t *testing.T) { provider := KeptnPrometheusProvider{ K8sClient: fclient, Log: ctrl.Log.WithName("testytest"), - Getter: GetRoundtripper, + Getter: RoundTripperRetriever{}, } // Prepare the analysis spec @@ -398,14 +399,16 @@ func TestKeptnPrometheusProvider_setupApi(t *testing.T) { var b byte = 0x7f tests := []struct { name string - getter RountripGetter + getter IRoundTripper provider metricsapi.KeptnMetricsProvider expectedError string }{ { name: "Successful setup", - getter: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { - return promapi.DefaultRoundTripper, nil + getter: &fakeprom.IRoundTripperMock{ + GetRoundTripperFunc: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + return promapi.DefaultRoundTripper, nil + }, }, provider: metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ @@ -416,9 +419,12 @@ func TestKeptnPrometheusProvider_setupApi(t *testing.T) { }, { name: "Error in getter", - getter: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { - return nil, errors.New("bad") + getter: &fakeprom.IRoundTripperMock{ + GetRoundTripperFunc: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + return nil, errors.New("bad") + }, }, + provider: metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ TargetServer: "http://example.com", @@ -428,8 +434,10 @@ func TestKeptnPrometheusProvider_setupApi(t *testing.T) { }, { name: "Error in NewClient", - getter: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { - return promapi.DefaultRoundTripper, nil + getter: &fakeprom.IRoundTripperMock{ + GetRoundTripperFunc: func(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (http.RoundTripper, error) { + return promapi.DefaultRoundTripper, nil + }, }, provider: metricsapi.KeptnMetricsProvider{ Spec: metricsapi.KeptnMetricsProviderSpec{ diff --git a/metrics-operator/controllers/common/providers/provider.go b/metrics-operator/controllers/common/providers/provider.go index 69af3741a2..91bb1986b2 100644 --- a/metrics-operator/controllers/common/providers/provider.go +++ b/metrics-operator/controllers/common/providers/provider.go @@ -30,11 +30,7 @@ func NewProvider(providerType string, log logr.Logger, k8sClient client.Client) switch strings.ToLower(providerType) { case PrometheusProviderType: - return &prometheus.KeptnPrometheusProvider{ - K8sClient: k8sClient, - Log: log, - Getter: prometheus.GetRoundtripper, - }, nil + return prometheus.NewPrometheusProvider(log, k8sClient), nil case DynatraceProviderType: return &dynatrace.KeptnDynatraceProvider{ HttpClient: http.Client{}, From 16954d3934e3c142d69dc84c0afc958b555b88cb Mon Sep 17 00:00:00 2001 From: realanna Date: Wed, 27 Sep 2023 14:13:21 +0200 Subject: [PATCH 23/27] feat: add interface Signed-off-by: realanna --- .../controllers/common/providers/prometheus/prometheus_test.go | 2 -- 1 file changed, 2 deletions(-) diff --git a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go index efb87bd6b6..cdc742a155 100644 --- a/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go +++ b/metrics-operator/controllers/common/providers/prometheus/prometheus_test.go @@ -10,8 +10,6 @@ import ( "testing" "time" - "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" - metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1alpha3" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" fakeprom "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/providers/prometheus/fake" From 40fa7d216bfdaad7c4c1b483b577a7048f0d5da1 Mon Sep 17 00:00:00 2001 From: realanna Date: Wed, 27 Sep 2023 14:16:02 +0200 Subject: [PATCH 24/27] feat: add interface Signed-off-by: realanna --- .../invalid-analysis-1.yaml~merged | 24 ------------------- 1 file changed, 24 deletions(-) delete mode 100644 test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged diff --git a/test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged b/test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged deleted file mode 100644 index c4ee6eb537..0000000000 --- a/test/testanalysis/analysis-resources/invalid-analysis-1.yaml~merged +++ /dev/null @@ -1,24 +0,0 @@ -apiVersion: metrics.keptn.sh/v1alpha3 -kind: Analysis -metadata: - name: invalid-analysis-1 -spec: - timeframe: - # using 'recent' and 'from'/'to' at the same time - recent: 5m - from: 2023-05-05T05:05:05Z - to: 2023-05-05T10:10:10Z - args: - project: my-project - stage: dev - service: svc1 -<<<<<<< HEAD - foo: bar # can be any key/value pair; NOT only project/stage/service - analysisDefinition: - name: ed-my-proj-dev-svc1 -======= - nodename: test # can be any key/value pair; NOT only project/stage/service - analysisDefinition: - name: ed-my-proj-dev-svc1 - namespace: keptn-lifecycle-toolkit-system ->>>>>>> feat(metrics-operator): add support for user-friendly duration string for specifying time frame (#2147) From cff4bb215bf2edaf7bf5ee6055609294234ba444 Mon Sep 17 00:00:00 2001 From: realanna Date: Wed, 27 Sep 2023 14:18:41 +0200 Subject: [PATCH 25/27] feat: add fix for secrets Signed-off-by: realanna --- .../api/v1alpha3/keptnmetricsprovider_types.go | 11 +++++++++++ .../controllers/common/providers/dynatrace/common.go | 2 +- test/prometheus/secret.yaml | 2 +- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go b/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go index db9f84a842..afbd2d0654 100644 --- a/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go +++ b/metrics-operator/api/v1alpha3/keptnmetricsprovider_types.go @@ -75,6 +75,17 @@ func (p *KeptnMetricsProvider) HasSecretDefined() bool { return true } +func (p *KeptnMetricsProvider) HasSecretKeyDefined() bool { + if p.Spec.SecretKeyRef == (corev1.SecretKeySelector{}) { + return false + } + //if the secret name exists the secret is defined + if strings.TrimSpace(p.Spec.SecretKeyRef.Key) == "" { + return false + } + return true +} + func (p *KeptnMetricsProvider) GetType() string { if p.Spec.Type != "" { return p.Spec.Type diff --git a/metrics-operator/controllers/common/providers/dynatrace/common.go b/metrics-operator/controllers/common/providers/dynatrace/common.go index 08dc835eae..dee0b8fa94 100644 --- a/metrics-operator/controllers/common/providers/dynatrace/common.go +++ b/metrics-operator/controllers/common/providers/dynatrace/common.go @@ -25,7 +25,7 @@ type Error struct { } func getDTSecret(ctx context.Context, provider metricsapi.KeptnMetricsProvider, k8sClient client.Client) (string, error) { - if !provider.HasSecretDefined() { + if !provider.HasSecretDefined() || !provider.HasSecretKeyDefined() { return "", ErrSecretKeyRefNotDefined } dtCredsSecret := &corev1.Secret{} diff --git a/test/prometheus/secret.yaml b/test/prometheus/secret.yaml index fa0dd897c0..0c85e12599 100644 --- a/test/prometheus/secret.yaml +++ b/test/prometheus/secret.yaml @@ -5,4 +5,4 @@ metadata: data: password: dG9vcg== # toor user: YWRtaW4= # admin -type: Opaque \ No newline at end of file +type: Opaque From 9d4b69f68ead80ccba95f6856e0d6a403de6f23c Mon Sep 17 00:00:00 2001 From: RealAnna <89971034+RealAnna@users.noreply.github.com> Date: Wed, 27 Sep 2023 15:53:52 +0200 Subject: [PATCH 26/27] Update lifecycle-operator/go.mod Co-authored-by: odubajDT <93584209+odubajDT@users.noreply.github.com> Signed-off-by: RealAnna <89971034+RealAnna@users.noreply.github.com> --- lifecycle-operator/go.mod | 1 - 1 file changed, 1 deletion(-) diff --git a/lifecycle-operator/go.mod b/lifecycle-operator/go.mod index a45ca58a89..3ff1723412 100644 --- a/lifecycle-operator/go.mod +++ b/lifecycle-operator/go.mod @@ -25,7 +25,6 @@ require ( go.opentelemetry.io/otel/sdk/metric v0.41.0 go.opentelemetry.io/otel/trace v1.18.0 golang.org/x/net v0.15.0 - gomodules.xyz/jsonpatch/v2 v2.4.0 google.golang.org/grpc v1.58.2 k8s.io/api v0.28.2 k8s.io/apiextensions-apiserver v0.28.2 From 3f2f736b848eda50981f456c02675f9c018f6297 Mon Sep 17 00:00:00 2001 From: realanna Date: Wed, 27 Sep 2023 16:25:00 +0200 Subject: [PATCH 27/27] feat: remove mod error Signed-off-by: realanna --- lifecycle-operator/go.mod | 1 + 1 file changed, 1 insertion(+) diff --git a/lifecycle-operator/go.mod b/lifecycle-operator/go.mod index 3ff1723412..d4991cc604 100644 --- a/lifecycle-operator/go.mod +++ b/lifecycle-operator/go.mod @@ -83,6 +83,7 @@ require ( golang.org/x/text v0.13.0 // indirect golang.org/x/time v0.3.0 // indirect golang.org/x/tools v0.12.0 // indirect + gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/api v0.0.0-20230711160842-782d3b101e98 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230711160842-782d3b101e98 // indirect