diff --git a/go.mod b/go.mod index 20f4366ff..0ad7c6ccf 100644 --- a/go.mod +++ b/go.mod @@ -31,10 +31,10 @@ require ( github.com/stretchr/testify v1.7.0 golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e gopkg.in/yaml.v2 v2.4.0 - k8s.io/api v0.0.0-20211115232129-3b96cd16e7e6 + k8s.io/api v0.0.0-20211116232201-3ba85978261d k8s.io/apimachinery v0.0.0-20211116191949-10158cf6d3ff k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57 - k8s.io/client-go v0.0.0-20211116192514-28b1932f622b + k8s.io/client-go v0.0.0-20211116232531-d9ceca58715c k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88 k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda k8s.io/klog/v2 v2.30.0 @@ -47,10 +47,10 @@ require ( ) replace ( - k8s.io/api => k8s.io/api v0.0.0-20211115232129-3b96cd16e7e6 + k8s.io/api => k8s.io/api v0.0.0-20211116232201-3ba85978261d k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20211116191949-10158cf6d3ff k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57 - k8s.io/client-go => k8s.io/client-go v0.0.0-20211116192514-28b1932f622b + k8s.io/client-go => k8s.io/client-go v0.0.0-20211116232531-d9ceca58715c k8s.io/code-generator => k8s.io/code-generator v0.0.0-20211111071655-7b5df4132daf k8s.io/component-base => k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88 k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda diff --git a/go.sum b/go.sum index 2c9d10e43..862a6a64a 100644 --- a/go.sum +++ b/go.sum @@ -909,14 +909,14 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg= honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k= -k8s.io/api v0.0.0-20211115232129-3b96cd16e7e6 h1:/Rn6GeqmvNXzLe9ucZcuEsmdfh1n//ewpE6URUfcFaw= -k8s.io/api v0.0.0-20211115232129-3b96cd16e7e6/go.mod h1:E/YSMnKP4hG73T35MZ3pw2P2Hy9cFo7KBeUkEPevRjk= +k8s.io/api v0.0.0-20211116232201-3ba85978261d h1:1nPNhVa28WnzWaJ42b49kcwa05Z2qqxcqPYD0OEHQJ8= +k8s.io/api v0.0.0-20211116232201-3ba85978261d/go.mod h1:EgyfCRAySNu6W9i8g81nY2/AJR7UVniCSHwGWPDshGs= k8s.io/apimachinery v0.0.0-20211116191949-10158cf6d3ff h1:48ZHXvUs3bTxiEDlE97wNDgMMCRLmVdqV+/W2d7Hvpg= k8s.io/apimachinery v0.0.0-20211116191949-10158cf6d3ff/go.mod h1:/fTTuFZJpMy6M4dc6F6QbWWj88D/Yd/ZdqJMvTIcbkE= k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57 h1:FfOBlRUNisClngHiIBDEyTW5N2yEbKy1/KsNSgwYZSk= k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57/go.mod h1:aityjoTxZbPYy/7mU1LOCtwGFSCt2chNtENDPWtlOP8= -k8s.io/client-go v0.0.0-20211116192514-28b1932f622b h1:NqlLLodrwLap7Z6YVK45ynIgAUkRsS6mb3rjfTR34IE= -k8s.io/client-go v0.0.0-20211116192514-28b1932f622b/go.mod h1:wXDqK4ut3vuSXCpI06QbVyMBvCgMy70Osa77HAmfMEM= +k8s.io/client-go v0.0.0-20211116232531-d9ceca58715c h1:SDq4/91oIjf7l+P75rjlP5jOa+XP56qTzaD9RcQheDU= +k8s.io/client-go v0.0.0-20211116232531-d9ceca58715c/go.mod h1:ucUV9EL6PE378vUCjYaoKbFsIcXbO4ObSfCOKgoj/88= k8s.io/code-generator v0.0.0-20211111071655-7b5df4132daf/go.mod h1:elIIhU8sF9q1YQFV7vZBy0EXwIqmRQ1K0HjPRxMHdEQ= k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88 h1:Vx0Rn2Mw8GS2IlGhN5SMRhU9WIm4jnCkruJwGZLYYGE= k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88/go.mod h1:1FNCGI8+JFGNYTnOJidyT0C6gBaT3hZp0P5Nv/9NKr8= diff --git a/pkg/describe/describe.go b/pkg/describe/describe.go index 9cadede5d..85da68194 100644 --- a/pkg/describe/describe.go +++ b/pkg/describe/describe.go @@ -451,14 +451,31 @@ func describeNamespace(namespace *corev1.Namespace, resourceQuotaList *corev1.Re printLabelsMultiline(w, "Labels", namespace.Labels) printAnnotationsMultiline(w, "Annotations", namespace.Annotations) w.Write(LEVEL_0, "Status:\t%s\n", string(namespace.Status.Phase)) + + if len(namespace.Status.Conditions) > 0 { + w.Write(LEVEL_0, "Conditions:\n") + w.Write(LEVEL_1, "Type\tStatus\tLastTransitionTime\tReason\tMessage\n") + w.Write(LEVEL_1, "----\t------\t------------------\t------\t-------\n") + for _, c := range namespace.Status.Conditions { + w.Write(LEVEL_1, "%v\t%v\t%s\t%v\t%v\n", + c.Type, + c.Status, + c.LastTransitionTime.Time.Format(time.RFC1123Z), + c.Reason, + c.Message) + } + } + if resourceQuotaList != nil { w.Write(LEVEL_0, "\n") DescribeResourceQuotas(resourceQuotaList, w) } + if limitRangeList != nil { w.Write(LEVEL_0, "\n") DescribeLimitRanges(limitRangeList, w) } + return nil }) } diff --git a/pkg/describe/describe_test.go b/pkg/describe/describe_test.go index 97b08a411..7a5b67772 100644 --- a/pkg/describe/describe_test.go +++ b/pkg/describe/describe_test.go @@ -236,19 +236,88 @@ func TestDescribeSecret(t *testing.T) { } func TestDescribeNamespace(t *testing.T) { - fake := fake.NewSimpleClientset(&corev1.Namespace{ - ObjectMeta: metav1.ObjectMeta{ - Name: "myns", + exampleNamespaceName := "example" + + testCases := []struct { + name string + namespace *corev1.Namespace + expect []string + }{ + { + name: "no quotas or limit ranges", + namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: exampleNamespaceName, + }, + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceActive, + }, + }, + expect: []string{ + "Name", + exampleNamespaceName, + "Status", + string(corev1.NamespaceActive), + "No resource quota", + "No LimitRange resource.", + }, + }, + { + name: "has conditions", + namespace: &corev1.Namespace{ + ObjectMeta: metav1.ObjectMeta{ + Name: exampleNamespaceName, + }, + Status: corev1.NamespaceStatus{ + Phase: corev1.NamespaceTerminating, + Conditions: []corev1.NamespaceCondition{ + { + LastTransitionTime: metav1.NewTime(time.Date(2014, time.January, 15, 0, 0, 0, 0, time.UTC)), + Message: "example message", + Reason: "example reason", + Status: corev1.ConditionTrue, + Type: corev1.NamespaceDeletionContentFailure, + }, + }, + }, + }, + expect: []string{ + "Name", + exampleNamespaceName, + "Status", + string(corev1.NamespaceTerminating), + "Conditions", + "Type", + string(corev1.NamespaceDeletionContentFailure), + "Status", + string(corev1.ConditionTrue), + "Reason", + "example reason", + "Message", + "example message", + "No resource quota", + "No LimitRange resource.", + }, }, - }) - c := &describeClient{T: t, Namespace: "", Interface: fake} - d := NamespaceDescriber{c} - out, err := d.Describe("", "myns", DescriberSettings{ShowEvents: true}) - if err != nil { - t.Errorf("unexpected error: %v", err) } - if !strings.Contains(out, "myns") { - t.Errorf("unexpected out: %s", out) + + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + fake := fake.NewSimpleClientset(testCase.namespace) + c := &describeClient{T: t, Namespace: "", Interface: fake} + d := NamespaceDescriber{c} + + out, err := d.Describe("", testCase.namespace.Name, DescriberSettings{ShowEvents: true}) + if err != nil { + t.Errorf("unexpected error: %v", err) + } + + for _, expected := range testCase.expect { + if !strings.Contains(out, expected) { + t.Errorf("expected to find %q in output: %q", expected, out) + } + } + }) } }