Merge pull request #109563 from ardaguclu/describe-topologyspreadconstraints
Show topologySpreadConstraints in Describe command Kubernetes-commit: b1e130fe83156783153538b6d79821c2fdaa85bb
This commit is contained in:
commit
af1141b947
20
go.mod
20
go.mod
|
|
@ -31,11 +31,11 @@ require (
|
||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
golang.org/x/sys v0.0.0-20220209214540-3681064d5158
|
golang.org/x/sys v0.0.0-20220209214540-3681064d5158
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
k8s.io/api v0.0.0-20220504022944-af4f75e1994c
|
k8s.io/api v0.0.0-20220504102935-d672b36ea3cc
|
||||||
k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5
|
k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493
|
||||||
k8s.io/cli-runtime v0.0.0-20220504025609-ddf455f66463
|
k8s.io/cli-runtime v0.0.0-20220504105501-409fed9c3710
|
||||||
k8s.io/client-go v0.0.0-20220504023308-2cf1a8ffd6db
|
k8s.io/client-go v0.0.0-20220504103257-671a40c59fca
|
||||||
k8s.io/component-base v0.0.0-20220331212037-3b9b201c27aa
|
k8s.io/component-base v0.0.0-20220504063447-4aebdd2c2313
|
||||||
k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6
|
k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6
|
||||||
k8s.io/klog/v2 v2.60.1
|
k8s.io/klog/v2 v2.60.1
|
||||||
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42
|
k8s.io/kube-openapi v0.0.0-20220328201542-3ee0da9b0b42
|
||||||
|
|
@ -48,12 +48,12 @@ require (
|
||||||
)
|
)
|
||||||
|
|
||||||
replace (
|
replace (
|
||||||
k8s.io/api => k8s.io/api v0.0.0-20220504022944-af4f75e1994c
|
k8s.io/api => k8s.io/api v0.0.0-20220504102935-d672b36ea3cc
|
||||||
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5
|
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493
|
||||||
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20220504025609-ddf455f66463
|
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20220504105501-409fed9c3710
|
||||||
k8s.io/client-go => k8s.io/client-go v0.0.0-20220504023308-2cf1a8ffd6db
|
k8s.io/client-go => k8s.io/client-go v0.0.0-20220504103257-671a40c59fca
|
||||||
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20220330050606-8f17de063761
|
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20220330050606-8f17de063761
|
||||||
k8s.io/component-base => k8s.io/component-base v0.0.0-20220331212037-3b9b201c27aa
|
k8s.io/component-base => k8s.io/component-base v0.0.0-20220504063447-4aebdd2c2313
|
||||||
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6
|
k8s.io/component-helpers => k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6
|
||||||
k8s.io/metrics => k8s.io/metrics v0.0.0-20220330053428-cc6cd56b3aba
|
k8s.io/metrics => k8s.io/metrics v0.0.0-20220330053428-cc6cd56b3aba
|
||||||
)
|
)
|
||||||
|
|
|
||||||
20
go.sum
20
go.sum
|
|
@ -878,17 +878,17 @@ 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-20220504022944-af4f75e1994c h1:4chKbSSvIxpT/ls7NTHZyE0xnKewL0HSbdaYyesfrmQ=
|
k8s.io/api v0.0.0-20220504102935-d672b36ea3cc h1:7YyduXrzE67vThuTuLf/1u86WWFx4sXiqIjmy1Ma0Ew=
|
||||||
k8s.io/api v0.0.0-20220504022944-af4f75e1994c/go.mod h1:jimmvAe8QfauNx6CM87E20mTsK3CPgiOzVhfaNASkJc=
|
k8s.io/api v0.0.0-20220504102935-d672b36ea3cc/go.mod h1:Vj1A561tKmF3X1XV1/cGWVWkImJjDjTF6HwinifdHTU=
|
||||||
k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5 h1:nG9Zc74nUlkVHMapMJVjlH8hT3z/fBVixlVfrsQgi24=
|
k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493 h1:82cE3vib2ZIhoyz153bSAnuxMUdXg1OpLaUM6pzES7M=
|
||||||
k8s.io/apimachinery v0.0.0-20220406001655-080c0c77fab5/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
|
k8s.io/apimachinery v0.0.0-20220504062721-f71cc2793493/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
|
||||||
k8s.io/cli-runtime v0.0.0-20220504025609-ddf455f66463 h1:Ici2x2ahD3k0wJrSae1tKf+EcRyRLqCVE8A5UtOvHjo=
|
k8s.io/cli-runtime v0.0.0-20220504105501-409fed9c3710 h1:yVfKFMu1WND4kXkZ9Omz+ARwv100u79FCK/NvkUtSoQ=
|
||||||
k8s.io/cli-runtime v0.0.0-20220504025609-ddf455f66463/go.mod h1:QPB7YO7HzmeJ2395hCEgbQFW3niSRHB9AXZpY2EFzAo=
|
k8s.io/cli-runtime v0.0.0-20220504105501-409fed9c3710/go.mod h1:gWdRQ13VLR/a+yiU58iF3g8mWSDus9mSPRN5446AX78=
|
||||||
k8s.io/client-go v0.0.0-20220504023308-2cf1a8ffd6db h1:aXmNBd0tI9tm/FSO/qvvW+lyICneJG6ca2i/8qLz1w8=
|
k8s.io/client-go v0.0.0-20220504103257-671a40c59fca h1:pEW1UmtrNAzdrTfqNGWiHWaT9KDfIIZfs6vr92QS7sw=
|
||||||
k8s.io/client-go v0.0.0-20220504023308-2cf1a8ffd6db/go.mod h1:KJemYjNFgrswAbSygu5ZHEKc0dcSAqtdDT+4yUrlbmU=
|
k8s.io/client-go v0.0.0-20220504103257-671a40c59fca/go.mod h1:MC9EDRCerAZmmAej+VErcA2dxQjPkyFIQGdQqQ9ukns=
|
||||||
k8s.io/code-generator v0.0.0-20220330050606-8f17de063761/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
|
k8s.io/code-generator v0.0.0-20220330050606-8f17de063761/go.mod h1:dpVhs00hTuTdTY6jvVxvTFCk6gSMrtfRydbhZwHI15w=
|
||||||
k8s.io/component-base v0.0.0-20220331212037-3b9b201c27aa h1:HXrw3PNPz5LUdx4tWHrhjcRadLTrUmerZmNc4MRYuOg=
|
k8s.io/component-base v0.0.0-20220504063447-4aebdd2c2313 h1:NkLMk8jPcPD+PW//Vd7hDEkWBObtjYK7rBdrO+wA3Q8=
|
||||||
k8s.io/component-base v0.0.0-20220331212037-3b9b201c27aa/go.mod h1:3bhERi0RMmLibjhzQTaOenaiYbqZrwtoCRd58dbFtDk=
|
k8s.io/component-base v0.0.0-20220504063447-4aebdd2c2313/go.mod h1:yrC0IokBPJIarOJTeyCdZaGTO58y88bGUVvoT8PQbwQ=
|
||||||
k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6 h1:uk/kmIZFMsRpJhHc2o+5bsfgtM1jBPwIruKSzG61O98=
|
k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6 h1:uk/kmIZFMsRpJhHc2o+5bsfgtM1jBPwIruKSzG61O98=
|
||||||
k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6/go.mod h1:Pn21kKbelGrlFs9SrhcV8MpJLWSlCkH/7K8qUl00wcg=
|
k8s.io/component-helpers v0.0.0-20220330052013-855d491da0b6/go.mod h1:Pn21kKbelGrlFs9SrhcV8MpJLWSlCkH/7K8qUl00wcg=
|
||||||
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
|
||||||
|
|
|
||||||
|
|
@ -840,6 +840,7 @@ func describePod(pod *corev1.Pod, events *corev1.EventList) (string, error) {
|
||||||
}
|
}
|
||||||
printLabelsMultiline(w, "Node-Selectors", pod.Spec.NodeSelector)
|
printLabelsMultiline(w, "Node-Selectors", pod.Spec.NodeSelector)
|
||||||
printPodTolerationsMultiline(w, "Tolerations", pod.Spec.Tolerations)
|
printPodTolerationsMultiline(w, "Tolerations", pod.Spec.Tolerations)
|
||||||
|
describeTopologySpreadConstraints(pod.Spec.TopologySpreadConstraints, w, "")
|
||||||
if events != nil {
|
if events != nil {
|
||||||
DescribeEvents(events, w)
|
DescribeEvents(events, w)
|
||||||
}
|
}
|
||||||
|
|
@ -865,6 +866,32 @@ func describePodIPs(pod *corev1.Pod, w PrefixWriter, space string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func describeTopologySpreadConstraints(tscs []corev1.TopologySpreadConstraint, w PrefixWriter, space string) {
|
||||||
|
if len(tscs) == 0 {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
sort.Slice(tscs, func(i, j int) bool {
|
||||||
|
return tscs[i].TopologyKey < tscs[j].TopologyKey
|
||||||
|
})
|
||||||
|
|
||||||
|
w.Write(LEVEL_0, "%sTopology Spread Constraints:\t", space)
|
||||||
|
for i, tsc := range tscs {
|
||||||
|
if i != 0 {
|
||||||
|
w.Write(LEVEL_0, "%s", space)
|
||||||
|
w.Write(LEVEL_0, "%s", "\t")
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Write(LEVEL_0, "%s:", tsc.TopologyKey)
|
||||||
|
w.Write(LEVEL_0, "%v", tsc.WhenUnsatisfiable)
|
||||||
|
w.Write(LEVEL_0, " when max skew %d is exceeded", tsc.MaxSkew)
|
||||||
|
if tsc.LabelSelector != nil {
|
||||||
|
w.Write(LEVEL_0, " for selector %s", metav1.FormatLabelSelector(tsc.LabelSelector))
|
||||||
|
}
|
||||||
|
w.Write(LEVEL_0, "\n")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func describeVolumes(volumes []corev1.Volume, w PrefixWriter, space string) {
|
func describeVolumes(volumes []corev1.Volume, w PrefixWriter, space string) {
|
||||||
if len(volumes) == 0 {
|
if len(volumes) == 0 {
|
||||||
w.Write(LEVEL_0, "%sVolumes:\t<none>\n", space)
|
w.Write(LEVEL_0, "%sVolumes:\t<none>\n", space)
|
||||||
|
|
@ -2110,6 +2137,7 @@ func DescribePodTemplate(template *corev1.PodTemplateSpec, w PrefixWriter) {
|
||||||
}
|
}
|
||||||
describeContainers("Containers", template.Spec.Containers, nil, nil, w, " ")
|
describeContainers("Containers", template.Spec.Containers, nil, nil, w, " ")
|
||||||
describeVolumes(template.Spec.Volumes, w, " ")
|
describeVolumes(template.Spec.Volumes, w, " ")
|
||||||
|
describeTopologySpreadConstraints(template.Spec.TopologySpreadConstraints, w, " ")
|
||||||
if len(template.Spec.PriorityClassName) > 0 {
|
if len(template.Spec.PriorityClassName) > 0 {
|
||||||
w.Write(LEVEL_1, "Priority Class Name:\t%s\n", template.Spec.PriorityClassName)
|
w.Write(LEVEL_1, "Priority Class Name:\t%s\n", template.Spec.PriorityClassName)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -211,6 +211,40 @@ func TestDescribePodTolerations(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestDescribeTopologySpreadConstraints(t *testing.T) {
|
||||||
|
fake := fake.NewSimpleClientset(&corev1.Pod{
|
||||||
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
Name: "bar",
|
||||||
|
Namespace: "foo",
|
||||||
|
},
|
||||||
|
Spec: corev1.PodSpec{
|
||||||
|
TopologySpreadConstraints: []corev1.TopologySpreadConstraint{
|
||||||
|
{
|
||||||
|
MaxSkew: 3,
|
||||||
|
TopologyKey: "topology.kubernetes.io/test1",
|
||||||
|
WhenUnsatisfiable: "DoNotSchedule",
|
||||||
|
LabelSelector: &metav1.LabelSelector{MatchLabels: map[string]string{"key1": "val1", "key2": "val2"}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
MaxSkew: 1,
|
||||||
|
TopologyKey: "topology.kubernetes.io/test2",
|
||||||
|
WhenUnsatisfiable: "ScheduleAnyway",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
})
|
||||||
|
c := &describeClient{T: t, Namespace: "foo", Interface: fake}
|
||||||
|
d := PodDescriber{c}
|
||||||
|
out, err := d.Describe("foo", "bar", DescriberSettings{})
|
||||||
|
if err != nil {
|
||||||
|
t.Errorf("unexpected error: %v", err)
|
||||||
|
}
|
||||||
|
if !strings.Contains(out, "topology.kubernetes.io/test1:DoNotSchedule when max skew 3 is exceeded for selector key1=val1,key2=val2\n") ||
|
||||||
|
!strings.Contains(out, "topology.kubernetes.io/test2:ScheduleAnyway when max skew 1 is exceeded\n") {
|
||||||
|
t.Errorf("unexpected out:\n%s", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestDescribeSecret(t *testing.T) {
|
func TestDescribeSecret(t *testing.T) {
|
||||||
fake := fake.NewSimpleClientset(&corev1.Secret{
|
fake := fake.NewSimpleClientset(&corev1.Secret{
|
||||||
ObjectMeta: metav1.ObjectMeta{
|
ObjectMeta: metav1.ObjectMeta{
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue