Merge pull request #122618 from ivanvc/improve-describe-job-output

describer: improve job and pod template output

Kubernetes-commit: cf2003fde41756d1d16fcb2d941a86708e8c5460
This commit is contained in:
Kubernetes Publisher 2024-01-23 20:03:53 +01:00
commit 97bd96adbc
5 changed files with 85 additions and 28 deletions

8
go.mod
View File

@ -33,8 +33,8 @@ require (
k8s.io/api v0.0.0-20240118211853-d5724e467262
k8s.io/apimachinery v0.0.0-20240118211638-f14778da5523
k8s.io/cli-runtime v0.0.0-20240118214801-ad54ff319bf2
k8s.io/client-go v0.0.0-20240118212159-ffe7bf60ebbf
k8s.io/component-base v0.0.0-20240118212833-be1cabd1bd81
k8s.io/client-go v0.0.0-20240122172058-657d7be98b25
k8s.io/component-base v0.0.0-20240123212339-5f9f8131aa48
k8s.io/component-helpers v0.0.0-20240118212950-9a5801419916
k8s.io/klog/v2 v2.120.1
k8s.io/kube-openapi v0.0.0-20231113174909-778a5567bc1e
@ -99,9 +99,9 @@ replace (
k8s.io/api => k8s.io/api v0.0.0-20240118211853-d5724e467262
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20240118211638-f14778da5523
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20240118214801-ad54ff319bf2
k8s.io/client-go => k8s.io/client-go v0.0.0-20240118212159-ffe7bf60ebbf
k8s.io/client-go => k8s.io/client-go v0.0.0-20240122172058-657d7be98b25
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20240118211431-5ad9f43b6468
k8s.io/component-base => k8s.io/component-base v0.0.0-20240118212833-be1cabd1bd81
k8s.io/component-base => k8s.io/component-base v0.0.0-20240123212339-5f9f8131aa48
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20240118212950-9a5801419916
k8s.io/metrics => k8s.io/metrics v0.0.0-20240118214633-5b4611d6f391
)

8
go.sum
View File

@ -286,10 +286,10 @@ k8s.io/apimachinery v0.0.0-20240118211638-f14778da5523 h1:1iJCbQAZv58v4zxd0ECIIM
k8s.io/apimachinery v0.0.0-20240118211638-f14778da5523/go.mod h1:Oh3ZrffM1/I8O/43oAA+aoOYgSregIXHxcWJB9ZRfQ8=
k8s.io/cli-runtime v0.0.0-20240118214801-ad54ff319bf2 h1:KFiGqjF1kq6YDXgsWmsms2bu10g1M17P9HRO2lGYry4=
k8s.io/cli-runtime v0.0.0-20240118214801-ad54ff319bf2/go.mod h1:zmPMirb3vXLcTGRaL9Pw5SifCP8EY2asTp+PTgnwSYI=
k8s.io/client-go v0.0.0-20240118212159-ffe7bf60ebbf h1:EHCH0rRKB6iA689XpLPl32Dqx+r+u8EgTu4HA6tNGWM=
k8s.io/client-go v0.0.0-20240118212159-ffe7bf60ebbf/go.mod h1:WuuT9L6+pj4rHmL2pb22xnOdtSvjiEcpB18g9Fuk0js=
k8s.io/component-base v0.0.0-20240118212833-be1cabd1bd81 h1:Ks1+11dEZI6KLON5tZqbVNkF8+m9QPx395I8Ay50a+U=
k8s.io/component-base v0.0.0-20240118212833-be1cabd1bd81/go.mod h1:VQmPwZSYOM8FYEnNvSHNO/JiRnejhPJqWOPLG4/BWfU=
k8s.io/client-go v0.0.0-20240122172058-657d7be98b25 h1:iBiouUazhDUHxrqDywgcbmARvao6UwVu+nSbIrIRh4k=
k8s.io/client-go v0.0.0-20240122172058-657d7be98b25/go.mod h1:WuuT9L6+pj4rHmL2pb22xnOdtSvjiEcpB18g9Fuk0js=
k8s.io/component-base v0.0.0-20240123212339-5f9f8131aa48 h1:3HvTUZ0ry5c0P15P+glBxBj+eh8Uv2ijNvjEORH+oOQ=
k8s.io/component-base v0.0.0-20240123212339-5f9f8131aa48/go.mod h1:ANnr9YwsqK1XgjzXj9fGHEMDOp0QddDkKgQLLBPZ7Kg=
k8s.io/component-helpers v0.0.0-20240118212950-9a5801419916 h1:Ptl0rZGRIrjdZuSqSO8Dwok1SWA9bqAi/Vcc3HYA/Ks=
k8s.io/component-helpers v0.0.0-20240118212950-9a5801419916/go.mod h1:4V7UGu7FNss4L6SfgJQBjIY9/bRlGoLO8pp5GY+UlGA=
k8s.io/klog/v2 v2.120.1 h1:QXU6cPEOIslTGvZaXvFWiP9VKyeet3sawzTOvdXb4Vw=

View File

@ -2215,6 +2215,8 @@ func DescribePodTemplate(template *corev1.PodTemplateSpec, w PrefixWriter) {
if len(template.Spec.PriorityClassName) > 0 {
w.Write(LEVEL_1, "Priority Class Name:\t%s\n", template.Spec.PriorityClassName)
}
printLabelsMultiline(w, " Node-Selectors", template.Spec.NodeSelector)
printPodTolerationsMultiline(w, " Tolerations", template.Spec.Tolerations)
}
// ReplicaSetDescriber generates information about a ReplicaSet and the pods it has created.
@ -2324,6 +2326,15 @@ func describeJob(job *batchv1.Job, events *corev1.EventList) (string, error) {
if job.Spec.CompletionMode != nil {
w.Write(LEVEL_0, "Completion Mode:\t%s\n", *job.Spec.CompletionMode)
}
if job.Spec.Suspend != nil {
w.Write(LEVEL_0, "Suspend:\t%v\n", *job.Spec.Suspend)
}
if job.Spec.BackoffLimit != nil {
w.Write(LEVEL_0, "Backoff Limit:\t%v\n", *job.Spec.BackoffLimit)
}
if job.Spec.TTLSecondsAfterFinished != nil {
w.Write(LEVEL_0, "TTL Seconds After Finished:\t%v\n", *job.Spec.TTLSecondsAfterFinished)
}
if job.Status.StartTime != nil {
w.Write(LEVEL_0, "Start Time:\t%s\n", job.Status.StartTime.Time.Format(time.RFC1123Z))
}

View File

@ -50,6 +50,7 @@ import (
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/kubernetes/fake"
utilpointer "k8s.io/utils/pointer"
"k8s.io/utils/ptr"
)
type describeClient struct {
@ -2261,9 +2262,11 @@ func TestDescribeDeployment(t *testing.T) {
"Replicas: 1 desired | 0 updated | 0 total | 0 available | 0 unavailable",
"Image: mytest-image:latest",
"Mounts:\n /tmp/vol-bar from vol-bar (rw)\n /tmp/vol-foo from vol-foo (rw)",
"OldReplicaSets: <none>",
"NewReplicaSet: bar-001 (1/1 replicas created)",
"Events: <none>",
"OldReplicaSets: <none>",
"NewReplicaSet: bar-001 (1/1 replicas created)",
"Events: <none>",
"Node-Selectors: <none>",
"Tolerations: <none>",
},
},
{
@ -2517,8 +2520,8 @@ func TestDescribeDeployment(t *testing.T) {
expects: []string{
"Replicas: 2 desired | 1 updated | 3 total | 2 available | 1 unavailable",
"Image: mytest-image:v2.0",
"OldReplicaSets: bar-001 (2/2 replicas created)",
"NewReplicaSet: bar-002 (1/1 replicas created)",
"OldReplicaSets: bar-001 (2/2 replicas created)",
"NewReplicaSet: bar-002 (1/1 replicas created)",
"Events:\n",
"Normal ScalingReplicaSet 12m (x3 over 20m) deployment-controller Scaled up replica set bar-002 to 1",
"Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set bar-001 to 2",
@ -2811,8 +2814,8 @@ func TestDescribeDeployment(t *testing.T) {
expects: []string{
"Replicas: 2 desired | 2 updated | 2 total | 2 available | 0 unavailable",
"Image: mytest-image:v2.0",
"OldReplicaSets: bar-001 (0/0 replicas created)",
"NewReplicaSet: bar-002 (2/2 replicas created)",
"OldReplicaSets: bar-001 (0/0 replicas created)",
"NewReplicaSet: bar-002 (2/2 replicas created)",
"Events:\n",
"Normal ScalingReplicaSet 12m (x3 over 20m) deployment-controller Scaled up replica set bar-002 to 1",
"Normal ScalingReplicaSet 10m deployment-controller Scaled up replica set bar-001 to 2",
@ -2845,10 +2848,11 @@ func TestDescribeDeployment(t *testing.T) {
func TestDescribeJob(t *testing.T) {
indexedCompletion := batchv1.IndexedCompletion
cases := map[string]struct {
job *batchv1.Job
wantCompletedIndexes string
job *batchv1.Job
wantElements []string
dontWantElements []string
}{
"not indexed": {
"empty job": {
job: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
@ -2856,8 +2860,9 @@ func TestDescribeJob(t *testing.T) {
},
Spec: batchv1.JobSpec{},
},
dontWantElements: []string{"Completed Indexes:", "Suspend:", "Backoff Limit:", "TTL Seconds After Finished:"},
},
"no indexes": {
"no completed indexes": {
job: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
@ -2867,7 +2872,7 @@ func TestDescribeJob(t *testing.T) {
CompletionMode: &indexedCompletion,
},
},
wantCompletedIndexes: "<none>",
wantElements: []string{"Completed Indexes: <none>"},
},
"few completed indexes": {
job: &batchv1.Job{
@ -2882,7 +2887,7 @@ func TestDescribeJob(t *testing.T) {
CompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32",
},
},
wantCompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32",
wantElements: []string{"Completed Indexes: 0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32"},
},
"too many completed indexes": {
job: &batchv1.Job{
@ -2897,7 +2902,37 @@ func TestDescribeJob(t *testing.T) {
CompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32-34,36,37",
},
},
wantCompletedIndexes: "0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32-34,...",
wantElements: []string{"Completed Indexes: 0-5,7,9,10,12,13,15,16,18,20,21,23,24,26,27,29,30,32-34,..."},
},
"suspend set to true": {
job: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
Namespace: "foo",
},
Spec: batchv1.JobSpec{
Suspend: ptr.To(true),
TTLSecondsAfterFinished: ptr.To(int32(123)),
BackoffLimit: ptr.To(int32(1)),
},
},
wantElements: []string{
"Suspend: true",
"TTL Seconds After Finished: 123",
"Backoff Limit: 1",
},
},
"suspend set to false": {
job: &batchv1.Job{
ObjectMeta: metav1.ObjectMeta{
Name: "bar",
Namespace: "foo",
},
Spec: batchv1.JobSpec{
Suspend: ptr.To(false),
},
},
wantElements: []string{"Suspend: false"},
},
}
for name, tc := range cases {
@ -2910,14 +2945,19 @@ func TestDescribeJob(t *testing.T) {
describer := JobDescriber{Interface: client}
out, err := describer.Describe(tc.job.Namespace, tc.job.Name, DescriberSettings{ShowEvents: true})
if err != nil {
t.Fatalf("Unexpected error describing object: %v", err)
t.Fatalf("unexpected error describing object: %v", err)
}
if tc.wantCompletedIndexes != "" {
if !strings.Contains(out, fmt.Sprintf("Completed Indexes: %s\n", tc.wantCompletedIndexes)) {
t.Errorf("Output didn't contain wanted Completed Indexes:\n%s", out)
for _, expected := range tc.wantElements {
if !strings.Contains(out, expected) {
t.Errorf("expected to find %q in output:\n %s", expected, out)
}
}
for _, unexpected := range tc.dontWantElements {
if strings.Contains(out, unexpected) {
t.Errorf("unexpected to find %q in output:\n %s", unexpected, out)
}
} else if strings.Contains(out, "Completed Indexes:") {
t.Errorf("Output contains unexpected completed indexes:\n%s", out)
}
})
}

View File

@ -159,6 +159,8 @@ func TestViewDeploymentHistory(t *testing.T) {
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
`
if result != expected {
t.Fatalf("unexpected output (%v was expected but got %v)", expected, result)
@ -267,6 +269,8 @@ func TestViewHistory(t *testing.T) {
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
`
if result != expected {
@ -371,6 +375,8 @@ func TestViewHistory(t *testing.T) {
Environment: <none>
Mounts: <none>
Volumes: <none>
Node-Selectors: <none>
Tolerations: <none>
`
if result != expected {