Skip to content

Commit

Permalink
SCC seccomp admission
Browse files Browse the repository at this point in the history
  • Loading branch information
pweil- committed Jul 29, 2016
1 parent a4689ed commit f31ccec
Show file tree
Hide file tree
Showing 2 changed files with 116 additions and 1 deletion.
6 changes: 5 additions & 1 deletion pkg/security/admission/admission.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ func assignSecurityContext(provider scc.SecurityContextConstraintsProvider, pod

errs := field.ErrorList{}

psc, err := provider.CreatePodSecurityContext(pod)
psc, generatedAnnotations, err := provider.CreatePodSecurityContext(pod)
if err != nil {
errs = append(errs, field.Invalid(field.NewPath("spec", "securityContext"), pod.Spec.SecurityContext, err.Error()))
}
Expand All @@ -178,7 +178,10 @@ func assignSecurityContext(provider scc.SecurityContextConstraintsProvider, pod
// set for container generation/validation. We will reset to original post container
// validation.
originalPSC := pod.Spec.SecurityContext
originalAnnotations := pod.Annotations

pod.Spec.SecurityContext = psc
pod.Annotations = generatedAnnotations
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
Expand Down Expand Up @@ -209,6 +212,7 @@ func assignSecurityContext(provider scc.SecurityContextConstraintsProvider, pod
if len(errs) > 0 {
// ensure psc is not mutated if there are errors
pod.Spec.SecurityContext = originalPSC
pod.Annotations = originalAnnotations
return errs
}

Expand Down
111 changes: 111 additions & 0 deletions pkg/security/admission/admission_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1485,6 +1485,117 @@ func TestAdmitWithPrioritizedSCC(t *testing.T) {
testSCCAdmission(matchingPriorityAndScoreSCCOnePod, plugin, matchingPriorityAndScoreSCCOne.Name, t)
}

func TestAdmitSeccomp(t *testing.T) {
createPodWithSeccomp := func(podAnnotation, containerAnnotation string) *kapi.Pod {
pod := goodPod()
pod.Annotations = map[string]string{}
if podAnnotation != "" {
pod.Annotations[kapi.SeccompPodAnnotationKey] = podAnnotation
}
if containerAnnotation != "" {
pod.Annotations[kapi.SeccompContainerAnnotationKeyPrefix+"container"] = containerAnnotation
}
pod.Spec.Containers[0].Name = "container"
return pod
}

noSeccompSCC := restrictiveSCC()
noSeccompSCC.Name = "noseccomp"

seccompSCC := restrictiveSCC()
seccompSCC.Name = "seccomp"
seccompSCC.SeccompProfiles = []string{"foo"}

wildcardSCC := restrictiveSCC()
wildcardSCC.Name = "wildcard"
wildcardSCC.SeccompProfiles = []string{"*"}

tests := map[string]struct {
pod *kapi.Pod
sccs []*kapi.SecurityContextConstraints
shouldPass bool
expectedPodAnnotation string
expectedSCC string
}{
"no seccomp, no requests": {
pod: goodPod(),
sccs: []*kapi.SecurityContextConstraints{noSeccompSCC},
shouldPass: true,
expectedSCC: noSeccompSCC.Name,
},
"no seccomp, bad container requests": {
pod: createPodWithSeccomp("foo", "bar"),
sccs: []*kapi.SecurityContextConstraints{noSeccompSCC},
shouldPass: false,
},
"seccomp, no requests": {
pod: goodPod(),
sccs: []*kapi.SecurityContextConstraints{seccompSCC},
shouldPass: true,
expectedPodAnnotation: "foo",
expectedSCC: seccompSCC.Name,
},
"seccomp, valid pod annotation, no container annotation": {
pod: createPodWithSeccomp("foo", ""),
sccs: []*kapi.SecurityContextConstraints{seccompSCC},
shouldPass: true,
expectedPodAnnotation: "foo",
expectedSCC: seccompSCC.Name,
},
"seccomp, no pod annotation, valid container annotation": {
pod: createPodWithSeccomp("", "foo"),
sccs: []*kapi.SecurityContextConstraints{seccompSCC},
shouldPass: true,
expectedPodAnnotation: "foo",
expectedSCC: seccompSCC.Name,
},
"seccomp, valid pod annotation, invalid container annotation": {
pod: createPodWithSeccomp("foo", "bar"),
sccs: []*kapi.SecurityContextConstraints{seccompSCC},
shouldPass: false,
},
"wild card, no requests": {
pod: goodPod(),
sccs: []*kapi.SecurityContextConstraints{wildcardSCC},
shouldPass: true,
expectedSCC: wildcardSCC.Name,
},
"wild card, requests": {
pod: createPodWithSeccomp("foo", "bar"),
sccs: []*kapi.SecurityContextConstraints{wildcardSCC},
shouldPass: true,
expectedPodAnnotation: "foo",
expectedSCC: wildcardSCC.Name,
},
}

for k, v := range tests {
testSCCAdmit(k, v.sccs, v.pod, v.shouldPass, t)

if v.shouldPass {
validatedSCC, ok := v.pod.Annotations[allocator.ValidatedSCCAnnotation]
if !ok {
t.Errorf("expected to find the validated annotation on the pod for the scc but found none")
return
}
if validatedSCC != v.expectedSCC {
t.Errorf("should have validated against %s but found %s", v.expectedSCC, validatedSCC)
}

if len(v.expectedPodAnnotation) > 0 {
annotation, found := v.pod.Annotations[kapi.SeccompPodAnnotationKey]
if !found {
t.Errorf("%s expected to have pod annotation for seccomp but found none", k)
}
if found && annotation != v.expectedPodAnnotation {
t.Errorf("%s expected pod annotation to be %s but found %s", k, v.expectedPodAnnotation, annotation)
}
}
}
}

}

// testSCCAdmission is a helper to admit the pod and ensure it was validated against the expected
// SCC.
func testSCCAdmission(pod *kapi.Pod, plugin kadmission.Interface, expectedSCC string, t *testing.T) {
Expand Down

0 comments on commit f31ccec

Please sign in to comment.