Inline some SecurityContext fields into PodSecurityContext

This commit is contained in:
Paul Morie
2015-10-20 14:03:32 -04:00
parent 236193a26d
commit 393e2bc019
22 changed files with 22183 additions and 21218 deletions

View File

@@ -46,8 +46,7 @@ func NewSecurityContextDeny(client client.Interface) admission.Interface {
}
}
// Admit will deny any SecurityContext that defines options that were not previously available in the api.Container
// struct (Capabilities and Privileged)
// Admit will deny any pod that defines SELinuxOptions or RunAsUser.
func (p *plugin) Admit(a admission.Attributes) (err error) {
if a.GetResource() != string(api.ResourcePods) {
return nil
@@ -61,6 +60,14 @@ func (p *plugin) Admit(a admission.Attributes) (err error) {
if pod.Spec.SecurityContext != nil && pod.Spec.SecurityContext.SupplementalGroups != nil {
return apierrors.NewForbidden(a.GetResource(), pod.Name, fmt.Errorf("SecurityContext.SupplementalGroups is forbidden"))
}
if pod.Spec.SecurityContext != nil {
if pod.Spec.SecurityContext.SELinuxOptions != nil {
return apierrors.NewForbidden(a.GetResource(), pod.Name, fmt.Errorf("pod.Spec.SecurityContext.SELinuxOptions is forbidden"))
}
if pod.Spec.SecurityContext.RunAsUser != nil {
return apierrors.NewForbidden(a.GetResource(), pod.Name, fmt.Errorf("pod.Spec.SecurityContext.RunAsUser is forbidden"))
}
}
for _, v := range pod.Spec.Containers {
if v.SecurityContext != nil {

View File

@@ -29,37 +29,64 @@ func TestAdmission(t *testing.T) {
var runAsUser int64 = 1
priv := true
successCases := map[string]*api.SecurityContext{
"no sc": nil,
"empty sc": {},
"valid sc": {Privileged: &priv, Capabilities: &api.Capabilities{}},
}
pod := api.Pod{
Spec: api.PodSpec{
Containers: []api.Container{
{},
},
cases := []struct {
name string
sc *api.SecurityContext
podSc *api.PodSecurityContext
expectError bool
}{
{
name: "unset",
},
{
name: "empty container.SecurityContext",
sc: &api.SecurityContext{},
},
{
name: "empty pod.Spec.SecurityContext",
podSc: &api.PodSecurityContext{},
},
{
name: "valid container.SecurityContext",
sc: &api.SecurityContext{Privileged: &priv, Capabilities: &api.Capabilities{}},
},
{
name: "valid pod.Spec.SecurityContext",
podSc: &api.PodSecurityContext{},
},
{
name: "container.SecurityContext.RunAsUser",
sc: &api.SecurityContext{RunAsUser: &runAsUser},
expectError: true,
},
{
name: "container.SecurityContext.SELinuxOptions",
sc: &api.SecurityContext{SELinuxOptions: &api.SELinuxOptions{}},
expectError: true,
},
{
name: "pod.Spec.SecurityContext.RunAsUser",
podSc: &api.PodSecurityContext{RunAsUser: &runAsUser},
expectError: true,
},
{
name: "pod.Spec.SecurityContext.SELinuxOptions",
podSc: &api.PodSecurityContext{SELinuxOptions: &api.SELinuxOptions{}},
expectError: true,
},
}
for k, v := range successCases {
pod.Spec.Containers[0].SecurityContext = v
err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", "foo", "name", string(api.ResourcePods), "", "ignored", nil))
if err != nil {
t.Errorf("Unexpected error returned from admission handler for case %s", k)
}
}
errorCases := map[string]*api.SecurityContext{
"run as user": {RunAsUser: &runAsUser},
"se linux optons": {SELinuxOptions: &api.SELinuxOptions{}},
"mixed settings": {Privileged: &priv, RunAsUser: &runAsUser, SELinuxOptions: &api.SELinuxOptions{}},
}
for k, v := range errorCases {
pod.Spec.Containers[0].SecurityContext = v
err := handler.Admit(admission.NewAttributesRecord(&pod, "Pod", "foo", "name", string(api.ResourcePods), "", "ignored", nil))
if err == nil {
t.Errorf("Expected error returned from admission handler for case %s", k)
for _, tc := range cases {
pod := pod()
pod.Spec.SecurityContext = tc.podSc
pod.Spec.Containers[0].SecurityContext = tc.sc
err := handler.Admit(admission.NewAttributesRecord(pod, "Pod", "foo", "name", string(api.ResourcePods), "", "ignored", nil))
if err != nil && !tc.expectError {
t.Errorf("%v: unexpected error: %v", tc.name, err)
} else if err == nil && tc.expectError {
t.Errorf("%v: expected error", tc.name)
}
}
}
@@ -118,3 +145,13 @@ func TestHandles(t *testing.T) {
}
}
}
func pod() *api.Pod {
return &api.Pod{
Spec: api.PodSpec{
Containers: []api.Container{
{},
},
},
}
}