From a4dac224e7ef5d4c1a50b5c6a5f89c39f3115381 Mon Sep 17 00:00:00 2001 From: "William, Yeh" Date: Sun, 23 Oct 2022 21:53:05 -0400 Subject: [PATCH] kubectl displays seccomp profile for pod and container --- .../k8s.io/kubectl/pkg/describe/describe.go | 12 ++ .../kubectl/pkg/describe/describe_test.go | 141 ++++++++++++++++++ 2 files changed, 153 insertions(+) diff --git a/staging/src/k8s.io/kubectl/pkg/describe/describe.go b/staging/src/k8s.io/kubectl/pkg/describe/describe.go index b3c47144446..4c30889a007 100644 --- a/staging/src/k8s.io/kubectl/pkg/describe/describe.go +++ b/staging/src/k8s.io/kubectl/pkg/describe/describe.go @@ -798,6 +798,12 @@ func describePod(pod *corev1.Pod, events *corev1.EventList) (string, error) { if len(pod.Status.Message) > 0 { w.Write(LEVEL_0, "Message:\t%s\n", pod.Status.Message) } + if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SeccompProfile != nil { + w.Write(LEVEL_0, "SeccompProfile:\t%s\n", pod.Spec.SecurityContext.SeccompProfile.Type) + if pod.Spec.SecurityContext.SeccompProfile.Type == corev1.SeccompProfileTypeLocalhost { + w.Write(LEVEL_0, "LocalhostProfile:\t%s\n", *pod.Spec.SecurityContext.SeccompProfile.LocalhostProfile) + } + } // remove when .IP field is depreciated w.Write(LEVEL_0, "IP:\t%s\n", pod.Status.PodIP) describePodIPs(pod, w, "") @@ -1755,6 +1761,12 @@ func describeContainerBasicInfo(container corev1.Container, status corev1.Contai } else { w.Write(LEVEL_2, "Host Port:\t%s\n", stringOrNone(hostPortString)) } + if container.SecurityContext != nil && container.SecurityContext.SeccompProfile != nil { + w.Write(LEVEL_2, "SeccompProfile:\t%s\n", container.SecurityContext.SeccompProfile.Type) + if container.SecurityContext.SeccompProfile.Type == corev1.SeccompProfileTypeLocalhost { + w.Write(LEVEL_3, "LocalhostProfile:\t%s\n", *container.SecurityContext.SeccompProfile.LocalhostProfile) + } + } } func describeContainerPorts(cPorts []corev1.ContainerPort) string { 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 adad2a8374f..be68cceff4c 100644 --- a/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go +++ b/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go @@ -5526,3 +5526,144 @@ func TestDescribeTerminalEscape(t *testing.T) { t.Errorf("unexpected out: %s", out) } } + +func TestDescribeSeccompProfile(t *testing.T) { + testLocalhostProfiles := []string{"lauseafoodpod", "tikkamasalaconatiner", "dropshotephemeral"} + + testCases := []struct { + name string + pod *corev1.Pod + expect []string + }{ + { + name: "podLocalhostSeccomp", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeLocalhost, + LocalhostProfile: &testLocalhostProfiles[0], + }, + }, + }, + }, + expect: []string{ + "SeccompProfile", "Localhost", + "LocalhostProfile", testLocalhostProfiles[0], + }, + }, + { + name: "podOther", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + SecurityContext: &corev1.PodSecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeRuntimeDefault, + }, + }, + }, + }, + expect: []string{ + "SeccompProfile", "RuntimeDefault", + }, + }, + { + name: "containerLocalhostSeccomp", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + SecurityContext: &corev1.SecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeLocalhost, + LocalhostProfile: &testLocalhostProfiles[1], + }, + }, + }, + }, + }, + }, + expect: []string{ + "SeccompProfile", "Localhost", + "LocalhostProfile", testLocalhostProfiles[1], + }, + }, + { + name: "containerOther", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + SecurityContext: &corev1.SecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeUnconfined, + }, + }, + }, + }, + }, + }, + expect: []string{ + "SeccompProfile", "Unconfined", + }, + }, + { + name: "ephemeralLocalhostSeccomp", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + EphemeralContainers: []corev1.EphemeralContainer{ + { + EphemeralContainerCommon: corev1.EphemeralContainerCommon{ + SecurityContext: &corev1.SecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeLocalhost, + LocalhostProfile: &testLocalhostProfiles[2], + }, + }, + }, + }, + }, + }, + }, + expect: []string{ + "SeccompProfile", "Localhost", + "LocalhostProfile", testLocalhostProfiles[2], + }, + }, + { + name: "ephemeralOther", + pod: &corev1.Pod{ + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + SecurityContext: &corev1.SecurityContext{ + SeccompProfile: &corev1.SeccompProfile{ + Type: corev1.SeccompProfileTypeUnconfined, + }, + }, + }, + }, + }, + }, + expect: []string{ + "SeccompProfile", "Unconfined", + }, + }, + } + for _, testCase := range testCases { + t.Run(testCase.name, func(t *testing.T) { + fake := fake.NewSimpleClientset(testCase.pod) + c := &describeClient{T: t, Interface: fake} + d := PodDescriber{c} + out, err := d.Describe("", "", 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) + } + } + }) + } +}