Skip to content

Commit

Permalink
Add KEDAScalersInfo to display important information
Browse files Browse the repository at this point in the history
Signed-off-by: rickbrouwer <[email protected]>
  • Loading branch information
rickbrouwer committed Nov 12, 2024
1 parent aae3192 commit c48de5d
Show file tree
Hide file tree
Showing 7 changed files with 114 additions and 8 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ New deprecation(s):
### Other

- **General**: Bump newrelic-client-go deps to 2.51.2 (latest) ([#6325](https://github.com/kedacore/keda/pull/6325))
- **General**: New eventreason KEDAScalersInfo to display important information ([#6328](https://github.com/kedacore/keda/pull/6328))


## v2.16.0
Expand Down
3 changes: 3 additions & 0 deletions pkg/eventreason/eventreason.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@ const (
// ScaledJobDeleted is for event when ScaledJob is deleted
ScaledJobDeleted = "ScaledJobDeleted"

// KEDAScalersInfo is for event when Scaler has additional info
KEDAScalersInfo = "KEDAScalerInfo"

// KEDAScalersStarted is for event when scalers watch started for ScaledObject or ScaledJob
KEDAScalersStarted = "KEDAScalersStarted"

Expand Down
21 changes: 16 additions & 5 deletions pkg/scalers/cpu_memory_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ type cpuMemoryScaler struct {
metadata cpuMemoryMetadata
resourceName v1.ResourceName
logger logr.Logger
info string
}

type cpuMemoryMetadata struct {
Expand All @@ -33,19 +34,26 @@ type cpuMemoryMetadata struct {
func NewCPUMemoryScaler(resourceName v1.ResourceName, config *scalersconfig.ScalerConfig) (Scaler, error) {
logger := InitializeLogger(config, "cpu_memory_scaler")

meta, err := parseResourceMetadata(config, logger)
meta, err := parseResourceMetadata(config)
if err != nil {
return nil, fmt.Errorf("error parsing %s metadata: %w", resourceName, err)
}

return &cpuMemoryScaler{
scaler := &cpuMemoryScaler{
metadata: meta,
resourceName: resourceName,
logger: logger,
}, nil
}

// This is deprecated and can be removed later
if meta.Type != "" {
scaler.info = "The 'type' setting is DEPRECATED and will be removed in v2.18 - Use 'metricType' instead."
}

return scaler, nil
}

func parseResourceMetadata(config *scalersconfig.ScalerConfig, logger logr.Logger) (cpuMemoryMetadata, error) {
func parseResourceMetadata(config *scalersconfig.ScalerConfig) (cpuMemoryMetadata, error) {
meta := cpuMemoryMetadata{}
err := config.TypedConfig(&meta)
if err != nil {
Expand All @@ -58,7 +66,6 @@ func parseResourceMetadata(config *scalersconfig.ScalerConfig, logger logr.Logge

// This is deprecated and can be removed later
if meta.Type != "" {
logger.Info("The 'type' setting is DEPRECATED and will be removed in v2.18 - Use 'metricType' instead.")
switch meta.Type {
case "AverageValue":
meta.MetricType = v2.AverageValueMetricType
Expand Down Expand Up @@ -100,6 +107,10 @@ func (s *cpuMemoryScaler) Close(context.Context) error {
return nil
}

func (s *cpuMemoryScaler) GetScalerInfo() string {
return s.info
}

// GetMetricSpecForScaling returns the metric spec for the HPA
func (s *cpuMemoryScaler) GetMetricSpecForScaling(context.Context) []v2.MetricSpec {
metricType := s.metadata.MetricType
Expand Down
17 changes: 14 additions & 3 deletions pkg/scalers/ibmmq_scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ type ibmmqScaler struct {
metadata ibmmqMetadata
httpClient *http.Client
logger logr.Logger
info string
}

type ibmmqMetadata struct {
Expand Down Expand Up @@ -92,7 +93,6 @@ func NewIBMMQScaler(config *scalersconfig.ScalerConfig) (Scaler, error) {

// TODO: DEPRECATED to be removed in v2.18
if meta.TLS {
logger.Info("The 'tls' setting is DEPRECATED and will be removed in v2.18 - Use 'unsafeSsl' instead")
meta.UnsafeSsl = meta.TLS
}

Expand All @@ -106,12 +106,19 @@ func NewIBMMQScaler(config *scalersconfig.ScalerConfig) (Scaler, error) {
httpClient.Transport = kedautil.CreateHTTPTransportWithTLSConfig(tlsConfig)
}

return &ibmmqScaler{
scaler := &ibmmqScaler{
metricType: metricType,
metadata: meta,
httpClient: httpClient,
logger: logger,
}, nil
}

// TODO: DEPRECATED to be removed in v2.18
if meta.TLS {
scaler.info = "The 'tls' setting is DEPRECATED and will be removed in v2.18 - Use 'unsafeSsl' instead"
}

return scaler, nil
}

func (s *ibmmqScaler) Close(context.Context) error {
Expand All @@ -121,6 +128,10 @@ func (s *ibmmqScaler) Close(context.Context) error {
return nil
}

func (s *ibmmqScaler) GetScalerInfo() string {
return s.info
}

func parseIBMMQMetadata(config *scalersconfig.ScalerConfig) (ibmmqMetadata, error) {
meta := ibmmqMetadata{triggerIndex: config.TriggerIndex}
if err := config.TypedConfig(&meta); err != nil {
Expand Down
5 changes: 5 additions & 0 deletions pkg/scalers/scaler.go
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,11 @@ type Scaler interface {
Close(ctx context.Context) error
}

// InfoProvider is an optional interface that scalers can implement to provide additional information
type InfoProvider interface {
GetScalerInfo() string
}

// PushScaler interface
type PushScaler interface {
Scaler
Expand Down
68 changes: 68 additions & 0 deletions pkg/scalers/scaler_test.go
Original file line number Diff line number Diff line change
@@ -1,16 +1,46 @@
package scalers

import (
"context"
"reflect"
"testing"

"github.com/stretchr/testify/assert"
v2 "k8s.io/api/autoscaling/v2"
"k8s.io/apimachinery/pkg/api/resource"
"k8s.io/metrics/pkg/apis/external_metrics"

scalersconfig "github.com/kedacore/keda/v2/pkg/scalers/scalersconfig"
)

type mockScaler struct {
info string
}

func (s *mockScaler) GetMetricSpecForScaling(context.Context) []v2.MetricSpec {
return nil
}

func (s *mockScaler) GetMetrics(context.Context, string) ([]external_metrics.ExternalMetricValue, error) {
return nil, nil
}

func (s *mockScaler) IsActive(context.Context) (bool, error) {
return false, nil
}

func (s *mockScaler) Close(context.Context) error {
return nil
}

func (s *mockScaler) GetMetricsAndActivity(context.Context, string) ([]external_metrics.ExternalMetricValue, bool, error) {
return nil, false, nil
}

func (s *mockScaler) GetScalerInfo() string {
return s.info
}

func TestGetMetricTargetType(t *testing.T) {
cases := []struct {
name string
Expand Down Expand Up @@ -473,3 +503,41 @@ func TestConvertStringToType(t *testing.T) {
}
}
}

func TestScalerInfo(t *testing.T) {
cases := []struct {
name string
scaler Scaler
expectedInfo string
expectingInfo bool
}{
{
name: "scaler with info",
scaler: &mockScaler{info: "test info message"},
expectedInfo: "test info message",
expectingInfo: true,
},
{
name: "scaler with empty info",
scaler: &mockScaler{info: ""},
expectedInfo: "",
expectingInfo: false,
},
}

for _, testCase := range cases {
tc := testCase
t.Run(tc.name, func(t *testing.T) {
if infoProvider, ok := tc.scaler.(InfoProvider); ok {
info := infoProvider.GetScalerInfo()
if tc.expectingInfo {
assert.Equal(t, tc.expectedInfo, info)
} else {
assert.Empty(t, info)
}
} else {
t.Error("Scaler does not implement InfoProvider interface")
}
})
}
}
7 changes: 7 additions & 0 deletions pkg/scaling/scalers_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,13 @@ func (h *scaleHandler) buildScalers(ctx context.Context, withTriggers *kedav1alp
msg := fmt.Sprintf(message.ScalerIsBuiltMsg, trigger.Type)
h.recorder.Event(withTriggers, corev1.EventTypeNormal, eventreason.KEDAScalersStarted, msg)

if infoProvider, ok := scaler.(scalers.InfoProvider); ok {
if info := infoProvider.GetScalerInfo(); info != "" {
infoMsg := fmt.Sprintf("Scaler %s additional info: %s", trigger.Type, info)
h.recorder.Event(withTriggers, corev1.EventTypeNormal, eventreason.KEDAScalersInfo, infoMsg)
}
}

result = append(result, cache.ScalerBuilder{
Scaler: scaler,
ScalerConfig: *config,
Expand Down

0 comments on commit c48de5d

Please sign in to comment.