Add init containers to PSP admission

Treat them just like regular containers.
This commit is contained in:
Clayton Coleman 2016-05-18 16:24:44 -04:00
parent 01cf9869fc
commit e2afc97587
No known key found for this signature in database
GPG Key ID: 3D16906B4F1C5CB3
2 changed files with 58 additions and 0 deletions

View File

@ -186,6 +186,7 @@ func (c *podSecurityPolicyPlugin) Admit(a admission.Attributes) error {
// the same psp or is not considered valid.
func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.Path) field.ErrorList {
generatedSCs := make([]*api.SecurityContext, len(pod.Spec.Containers))
var generatedInitSCs []*api.SecurityContext
errs := field.ErrorList{}
@ -201,6 +202,26 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P
pod.Spec.SecurityContext = psc
errs = append(errs, provider.ValidatePodSecurityContext(pod, field.NewPath("spec", "securityContext"))...)
// Note: this is not changing the original container, we will set container SCs later so long
// as all containers validated under the same PSP.
for i, containerCopy := range pod.Spec.InitContainers {
// We will determine the effective security context for the container and validate against that
// since that is how the sc provider will eventually apply settings in the runtime.
// This results in an SC that is based on the Pod's PSC with the set fields from the container
// overriding pod level settings.
containerCopy.SecurityContext = sc.DetermineEffectiveSecurityContext(pod, &containerCopy)
sc, err := provider.CreateContainerSecurityContext(pod, &containerCopy)
if err != nil {
errs = append(errs, field.Invalid(field.NewPath("spec", "initContainers").Index(i).Child("securityContext"), "", err.Error()))
continue
}
generatedInitSCs = append(generatedInitSCs, sc)
containerCopy.SecurityContext = sc
errs = append(errs, provider.ValidateContainerSecurityContext(pod, &containerCopy, field.NewPath("spec", "initContainers").Index(i).Child("securityContext"))...)
}
// Note: this is not changing the original container, we will set container SCs later so long
// as all containers validated under the same PSP.
for i, containerCopy := range pod.Spec.Containers {
@ -229,6 +250,9 @@ func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.P
// if we've reached this code then we've generated and validated an SC for every container in the
// pod so let's apply what we generated. Note: the psc is already applied.
for i, sc := range generatedInitSCs {
pod.Spec.InitContainers[i].SecurityContext = sc
}
for i, sc := range generatedSCs {
pod.Spec.Containers[i].SecurityContext = sc
}

View File

@ -44,6 +44,12 @@ func NewTestAdmission(store cache.Store, kclient clientset.Interface) kadmission
}
}
func useInitContainers(pod *kapi.Pod) *kapi.Pod {
pod.Spec.InitContainers = pod.Spec.Containers
pod.Spec.Containers = []kapi.Container{}
return pod
}
func TestAdmitPrivileged(t *testing.T) {
createPodWithPriv := func(priv bool) *kapi.Pod {
pod := goodPod()
@ -203,6 +209,18 @@ func TestAdmitCaps(t *testing.T) {
}
}
}
for k, v := range tc {
useInitContainers(v.pod)
testPSPAdmit(k, v.psps, v.pod, v.shouldPass, v.expectedPSP, t)
if v.expectedCapabilities != nil {
if !reflect.DeepEqual(v.expectedCapabilities, v.pod.Spec.InitContainers[0].SecurityContext.Capabilities) {
t.Errorf("%s resulted in caps that were not expected - expected: %v, received: %v", k, v.expectedCapabilities, v.pod.Spec.InitContainers[0].SecurityContext.Capabilities)
}
}
}
}
func TestAdmitVolumes(t *testing.T) {
@ -235,6 +253,10 @@ func TestAdmitVolumes(t *testing.T) {
// expect a denial for this PSP
testPSPAdmit(fmt.Sprintf("%s denial", string(fsType)), []*extensions.PodSecurityPolicy{psp}, pod, false, "", t)
// also expect a denial for this PSP if it's an init container
useInitContainers(pod)
testPSPAdmit(fmt.Sprintf("%s denial", string(fsType)), []*extensions.PodSecurityPolicy{psp}, pod, false, "", t)
// now add the fstype directly to the psp and it should validate
psp.Spec.Volumes = []extensions.FSType{fsType}
testPSPAdmit(fmt.Sprintf("%s direct accept", string(fsType)), []*extensions.PodSecurityPolicy{psp}, pod, true, psp.Name, t)
@ -304,6 +326,18 @@ func TestAdmitHostNetwork(t *testing.T) {
}
}
}
// test again with init containers
for k, v := range tests {
useInitContainers(v.pod)
testPSPAdmit(k, v.psps, v.pod, v.shouldPass, v.expectedPSP, t)
if v.shouldPass {
if v.pod.Spec.SecurityContext.HostNetwork != v.expectedHostNetwork {
t.Errorf("%s expected hostNetwork to be %t", k, v.expectedHostNetwork)
}
}
}
}
func TestAdmitHostPorts(t *testing.T) {