github.com/gocrane/crane@v0.11.0/pkg/utils/ehpa.go (about)

     1  package utils
     2  
     3  import (
     4  	"fmt"
     5  	"regexp"
     6  	"strings"
     7  
     8  	autoscalingapi "github.com/gocrane/api/autoscaling/v1alpha1"
     9  	autoscalingv2 "k8s.io/api/autoscaling/v2beta2"
    10  
    11  	"github.com/gocrane/crane/pkg/known"
    12  )
    13  
    14  func IsEHPAPredictionEnabled(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool {
    15  	return ehpa.Spec.Prediction != nil && ehpa.Spec.Prediction.PredictionWindowSeconds != nil && ehpa.Spec.Prediction.PredictionAlgorithm != nil
    16  }
    17  
    18  func IsEHPAHasPredictionMetric(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool {
    19  	for _, metric := range ehpa.Spec.Metrics {
    20  		metricName := GetPredictionMetricName(metric.Type)
    21  		if len(metricName) == 0 {
    22  			continue
    23  		}
    24  		return true
    25  	}
    26  
    27  	for key := range ehpa.Annotations {
    28  		if strings.HasPrefix(key, known.EffectiveHorizontalPodAutoscalerExternalMetricsAnnotationPrefix) {
    29  			return true
    30  		}
    31  	}
    32  	return false
    33  }
    34  
    35  func IsEHPACronEnabled(ehpa *autoscalingapi.EffectiveHorizontalPodAutoscaler) bool {
    36  	return len(ehpa.Spec.Crons) > 0
    37  }
    38  
    39  // GetPredictionMetricName return metric name used by prediction
    40  func GetPredictionMetricName(sourceType autoscalingv2.MetricSourceType) (metricName string) {
    41  	switch sourceType {
    42  	case autoscalingv2.ResourceMetricSourceType, autoscalingv2.PodsMetricSourceType, autoscalingv2.ExternalMetricSourceType:
    43  		metricName = known.MetricNamePrediction
    44  	}
    45  
    46  	return metricName
    47  }
    48  
    49  // GetCronMetricName return metric name used by cron
    50  func GetCronMetricName() string {
    51  	return known.MetricNameCron
    52  }
    53  
    54  // GetGeneralPredictionMetricName return metric name used by prediction
    55  func GetMetricIdentifier(metric autoscalingv2.MetricSpec, name string) string {
    56  	var prefix string
    57  	switch metric.Type {
    58  	case autoscalingv2.PodsMetricSourceType:
    59  		prefix = "pods"
    60  	case autoscalingv2.ResourceMetricSourceType:
    61  		prefix = "resource"
    62  	case autoscalingv2.ExternalMetricSourceType:
    63  		prefix = "external"
    64  	}
    65  
    66  	return fmt.Sprintf("%s.%s", prefix, name)
    67  }
    68  
    69  // GetExpressionQueryAnnotation return metric query from annotation by metricName
    70  func GetExpressionQueryAnnotation(metricIdentifier string, annotations map[string]string) string {
    71  	for k, v := range annotations {
    72  		if strings.HasPrefix(k, known.EffectiveHorizontalPodAutoscalerExternalMetricsAnnotationPrefix) {
    73  			compileRegex := regexp.MustCompile(fmt.Sprintf("%s(.*)", known.EffectiveHorizontalPodAutoscalerExternalMetricsAnnotationPrefix))
    74  			matchArr := compileRegex.FindStringSubmatch(k)
    75  			if len(matchArr) == 2 && matchArr[1][1:] == metricIdentifier {
    76  				return v
    77  			}
    78  		}
    79  	}
    80  
    81  	return ""
    82  }
    83  
    84  func IsExpressionQueryAnnotationEnabled(metricIdentifier string, annotations map[string]string) bool {
    85  	for k := range annotations {
    86  		if strings.HasPrefix(k, known.EffectiveHorizontalPodAutoscalerExternalMetricsAnnotationPrefix) {
    87  			compileRegex := regexp.MustCompile(fmt.Sprintf("%s(.*)", known.EffectiveHorizontalPodAutoscalerExternalMetricsAnnotationPrefix))
    88  			matchArr := compileRegex.FindStringSubmatch(k)
    89  			if len(matchArr) == 2 && matchArr[1][1:] == metricIdentifier {
    90  				return true
    91  			}
    92  		}
    93  	}
    94  
    95  	return false
    96  }
    97  
    98  // GetExpressionQuery return metric query
    99  func GetExpressionQueryDefault(metric autoscalingv2.MetricSpec, namespace string, name string, kind string) string {
   100  	var expressionQuery string
   101  	switch metric.Type {
   102  	case autoscalingv2.ResourceMetricSourceType:
   103  		switch metric.Resource.Name {
   104  		case "cpu":
   105  			expressionQuery = GetWorkloadCpuUsageExpression(namespace, name, kind)
   106  		case "memory":
   107  			expressionQuery = GetWorkloadMemUsageExpression(namespace, name, kind)
   108  		}
   109  	case autoscalingv2.PodsMetricSourceType:
   110  		var labels []string
   111  		if metric.Pods.Metric.Selector != nil {
   112  			for k, v := range metric.Pods.Metric.Selector.MatchLabels {
   113  				labels = append(labels, k+"="+`"`+v+`"`)
   114  			}
   115  		}
   116  		expressionQuery = GetCustomerExpression(metric.Pods.Metric.Name, strings.Join(labels, ","))
   117  	case autoscalingv2.ExternalMetricSourceType:
   118  		var labels []string
   119  		if metric.External.Metric.Selector != nil {
   120  			for k, v := range metric.External.Metric.Selector.MatchLabels {
   121  				labels = append(labels, k+"="+`"`+v+`"`)
   122  			}
   123  		}
   124  		expressionQuery = GetCustomerExpression(metric.External.Metric.Name, strings.Join(labels, ","))
   125  	}
   126  
   127  	return expressionQuery
   128  }