diff --git a/.github/scripts/.helm-tests/Openshift/result.yaml b/.github/scripts/.helm-tests/Openshift/result.yaml index 319c1178ac..29ea5d3a94 100644 --- a/.github/scripts/.helm-tests/Openshift/result.yaml +++ b/.github/scripts/.helm-tests/Openshift/result.yaml @@ -13587,6 +13587,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/.github/scripts/.helm-tests/default/result.yaml b/.github/scripts/.helm-tests/default/result.yaml index 1f23c3d07d..34db20df9f 100644 --- a/.github/scripts/.helm-tests/default/result.yaml +++ b/.github/scripts/.helm-tests/default/result.yaml @@ -13587,6 +13587,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/.github/scripts/.helm-tests/local-global-precedence/result.yaml b/.github/scripts/.helm-tests/local-global-precedence/result.yaml index 7a6526f502..a1640d15bd 100644 --- a/.github/scripts/.helm-tests/local-global-precedence/result.yaml +++ b/.github/scripts/.helm-tests/local-global-precedence/result.yaml @@ -13723,6 +13723,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/.github/scripts/.helm-tests/metrics-only-with-apiservice-disabled/result.yaml b/.github/scripts/.helm-tests/metrics-only-with-apiservice-disabled/result.yaml index ced5c8204a..3db85e9937 100644 --- a/.github/scripts/.helm-tests/metrics-only-with-apiservice-disabled/result.yaml +++ b/.github/scripts/.helm-tests/metrics-only-with-apiservice-disabled/result.yaml @@ -2562,6 +2562,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/.github/scripts/.helm-tests/metrics-only/result.yaml b/.github/scripts/.helm-tests/metrics-only/result.yaml index c1a45c4d9d..e279149345 100644 --- a/.github/scripts/.helm-tests/metrics-only/result.yaml +++ b/.github/scripts/.helm-tests/metrics-only/result.yaml @@ -2562,6 +2562,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/.github/scripts/.helm-tests/metrics-with-certs/result.yaml b/.github/scripts/.helm-tests/metrics-with-certs/result.yaml index 845cc35977..ad480d19f4 100644 --- a/.github/scripts/.helm-tests/metrics-with-certs/result.yaml +++ b/.github/scripts/.helm-tests/metrics-with-certs/result.yaml @@ -2577,6 +2577,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/docs/docs/reference/api-reference/metrics/v1/index.md b/docs/docs/reference/api-reference/metrics/v1/index.md index 498ebc7f70..049c78b7db 100644 --- a/docs/docs/reference/api-reference/metrics/v1/index.md +++ b/docs/docs/reference/api-reference/metrics/v1/index.md @@ -376,6 +376,7 @@ _Appears in:_ | `type` _string_ | Type represents the provider type. This can be one of cortex, datadog, dql, dynatrace, prometheus or thanos. || x | Optional: {}
Pattern: `cortex|datadog|dql|dynatrace|prometheus|thanos`
| | `targetServer` _string_ | TargetServer defines URL (including port and protocol) at which the metrics provider is reachable. || x | | | `secretKeyRef` _[SecretKeySelector](https://kubernetes.io/docs/reference/generated/kubernetes-api/v1.28/#secretkeyselector-v1-core)_ | SecretKeyRef defines an optional secret for access credentials to the metrics provider. || ✓ | Optional: {}
| +| `insecureSkipTlsVerify` _boolean_ | InsecureSkipTlsVerify skips verification of the tls certificate when fetching metrics |false| ✓ | | #### ObjectReference diff --git a/metrics-operator/api/v1/keptnmetricsprovider_types.go b/metrics-operator/api/v1/keptnmetricsprovider_types.go index ad2537cd48..48fbaf08b0 100644 --- a/metrics-operator/api/v1/keptnmetricsprovider_types.go +++ b/metrics-operator/api/v1/keptnmetricsprovider_types.go @@ -35,6 +35,10 @@ type KeptnMetricsProviderSpec struct { // SecretKeyRef defines an optional secret for access credentials to the metrics provider. // +optional SecretKeyRef corev1.SecretKeySelector `json:"secretKeyRef,omitempty"` + // InsecureSkipTlsVerify skips verification of the tls certificate when fetching metrics + // +kubebuilder:default:=false + // +optional + InsecureSkipTlsVerify bool `json:"insecureSkipTlsVerify,omitempty"` } // +kubebuilder:object:root=true diff --git a/metrics-operator/chart/templates/keptnmetricsprovider-crd.yaml b/metrics-operator/chart/templates/keptnmetricsprovider-crd.yaml index 4ce5b9db54..9be49d5680 100644 --- a/metrics-operator/chart/templates/keptnmetricsprovider-crd.yaml +++ b/metrics-operator/chart/templates/keptnmetricsprovider-crd.yaml @@ -50,6 +50,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/metrics-operator/config/crd/bases/metrics.keptn.sh_keptnmetricsproviders.yaml b/metrics-operator/config/crd/bases/metrics.keptn.sh_keptnmetricsproviders.yaml index 179e7c2c09..5541e9366c 100644 --- a/metrics-operator/config/crd/bases/metrics.keptn.sh_keptnmetricsproviders.yaml +++ b/metrics-operator/config/crd/bases/metrics.keptn.sh_keptnmetricsproviders.yaml @@ -42,6 +42,11 @@ spec: spec: description: KeptnMetricsProviderSpec defines the desired state of KeptnMetricsProvider properties: + insecureSkipTlsVerify: + default: false + description: InsecureSkipTlsVerify skips verification of the tls certificate + when fetching metrics + type: boolean secretKeyRef: description: SecretKeyRef defines an optional secret for access credentials to the metrics provider. diff --git a/metrics-operator/controllers/analysis/fake/evaluator_mock.go b/metrics-operator/controllers/analysis/fake/evaluator_mock.go index d5ff3a5add..dd73ebbf22 100644 --- a/metrics-operator/controllers/analysis/fake/evaluator_mock.go +++ b/metrics-operator/controllers/analysis/fake/evaluator_mock.go @@ -6,6 +6,7 @@ package fake import ( "context" metricstypes "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/analysis/types" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1" "sync" ) @@ -15,7 +16,7 @@ import ( // // // make and configure a mocked analysis.IObjectivesEvaluator // mockedIObjectivesEvaluator := &IObjectivesEvaluatorMock{ -// EvaluateFunc: func(ctx context.Context, providerType string, obj chan metricstypes.ProviderRequest) { +// EvaluateFunc: func(ctx context.Context, metricsProvider *metricsapi.KeptnMetricsProvider, obj chan metricstypes.ProviderRequest) { // panic("mock out the Evaluate method") // }, // } @@ -26,7 +27,7 @@ import ( // } type IObjectivesEvaluatorMock struct { // EvaluateFunc mocks the Evaluate method. - EvaluateFunc func(ctx context.Context, providerType string, obj chan metricstypes.ProviderRequest) + EvaluateFunc func(ctx context.Context, metricsProvider *metricsapi.KeptnMetricsProvider, obj chan metricstypes.ProviderRequest) // calls tracks calls to the methods. calls struct { @@ -35,7 +36,7 @@ type IObjectivesEvaluatorMock struct { // Ctx is the ctx argument value. Ctx context.Context // ProviderType is the providerType argument value. - ProviderType string + metricsProvider *metricsapi.KeptnMetricsProvider // Obj is the obj argument value. Obj chan metricstypes.ProviderRequest } @@ -44,23 +45,23 @@ type IObjectivesEvaluatorMock struct { } // Evaluate calls EvaluateFunc. -func (mock *IObjectivesEvaluatorMock) Evaluate(ctx context.Context, providerType string, obj chan metricstypes.ProviderRequest) { +func (mock *IObjectivesEvaluatorMock) Evaluate(ctx context.Context, metricsProvider *metricsapi.KeptnMetricsProvider, obj chan metricstypes.ProviderRequest) { if mock.EvaluateFunc == nil { panic("IObjectivesEvaluatorMock.EvaluateFunc: method is nil but IObjectivesEvaluator.Evaluate was just called") } callInfo := struct { Ctx context.Context - ProviderType string + metricsProvider *metricsapi.KeptnMetricsProvider Obj chan metricstypes.ProviderRequest }{ Ctx: ctx, - ProviderType: providerType, + metricsProvider: metricsProvider, Obj: obj, } mock.lockEvaluate.Lock() mock.calls.Evaluate = append(mock.calls.Evaluate, callInfo) mock.lockEvaluate.Unlock() - mock.EvaluateFunc(ctx, providerType, obj) + mock.EvaluateFunc(ctx, metricsProvider, obj) } // EvaluateCalls gets all the calls that were made to Evaluate. @@ -69,12 +70,12 @@ func (mock *IObjectivesEvaluatorMock) Evaluate(ctx context.Context, providerType // len(mockedIObjectivesEvaluator.EvaluateCalls()) func (mock *IObjectivesEvaluatorMock) EvaluateCalls() []struct { Ctx context.Context - ProviderType string + metricsProvider *metricsapi.KeptnMetricsProvider Obj chan metricstypes.ProviderRequest } { var calls []struct { Ctx context.Context - ProviderType string + metricsProvider *metricsapi.KeptnMetricsProvider Obj chan metricstypes.ProviderRequest } mock.lockEvaluate.RLock() diff --git a/metrics-operator/controllers/analysis/objectives_evaluator.go b/metrics-operator/controllers/analysis/objectives_evaluator.go index fe2409b2ab..a5d0da4f72 100644 --- a/metrics-operator/controllers/analysis/objectives_evaluator.go +++ b/metrics-operator/controllers/analysis/objectives_evaluator.go @@ -11,7 +11,7 @@ import ( //go:generate moq -pkg fake -skip-ensure -out ./fake/evaluator_mock.go . IObjectivesEvaluator type IObjectivesEvaluator interface { - Evaluate(ctx context.Context, providerType string, obj chan metricstypes.ProviderRequest) + Evaluate(ctx context.Context, metricsProvider *metricsapi.KeptnMetricsProvider, obj chan metricstypes.ProviderRequest) } type ObjectivesEvaluator struct { @@ -23,8 +23,8 @@ type ObjectivesEvaluator struct { cancel context.CancelFunc } -func (oe ObjectivesEvaluator) Evaluate(ctx context.Context, providerType string, obj chan metricstypes.ProviderRequest) { - provider, err := oe.ProviderFactory(providerType, oe.log, oe.Client) +func (oe ObjectivesEvaluator) Evaluate(ctx context.Context, metricsProvider *metricsapi.KeptnMetricsProvider, obj chan metricstypes.ProviderRequest) { + provider, err := oe.ProviderFactory(metricsProvider, oe.log, oe.Client) if err != nil { oe.log.Error(err, "Failed to get the correct Provider") oe.cancel() @@ -44,7 +44,7 @@ func (oe ObjectivesEvaluator) Evaluate(ctx context.Context, providerType string, Value: value, ErrMsg: strErr, } - oe.log.Info("provider", "id:", providerType, "finished job:", o.Objective.AnalysisValueTemplateRef.Name, "result:", result) + oe.log.Info("provider", "id:", metricsProvider.Spec.Type, "finished job:", o.Objective.AnalysisValueTemplateRef.Name, "result:", result) oe.results <- result } } diff --git a/metrics-operator/controllers/analysis/objectives_evaluator_test.go b/metrics-operator/controllers/analysis/objectives_evaluator_test.go index 856e994e69..91d002304a 100644 --- a/metrics-operator/controllers/analysis/objectives_evaluator_test.go +++ b/metrics-operator/controllers/analysis/objectives_evaluator_test.go @@ -20,15 +20,13 @@ func TestEvaluate(t *testing.T) { // Define test cases testCases := []struct { name string - providerType string mockProvider providers.KeptnSLIProvider providerRequest metricstypes.ProviderRequest expectedResult metricsapi.ProviderResult expectedError string }{ { - name: "SuccessfulEvaluation", - providerType: "mockProvider", + name: "SuccessfulEvaluation", mockProvider: &fake2.KeptnSLIProviderMock{ FetchAnalysisValueFunc: func(ctx context.Context, query string, spec metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { return "10", nil @@ -56,8 +54,7 @@ func TestEvaluate(t *testing.T) { expectedError: "", }, { - name: "FailedEvaluation", - providerType: "mockProvider", + name: "FailedEvaluation", mockProvider: &fake2.KeptnSLIProviderMock{ FetchAnalysisValueFunc: func(ctx context.Context, query string, spec metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) { return "", fmt.Errorf("something bad") @@ -88,7 +85,7 @@ func TestEvaluate(t *testing.T) { for _, tc := range testCases { t.Run(tc.name, func(t *testing.T) { - mockProviderFactory := func(providerType string, log logr.Logger, client client.Client) (providers.KeptnSLIProvider, error) { + mockProviderFactory := func(metricsProvider *metricsapi.KeptnMetricsProvider, log logr.Logger, client client.Client) (providers.KeptnSLIProvider, error) { // Define your mock provider implementation return tc.mockProvider, nil } @@ -115,7 +112,7 @@ func TestEvaluate(t *testing.T) { objChan <- tc.providerRequest close(objChan) }() - objectivesEvaluator.Evaluate(ctx, tc.providerType, objChan) + objectivesEvaluator.Evaluate(ctx, tc.providerRequest.Provider, objChan) close(objectivesEvaluator.results) result := <-objectivesEvaluator.results diff --git a/metrics-operator/controllers/analysis/provider_selector.go b/metrics-operator/controllers/analysis/provider_selector.go index 84efc30ddd..4fc204849e 100644 --- a/metrics-operator/controllers/analysis/provider_selector.go +++ b/metrics-operator/controllers/analysis/provider_selector.go @@ -39,7 +39,12 @@ func (ps ProvidersPool) StartProviders(ctx context.Context, numJobs int) { for _, provider := range providers.SupportedProviders { channel := make(chan metricstypes.ProviderRequest, numJobs) ps.providers[provider] = channel - go ps.Evaluate(ctx, provider, channel) + metricsProvider := &metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: provider, + }, + } + go ps.Evaluate(ctx, metricsProvider, channel) } } diff --git a/metrics-operator/controllers/analysis/provider_selector_test.go b/metrics-operator/controllers/analysis/provider_selector_test.go index d246595dd5..a067bab2d0 100644 --- a/metrics-operator/controllers/analysis/provider_selector_test.go +++ b/metrics-operator/controllers/analysis/provider_selector_test.go @@ -251,7 +251,7 @@ func TestProvidersPool_StartProviders(t *testing.T) { resChan := make(chan metricsapi.ProviderResult) // Create a mock IObjectivesEvaluator, Client, and Logger for testing mockEvaluator := &fake.IObjectivesEvaluatorMock{ - EvaluateFunc: func(ctx context.Context, providerType string, obj chan metricstypes.ProviderRequest) { + EvaluateFunc: func(ctx context.Context, metricsProvider *metricsapi.KeptnMetricsProvider, obj chan metricstypes.ProviderRequest) { }, } diff --git a/metrics-operator/controllers/common/providers/dynatrace/dynatrace_dql.go b/metrics-operator/controllers/common/providers/dynatrace/dynatrace_dql.go index 7a25276f8c..d52428108e 100644 --- a/metrics-operator/controllers/common/providers/dynatrace/dynatrace_dql.go +++ b/metrics-operator/controllers/common/providers/dynatrace/dynatrace_dql.go @@ -2,6 +2,7 @@ package dynatrace import ( "context" + "crypto/tls" "encoding/json" "fmt" "net/http" @@ -27,8 +28,9 @@ type keptnDynatraceDQLProvider struct { log logr.Logger k8sClient client.Client - dtClient dtclient.DTAPIClient - clock clock.Clock + dtClient dtclient.DTAPIClient + clock clock.Clock + insecureSkipTlsVerify bool } type DynatraceDQLHandler struct { @@ -118,6 +120,12 @@ func WithLogger(logger logr.Logger) KeptnDynatraceDQLProviderOption { } } +func WithInsecureSkipTlsVerify(skipCert bool) KeptnDynatraceDQLProviderOption { + return func(provider *keptnDynatraceDQLProvider) { + provider.insecureSkipTlsVerify = skipCert + } +} + // NewKeptnDynatraceDQLProvider creates and returns a new KeptnDynatraceDQLProvider func NewKeptnDynatraceDQLProvider(k8sClient client.Client, opts ...KeptnDynatraceDQLProviderOption) *keptnDynatraceDQLProvider { provider := &keptnDynatraceDQLProvider{ @@ -265,7 +273,15 @@ func (d *keptnDynatraceDQLProvider) ensureDTClientIsSetUp(ctx context.Context, p if err != nil { return err } - d.dtClient = dtclient.NewAPIClient(*config, dtclient.WithLogger(d.log)) + d.dtClient = dtclient.NewAPIClient(*config, dtclient.WithLogger(d.log), dtclient.WithHTTPClient( + http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: d.insecureSkipTlsVerify, + }, + }, + }, + )) } return nil } diff --git a/metrics-operator/controllers/common/providers/provider.go b/metrics-operator/controllers/common/providers/provider.go index f2164aec0f..d57dc32af8 100644 --- a/metrics-operator/controllers/common/providers/provider.go +++ b/metrics-operator/controllers/common/providers/provider.go @@ -2,6 +2,7 @@ package providers import ( "context" + "crypto/tls" "fmt" "net/http" "strings" @@ -23,32 +24,45 @@ type KeptnSLIProvider interface { FetchAnalysisValue(ctx context.Context, query string, spec metricsapi.Analysis, provider *metricsapi.KeptnMetricsProvider) (string, error) } -type ProviderFactory func(providerType string, log logr.Logger, k8sClient client.Client) (KeptnSLIProvider, error) +type ProviderFactory func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient client.Client) (KeptnSLIProvider, error) // NewProvider is a factory method that chooses the right implementation of KeptnSLIProvider -func NewProvider(providerType string, log logr.Logger, k8sClient client.Client) (KeptnSLIProvider, error) { +func NewProvider(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient client.Client) (KeptnSLIProvider, error) { - switch strings.ToLower(providerType) { + switch strings.ToLower(provider.Spec.Type) { case PrometheusProviderType, ThanosProviderType, CortexProviderType: return prometheus.NewPrometheusProvider(log, k8sClient), nil case DynatraceProviderType: return &dynatrace.KeptnDynatraceProvider{ - HttpClient: http.Client{}, - Log: log, - K8sClient: k8sClient, + HttpClient: http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: provider.Spec.InsecureSkipTlsVerify, + }, + }, + }, + Log: log, + K8sClient: k8sClient, }, nil case DynatraceDQLProviderType: return dynatrace.NewKeptnDynatraceDQLProvider( k8sClient, dynatrace.WithLogger(log), + dynatrace.WithInsecureSkipTlsVerify(provider.Spec.InsecureSkipTlsVerify), ), nil case DataDogProviderType: return &datadog.KeptnDataDogProvider{ - Log: log, - HttpClient: http.Client{}, - K8sClient: k8sClient, + Log: log, + HttpClient: http.Client{ + Transport: &http.Transport{ + TLSClientConfig: &tls.Config{ + InsecureSkipVerify: provider.Spec.InsecureSkipTlsVerify, + }, + }, + }, + K8sClient: k8sClient, }, nil default: - return nil, fmt.Errorf("provider %s not supported", providerType) + return nil, fmt.Errorf("provider %s not supported", provider.Spec.Type) } } diff --git a/metrics-operator/controllers/common/providers/provider_test.go b/metrics-operator/controllers/common/providers/provider_test.go index 08f2aac738..7288bde6ae 100644 --- a/metrics-operator/controllers/common/providers/provider_test.go +++ b/metrics-operator/controllers/common/providers/provider_test.go @@ -4,6 +4,7 @@ import ( "testing" "github.com/go-logr/logr" + metricsapi "github.com/keptn/lifecycle-toolkit/metrics-operator/api/v1" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/fake" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/providers/datadog" "github.com/keptn/lifecycle-toolkit/metrics-operator/controllers/common/providers/dynatrace" @@ -13,50 +14,78 @@ import ( func TestFactory(t *testing.T) { tests := []struct { - providerType string - provider interface{} - err bool + metricsProvider metricsapi.KeptnMetricsProvider + provider interface{} + err bool }{ { - providerType: PrometheusProviderType, - provider: &prometheus.KeptnPrometheusProvider{}, - err: false, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: PrometheusProviderType, + }, + }, + provider: &prometheus.KeptnPrometheusProvider{}, + err: false, }, { - providerType: ThanosProviderType, - provider: &prometheus.KeptnPrometheusProvider{}, - err: false, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: ThanosProviderType, + }, + }, + provider: &prometheus.KeptnPrometheusProvider{}, + err: false, }, { - providerType: CortexProviderType, - provider: &prometheus.KeptnPrometheusProvider{}, - err: false, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: CortexProviderType, + }, + }, + provider: &prometheus.KeptnPrometheusProvider{}, + err: false, }, { - providerType: DynatraceProviderType, - provider: &dynatrace.KeptnDynatraceProvider{}, - err: false, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: DynatraceProviderType, + }, + }, + provider: &dynatrace.KeptnDynatraceProvider{}, + err: false, }, { - providerType: DynatraceDQLProviderType, - provider: dynatrace.NewKeptnDynatraceDQLProvider(fake.NewClient()), - err: false, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: DynatraceDQLProviderType, + }, + }, + provider: dynatrace.NewKeptnDynatraceDQLProvider(fake.NewClient()), + err: false, }, { - providerType: DataDogProviderType, - provider: &datadog.KeptnDataDogProvider{}, - err: false, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: DataDogProviderType, + }, + }, + provider: &datadog.KeptnDataDogProvider{}, + err: false, }, { - providerType: "invalid", - provider: nil, - err: true, + metricsProvider: metricsapi.KeptnMetricsProvider{ + Spec: metricsapi.KeptnMetricsProviderSpec{ + Type: "invalid", + }, + }, + provider: nil, + err: true, }, } for _, tt := range tests { - t.Run(tt.providerType, func(t *testing.T) { - p, e := NewProvider(tt.providerType, logr.Logger{}, nil) + t.Run(tt.metricsProvider.Spec.Type, func(t *testing.T) { + p, e := NewProvider(&tt.metricsProvider, logr.Logger{}, nil) require.IsType(t, tt.provider, p) if tt.err { require.NotNil(t, e) diff --git a/metrics-operator/controllers/metrics/controller.go b/metrics-operator/controllers/metrics/controller.go index faa0151f08..0dcb2800a9 100644 --- a/metrics-operator/controllers/metrics/controller.go +++ b/metrics-operator/controllers/metrics/controller.go @@ -86,7 +86,7 @@ func (r *KeptnMetricReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{Requeue: true, RequeueAfter: diff}, nil } - metricProvider, err := r.fetchProvider(ctx, types.NamespacedName{Name: metric.Spec.Provider.Name, Namespace: metric.Namespace}) + metricsProvider, err := r.fetchProvider(ctx, types.NamespacedName{Name: metric.Spec.Provider.Name, Namespace: metric.Namespace}) if err != nil { if errors.IsNotFound(err) { r.Log.Info(err.Error()+", ignoring error since object must be deleted", "requestInfo", requestInfo) @@ -96,14 +96,14 @@ func (r *KeptnMetricReconciler) Reconcile(ctx context.Context, req ctrl.Request) return ctrl.Result{RequeueAfter: 10 * time.Second}, nil } // load the provider - provider, err2 := r.ProviderFactory(metricProvider.GetType(), r.Log, r.Client) + provider, err2 := r.ProviderFactory(metricsProvider, r.Log, r.Client) if err2 != nil { r.Log.Error(err2, "Failed to get the correct Metric Provider", "requestInfo", requestInfo) return ctrl.Result{Requeue: false}, err2 } reconcile := ctrl.Result{Requeue: true, RequeueAfter: 10 * time.Second} - value, rawValue, err := r.getResults(ctx, metric, provider, metricProvider) + value, rawValue, err := r.getResults(ctx, metric, provider, metricsProvider) reconcile = r.updateMetric(metric, value, rawValue, reconcile, err) @@ -150,22 +150,22 @@ func (r *KeptnMetricReconciler) updateMetric(metric *metricsapi.KeptnMetric, val return reconcile } -func (r *KeptnMetricReconciler) getResults(ctx context.Context, metric *metricsapi.KeptnMetric, provider providers.KeptnSLIProvider, metricProvider *metricsapi.KeptnMetricsProvider) (string, []byte, error) { +func (r *KeptnMetricReconciler) getResults(ctx context.Context, metric *metricsapi.KeptnMetric, provider providers.KeptnSLIProvider, metricsProvider *metricsapi.KeptnMetricsProvider) (string, []byte, error) { if metric.Spec.Range != nil && metric.Spec.Range.Step != "" { - return r.getStepQueryResults(ctx, metric, provider, metricProvider) + return r.getStepQueryResults(ctx, metric, provider, metricsProvider) } - return r.getQueryResults(ctx, metric, provider, metricProvider) + return r.getQueryResults(ctx, metric, provider, metricsProvider) } -func (r *KeptnMetricReconciler) getQueryResults(ctx context.Context, metric *metricsapi.KeptnMetric, provider providers.KeptnSLIProvider, metricProvider *metricsapi.KeptnMetricsProvider) (string, []byte, error) { - value, rawValue, err := provider.EvaluateQuery(ctx, *metric, *metricProvider) +func (r *KeptnMetricReconciler) getQueryResults(ctx context.Context, metric *metricsapi.KeptnMetric, provider providers.KeptnSLIProvider, metricsProvider *metricsapi.KeptnMetricsProvider) (string, []byte, error) { + value, rawValue, err := provider.EvaluateQuery(ctx, *metric, *metricsProvider) if err != nil { r.Log.Error(err, "Failed to evaluate the query", "Response from provider was:", (string)(rawValue)) return "", cupSize(rawValue), err } return value, cupSize(rawValue), nil } -func (r *KeptnMetricReconciler) getStepQueryResults(ctx context.Context, metric *metricsapi.KeptnMetric, provider providers.KeptnSLIProvider, metricProvider *metricsapi.KeptnMetricsProvider) (string, []byte, error) { - value, rawValue, err := provider.EvaluateQueryForStep(ctx, *metric, *metricProvider) +func (r *KeptnMetricReconciler) getStepQueryResults(ctx context.Context, metric *metricsapi.KeptnMetric, provider providers.KeptnSLIProvider, metricsProvider *metricsapi.KeptnMetricsProvider) (string, []byte, error) { + value, rawValue, err := provider.EvaluateQueryForStep(ctx, *metric, *metricsProvider) if err != nil { r.Log.Error(err, "Failed to evaluate the query", "Response from provider was:", (string)(rawValue)) return "", cupSize(rawValue), err diff --git a/metrics-operator/controllers/metrics/controller_test.go b/metrics-operator/controllers/metrics/controller_test.go index 27026bd9b0..ac1eab7074 100644 --- a/metrics-operator/controllers/metrics/controller_test.go +++ b/metrics-operator/controllers/metrics/controller_test.go @@ -217,7 +217,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric2"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { return nil, fmt.Errorf("provider unsupported-type not supported") }, client: fake.NewClient(metric2, unsupportedProvider), @@ -232,7 +232,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric3"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { mymock := &providersfake.KeptnSLIProviderMock{ EvaluateQueryFunc: func(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) (string, []byte, error) { return "", nil, fmt.Errorf("client_error: client error: 404") @@ -262,7 +262,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric3"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { mymock := &providersfake.KeptnSLIProviderMock{ EvaluateQueryFunc: func(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) (string, []byte, error) { return "result", []byte("result"), nil @@ -292,7 +292,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric4"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { mymock := &providersfake.KeptnSLIProviderMock{ EvaluateQueryForStepFunc: func(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) ([]string, []byte, error) { return []string{}, nil, fmt.Errorf("client_error: client error: 404") @@ -323,7 +323,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric4"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { mymock := &providersfake.KeptnSLIProviderMock{ EvaluateQueryForStepFunc: func(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) ([]string, []byte, error) { return []string{"11"}, []byte("11"), nil @@ -353,7 +353,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric5"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { mymock := &providersfake.KeptnSLIProviderMock{ EvaluateQueryForStepFunc: func(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) ([]string, []byte, error) { return []string{}, nil, fmt.Errorf("client_error: client error: 404") @@ -385,7 +385,7 @@ func TestKeptnMetricReconciler_Reconcile(t *testing.T) { req: controllerruntime.Request{ NamespacedName: types.NamespacedName{Namespace: "default", Name: "mymetric5"}, }, - providerFactory: func(providerType string, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { + providerFactory: func(provider *metricsapi.KeptnMetricsProvider, log logr.Logger, k8sClient k8sclient.Client) (providers.KeptnSLIProvider, error) { mymock := &providersfake.KeptnSLIProviderMock{ EvaluateQueryForStepFunc: func(ctx context.Context, metric metricsapi.KeptnMetric, provider metricsapi.KeptnMetricsProvider) ([]string, []byte, error) { return []string{"11"}, []byte("11"), nil