2023-05-03 23:01:19 +02:00

113 lines
2.4 KiB
Go

package annotations
import (
"fmt"
"strings"
"time"
autoscalingv2 "k8s.io/api/autoscaling/v2"
)
const (
customMetricsPrefix = "metric-config."
perReplicaMetricsConfKey = "per-replica"
intervalMetricsConfKey = "interval"
minPodReadyAgeConfKey = "min-pod-ready-age"
)
type AnnotationConfigs struct {
CollectorType string
Configs map[string]string
PerReplica bool
Interval time.Duration
MinPodReadyAge time.Duration
}
type MetricConfigKey struct {
Type autoscalingv2.MetricSourceType
MetricName string
}
type AnnotationConfigMap map[MetricConfigKey]*AnnotationConfigs
func (m AnnotationConfigMap) Parse(annotations map[string]string) error {
for key, val := range annotations {
if !strings.HasPrefix(key, customMetricsPrefix) {
continue
}
parts := strings.Split(key, "/")
if len(parts) != 2 {
// TODO: error?
continue
}
configs := strings.Split(parts[0], ".")
if len(configs) != 4 {
// TODO: error?
continue
}
key := MetricConfigKey{
MetricName: configs[2],
}
switch configs[1] {
case "pods":
key.Type = autoscalingv2.PodsMetricSourceType
case "object":
key.Type = autoscalingv2.ObjectMetricSourceType
default:
key.Type = autoscalingv2.ExternalMetricSourceType
}
metricCollector := configs[3]
config, ok := m[key]
if !ok {
config = &AnnotationConfigs{
CollectorType: metricCollector,
Configs: map[string]string{},
}
m[key] = config
}
// TODO: fail if collector name doesn't match
if config.CollectorType != metricCollector {
continue
}
if parts[1] == perReplicaMetricsConfKey {
config.PerReplica = true
continue
}
if parts[1] == intervalMetricsConfKey {
interval, err := time.ParseDuration(val)
if err != nil {
return fmt.Errorf("failed to parse interval value %s for %s: %v", val, key, err)
}
config.Interval = interval
continue
}
if parts[1] == minPodReadyAgeConfKey {
minPodReadyAge, err := time.ParseDuration(val)
if err != nil {
return fmt.Errorf("failed to parse min-pod-ready-age value %s for %s: %v", val, key, err)
}
config.MinPodReadyAge = minPodReadyAge
continue
}
config.Configs[parts[1]] = val
}
return nil
}
func (m AnnotationConfigMap) GetAnnotationConfig(metricName string, metricType autoscalingv2.MetricSourceType) (*AnnotationConfigs, bool) {
key := MetricConfigKey{MetricName: metricName, Type: metricType}
config, ok := m[key]
return config, ok
}