mirror of https://github.com/k3s-io/k3s
make describers of different versions work properly when autoscaling/v2beta2 is not supported
parent
5c2fe63591
commit
814e1ca73f
|
@ -18,6 +18,7 @@ go_library(
|
|||
"//pkg/kubectl/util/slice:go_default_library",
|
||||
"//pkg/kubectl/util/storage:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/batch/v1beta1:go_default_library",
|
||||
|
@ -73,6 +74,7 @@ go_test(
|
|||
deps = [
|
||||
"//pkg/kubectl/describe:go_default_library",
|
||||
"//staging/src/k8s.io/api/apps/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/autoscaling/v2beta2:go_default_library",
|
||||
"//staging/src/k8s.io/api/core/v1:go_default_library",
|
||||
"//staging/src/k8s.io/api/networking/v1:go_default_library",
|
||||
|
|
|
@ -33,6 +33,7 @@ import (
|
|||
"github.com/fatih/camelcase"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
batchv1 "k8s.io/api/batch/v1"
|
||||
batchv1beta1 "k8s.io/api/batch/v1beta1"
|
||||
|
@ -3074,20 +3075,31 @@ type HorizontalPodAutoscalerDescriber struct {
|
|||
}
|
||||
|
||||
func (d *HorizontalPodAutoscalerDescriber) Describe(namespace, name string, describerSettings describe.DescriberSettings) (string, error) {
|
||||
hpa, err := d.client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).Get(name, metav1.GetOptions{})
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var events *corev1.EventList
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.client.CoreV1().Events(namespace).Search(scheme.Scheme, hpa)
|
||||
|
||||
// autoscaling/v2beta2 is introduced since v1.12 and autoscaling/v1 does not have full backward compatibility
|
||||
// with autoscaling/v2beta2, so describer will try to get and describe hpa v2beta2 object firstly, if it fails,
|
||||
// describer will fall back to do with hpa v1 object
|
||||
hpaV2beta2, err := d.client.AutoscalingV2beta2().HorizontalPodAutoscalers(namespace).Get(name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.client.CoreV1().Events(namespace).Search(scheme.Scheme, hpaV2beta2)
|
||||
}
|
||||
return describeHorizontalPodAutoscalerV2beta2(hpaV2beta2, events, d)
|
||||
}
|
||||
|
||||
return describeHorizontalPodAutoscaler(hpa, events, d)
|
||||
hpaV1, err := d.client.AutoscalingV1().HorizontalPodAutoscalers(namespace).Get(name, metav1.GetOptions{})
|
||||
if err == nil {
|
||||
if describerSettings.ShowEvents {
|
||||
events, _ = d.client.CoreV1().Events(namespace).Search(scheme.Scheme, hpaV1)
|
||||
}
|
||||
return describeHorizontalPodAutoscalerV1(hpaV1, events, d)
|
||||
}
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
func describeHorizontalPodAutoscaler(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, events *corev1.EventList, d *HorizontalPodAutoscalerDescriber) (string, error) {
|
||||
func describeHorizontalPodAutoscalerV2beta2(hpa *autoscalingv2beta2.HorizontalPodAutoscaler, events *corev1.EventList, d *HorizontalPodAutoscalerDescriber) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
w := NewPrefixWriter(out)
|
||||
w.Write(LEVEL_0, "Name:\t%s\n", hpa.Name)
|
||||
|
@ -3188,6 +3200,44 @@ func describeHorizontalPodAutoscaler(hpa *autoscalingv2beta2.HorizontalPodAutosc
|
|||
})
|
||||
}
|
||||
|
||||
func describeHorizontalPodAutoscalerV1(hpa *autoscalingv1.HorizontalPodAutoscaler, events *corev1.EventList, d *HorizontalPodAutoscalerDescriber) (string, error) {
|
||||
return tabbedString(func(out io.Writer) error {
|
||||
w := NewPrefixWriter(out)
|
||||
w.Write(LEVEL_0, "Name:\t%s\n", hpa.Name)
|
||||
w.Write(LEVEL_0, "Namespace:\t%s\n", hpa.Namespace)
|
||||
printLabelsMultiline(w, "Labels", hpa.Labels)
|
||||
printAnnotationsMultiline(w, "Annotations", hpa.Annotations)
|
||||
w.Write(LEVEL_0, "CreationTimestamp:\t%s\n", hpa.CreationTimestamp.Time.Format(time.RFC1123Z))
|
||||
w.Write(LEVEL_0, "Reference:\t%s/%s\n",
|
||||
hpa.Spec.ScaleTargetRef.Kind,
|
||||
hpa.Spec.ScaleTargetRef.Name)
|
||||
|
||||
if hpa.Spec.TargetCPUUtilizationPercentage != nil {
|
||||
w.Write(LEVEL_0, "Target CPU utilization:\t%d%%\n", *hpa.Spec.TargetCPUUtilizationPercentage)
|
||||
current := "<unknown>"
|
||||
if hpa.Status.CurrentCPUUtilizationPercentage != nil {
|
||||
current = fmt.Sprintf("%d", *hpa.Status.CurrentCPUUtilizationPercentage)
|
||||
}
|
||||
w.Write(LEVEL_0, "Current CPU utilization:\t%s%%\n", current)
|
||||
}
|
||||
|
||||
minReplicas := "<unset>"
|
||||
if hpa.Spec.MinReplicas != nil {
|
||||
minReplicas = fmt.Sprintf("%d", *hpa.Spec.MinReplicas)
|
||||
}
|
||||
w.Write(LEVEL_0, "Min replicas:\t%s\n", minReplicas)
|
||||
w.Write(LEVEL_0, "Max replicas:\t%d\n", hpa.Spec.MaxReplicas)
|
||||
w.Write(LEVEL_0, "%s pods:\t", hpa.Spec.ScaleTargetRef.Kind)
|
||||
w.Write(LEVEL_0, "%d current / %d desired\n", hpa.Status.CurrentReplicas, hpa.Status.DesiredReplicas)
|
||||
|
||||
if events != nil {
|
||||
DescribeEvents(events, w)
|
||||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
func describeNodeResource(nodeNonTerminatedPodsList *corev1.PodList, node *corev1.Node, w PrefixWriter) {
|
||||
w.Write(LEVEL_0, "Non-terminated Pods:\t(%d in total)\n", len(nodeNonTerminatedPodsList.Items))
|
||||
w.Write(LEVEL_1, "Namespace\tName\t\tCPU Requests\tCPU Limits\tMemory Requests\tMemory Limits\tAGE\n")
|
||||
|
|
|
@ -26,6 +26,7 @@ import (
|
|||
"time"
|
||||
|
||||
appsv1 "k8s.io/api/apps/v1"
|
||||
autoscalingv1 "k8s.io/api/autoscaling/v1"
|
||||
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta2"
|
||||
"k8s.io/api/core/v1"
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
|
@ -1628,7 +1629,7 @@ func TestDescribeHorizontalPodAutoscaler(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Errorf("unable to parse label selector: %v", err)
|
||||
}
|
||||
tests := []struct {
|
||||
testsV2beta2 := []struct {
|
||||
name string
|
||||
hpa autoscalingv2beta2.HorizontalPodAutoscaler
|
||||
}{
|
||||
|
@ -2270,7 +2271,102 @@ func TestDescribeHorizontalPodAutoscaler(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
for _, test := range testsV2beta2 {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.hpa.ObjectMeta = metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
Namespace: "foo",
|
||||
}
|
||||
fake := fake.NewSimpleClientset(&test.hpa)
|
||||
desc := HorizontalPodAutoscalerDescriber{fake}
|
||||
str, err := desc.Describe("foo", "bar", describe.DescriberSettings{ShowEvents: true})
|
||||
if err != nil {
|
||||
t.Errorf("Unexpected error for test %s: %v", test.name, err)
|
||||
}
|
||||
if str == "" {
|
||||
t.Errorf("Unexpected empty string for test %s. Expected HPA Describer output", test.name)
|
||||
}
|
||||
t.Logf("Description for %q:\n%s", test.name, str)
|
||||
})
|
||||
}
|
||||
|
||||
testsV1 := []struct {
|
||||
name string
|
||||
hpa autoscalingv1.HorizontalPodAutoscaler
|
||||
}{
|
||||
{
|
||||
"minReplicas unset",
|
||||
autoscalingv1.HorizontalPodAutoscaler{
|
||||
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
|
||||
Name: "some-rc",
|
||||
Kind: "ReplicationController",
|
||||
},
|
||||
MaxReplicas: 10,
|
||||
},
|
||||
Status: autoscalingv1.HorizontalPodAutoscalerStatus{
|
||||
CurrentReplicas: 4,
|
||||
DesiredReplicas: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"minReplicas set",
|
||||
autoscalingv1.HorizontalPodAutoscaler{
|
||||
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
|
||||
Name: "some-rc",
|
||||
Kind: "ReplicationController",
|
||||
},
|
||||
MinReplicas: &minReplicasVal,
|
||||
MaxReplicas: 10,
|
||||
},
|
||||
Status: autoscalingv1.HorizontalPodAutoscalerStatus{
|
||||
CurrentReplicas: 4,
|
||||
DesiredReplicas: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"with target no current",
|
||||
autoscalingv1.HorizontalPodAutoscaler{
|
||||
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
|
||||
Name: "some-rc",
|
||||
Kind: "ReplicationController",
|
||||
},
|
||||
MinReplicas: &minReplicasVal,
|
||||
MaxReplicas: 10,
|
||||
TargetCPUUtilizationPercentage: &targetUtilizationVal,
|
||||
},
|
||||
Status: autoscalingv1.HorizontalPodAutoscalerStatus{
|
||||
CurrentReplicas: 4,
|
||||
DesiredReplicas: 5,
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
"with target and current",
|
||||
autoscalingv1.HorizontalPodAutoscaler{
|
||||
Spec: autoscalingv1.HorizontalPodAutoscalerSpec{
|
||||
ScaleTargetRef: autoscalingv1.CrossVersionObjectReference{
|
||||
Name: "some-rc",
|
||||
Kind: "ReplicationController",
|
||||
},
|
||||
MinReplicas: &minReplicasVal,
|
||||
MaxReplicas: 10,
|
||||
TargetCPUUtilizationPercentage: &targetUtilizationVal,
|
||||
},
|
||||
Status: autoscalingv1.HorizontalPodAutoscalerStatus{
|
||||
CurrentReplicas: 4,
|
||||
DesiredReplicas: 5,
|
||||
CurrentCPUUtilizationPercentage: ¤tUtilizationVal,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range testsV1 {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
test.hpa.ObjectMeta = metav1.ObjectMeta{
|
||||
Name: "bar",
|
||||
|
|
Loading…
Reference in New Issue