diff --git a/staging/src/k8s.io/kubectl/pkg/describe/describe.go b/staging/src/k8s.io/kubectl/pkg/describe/describe.go index 18fe58e7ac5..d28db401063 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, "") @@ -1777,6 +1783,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 12dfa77e74b..27e1e2fd649 100644 --- a/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go +++ b/staging/src/k8s.io/kubectl/pkg/describe/describe_test.go @@ -5563,3 +5563,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) + } + } + }) + } +}