Adding support for pod level resources in kubectl

1. Add support for pod level resources in kubectl
2. Reuse the existing method to describe container resources and generalize it to describe both pod and container level resources
This commit is contained in:
ndixita 2024-10-24 21:13:54 +00:00
parent 85488b5f10
commit 502e0f55c4
2 changed files with 80 additions and 7 deletions

View File

@ -838,6 +838,11 @@ func describePod(pod *corev1.Pod, events *corev1.EventList) (string, error) {
w.Write(LEVEL_0, "NominatedNodeName:\t%s\n", pod.Status.NominatedNodeName)
}
if pod.Spec.Resources != nil {
w.Write(LEVEL_0, "Resources:\n")
describeResources(pod.Spec.Resources, w, LEVEL_1)
}
if len(pod.Spec.InitContainers) > 0 {
describeContainers("Init Containers", pod.Spec.InitContainers, pod.Status.InitContainerStatuses, EnvValueRetriever(pod), w, "")
}
@ -1800,7 +1805,7 @@ func describeContainers(label string, containers []corev1.Container, containerSt
if ok {
describeContainerState(status, w)
}
describeContainerResource(container, w)
describeResources(&container.Resources, w, LEVEL_2)
describeContainerProbe(container, w)
if len(container.EnvFrom) > 0 {
describeContainerEnvFrom(container, resolverFn, w)
@ -1886,22 +1891,25 @@ func describeContainerCommand(container corev1.Container, w PrefixWriter) {
}
}
func describeContainerResource(container corev1.Container, w PrefixWriter) {
resources := container.Resources
func describeResources(resources *corev1.ResourceRequirements, w PrefixWriter, level int) {
if resources == nil {
return
}
if len(resources.Limits) > 0 {
w.Write(LEVEL_2, "Limits:\n")
w.Write(level, "Limits:\n")
}
for _, name := range SortedResourceNames(resources.Limits) {
quantity := resources.Limits[name]
w.Write(LEVEL_3, "%s:\t%s\n", name, quantity.String())
w.Write(level+1, "%s:\t%s\n", name, quantity.String())
}
if len(resources.Requests) > 0 {
w.Write(LEVEL_2, "Requests:\n")
w.Write(level, "Requests:\n")
}
for _, name := range SortedResourceNames(resources.Requests) {
quantity := resources.Requests[name]
w.Write(LEVEL_3, "%s:\t%s\n", name, quantity.String())
w.Write(level+1, "%s:\t%s\n", name, quantity.String())
}
}

View File

@ -1179,6 +1179,71 @@ func VerifyDatesInOrder(
}
}
func TestDescribeResources(t *testing.T) {
testCases := []struct {
resources *corev1.ResourceRequirements
expectedElements map[string]int
}{
{
resources: &corev1.ResourceRequirements{},
expectedElements: map[string]int{},
},
{
resources: &corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1000"),
corev1.ResourceMemory: resource.MustParse("100Mi"),
},
Limits: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1000"),
corev1.ResourceMemory: resource.MustParse("100Mi"),
},
},
expectedElements: map[string]int{"cpu": 2, "memory": 2, "Requests": 1, "Limits": 1, "1k": 2, "100Mi": 2},
},
{
resources: &corev1.ResourceRequirements{
Limits: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1000"),
corev1.ResourceMemory: resource.MustParse("100Mi"),
},
},
expectedElements: map[string]int{"cpu": 1, "memory": 1, "Limits": 1, "1k": 1, "100Mi": 1},
},
{
resources: &corev1.ResourceRequirements{
Requests: corev1.ResourceList{
corev1.ResourceCPU: resource.MustParse("1000"),
corev1.ResourceMemory: resource.MustParse("100Mi"),
},
},
expectedElements: map[string]int{"cpu": 1, "memory": 1, "Requests": 1, "1k": 1, "100Mi": 1},
},
}
for i, testCase := range testCases {
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
out := new(bytes.Buffer)
writer := NewPrefixWriter(out)
describeResources(testCase.resources, writer, LEVEL_1)
output := out.String()
gotElements := make(map[string]int)
for key, val := range testCase.expectedElements {
count := strings.Count(output, key)
if count == 0 {
t.Errorf("expected to find %q in output: %q", val, output)
continue
}
gotElements[key] = count
}
if !reflect.DeepEqual(gotElements, testCase.expectedElements) {
t.Errorf("Expected %v, got %v in output string: %q", testCase.expectedElements, gotElements, output)
}
})
}
}
func TestDescribeContainers(t *testing.T) {
trueVal := true
testCases := []struct {