Merge pull request #106219 from dlipovetsky/describe-ns-conditions

Include Conditions in `kubectl describe namespace`

Kubernetes-commit: 824ad80bf33db291a5127c41985f94f04371f662
This commit is contained in:
Kubernetes Publisher 2021-11-16 13:21:45 -08:00
commit 98b602f535
4 changed files with 105 additions and 19 deletions

8
go.mod
View File

@ -31,10 +31,10 @@ require (
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e golang.org/x/sys v0.0.0-20210831042530-f4d43177bf5e
gopkg.in/yaml.v2 v2.4.0 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/apimachinery v0.0.0-20211116191949-10158cf6d3ff
k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57 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-base v0.0.0-20211115192801-2ba78dffde88
k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda
k8s.io/klog/v2 v2.30.0 k8s.io/klog/v2 v2.30.0
@ -47,10 +47,10 @@ require (
) )
replace ( 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/apimachinery => k8s.io/apimachinery v0.0.0-20211116191949-10158cf6d3ff
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57 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/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-base => k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20211112155227-f6f6db02ccda

8
go.sum
View File

@ -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-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.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
honnef.co/go/tools v0.0.1-2020.1.4/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-20211116232201-3ba85978261d h1:1nPNhVa28WnzWaJ42b49kcwa05Z2qqxcqPYD0OEHQJ8=
k8s.io/api v0.0.0-20211115232129-3b96cd16e7e6/go.mod h1:E/YSMnKP4hG73T35MZ3pw2P2Hy9cFo7KBeUkEPevRjk= 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 h1:48ZHXvUs3bTxiEDlE97wNDgMMCRLmVdqV+/W2d7Hvpg=
k8s.io/apimachinery v0.0.0-20211116191949-10158cf6d3ff/go.mod h1:/fTTuFZJpMy6M4dc6F6QbWWj88D/Yd/ZdqJMvTIcbkE= 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 h1:FfOBlRUNisClngHiIBDEyTW5N2yEbKy1/KsNSgwYZSk=
k8s.io/cli-runtime v0.0.0-20211113000837-3353a80fdd57/go.mod h1:aityjoTxZbPYy/7mU1LOCtwGFSCt2chNtENDPWtlOP8= 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-20211116232531-d9ceca58715c h1:SDq4/91oIjf7l+P75rjlP5jOa+XP56qTzaD9RcQheDU=
k8s.io/client-go v0.0.0-20211116192514-28b1932f622b/go.mod h1:wXDqK4ut3vuSXCpI06QbVyMBvCgMy70Osa77HAmfMEM= 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/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 h1:Vx0Rn2Mw8GS2IlGhN5SMRhU9WIm4jnCkruJwGZLYYGE=
k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88/go.mod h1:1FNCGI8+JFGNYTnOJidyT0C6gBaT3hZp0P5Nv/9NKr8= k8s.io/component-base v0.0.0-20211115192801-2ba78dffde88/go.mod h1:1FNCGI8+JFGNYTnOJidyT0C6gBaT3hZp0P5Nv/9NKr8=

View File

@ -451,14 +451,31 @@ func describeNamespace(namespace *corev1.Namespace, resourceQuotaList *corev1.Re
printLabelsMultiline(w, "Labels", namespace.Labels) printLabelsMultiline(w, "Labels", namespace.Labels)
printAnnotationsMultiline(w, "Annotations", namespace.Annotations) printAnnotationsMultiline(w, "Annotations", namespace.Annotations)
w.Write(LEVEL_0, "Status:\t%s\n", string(namespace.Status.Phase)) 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 { if resourceQuotaList != nil {
w.Write(LEVEL_0, "\n") w.Write(LEVEL_0, "\n")
DescribeResourceQuotas(resourceQuotaList, w) DescribeResourceQuotas(resourceQuotaList, w)
} }
if limitRangeList != nil { if limitRangeList != nil {
w.Write(LEVEL_0, "\n") w.Write(LEVEL_0, "\n")
DescribeLimitRanges(limitRangeList, w) DescribeLimitRanges(limitRangeList, w)
} }
return nil return nil
}) })
} }

View File

@ -236,19 +236,88 @@ func TestDescribeSecret(t *testing.T) {
} }
func TestDescribeNamespace(t *testing.T) { func TestDescribeNamespace(t *testing.T) {
fake := fake.NewSimpleClientset(&corev1.Namespace{ exampleNamespaceName := "example"
ObjectMeta: metav1.ObjectMeta{
Name: "myns", 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)
}
}
})
} }
} }