Commit 26ef38fe authored by Solly Ross's avatar Solly Ross

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.
parent 0cff8393
...@@ -24,6 +24,10 @@ const MetricSpecsAnnotation = "autoscaling.alpha.kubernetes.io/metrics" ...@@ -24,6 +24,10 @@ const MetricSpecsAnnotation = "autoscaling.alpha.kubernetes.io/metrics"
// statuses when converting the `CurrentMetrics` field from autoscaling/v2alpha1 // statuses when converting the `CurrentMetrics` field from autoscaling/v2alpha1
const MetricStatusesAnnotation = "autoscaling.alpha.kubernetes.io/current-metrics" 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 // 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 // metrics are present. This is here because it's used by both the v2alpha1 defaulting
// logic, and the pseudo-defaulting done in v1 conversion. // logic, and the pseudo-defaulting done in v1 conversion.
......
...@@ -202,6 +202,59 @@ type HorizontalPodAutoscalerStatus struct { ...@@ -202,6 +202,59 @@ type HorizontalPodAutoscalerStatus struct {
// CurrentMetrics is the last read state of the metrics used by this autoscaler. // CurrentMetrics is the last read state of the metrics used by this autoscaler.
CurrentMetrics []MetricStatus 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. // MetricStatus describes the last-read state of a single metric.
......
...@@ -68,9 +68,17 @@ func Convert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(i ...@@ -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 old := out.Annotations
out.Annotations = make(map[string]string, len(old)+2) out.Annotations = make(map[string]string, len(old)+3)
if old != nil { if old != nil {
for k, v := range old { for k, v := range old {
out.Annotations[k] = v out.Annotations[k] = v
...@@ -94,6 +102,14 @@ func Convert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(i ...@@ -94,6 +102,14 @@ func Convert_autoscaling_HorizontalPodAutoscaler_To_v1_HorizontalPodAutoscaler(i
out.Annotations[autoscaling.MetricStatusesAnnotation] = string(currentMetricsEnc) 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 return nil
} }
...@@ -154,6 +170,21 @@ func Convert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(i ...@@ -154,6 +170,21 @@ func Convert_v1_HorizontalPodAutoscaler_To_autoscaling_HorizontalPodAutoscaler(i
*out.Spec.Metrics[0].Resource.TargetAverageUtilization = autoscaling.DefaultCPUUtilization *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 return nil
} }
......
...@@ -251,6 +251,42 @@ type MetricStatus struct { ...@@ -251,6 +251,42 @@ type MetricStatus struct {
Resource *ResourceMetricStatus `json:"resource,omitempty" protobuf:"bytes,4,opt,name=resource"` 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 // ObjectMetricStatus indicates the current value of a metric describing a
// kubernetes object (for example, hits-per-second on an Ingress object). // kubernetes object (for example, hits-per-second on an Ingress object).
type ObjectMetricStatus struct { type ObjectMetricStatus struct {
......
...@@ -166,6 +166,46 @@ type HorizontalPodAutoscalerStatus struct { ...@@ -166,6 +166,46 @@ type HorizontalPodAutoscalerStatus struct {
// currentMetrics is the last read state of the metrics used by this autoscaler. // currentMetrics is the last read state of the metrics used by this autoscaler.
CurrentMetrics []MetricStatus `json:"currentMetrics" protobuf:"bytes,5,rep,name=currentMetrics"` 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. // MetricStatus describes the last-read state of a single metric.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment