diff --git a/pkg/api/pod/warnings.go b/pkg/api/pod/warnings.go index 2275914e20b..e0c34511f0b 100644 --- a/pkg/api/pod/warnings.go +++ b/pkg/api/pod/warnings.go @@ -77,11 +77,6 @@ var deprecatedAnnotations = []struct { key: `scheduler.alpha.kubernetes.io/critical-pod`, message: `non-functional in v1.16+; use the "priorityClassName" field instead`, }, - { - key: `seccomp.security.alpha.kubernetes.io/pod`, - prefix: `container.seccomp.security.alpha.kubernetes.io/`, - message: `deprecated since v1.19; use the "seccompProfile" field instead`, - }, { key: `security.alpha.kubernetes.io/sysctls`, message: `non-functional in v1.11+; use the "sysctls" field instead`, @@ -239,7 +234,21 @@ func warningsForPodSpecAndMeta(fieldPath *field.Path, podSpec *api.PodSpec, meta warnings = append(warnings, fmt.Sprintf("%s: fractional byte value %q is invalid, must be an integer", fieldPath.Child("spec", "overhead").Key(string(api.ResourceEphemeralStorage)), value.String())) } + // 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; use the "seccompProfile" field instead`, fieldPath.Child("metadata", "annotations").Key(api.SeccompPodAnnotationKey))) + } + } + pods.VisitContainersWithPath(podSpec, fieldPath.Child("spec"), func(c *api.Container, p *field.Path) bool { + // 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; use the "seccompProfile" field instead`, fieldPath.Child("metadata", "annotations").Key(api.SeccompContainerAnnotationKeyPrefix+c.Name))) + } + } + // fractional memory/ephemeral-storage requests/limits (#79950, #49442, #18538) if value, ok := c.Resources.Limits[api.ResourceMemory]; ok && value.MilliValue()%int64(1000) != int64(0) { warnings = append(warnings, fmt.Sprintf("%s: fractional byte value %q is invalid, must be an integer", p.Child("resources", "limits").Key(string(api.ResourceMemory)), value.String())) diff --git a/pkg/api/pod/warnings_test.go b/pkg/api/pod/warnings_test.go index 644e0d86290..a38c6408320 100644 --- a/pkg/api/pod/warnings_test.go +++ b/pkg/api/pod/warnings_test.go @@ -410,14 +410,17 @@ func TestWarnings(t *testing.T) { }, { name: "annotations", - template: &api.PodTemplateSpec{ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ - `foo`: `bar`, - `scheduler.alpha.kubernetes.io/critical-pod`: `true`, - `seccomp.security.alpha.kubernetes.io/pod`: `default`, - `container.seccomp.security.alpha.kubernetes.io/foo`: `default`, - `security.alpha.kubernetes.io/sysctls`: `a,b,c`, - `security.alpha.kubernetes.io/unsafe-sysctls`: `d,e,f`, - }}}, + template: &api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ + `foo`: `bar`, + `scheduler.alpha.kubernetes.io/critical-pod`: `true`, + `seccomp.security.alpha.kubernetes.io/pod`: `default`, + `container.seccomp.security.alpha.kubernetes.io/foo`: `default`, + `security.alpha.kubernetes.io/sysctls`: `a,b,c`, + `security.alpha.kubernetes.io/unsafe-sysctls`: `d,e,f`, + }}, + Spec: api.PodSpec{Containers: []api.Container{{Name: "foo"}}}, + }, 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; use the "seccompProfile" field instead`, @@ -426,6 +429,27 @@ func TestWarnings(t *testing.T) { `metadata.annotations[security.alpha.kubernetes.io/unsafe-sysctls]: non-functional in v1.11+; use the "sysctls" field instead`, }, }, + { + name: "seccomp fields", + template: &api.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{Annotations: map[string]string{ + `seccomp.security.alpha.kubernetes.io/pod`: `default`, + `container.seccomp.security.alpha.kubernetes.io/foo`: `default`, + }}, + Spec: api.PodSpec{ + SecurityContext: &api.PodSecurityContext{ + SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault}, + }, + Containers: []api.Container{{ + Name: "foo", + SecurityContext: &api.SecurityContext{ + SeccompProfile: &api.SeccompProfile{Type: api.SeccompProfileTypeRuntimeDefault}, + }, + }}, + }, + }, + expected: []string{}, + }, } for _, tc := range testcases {