forked from kedacore/keda
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
support cpu/memory scaler (kedacore#1215)
Signed-off-by: silenceper <[email protected]>
- Loading branch information
1 parent
3be0c56
commit a17ac2a
Showing
8 changed files
with
201 additions
and
97 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package scalers | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
"strconv" | ||
|
||
"k8s.io/api/autoscaling/v2beta2" | ||
v1 "k8s.io/api/core/v1" | ||
"k8s.io/apimachinery/pkg/api/resource" | ||
"k8s.io/apimachinery/pkg/labels" | ||
"k8s.io/metrics/pkg/apis/external_metrics" | ||
) | ||
|
||
type cpuMemoryScaler struct { | ||
metadata *cpuMemoryMetadata | ||
resourceName v1.ResourceName | ||
} | ||
|
||
type cpuMemoryMetadata struct { | ||
Type v2beta2.MetricTargetType | ||
Value *resource.Quantity | ||
AverageValue *resource.Quantity | ||
AverageUtilization *int32 | ||
} | ||
|
||
// NewCPUMemoryScaler creates a new cpuMemoryScaler | ||
func NewCPUMemoryScaler(resourceName v1.ResourceName, config *ScalerConfig) (Scaler, error) { | ||
meta, parseErr := parseResourceMetadata(config) | ||
if parseErr != nil { | ||
return nil, fmt.Errorf("error parsing %s metadata: %s", resourceName, parseErr) | ||
} | ||
|
||
return &cpuMemoryScaler{ | ||
metadata: meta, | ||
resourceName: resourceName, | ||
}, nil | ||
} | ||
|
||
func parseResourceMetadata(config *ScalerConfig) (*cpuMemoryMetadata, error) { | ||
meta := &cpuMemoryMetadata{} | ||
if val, ok := config.TriggerMetadata["type"]; ok && val != "" { | ||
meta.Type = v2beta2.MetricTargetType(val) | ||
} else { | ||
return nil, fmt.Errorf("no type given") | ||
} | ||
|
||
var value string | ||
var ok bool | ||
if value, ok = config.TriggerMetadata["value"]; !ok || value == "" { | ||
return nil, fmt.Errorf("no value given") | ||
} | ||
switch meta.Type { | ||
case v2beta2.ValueMetricType: | ||
valueQuantity := resource.MustParse(value) | ||
meta.Value = &valueQuantity | ||
case v2beta2.AverageValueMetricType: | ||
averageValueQuantity := resource.MustParse(value) | ||
meta.AverageValue = &averageValueQuantity | ||
case v2beta2.UtilizationMetricType: | ||
valueNum, err := strconv.Atoi(value) | ||
if err != nil { | ||
return nil, err | ||
} | ||
utilizationNum := int32(valueNum) | ||
meta.AverageUtilization = &utilizationNum | ||
default: | ||
return nil, fmt.Errorf("unsupport type") | ||
} | ||
return meta, nil | ||
} | ||
|
||
// IsActive always return true for cpu/memory scaler | ||
func (s *cpuMemoryScaler) IsActive(ctx context.Context) (bool, error) { | ||
return true, nil | ||
} | ||
|
||
//Close no need for cpuMemory scaler | ||
func (s *cpuMemoryScaler) Close() error { | ||
return nil | ||
} | ||
|
||
// GetMetricSpecForScaling returns the metric spec for the HPA | ||
func (s *cpuMemoryScaler) GetMetricSpecForScaling() []v2beta2.MetricSpec { | ||
cpuMemoryMetric := &v2beta2.ResourceMetricSource{ | ||
Name: s.resourceName, | ||
Target: v2beta2.MetricTarget{ | ||
Type: s.metadata.Type, | ||
Value: s.metadata.Value, | ||
AverageUtilization: s.metadata.AverageUtilization, | ||
AverageValue: s.metadata.AverageValue, | ||
}, | ||
} | ||
metricSpec := v2beta2.MetricSpec{Resource: cpuMemoryMetric, Type: v2beta2.ResourceMetricSourceType} | ||
return []v2beta2.MetricSpec{metricSpec} | ||
} | ||
|
||
// GetMetrics no need for cpu/memory scaler | ||
func (s *cpuMemoryScaler) GetMetrics(ctx context.Context, metricName string, metricSelector labels.Selector) ([]external_metrics.ExternalMetricValue, error) { | ||
return nil, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
package scalers | ||
|
||
import ( | ||
"testing" | ||
|
||
"github.com/stretchr/testify/assert" | ||
"k8s.io/api/autoscaling/v2beta2" | ||
v1 "k8s.io/api/core/v1" | ||
) | ||
|
||
type parseCPUMemoryMetadataTestData struct { | ||
metadata map[string]string | ||
isError bool | ||
} | ||
|
||
// A complete valid metadata example for reference | ||
var validCPUMemoryMetadata = map[string]string{ | ||
"type": "Utilization", | ||
"value": "50", | ||
} | ||
|
||
var testCPUMemoryMetadata = []parseCPUMemoryMetadataTestData{ | ||
{map[string]string{}, true}, | ||
{validCPUMemoryMetadata, false}, | ||
{map[string]string{"type": "Utilization", "value": "50"}, false}, | ||
{map[string]string{"type": "Value", "value": "50"}, false}, | ||
{map[string]string{"type": "AverageValue", "value": "50"}, false}, | ||
{map[string]string{"type": "AverageValue"}, true}, | ||
{map[string]string{"type": "xxx", "value": "50"}, true}, | ||
} | ||
|
||
func TestCPUMemoryParseMetadata(t *testing.T) { | ||
for _, testData := range testCPUMemoryMetadata { | ||
config := &ScalerConfig{ | ||
TriggerMetadata: testData.metadata, | ||
} | ||
_, err := parseResourceMetadata(config) | ||
if err != nil && !testData.isError { | ||
t.Error("Expected success but got error", err) | ||
} | ||
if testData.isError && err == nil { | ||
t.Error("Expected error but got success") | ||
} | ||
} | ||
} | ||
|
||
func TestGetMetricSpecForScaling(t *testing.T) { | ||
config := &ScalerConfig{ | ||
TriggerMetadata: validCPUMemoryMetadata, | ||
} | ||
scaler, _ := NewCPUMemoryScaler(v1.ResourceCPU, config) | ||
metricSpec := scaler.GetMetricSpecForScaling() | ||
|
||
assert.Equal(t, metricSpec[0].Type, v2beta2.ResourceMetricSourceType) | ||
assert.Equal(t, metricSpec[0].Resource.Name, v1.ResourceCPU) | ||
assert.Equal(t, metricSpec[0].Resource.Target.Type, v2beta2.UtilizationMetricType) | ||
} |
Oops, something went wrong.