func (s *strategy) Validate(pod *api.Pod, container *api.Container) field.ErrorList { if s.allowedProfiles == nil { // Unrestricted: allow all. return nil } allErrs := field.ErrorList{} fieldPath := field.NewPath("pod", "metadata", "annotations").Key(apparmor.ContainerAnnotationKeyPrefix + container.Name) profile := apparmor.GetProfileName(pod, container.Name) if profile == "" { if len(s.allowedProfiles) > 0 { allErrs = append(allErrs, field.Forbidden(fieldPath, "AppArmor profile must be set")) return allErrs } return nil } if !s.allowedProfiles[profile] { msg := fmt.Sprintf("%s is not an allowed profile. Allowed values: %q", profile, s.allowedProfilesString) allErrs = append(allErrs, field.Forbidden(fieldPath, msg)) } return allErrs }
func TestAdmitAppArmor(t *testing.T) { createPodWithAppArmor := func(profile string) *kapi.Pod { pod := goodPod() apparmor.SetProfileName(pod, defaultContainerName, profile) return pod } unconstrainedPSP := restrictivePSP() defaultedPSP := restrictivePSP() defaultedPSP.Annotations = map[string]string{ apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, } appArmorPSP := restrictivePSP() appArmorPSP.Annotations = map[string]string{ apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault, } appArmorDefaultPSP := restrictivePSP() appArmorDefaultPSP.Annotations = map[string]string{ apparmor.DefaultProfileAnnotationKey: apparmor.ProfileRuntimeDefault, apparmor.AllowedProfilesAnnotationKey: apparmor.ProfileRuntimeDefault + "," + apparmor.ProfileNamePrefix + "foo", } tests := map[string]struct { pod *kapi.Pod psp *extensions.PodSecurityPolicy shouldPass bool expectedProfile string }{ "unconstrained with no profile": { pod: goodPod(), psp: unconstrainedPSP, shouldPass: true, expectedProfile: "", }, "unconstrained with profile": { pod: createPodWithAppArmor(apparmor.ProfileRuntimeDefault), psp: unconstrainedPSP, shouldPass: true, expectedProfile: apparmor.ProfileRuntimeDefault, }, "unconstrained with default profile": { pod: goodPod(), psp: defaultedPSP, shouldPass: true, expectedProfile: apparmor.ProfileRuntimeDefault, }, "AppArmor enforced with no profile": { pod: goodPod(), psp: appArmorPSP, shouldPass: false, }, "AppArmor enforced with default profile": { pod: goodPod(), psp: appArmorDefaultPSP, shouldPass: true, expectedProfile: apparmor.ProfileRuntimeDefault, }, "AppArmor enforced with good profile": { pod: createPodWithAppArmor(apparmor.ProfileNamePrefix + "foo"), psp: appArmorDefaultPSP, shouldPass: true, expectedProfile: apparmor.ProfileNamePrefix + "foo", }, "AppArmor enforced with local profile": { pod: createPodWithAppArmor(apparmor.ProfileNamePrefix + "bar"), psp: appArmorPSP, shouldPass: false, }, } for k, v := range tests { testPSPAdmit(k, []*extensions.PodSecurityPolicy{v.psp}, v.pod, v.shouldPass, v.psp.Name, t) if v.shouldPass { assert.Equal(t, v.expectedProfile, apparmor.GetProfileName(v.pod, defaultContainerName), k) } } }