Merge pull request #113284 from williamyeh/display_seccomp

kubectl displays seccomp profile for pod and container

Kubernetes-commit: 6d81a2c30dd5e88d92335f4b1088f2d19775e3f7
This commit is contained in:
Kubernetes Publisher 2022-12-09 14:33:56 -08:00
commit 2ef5d7b1b7
4 changed files with 157 additions and 4 deletions

4
go.mod
View File

@ -31,7 +31,7 @@ require (
golang.org/x/sys v0.3.0 golang.org/x/sys v0.3.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
k8s.io/api v0.0.0-20221207015603-ed9fa272abb9 k8s.io/api v0.0.0-20221207015603-ed9fa272abb9
k8s.io/apimachinery v0.0.0-20221207014915-9bd0499e768a k8s.io/apimachinery v0.0.0-20221209232824-2e6c99af8b72
k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f
k8s.io/client-go v0.0.0-20221207020356-6cbd19f22fe1 k8s.io/client-go v0.0.0-20221207020356-6cbd19f22fe1
k8s.io/component-base v0.0.0-20221207022911-5a27a217e76d k8s.io/component-base v0.0.0-20221207022911-5a27a217e76d
@ -92,7 +92,7 @@ require (
replace ( replace (
k8s.io/api => k8s.io/api v0.0.0-20221207015603-ed9fa272abb9 k8s.io/api => k8s.io/api v0.0.0-20221207015603-ed9fa272abb9
k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20221207014915-9bd0499e768a k8s.io/apimachinery => k8s.io/apimachinery v0.0.0-20221209232824-2e6c99af8b72
k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f k8s.io/cli-runtime => k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f
k8s.io/client-go => k8s.io/client-go v0.0.0-20221207020356-6cbd19f22fe1 k8s.io/client-go => k8s.io/client-go v0.0.0-20221207020356-6cbd19f22fe1
k8s.io/code-generator => k8s.io/code-generator v0.0.0-20221207014433-154dfe63ab2d k8s.io/code-generator => k8s.io/code-generator v0.0.0-20221207014433-154dfe63ab2d

4
go.sum
View File

@ -542,8 +542,8 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
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-20221207015603-ed9fa272abb9 h1:HLAJNDewiVFOPssbWj15wbBwf+hux5vvKmb/IPOYRA0= k8s.io/api v0.0.0-20221207015603-ed9fa272abb9 h1:HLAJNDewiVFOPssbWj15wbBwf+hux5vvKmb/IPOYRA0=
k8s.io/api v0.0.0-20221207015603-ed9fa272abb9/go.mod h1:vEl0AqSszI3xQA7JB97wMoYep+pWYIJ0q/Y02t23lBE= k8s.io/api v0.0.0-20221207015603-ed9fa272abb9/go.mod h1:vEl0AqSszI3xQA7JB97wMoYep+pWYIJ0q/Y02t23lBE=
k8s.io/apimachinery v0.0.0-20221207014915-9bd0499e768a h1:fTLcpcQ80F7+fAF/GSC2IWZAD1V3NcOy4kO0kdDRujQ= k8s.io/apimachinery v0.0.0-20221209232824-2e6c99af8b72 h1:z8gl4KftM5LFWJyJ3D0+iGodkGpODLL55sSsZbf/A1Y=
k8s.io/apimachinery v0.0.0-20221207014915-9bd0499e768a/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74= k8s.io/apimachinery v0.0.0-20221209232824-2e6c99af8b72/go.mod h1:tnPmbONNJ7ByJNz9+n9kMjNP8ON+1qoAIIC70lztu74=
k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f h1:5ows8uOPcwt9tf1i3gkUKcJI9MUdr+7xg9L1h2gZ+Vo= k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f h1:5ows8uOPcwt9tf1i3gkUKcJI9MUdr+7xg9L1h2gZ+Vo=
k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f/go.mod h1:O2C0cvncfysbWQJ0s0LJ1VXL2iYB/z+Lt4GQHK+/PSA= k8s.io/cli-runtime v0.0.0-20221207032320-501e6958314f/go.mod h1:O2C0cvncfysbWQJ0s0LJ1VXL2iYB/z+Lt4GQHK+/PSA=
k8s.io/client-go v0.0.0-20221207020356-6cbd19f22fe1 h1:9B050CQqaBS1G2H/dAO67XbJ30PE3s/yWVFefBB0Oak= k8s.io/client-go v0.0.0-20221207020356-6cbd19f22fe1 h1:9B050CQqaBS1G2H/dAO67XbJ30PE3s/yWVFefBB0Oak=

View File

@ -798,6 +798,12 @@ func describePod(pod *corev1.Pod, events *corev1.EventList) (string, error) {
if len(pod.Status.Message) > 0 { if len(pod.Status.Message) > 0 {
w.Write(LEVEL_0, "Message:\t%s\n", pod.Status.Message) 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 // remove when .IP field is depreciated
w.Write(LEVEL_0, "IP:\t%s\n", pod.Status.PodIP) w.Write(LEVEL_0, "IP:\t%s\n", pod.Status.PodIP)
describePodIPs(pod, w, "") describePodIPs(pod, w, "")
@ -1777,6 +1783,12 @@ func describeContainerBasicInfo(container corev1.Container, status corev1.Contai
} else { } else {
w.Write(LEVEL_2, "Host Port:\t%s\n", stringOrNone(hostPortString)) 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 { func describeContainerPorts(cPorts []corev1.ContainerPort) string {

View File

@ -5563,3 +5563,144 @@ func TestDescribeTerminalEscape(t *testing.T) {
t.Errorf("unexpected out: %s", out) 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)
}
}
})
}
}