diff --git a/staging/src/k8s.io/kubectl/pkg/describe/describe.go b/staging/src/k8s.io/kubectl/pkg/describe/describe.go index 41a09aa6eda..ead94b38d5c 100644 --- a/staging/src/k8s.io/kubectl/pkg/describe/describe.go +++ b/staging/src/k8s.io/kubectl/pkg/describe/describe.go @@ -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)) } diff --git a/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go b/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go index 59162a496ef..9c7e5b6f6af 100644 --- a/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go +++ b/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go @@ -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: ", - "NewReplicaSet: bar-001 (1/1 replicas created)", - "Events: ", + "OldReplicaSets: ", + "NewReplicaSet: bar-001 (1/1 replicas created)", + "Events: ", + "Node-Selectors: ", + "Tolerations: ", }, }, { @@ -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: "", + wantElements: []string{"Completed Indexes: "}, }, "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) } }) } diff --git a/staging/src/k8s.io/kubectl/pkg/polymorphichelpers/history_test.go b/staging/src/k8s.io/kubectl/pkg/polymorphichelpers/history_test.go index 4f55326d0d5..239f30c6580 100644 --- a/staging/src/k8s.io/kubectl/pkg/polymorphichelpers/history_test.go +++ b/staging/src/k8s.io/kubectl/pkg/polymorphichelpers/history_test.go @@ -159,6 +159,8 @@ func TestViewDeploymentHistory(t *testing.T) { Environment: Mounts: Volumes: + Node-Selectors: + Tolerations: ` 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: Mounts: Volumes: + Node-Selectors: + Tolerations: ` if result != expected { @@ -371,6 +375,8 @@ func TestViewHistory(t *testing.T) { Environment: Mounts: Volumes: + Node-Selectors: + Tolerations: ` if result != expected {