Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ To learn more about active deprecations, we recommend checking [GitHub Discussio

- **General**: Add CRD-level validation markers (Minimum, MinLength, MinItems, Enum) for ScaledObject, ScaledJob, ScaleTriggers, and TriggerAuthentication API types ([#7533](https://github.com/kedacore/keda/pull/7533))
- **Elasticsearch Scaler**: Add HTTP status check for Elasticsearch errors ([#7480](https://github.com/kedacore/keda/pull/7480))
- **Metrics API Scaler**: Add custom HTTP client timeout ([#7549](https://github.com/kedacore/keda/issues/7549))

### Fixes

Expand Down
17 changes: 16 additions & 1 deletion pkg/scalers/metrics_api_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (
"strconv"
"strings"
"sync"
"time"

"github.com/go-logr/logr"
"github.com/prometheus/common/expfmt"
Expand Down Expand Up @@ -48,6 +49,7 @@ type metricsAPIScalerMetadata struct {
UnsafeSsl bool `keda:"name=unsafeSsl,order=triggerMetadata,default=false"`
AggregateFromKubeServiceEndpoints bool `keda:"name=aggregateFromKubeServiceEndpoints,order=triggerMetadata,default=false"`
AggregationType AggregationType `keda:"name=aggregationType,order=triggerMetadata,default=average,enum=average;sum;max;min"`
Timeout time.Duration `keda:"name=timeout, order=triggerMetadata, optional"`
// Authentication parameters for connecting to the metrics API
MetricsAPIAuth *authentication.Config `keda:"optional"`

Expand Down Expand Up @@ -93,7 +95,13 @@ func NewMetricsAPIScaler(config *scalersconfig.ScalerConfig, kubeClient client.C
return nil, fmt.Errorf("error parsing metric API metadata: %w", err)
}

httpClient := kedautil.CreateHTTPClient(config.GlobalHTTPTimeout, meta.UnsafeSsl)
// handle HTTP client timeout
httpClientTimeout := config.GlobalHTTPTimeout
if meta.Timeout > 0 {
httpClientTimeout = time.Duration(meta.Timeout) * time.Millisecond
}

httpClient := kedautil.CreateHTTPClient(httpClientTimeout, meta.UnsafeSsl)

// Handle TLS configuration with authentication config
if meta.MetricsAPIAuth != nil && meta.MetricsAPIAuth.EnabledTLS() {
Expand Down Expand Up @@ -126,6 +134,13 @@ func parseMetricsAPIMetadata(config *scalersconfig.ScalerConfig) (*metricsAPISca
return nil, fmt.Errorf("no targetValue given in metadata")
}

// Resolve HTTP client timeout
meta.Timeout = config.GlobalHTTPTimeout
// validate the timeout
if meta.Timeout < 0 {
return nil, fmt.Errorf("timeout must be greater than 0: %d", meta.Timeout)
}

return meta, nil
}

Expand Down
6 changes: 6 additions & 0 deletions pkg/scalers/metrics_api_scaler_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@ var testMetricsAPIMetadata = []metricsAPIMetadataTestData{
{metadata: map[string]string{"valueLocation": "metric", "targetValue": "aa"}, raisesError: true},
// Missing targetValue
{metadata: map[string]string{"url": "http://dummy:1230/api/v1/", "valueLocation": "metric"}, raisesError: true},
// Valid HTTP timeout
{metadata: map[string]string{"url": "http://dummy:1230/api/v1/", "valueLocation": "metric", "targetValue": "42", "timeout": "1000"}, raisesError: false},
// Invalid - negative - HTTP timeout
{metadata: map[string]string{"url": "http://dummy:1230/api/v1/", "valueLocation": "metric", "targetValue": "42", "timeout": "-1"}, raisesError: true},
// Invalid - not a number - HTTP timeout
{metadata: map[string]string{"url": "http://dummy:1230/api/v1/", "valueLocation": "metric", "targetValue": "42", "timeout": "a"}, raisesError: true},
}

type metricAPIAuthMetadataTestData struct {
Expand Down
Loading