Unverified Commit ccc90b2b authored by Kubernetes Prow Robot's avatar Kubernetes Prow Robot Committed by GitHub

Merge pull request #75680 from tallclair/psp-refactor

Clean up some PodSecurityPolicy code
parents 743fddd1 a3874095
...@@ -49,8 +49,6 @@ go_test( ...@@ -49,8 +49,6 @@ go_test(
"//staging/src/k8s.io/api/policy/v1beta1:go_default_library", "//staging/src/k8s.io/api/policy/v1beta1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library", "//staging/src/k8s.io/apimachinery/pkg/util/diff:go_default_library",
"//staging/src/k8s.io/apimachinery/pkg/util/validation/field:go_default_library",
"//vendor/github.com/davecgh/go-spew/spew:go_default_library",
"//vendor/github.com/stretchr/testify/assert:go_default_library", "//vendor/github.com/stretchr/testify/assert:go_default_library",
"//vendor/github.com/stretchr/testify/require:go_default_library", "//vendor/github.com/stretchr/testify/require:go_default_library",
], ],
......
...@@ -59,10 +59,10 @@ func NewSimpleProvider(psp *policy.PodSecurityPolicy, namespace string, strategy ...@@ -59,10 +59,10 @@ func NewSimpleProvider(psp *policy.PodSecurityPolicy, namespace string, strategy
}, nil }, nil
} }
// DefaultPodSecurityContext sets the default values of the required but not filled fields. // MutatePod sets the default values of the required but not filled fields.
// It modifies the SecurityContext and annotations of the provided pod. Validation should be // Validation should be used after the context is defaulted to ensure it
// used after the context is defaulted to ensure it complies with the required restrictions. // complies with the required restrictions.
func (s *simpleProvider) DefaultPodSecurityContext(pod *api.Pod) error { func (s *simpleProvider) MutatePod(pod *api.Pod) error {
sc := securitycontext.NewPodSecurityContextMutator(pod.Spec.SecurityContext) sc := securitycontext.NewPodSecurityContextMutator(pod.Spec.SecurityContext)
if sc.SupplementalGroups() == nil { if sc.SupplementalGroups() == nil {
...@@ -104,13 +104,25 @@ func (s *simpleProvider) DefaultPodSecurityContext(pod *api.Pod) error { ...@@ -104,13 +104,25 @@ func (s *simpleProvider) DefaultPodSecurityContext(pod *api.Pod) error {
pod.Spec.SecurityContext = sc.PodSecurityContext() pod.Spec.SecurityContext = sc.PodSecurityContext()
for i := range pod.Spec.InitContainers {
if err := s.mutateContainer(pod, &pod.Spec.InitContainers[i]); err != nil {
return err
}
}
for i := range pod.Spec.Containers {
if err := s.mutateContainer(pod, &pod.Spec.Containers[i]); err != nil {
return err
}
}
return nil return nil
} }
// DefaultContainerSecurityContext sets the default values of the required but not filled fields. // mutateContainer sets the default values of the required but not filled fields.
// It modifies the SecurityContext of the container and annotations of the pod. Validation should // It modifies the SecurityContext of the container and annotations of the pod. Validation should
// be used after the context is defaulted to ensure it complies with the required restrictions. // be used after the context is defaulted to ensure it complies with the required restrictions.
func (s *simpleProvider) DefaultContainerSecurityContext(pod *api.Pod, container *api.Container) error { func (s *simpleProvider) mutateContainer(pod *api.Pod, container *api.Container) error {
sc := securitycontext.NewEffectiveContainerSecurityContextMutator( sc := securitycontext.NewEffectiveContainerSecurityContextMutator(
securitycontext.NewPodSecurityContextAccessor(pod.Spec.SecurityContext), securitycontext.NewPodSecurityContextAccessor(pod.Spec.SecurityContext),
securitycontext.NewContainerSecurityContextMutator(container.SecurityContext), securitycontext.NewContainerSecurityContextMutator(container.SecurityContext),
...@@ -282,11 +294,22 @@ func (s *simpleProvider) ValidatePod(pod *api.Pod) field.ErrorList { ...@@ -282,11 +294,22 @@ func (s *simpleProvider) ValidatePod(pod *api.Pod) field.ErrorList {
} }
} }
} }
fldPath := field.NewPath("spec", "initContainers")
for i := range pod.Spec.InitContainers {
allErrs = append(allErrs, s.validateContainer(pod, &pod.Spec.InitContainers[i], fldPath.Index(i))...)
}
fldPath = field.NewPath("spec", "containers")
for i := range pod.Spec.Containers {
allErrs = append(allErrs, s.validateContainer(pod, &pod.Spec.Containers[i], fldPath.Index(i))...)
}
return allErrs return allErrs
} }
// Ensure a container's SecurityContext is in compliance with the given constraints // Ensure a container's SecurityContext is in compliance with the given constraints
func (s *simpleProvider) ValidateContainer(pod *api.Pod, container *api.Container, containerPath *field.Path) field.ErrorList { func (s *simpleProvider) validateContainer(pod *api.Pod, container *api.Container, containerPath *field.Path) field.ErrorList {
allErrs := field.ErrorList{} allErrs := field.ErrorList{}
podSC := securitycontext.NewPodSecurityContextAccessor(pod.Spec.SecurityContext) podSC := securitycontext.NewPodSecurityContextAccessor(pod.Spec.SecurityContext)
......
...@@ -32,16 +32,12 @@ import ( ...@@ -32,16 +32,12 @@ import (
// Provider provides the implementation to generate a new security // Provider provides the implementation to generate a new security
// context based on constraints or validate an existing security context against constraints. // context based on constraints or validate an existing security context against constraints.
type Provider interface { type Provider interface {
// DefaultPodSecurityContext sets the default values of the required but not filled fields. // MutatePod sets the default values of the required but not filled fields of the pod and all
// It modifies the SecurityContext and annotations of the provided pod. // containers in the pod.
DefaultPodSecurityContext(pod *api.Pod) error MutatePod(pod *api.Pod) error
// DefaultContainerSecurityContext sets the default values of the required but not filled fields. // ValidatePod ensures a pod and all its containers are in compliance with the given constraints.
// It modifies the SecurityContext of the container and annotations of the pod. // ValidatePod MUST NOT mutate the pod.
DefaultContainerSecurityContext(pod *api.Pod, container *api.Container) error
// Ensure a pod is in compliance with the given constraints.
ValidatePod(pod *api.Pod) field.ErrorList ValidatePod(pod *api.Pod) field.ErrorList
// Ensure a container's SecurityContext is in compliance with the given constraints.
ValidateContainer(pod *api.Pod, container *api.Container, containerPath *field.Path) field.ErrorList
// Get the name of the PSP that this provider was initialized with. // Get the name of the PSP that this provider was initialized with.
GetPSPName() string GetPSPName() string
} }
......
...@@ -306,35 +306,14 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, ...@@ -306,35 +306,14 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList { func assignSecurityContext(provider psp.Provider, pod *api.Pod) field.ErrorList {
errs := field.ErrorList{} errs := field.ErrorList{}
err := provider.DefaultPodSecurityContext(pod) if err := provider.MutatePod(pod); err != nil {
if err != nil { // TODO(tallclair): MutatePod should return a field.ErrorList
errs = append(errs, field.Invalid(field.NewPath("spec", "securityContext"), pod.Spec.SecurityContext, err.Error())) errs = append(errs, field.Invalid(field.NewPath(""), pod, err.Error()))
} }
errs = append(errs, provider.ValidatePod(pod)...) errs = append(errs, provider.ValidatePod(pod)...)
for i := range pod.Spec.InitContainers { return errs
err := provider.DefaultContainerSecurityContext(pod, &pod.Spec.InitContainers[i])
if err != nil {
errs = append(errs, field.Invalid(field.NewPath("spec", "initContainers").Index(i).Child("securityContext"), "", err.Error()))
continue
}
errs = append(errs, provider.ValidateContainer(pod, &pod.Spec.InitContainers[i], field.NewPath("spec", "initContainers").Index(i))...)
}
for i := range pod.Spec.Containers {
err := provider.DefaultContainerSecurityContext(pod, &pod.Spec.Containers[i])
if err != nil {
errs = append(errs, field.Invalid(field.NewPath("spec", "containers").Index(i).Child("securityContext"), "", err.Error()))
continue
}
errs = append(errs, provider.ValidateContainer(pod, &pod.Spec.Containers[i], field.NewPath("spec", "containers").Index(i))...)
}
if len(errs) > 0 {
return errs
}
return nil
} }
// createProvidersFromPolicies creates providers from the constraints supplied. // createProvidersFromPolicies creates providers from the constraints supplied.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment