diff --git a/pkg/api/pod/util.go b/pkg/api/pod/util.go index 36e1e86c405..a0af5b15de9 100644 --- a/pkg/api/pod/util.go +++ b/pkg/api/pod/util.go @@ -777,36 +777,6 @@ func SeccompAnnotationForField(field *api.SeccompProfile) string { return "" } -// SeccompFieldForAnnotation takes a pod annotation and returns the converted -// seccomp profile field. -func SeccompFieldForAnnotation(annotation string) *api.SeccompProfile { - // If only seccomp annotations are specified, copy the values into the - // corresponding fields. This ensures that existing applications continue - // to enforce seccomp, and prevents the kubelet from needing to resolve - // annotations & fields. - if annotation == v1.SeccompProfileNameUnconfined { - return &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined} - } - - if annotation == api.SeccompProfileRuntimeDefault || annotation == api.DeprecatedSeccompProfileDockerDefault { - return &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault} - } - - if strings.HasPrefix(annotation, v1.SeccompLocalhostProfileNamePrefix) { - localhostProfile := strings.TrimPrefix(annotation, v1.SeccompLocalhostProfileNamePrefix) - if localhostProfile != "" { - return &api.SeccompProfile{ - Type: api.SeccompProfileTypeLocalhost, - LocalhostProfile: &localhostProfile, - } - } - } - - // we can only reach this code path if the localhostProfile name has a zero - // length or if the annotation has an unrecognized value - return nil -} - // setsWindowsHostProcess returns true if WindowsOptions.HostProcess is set (true or false) // anywhere in the pod spec. func setsWindowsHostProcess(podSpec *api.PodSpec) bool { diff --git a/pkg/api/pod/warnings.go b/pkg/api/pod/warnings.go index bacf1ce651c..79f5db2f357 100644 --- a/pkg/api/pod/warnings.go +++ b/pkg/api/pod/warnings.go @@ -240,7 +240,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta // use of pod seccomp annotation without accompanying field if podSpec.SecurityContext == nil || podSpec.SecurityContext.SeccompProfile == nil { if _, exists := meta.Annotations[api.SeccompPodAnnotationKey]; exists { - warnings = append(warnings, fmt.Sprintf(`%s: deprecated since v1.19, non-functional in v1.25+; use the "seccompProfile" field instead`, fieldPath.Child("metadata", "annotations").Key(api.SeccompPodAnnotationKey))) + warnings = append(warnings, fmt.Sprintf(`%s: deprecated since v1.19, non-functional in a future release; use the "seccompProfile" field instead`, fieldPath.Child("metadata", "annotations").Key(api.SeccompPodAnnotationKey))) } } @@ -248,7 +248,7 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta // use of container seccomp annotation without accompanying field if c.SecurityContext == nil || c.SecurityContext.SeccompProfile == nil { if _, exists := meta.Annotations[api.SeccompContainerAnnotationKeyPrefix+c.Name]; exists { - warnings = append(warnings, fmt.Sprintf(`%s: deprecated since v1.19, non-functional in v1.25+; use the "seccompProfile" field instead`, fieldPath.Child("metadata", "annotations").Key(api.SeccompContainerAnnotationKeyPrefix+c.Name))) + warnings = append(warnings, fmt.Sprintf(`%s: deprecated since v1.19, non-functional in a future release; use the "seccompProfile" field instead`, fieldPath.Child("metadata", "annotations").Key(api.SeccompContainerAnnotationKeyPrefix+c.Name))) } } diff --git a/pkg/api/pod/warnings_test.go b/pkg/api/pod/warnings_test.go index 0d322399c09..0b9bb00c915 100644 --- a/pkg/api/pod/warnings_test.go +++ b/pkg/api/pod/warnings_test.go @@ -432,8 +432,8 @@ func TestWarnings(t *testing.T) { }, expected: []string{ `metadata.annotations[scheduler.alpha.kubernetes.io/critical-pod]: non-functional in v1.16+; use the "priorityClassName" field instead`, - `metadata.annotations[seccomp.security.alpha.kubernetes.io/pod]: deprecated since v1.19, non-functional in v1.25+; use the "seccompProfile" field instead`, - `metadata.annotations[container.seccomp.security.alpha.kubernetes.io/foo]: deprecated since v1.19, non-functional in v1.25+; use the "seccompProfile" field instead`, + `metadata.annotations[seccomp.security.alpha.kubernetes.io/pod]: deprecated since v1.19, non-functional in a future release; use the "seccompProfile" field instead`, + `metadata.annotations[container.seccomp.security.alpha.kubernetes.io/foo]: deprecated since v1.19, non-functional in a future release; use the "seccompProfile" field instead`, `metadata.annotations[security.alpha.kubernetes.io/sysctls]: non-functional in v1.11+; use the "sysctls" field instead`, `metadata.annotations[security.alpha.kubernetes.io/unsafe-sysctls]: non-functional in v1.11+; use the "sysctls" field instead`, }, diff --git a/pkg/apis/core/validation/validation.go b/pkg/apis/core/validation/validation.go index a5e24e83cad..fd8a67b2313 100644 --- a/pkg/apis/core/validation/validation.go +++ b/pkg/apis/core/validation/validation.go @@ -4218,7 +4218,7 @@ func ValidatePodCreate(pod *core.Pod, opts PodValidationOptions) field.ErrorList return allErrs } -// ValidateSeccompAnnotationsAndFields iterates through all containers and ensure that when both seccompProfile and seccomp annotations exist they match. +// validateSeccompAnnotationsAndFields iterates through all containers and ensure that when both seccompProfile and seccomp annotations exist they match. func validateSeccompAnnotationsAndFields(objectMeta metav1.ObjectMeta, podSpec *core.PodSpec, specPath *field.Path) field.ErrorList { allErrs := field.ErrorList{} diff --git a/pkg/kubelet/kuberuntime/helpers.go b/pkg/kubelet/kuberuntime/helpers.go index de289836a8b..0f8e2eb718f 100644 --- a/pkg/kubelet/kuberuntime/helpers.go +++ b/pkg/kubelet/kuberuntime/helpers.go @@ -234,15 +234,6 @@ func fieldProfile(scmp *v1.SeccompProfile, profileRootPath string, fallbackToRun return "" } -func annotationProfile(profile, profileRootPath string) string { - if strings.HasPrefix(profile, v1.SeccompLocalhostProfileNamePrefix) { - name := strings.TrimPrefix(profile, v1.SeccompLocalhostProfileNamePrefix) - fname := filepath.Join(profileRootPath, filepath.FromSlash(name)) - return v1.SeccompLocalhostProfileNamePrefix + fname - } - return profile -} - func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string]string, containerName string, podSecContext *v1.PodSecurityContext, containerSecContext *v1.SecurityContext, fallbackToRuntimeDefault bool) string { // container fields are applied first @@ -250,23 +241,11 @@ func (m *kubeGenericRuntimeManager) getSeccompProfilePath(annotations map[string return fieldProfile(containerSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault) } - // if container field does not exist, try container annotation (deprecated) - if containerName != "" { - if profile, ok := annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName]; ok { - return annotationProfile(profile, m.seccompProfileRoot) - } - } - // when container seccomp is not defined, try to apply from pod field if podSecContext != nil && podSecContext.SeccompProfile != nil { return fieldProfile(podSecContext.SeccompProfile, m.seccompProfileRoot, fallbackToRuntimeDefault) } - // as last resort, try to apply pod annotation (deprecated) - if profile, ok := annotations[v1.SeccompPodAnnotationKey]; ok { - return annotationProfile(profile, m.seccompProfileRoot) - } - if fallbackToRuntimeDefault { return v1.SeccompProfileRuntimeDefault } diff --git a/pkg/kubelet/kuberuntime/helpers_test.go b/pkg/kubelet/kuberuntime/helpers_test.go index 25065f30411..faf2e15e567 100644 --- a/pkg/kubelet/kuberuntime/helpers_test.go +++ b/pkg/kubelet/kuberuntime/helpers_test.go @@ -369,91 +369,6 @@ func TestGetSeccompProfilePath(t *testing.T) { containerName: "container1", expectedProfile: "", }, - { - description: "annotations: pod runtime/default seccomp profile should return runtime/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault, - }, - expectedProfile: "runtime/default", - }, - { - description: "annotations: pod docker/default seccomp profile should return docker/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault, - }, - expectedProfile: "docker/default", - }, - { - description: "annotations: pod runtime/default seccomp profile with containerName should return runtime/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault, - }, - containerName: "container1", - expectedProfile: "runtime/default", - }, - { - description: "annotations: pod docker/default seccomp profile with containerName should return docker/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault, - }, - containerName: "container1", - expectedProfile: "docker/default", - }, - { - description: "annotations: pod unconfined seccomp profile should return unconfined", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, - }, - expectedProfile: "unconfined", - }, - { - description: "annotations: pod unconfined seccomp profile with containerName should return unconfined", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, - }, - containerName: "container1", - expectedProfile: "unconfined", - }, - { - description: "annotations: pod localhost seccomp profile should return local profile path", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/chmod.json", - }, - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: pod localhost seccomp profile with containerName should return local profile path", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/chmod.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: container localhost seccomp profile with containerName should return local profile path", - annotation: map[string]string{ - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: container localhost seccomp profile should override pod profile", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: container localhost seccomp profile with unmatched containerName should return empty", - annotation: map[string]string{ - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json", - }, - containerName: "container2", - expectedProfile: "", - }, { description: "pod seccomp profile set to unconfined returns unconfined", podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}}, @@ -500,36 +415,6 @@ func TestGetSeccompProfilePath(t *testing.T) { containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}}, expectedProfile: "runtime/default", }, - { - description: "prioritise container field over container annotation, pod field and pod annotation", - podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}}, - containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}}, - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json", - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("field-cont-profile.json"), - }, - { - description: "prioritise container annotation over pod field", - podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}}, - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json", - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("annota-cont-profile.json"), - }, - { - description: "prioritise pod field over pod annotation", - podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}}, - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("field-pod-profile.json"), - }, } for i, test := range tests { @@ -559,91 +444,6 @@ func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) { containerName: "container1", expectedProfile: v1.SeccompProfileRuntimeDefault, }, - { - description: "annotations: pod runtime/default seccomp profile should return runtime/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault, - }, - expectedProfile: v1.SeccompProfileRuntimeDefault, - }, - { - description: "annotations: pod docker/default seccomp profile should return docker/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault, - }, - expectedProfile: "docker/default", - }, - { - description: "annotations: pod runtime/default seccomp profile with containerName should return runtime/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileRuntimeDefault, - }, - containerName: "container1", - expectedProfile: v1.SeccompProfileRuntimeDefault, - }, - { - description: "annotations: pod docker/default seccomp profile with containerName should return docker/default", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.DeprecatedSeccompProfileDockerDefault, - }, - containerName: "container1", - expectedProfile: "docker/default", - }, - { - description: "annotations: pod unconfined seccomp profile should return unconfined", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, - }, - expectedProfile: "unconfined", - }, - { - description: "annotations: pod unconfined seccomp profile with containerName should return unconfined", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, - }, - containerName: "container1", - expectedProfile: "unconfined", - }, - { - description: "annotations: pod localhost seccomp profile should return local profile path", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/chmod.json", - }, - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: pod localhost seccomp profile with containerName should return local profile path", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/chmod.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: container localhost seccomp profile with containerName should return local profile path", - annotation: map[string]string{ - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: container localhost seccomp profile should override pod profile", - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: v1.SeccompProfileNameUnconfined, - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("chmod.json"), - }, - { - description: "annotations: container localhost seccomp profile with unmatched containerName should return runtime/default", - annotation: map[string]string{ - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/chmod.json", - }, - containerName: "container2", - expectedProfile: v1.SeccompProfileRuntimeDefault, - }, { description: "pod seccomp profile set to unconfined returns unconfined", podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}}, @@ -690,36 +490,6 @@ func TestGetSeccompProfilePathDefaultSeccomp(t *testing.T) { containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}}, expectedProfile: "runtime/default", }, - { - description: "prioritise container field over container annotation, pod field and pod annotation", - podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}}, - containerSc: &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-cont-profile.json")}}, - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json", - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("field-cont-profile.json"), - }, - { - description: "prioritise container annotation over pod field", - podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}}, - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json", - v1.SeccompContainerAnnotationKeyPrefix + "container1": "localhost/annota-cont-profile.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("annota-cont-profile.json"), - }, - { - description: "prioritise pod field over pod annotation", - podSc: &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeLocalhost, LocalhostProfile: getLocal("field-pod-profile.json")}}, - annotation: map[string]string{ - v1.SeccompPodAnnotationKey: "localhost/annota-pod-profile.json", - }, - containerName: "container1", - expectedProfile: seccompLocalhostPath("field-pod-profile.json"), - }, } for i, test := range tests { diff --git a/pkg/kubelet/kuberuntime/kuberuntime_sandbox_test.go b/pkg/kubelet/kuberuntime/kuberuntime_sandbox_test.go index 00d3b3281f3..3d1738daf3e 100644 --- a/pkg/kubelet/kuberuntime/kuberuntime_sandbox_test.go +++ b/pkg/kubelet/kuberuntime/kuberuntime_sandbox_test.go @@ -158,12 +158,6 @@ func newTestPod() *v1.Pod { func newSeccompPod(podFieldProfile, containerFieldProfile *v1.SeccompProfile, podAnnotationProfile, containerAnnotationProfile string) *v1.Pod { pod := newTestPod() - if podAnnotationProfile != "" { - pod.Annotations = map[string]string{v1.SeccompPodAnnotationKey: podAnnotationProfile} - } - if containerAnnotationProfile != "" { - pod.Annotations = map[string]string{v1.SeccompContainerAnnotationKeyPrefix + "": containerAnnotationProfile} - } if podFieldProfile != nil { pod.Spec.SecurityContext = &v1.PodSecurityContext{ SeccompProfile: podFieldProfile, diff --git a/pkg/registry/core/pod/strategy.go b/pkg/registry/core/pod/strategy.go index 3f4df90d650..5a50105cadc 100644 --- a/pkg/registry/core/pod/strategy.go +++ b/pkg/registry/core/pod/strategy.go @@ -644,28 +644,20 @@ func validateContainer(container string, pod *api.Pod) (string, error) { // applySeccompVersionSkew implements the version skew behavior described in: // https://github.com/kubernetes/enhancements/tree/master/keps/sig-node/135-seccomp#version-skew-strategy +// Note that we dropped copying the field to annotation synchronization in +// v1.25 with the functional removal of the annotations. func applySeccompVersionSkew(pod *api.Pod) { // get possible annotation and field annotation, hasAnnotation := pod.Annotations[v1.SeccompPodAnnotationKey] - field, hasField := (*api.SeccompProfile)(nil), false + hasField := false if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SeccompProfile != nil { - field = pod.Spec.SecurityContext.SeccompProfile hasField = true } // sync field and annotation - if hasField && !hasAnnotation { - newAnnotation := podutil.SeccompAnnotationForField(field) - - if newAnnotation != "" { - if pod.Annotations == nil { - pod.Annotations = map[string]string{} - } - pod.Annotations[v1.SeccompPodAnnotationKey] = newAnnotation - } - } else if hasAnnotation && !hasField { - newField := podutil.SeccompFieldForAnnotation(annotation) + if hasAnnotation && !hasField { + newField := seccompFieldForAnnotation(annotation) if newField != nil { if pod.Spec.SecurityContext == nil { @@ -682,24 +674,14 @@ func applySeccompVersionSkew(pod *api.Pod) { key := api.SeccompContainerAnnotationKeyPrefix + ctr.Name annotation, hasAnnotation := pod.Annotations[key] - field, hasField := (*api.SeccompProfile)(nil), false + hasField := false if ctr.SecurityContext != nil && ctr.SecurityContext.SeccompProfile != nil { - field = ctr.SecurityContext.SeccompProfile hasField = true } // sync field and annotation - if hasField && !hasAnnotation { - newAnnotation := podutil.SeccompAnnotationForField(field) - - if newAnnotation != "" { - if pod.Annotations == nil { - pod.Annotations = map[string]string{} - } - pod.Annotations[key] = newAnnotation - } - } else if hasAnnotation && !hasField { - newField := podutil.SeccompFieldForAnnotation(annotation) + if hasAnnotation && !hasField { + newField := seccompFieldForAnnotation(annotation) if newField != nil { if ctr.SecurityContext == nil { @@ -712,3 +694,33 @@ func applySeccompVersionSkew(pod *api.Pod) { return true }) } + +// seccompFieldForAnnotation takes a pod annotation and returns the converted +// seccomp profile field. +func seccompFieldForAnnotation(annotation string) *api.SeccompProfile { + // If only seccomp annotations are specified, copy the values into the + // corresponding fields. This ensures that existing applications continue + // to enforce seccomp, and prevents the kubelet from needing to resolve + // annotations & fields. + if annotation == v1.SeccompProfileNameUnconfined { + return &api.SeccompProfile{Type: api.SeccompProfileTypeUnconfined} + } + + if annotation == api.SeccompProfileRuntimeDefault || annotation == api.DeprecatedSeccompProfileDockerDefault { + return &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault} + } + + if strings.HasPrefix(annotation, v1.SeccompLocalhostProfileNamePrefix) { + localhostProfile := strings.TrimPrefix(annotation, v1.SeccompLocalhostProfileNamePrefix) + if localhostProfile != "" { + return &api.SeccompProfile{ + Type: api.SeccompProfileTypeLocalhost, + LocalhostProfile: &localhostProfile, + } + } + } + + // we can only reach this code path if the localhostProfile name has a zero + // length or if the annotation has an unrecognized value + return nil +} diff --git a/pkg/registry/core/pod/strategy_test.go b/pkg/registry/core/pod/strategy_test.go index 7e6022e7598..a6e4a530eb7 100644 --- a/pkg/registry/core/pod/strategy_test.go +++ b/pkg/registry/core/pod/strategy_test.go @@ -749,7 +749,7 @@ func TestApplySeccompVersionSkew(t *testing.T) { }, }, { - description: "Field type unconfined and no annotation present", + description: "Field set and no annotation present", pod: &api.Pod{ Spec: api.PodSpec{ SecurityContext: &api.PodSecurityContext{ @@ -759,55 +759,6 @@ func TestApplySeccompVersionSkew(t *testing.T) { }, }, }, - validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 1) - require.Equal(t, v1.SeccompProfileNameUnconfined, pod.Annotations[api.SeccompPodAnnotationKey]) - }, - }, - { - description: "Field type default and no annotation present", - pod: &api.Pod{ - Spec: api.PodSpec{ - SecurityContext: &api.PodSecurityContext{ - SeccompProfile: &api.SeccompProfile{ - Type: api.SeccompProfileTypeRuntimeDefault, - }, - }, - }, - }, - validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 1) - require.Equal(t, v1.SeccompProfileRuntimeDefault, pod.Annotations[v1.SeccompPodAnnotationKey]) - }, - }, - { - description: "Field type localhost and no annotation present", - pod: &api.Pod{ - Spec: api.PodSpec{ - SecurityContext: &api.PodSecurityContext{ - SeccompProfile: &api.SeccompProfile{ - Type: api.SeccompProfileTypeLocalhost, - LocalhostProfile: &testProfile, - }, - }, - }, - }, - validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 1) - require.Equal(t, "localhost/test", pod.Annotations[v1.SeccompPodAnnotationKey]) - }, - }, - { - description: "Field type localhost but profile is nil", - pod: &api.Pod{ - Spec: api.PodSpec{ - SecurityContext: &api.PodSecurityContext{ - SeccompProfile: &api.SeccompProfile{ - Type: api.SeccompProfileTypeLocalhost, - }, - }, - }, - }, validation: func(t *testing.T, pod *api.Pod) { require.Len(t, pod.Annotations, 0) }, @@ -911,7 +862,7 @@ func TestApplySeccompVersionSkew(t *testing.T) { }, }, { - description: "Field type unconfined and no annotation present (container)", + description: "Field set and no annotation present (container)", pod: &api.Pod{ Spec: api.PodSpec{ Containers: []api.Container{ @@ -927,51 +878,7 @@ func TestApplySeccompVersionSkew(t *testing.T) { }, }, validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 1) - require.Equal(t, v1.SeccompProfileNameUnconfined, pod.Annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName]) - }, - }, - { - description: "Field type runtime/default and no annotation present (container)", - pod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: containerName, - SecurityContext: &api.SecurityContext{ - SeccompProfile: &api.SeccompProfile{ - Type: api.SeccompProfileTypeRuntimeDefault, - }, - }, - }, - }, - }, - }, - validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 1) - require.Equal(t, v1.SeccompProfileRuntimeDefault, pod.Annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName]) - }, - }, - { - description: "Field type localhost and no annotation present (container)", - pod: &api.Pod{ - Spec: api.PodSpec{ - Containers: []api.Container{ - { - Name: containerName, - SecurityContext: &api.SecurityContext{ - SeccompProfile: &api.SeccompProfile{ - Type: api.SeccompProfileTypeLocalhost, - LocalhostProfile: &testProfile, - }, - }, - }, - }, - }, - }, - validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 1) - require.Equal(t, "localhost/test", pod.Annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName]) + require.Len(t, pod.Annotations, 0) }, }, { @@ -1002,9 +909,7 @@ func TestApplySeccompVersionSkew(t *testing.T) { }, }, validation: func(t *testing.T, pod *api.Pod) { - require.Len(t, pod.Annotations, 2) - require.Equal(t, v1.SeccompProfileNameUnconfined, pod.Annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName+"1"]) - require.Equal(t, v1.SeccompProfileRuntimeDefault, pod.Annotations[v1.SeccompContainerAnnotationKeyPrefix+containerName+"3"]) + require.Len(t, pod.Annotations, 0) }, }, { diff --git a/staging/src/k8s.io/pod-security-admission/admission/admission.go b/staging/src/k8s.io/pod-security-admission/admission/admission.go index 2d897a78c77..d6450a429f4 100644 --- a/staging/src/k8s.io/pod-security-admission/admission/admission.go +++ b/staging/src/k8s.io/pod-security-admission/admission/admission.go @@ -626,13 +626,10 @@ func (a *Admission) PolicyToEvaluate(labels map[string]string) (api.Policy, fiel } // isSignificantPodUpdate determines whether a pod update should trigger a policy evaluation. -// Relevant mutable pod fields as of 1.21 are image and seccomp annotations: +// Relevant mutable pod fields as of 1.21 are image annotations: // * https://github.com/kubernetes/kubernetes/blob/release-1.21/pkg/apis/core/validation/validation.go#L3947-L3949 func isSignificantPodUpdate(pod, oldPod *corev1.Pod) bool { // TODO: invert this logic to only allow specific update types. - if pod.Annotations[corev1.SeccompPodAnnotationKey] != oldPod.Annotations[corev1.SeccompPodAnnotationKey] { - return true - } if len(pod.Spec.Containers) != len(oldPod.Spec.Containers) { return true } @@ -672,6 +669,7 @@ func isSignificantContainerUpdate(container, oldContainer *corev1.Container, ann if container.Image != oldContainer.Image { return true } + // TODO(saschagrunert): Remove this logic in 1.27. seccompKey := corev1.SeccompContainerAnnotationKeyPrefix + container.Name return annotations[seccompKey] != oldAnnotations[seccompKey] } diff --git a/test/e2e/node/security_context.go b/test/e2e/node/security_context.go index 5a1dbb17d97..9f0a6aa140f 100644 --- a/test/e2e/node/security_context.go +++ b/test/e2e/node/security_context.go @@ -165,27 +165,27 @@ var _ = SIGDescribe("Security Context", func() { pod.Spec.Containers[0].SecurityContext = &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}} pod.Spec.SecurityContext = &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}} pod.Spec.Containers[0].Command = []string{"grep", "ecc", "/proc/self/status"} - f.TestContainerOutput(v1.SeccompPodAnnotationKey, pod, 0, []string{"0"}) // seccomp disabled + f.TestContainerOutput("seccomp unconfined container", pod, 0, []string{"0"}) // seccomp disabled }) ginkgo.It("should support seccomp unconfined on the pod [LinuxOnly]", func() { pod := scTestPod(false, false) pod.Spec.SecurityContext = &v1.PodSecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeUnconfined}} pod.Spec.Containers[0].Command = []string{"grep", "ecc", "/proc/self/status"} - f.TestContainerOutput(v1.SeccompPodAnnotationKey, pod, 0, []string{"0"}) // seccomp disabled + f.TestContainerOutput("seccomp unconfined pod", pod, 0, []string{"0"}) // seccomp disabled }) ginkgo.It("should support seccomp runtime/default [LinuxOnly]", func() { pod := scTestPod(false, false) pod.Spec.Containers[0].SecurityContext = &v1.SecurityContext{SeccompProfile: &v1.SeccompProfile{Type: v1.SeccompProfileTypeRuntimeDefault}} pod.Spec.Containers[0].Command = []string{"grep", "ecc", "/proc/self/status"} - f.TestContainerOutput(v1.SeccompPodAnnotationKey, pod, 0, []string{"2"}) // seccomp filtered + f.TestContainerOutput("seccomp runtime/default", pod, 0, []string{"2"}) // seccomp filtered }) ginkgo.It("should support seccomp default which is unconfined [LinuxOnly]", func() { pod := scTestPod(false, false) pod.Spec.Containers[0].Command = []string{"grep", "ecc", "/proc/self/status"} - f.TestContainerOutput(v1.SeccompPodAnnotationKey, pod, 0, []string{"0"}) // seccomp disabled + f.TestContainerOutput("seccomp default unconfined", pod, 0, []string{"0"}) // seccomp disabled }) })