Add HPA status conditions to API types

This commit adds the new API status conditions to the API types.
The field exists as a field in autoscaling/v2alpha1, and is
round-tripped through an annotation in autoscaling/v1.
pull/6/head
Solly Ross 2017-05-24 16:53:25 -04:00
parent 0cff839317
commit 26ef38fe89
5 changed files with 166 additions and 2 deletions

View File

@ -24,6 +24,10 @@ const MetricSpecsAnnotation = "autoscaling.alpha.kubernetes.io/metrics"
// statuses when converting the `CurrentMetrics` field from autoscaling/v2alpha1
const MetricStatusesAnnotation = "autoscaling.alpha.kubernetes.io/current-metrics"
// HorizontalPodAutoscalerConditionsAnnotation is the annotation which holds the conditions
// of an HPA when converting the `Conditions` field from autoscaling/v2alpha1
const HorizontalPodAutoscalerConditionsAnnotation = "autoscaling.alpha.kubernetes.io/conditions"
// DefaultCPUUtilization is the default value for CPU utilization, provided no other
// metrics are present. This is here because it's used by both the v2alpha1 defaulting
// logic, and the pseudo-defaulting done in v1 conversion.

View File

@ -202,6 +202,59 @@ type HorizontalPodAutoscalerStatus struct {
// CurrentMetrics is the last read state of the metrics used by this autoscaler.
CurrentMetrics []MetricStatus
// Conditions is the set of conditions required for this autoscaler to scale its target,
// and indicates whether or not those conditions are met.
Conditions []HorizontalPodAutoscalerCondition
}
// ConditionStatus indicates the status of a condition (true, false, or unknown).
type ConditionStatus string
// These are valid condition statuses. "ConditionTrue" means a resource is in the condition;
// "ConditionFalse" means a resource is not in the condition; "ConditionUnknown" means kubernetes
// can't decide if a resource is in the condition or not. In the future, we could add other
// intermediate conditions, e.g. ConditionDegraded.
const (
ConditionTrue ConditionStatus = "True"
ConditionFalse ConditionStatus = "False"
ConditionUnknown ConditionStatus = "Unknown"
)
// HorizontalPodAutoscalerConditionType are the valid conditions of
// a HorizontalPodAutoscaler.
type HorizontalPodAutoscalerConditionType string
var (
// ScalingActive indicates that the HPA controller is able to scale if necessary:
// it's correctly configured, can fetch the desired metrics, and isn't disabled.
ScalingActive HorizontalPodAutoscalerConditionType = "ScalingActive"
// AbleToScale indicates a lack of transient issues which prevent scaling from occuring,
// such as being in a backoff window, or being unable to access/update the target scale.
AbleToScale HorizontalPodAutoscalerConditionType = "AbleToScale"
// ScalingLimited indicates that the calculated scale based on metrics would be above or
// below the range for the HPA, and has thus been capped.
ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited"
)
// HorizontalPodAutoscalerCondition describes the state of
// a HorizontalPodAutoscaler at a certain point.
type HorizontalPodAutoscalerCondition struct {
// Type describes the current condition
Type HorizontalPodAutoscalerConditionType
// Status is the status of the condition (True, False, Unknown)
Status ConditionStatus
// LastTransitionTime is the last time the condition transitioned from
// one status to another
// +optional
LastTransitionTime metav1.Time
// Reason is the reason for the condition's last transition.
// +optional
Reason string
// Message is a human-readable explanation containing details about
// the transition
// +optional
Message string
}
// MetricStatus describes the last-read state of a single metric.

View File

@ -68,9 +68,17 @@ func Convert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(i
}
}
if len(otherMetrics) > 0 || len(in.Status.CurrentMetrics) > 0 {
// store HPA conditions in an annotation
currentConditions := make([]HorizontalPodAutoscalerCondition, len(in.Status.Conditions))
for i, currentCondition := range in.Status.Conditions {
if err := Convert_autoscaling_HorizontalPodAutoscalerCondition_To_v1_HorizontalPodAutoscalerCondition(&currentCondition, &currentConditions[i], s); err != nil {
return err
}
}
if len(otherMetrics) > 0 || len(in.Status.CurrentMetrics) > 0 || len(currentConditions) > 0 {
old := out.Annotations
out.Annotations = make(map[string]string, len(old)+2)
out.Annotations = make(map[string]string, len(old)+3)
if old != nil {
for k, v := range old {
out.Annotations[k] = v
@ -94,6 +102,14 @@ func Convert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(i
out.Annotations[autoscaling.MetricStatusesAnnotation] = string(currentMetricsEnc)
}
if len(in.Status.Conditions) > 0 {
currentConditionsEnc, err := json.Marshal(currentConditions)
if err != nil {
return err
}
out.Annotations[autoscaling.HorizontalPodAutoscalerConditionsAnnotation] = string(currentConditionsEnc)
}
return nil
}
@ -154,6 +170,21 @@ func Convert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(i
*out.Spec.Metrics[0].Resource.TargetAverageUtilization = autoscaling.DefaultCPUUtilization
}
if currentConditionsEnc, hasCurrentConditions := out.Annotations[autoscaling.HorizontalPodAutoscalerConditionsAnnotation]; hasCurrentConditions {
var currentConditions []HorizontalPodAutoscalerCondition
if err := json.Unmarshal([]byte(currentConditionsEnc), &currentConditions); err != nil {
return err
}
out.Status.Conditions = make([]autoscaling.HorizontalPodAutoscalerCondition, len(currentConditions))
for i, currentCondition := range currentConditions {
if err := Convert_v1_HorizontalPodAutoscalerCondition_To_autoscaling_HorizontalPodAutoscalerCondition(&currentCondition, &out.Status.Conditions[i], s); err != nil {
return err
}
}
delete(out.Annotations, autoscaling.HorizontalPodAutoscalerConditionsAnnotation)
}
return nil
}

View File

@ -251,6 +251,42 @@ type MetricStatus struct {
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"`
}
// HorizontalPodAutoscalerConditionType are the valid conditions of
// a HorizontalPodAutoscaler.
type HorizontalPodAutoscalerConditionType string
var (
// ScalingActive indicates that the HPA controller is able to scale if necessary:
// it's correctly configured, can fetch the desired metrics, and isn't disabled.
ScalingActive HorizontalPodAutoscalerConditionType = "ScalingActive"
// AbleToScale indicates a lack of transient issues which prevent scaling from occuring,
// such as being in a backoff window, or being unable to access/update the target scale.
AbleToScale HorizontalPodAutoscalerConditionType = "AbleToScale"
// ScalingLimited indicates that the calculated scale based on metrics would be above or
// below the range for the HPA, and has thus been capped.
ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited"
)
// HorizontalPodAutoscalerCondition describes the state of
// a HorizontalPodAutoscaler at a certain point.
type HorizontalPodAutoscalerCondition struct {
// type describes the current condition
Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"`
// status is the status of the condition (True, False, Unknown)
Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"`
// lastTransitionTime is the last time the condition transitioned from
// one status to another
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
// reason is the reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
// message is a human-readable explanation containing details about
// the transition
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
}
// ObjectMetricStatus indicates the current value of a metric describing a
// kubernetes object (for example, hits-per-second on an Ingress object).
type ObjectMetricStatus struct {

View File

@ -166,6 +166,46 @@ type HorizontalPodAutoscalerStatus struct {
// currentMetrics is the last read state of the metrics used by this autoscaler.
CurrentMetrics []MetricStatus `json:"currentMetrics" protobuf:"bytes,5,rep,name=currentMetrics"`
// conditions is the set of conditions required for this autoscaler to scale its target,
// and indicates whether or not those conditions are met.
Conditions []HorizontalPodAutoscalerCondition `json:"conditions" protobuf:"bytes,6,rep,name=conditions"`
}
// HorizontalPodAutoscalerConditionType are the valid conditions of
// a HorizontalPodAutoscaler.
type HorizontalPodAutoscalerConditionType string
var (
// ScalingActive indicates that the HPA controller is able to scale if necessary:
// it's correctly configured, can fetch the desired metrics, and isn't disabled.
ScalingActive HorizontalPodAutoscalerConditionType = "ScalingActive"
// AbleToScale indicates a lack of transient issues which prevent scaling from occuring,
// such as being in a backoff window, or being unable to access/update the target scale.
AbleToScale HorizontalPodAutoscalerConditionType = "AbleToScale"
// ScalingLimited indicates that the calculated scale based on metrics would be above or
// below the range for the HPA, and has thus been capped.
ScalingLimited HorizontalPodAutoscalerConditionType = "ScalingLimited"
)
// HorizontalPodAutoscalerCondition describes the state of
// a HorizontalPodAutoscaler at a certain point.
type HorizontalPodAutoscalerCondition struct {
// type describes the current condition
Type HorizontalPodAutoscalerConditionType `json:"type" protobuf:"bytes,1,name=type"`
// status is the status of the condition (True, False, Unknown)
Status v1.ConditionStatus `json:"status" protobuf:"bytes,2,name=status"`
// lastTransitionTime is the last time the condition transitioned from
// one status to another
// +optional
LastTransitionTime metav1.Time `json:"lastTransitionTime,omitempty" protobuf:"bytes,3,opt,name=lastTransitionTime"`
// reason is the reason for the condition's last transition.
// +optional
Reason string `json:"reason,omitempty" protobuf:"bytes,4,opt,name=reason"`
// message is a human-readable explanation containing details about
// the transition
// +optional
Message string `json:"message,omitempty" protobuf:"bytes,5,opt,name=message"`
}
// MetricStatus describes the last-read state of a single metric.