-
Notifications
You must be signed in to change notification settings - Fork 21
/
object.go
98 lines (81 loc) · 3.66 KB
/
object.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
/*
Copyright 2016 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Modifications Copyright 2021 The Custom Pod Autoscaler Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Modified to split up evaluations and metric gathering to work with the
Custom Pod Autoscaler framework.
Original source:
https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/podautoscaler/horizontal.go
https://github.com/kubernetes/kubernetes/blob/master/pkg/controller/podautoscaler/replica_calculator.go
*/
package object
import (
"fmt"
"time"
"github.com/jthomperoo/custom-pod-autoscaler/internal/measure/podutil"
"github.com/jthomperoo/custom-pod-autoscaler/internal/measure/value"
autoscaling "k8s.io/api/autoscaling/v2beta2"
"k8s.io/apimachinery/pkg/labels"
metricsclient "k8s.io/kubernetes/pkg/controller/podautoscaler/metrics"
)
// Gatherer (Object) allows retrieval of object metrics.
type Gatherer interface {
GetMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, selector labels.Selector, metricSelector labels.Selector) (*Metric, error)
GetPerPodMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (*Metric, error)
}
// Metric (Object) is a metric describing a kubernetes object
// (for example, hits-per-second on an Ingress object).
type Metric struct {
Current value.MetricValue
ReadyPodCount *int64
Timestamp time.Time
}
// Gather (Object) provides functionality for retrieving metrics for object metric specs.
type Gather struct {
MetricsClient metricsclient.MetricsClient
PodReadyCounter podutil.PodReadyCounter
}
// GetMetric retrieves an object metric
func (c *Gather) GetMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, selector labels.Selector, metricSelector labels.Selector) (*Metric, error) {
// Get metrics
utilization, timestamp, err := c.MetricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
if err != nil {
return nil, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
}
// Calculate number of ready pods
readyPodCount, err := c.PodReadyCounter.GetReadyPodsCount(namespace, selector)
if err != nil {
return nil, fmt.Errorf("unable to calculate ready pods: %s", err)
}
return &Metric{
Current: value.MetricValue{
Value: &utilization,
},
ReadyPodCount: &readyPodCount,
Timestamp: timestamp,
}, nil
}
// GetPerPodMetric retrieves an object per pod metric
func (c *Gather) GetPerPodMetric(metricName string, namespace string, objectRef *autoscaling.CrossVersionObjectReference, metricSelector labels.Selector) (*Metric, error) {
// Get metrics
utilization, timestamp, err := c.MetricsClient.GetObjectMetric(metricName, namespace, objectRef, metricSelector)
if err != nil {
return nil, fmt.Errorf("unable to get metric %s: %v on %s %s/%s", metricName, objectRef.Kind, namespace, objectRef.Name, err)
}
return &Metric{
Current: value.MetricValue{
AverageValue: &utilization,
},
Timestamp: timestamp,
}, nil
}