mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-14 10:53:34 +00:00
vendor updates
This commit is contained in:
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/BUILD
generated
vendored
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/BUILD
generated
vendored
@ -13,6 +13,7 @@ go_library(
|
||||
deps = [
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/client/listers/extensions/internalversion:go_default_library",
|
||||
"//pkg/kubeapiserver/admission:go_default_library",
|
||||
@ -34,13 +35,13 @@ go_library(
|
||||
go_test(
|
||||
name = "go_default_test",
|
||||
srcs = ["admission_test.go"],
|
||||
importpath = "k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy",
|
||||
library = ":go_default_library",
|
||||
embed = [":go_default_library"],
|
||||
deps = [
|
||||
"//pkg/api/legacyscheme:go_default_library",
|
||||
"//pkg/apis/core:go_default_library",
|
||||
"//pkg/apis/core/helper:go_default_library",
|
||||
"//pkg/apis/extensions:go_default_library",
|
||||
"//pkg/apis/policy:go_default_library",
|
||||
"//pkg/client/informers/informers_generated/internalversion:go_default_library",
|
||||
"//pkg/controller:go_default_library",
|
||||
"//pkg/security/apparmor:go_default_library",
|
||||
@ -56,6 +57,7 @@ go_test(
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/serviceaccount:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authentication/user:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizer:go_default_library",
|
||||
"//vendor/k8s.io/apiserver/pkg/authorization/authorizerfactory:go_default_library",
|
||||
],
|
||||
)
|
||||
|
||||
|
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/OWNERS
generated
vendored
Normal file
6
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/OWNERS
generated
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
approvers:
|
||||
- tallclair
|
||||
- liggitt
|
||||
reviewers:
|
||||
- pweil-
|
||||
- php-coder
|
55
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go
generated
vendored
55
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission.go
generated
vendored
@ -33,6 +33,7 @@ import (
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
api "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/policy"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
extensionslisters "k8s.io/kubernetes/pkg/client/listers/extensions/internalversion"
|
||||
kubeapiserveradmission "k8s.io/kubernetes/pkg/kubeapiserver/admission"
|
||||
@ -122,8 +123,8 @@ func (c *PodSecurityPolicyPlugin) Admit(a admission.Attributes) error {
|
||||
|
||||
pod := a.GetObject().(*api.Pod)
|
||||
|
||||
// compute the context
|
||||
allowedPod, pspName, validationErrs, err := c.computeSecurityContext(a, pod, true)
|
||||
// compute the context. Mutation is allowed. ValidatedPSPAnnotation is not taken into account.
|
||||
allowedPod, pspName, validationErrs, err := c.computeSecurityContext(a, pod, true, "")
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
@ -152,8 +153,8 @@ func (c *PodSecurityPolicyPlugin) Validate(a admission.Attributes) error {
|
||||
|
||||
pod := a.GetObject().(*api.Pod)
|
||||
|
||||
// compute the context. Mutation is not allowed.
|
||||
allowedPod, _, validationErrs, err := c.computeSecurityContext(a, pod, false)
|
||||
// compute the context. Mutation is not allowed. ValidatedPSPAnnotation is used as a hint to gain same speed-up.
|
||||
allowedPod, _, validationErrs, err := c.computeSecurityContext(a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation])
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
@ -193,8 +194,9 @@ func shouldIgnore(a admission.Attributes) (bool, error) {
|
||||
|
||||
// computeSecurityContext derives a valid security context while trying to avoid any changes to the given pod. I.e.
|
||||
// if there is a matching policy with the same security context as given, it will be reused. If there is no
|
||||
// matching policy the returned pod will be nil and the pspName empty.
|
||||
func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, specMutationAllowed bool) (*api.Pod, string, field.ErrorList, error) {
|
||||
// matching policy the returned pod will be nil and the pspName empty. validatedPSPHint is the validated psp name
|
||||
// saved in kubernetes.io/psp annotation. This psp is usually the one we are looking for.
|
||||
func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, specMutationAllowed bool, validatedPSPHint string) (*api.Pod, string, field.ErrorList, error) {
|
||||
// get all constraints that are usable by the user
|
||||
glog.V(4).Infof("getting pod security policies for pod %s (generate: %s)", pod.Name, pod.GenerateName)
|
||||
var saInfo user.Info
|
||||
@ -213,9 +215,18 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
|
||||
return pod, "", nil, nil
|
||||
}
|
||||
|
||||
// sort by name to make order deterministic
|
||||
// sort policies by name to make order deterministic
|
||||
// If mutation is not allowed and validatedPSPHint is provided, check the validated policy first.
|
||||
// TODO(liggitt): add priority field to allow admins to bucket differently
|
||||
sort.SliceStable(policies, func(i, j int) bool {
|
||||
if !specMutationAllowed {
|
||||
if policies[i].Name == validatedPSPHint {
|
||||
return true
|
||||
}
|
||||
if policies[j].Name == validatedPSPHint {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return strings.Compare(policies[i].Name, policies[j].Name) < 0
|
||||
})
|
||||
|
||||
@ -244,7 +255,6 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
|
||||
}
|
||||
|
||||
// the entire pod validated
|
||||
|
||||
mutated := !apiequality.Semantic.DeepEqual(pod, podCopy)
|
||||
if mutated && !specMutationAllowed {
|
||||
continue
|
||||
@ -287,35 +297,28 @@ func (c *PodSecurityPolicyPlugin) computeSecurityContext(a admission.Attributes,
|
||||
func assignSecurityContext(provider psp.Provider, pod *api.Pod, fldPath *field.Path) field.ErrorList {
|
||||
errs := field.ErrorList{}
|
||||
|
||||
psc, pscAnnotations, err := provider.CreatePodSecurityContext(pod)
|
||||
err := provider.DefaultPodSecurityContext(pod)
|
||||
if err != nil {
|
||||
errs = append(errs, field.Invalid(field.NewPath("spec", "securityContext"), pod.Spec.SecurityContext, err.Error()))
|
||||
}
|
||||
pod.Spec.SecurityContext = psc
|
||||
pod.Annotations = pscAnnotations
|
||||
|
||||
errs = append(errs, provider.ValidatePodSecurityContext(pod, field.NewPath("spec", "securityContext"))...)
|
||||
errs = append(errs, provider.ValidatePod(pod, field.NewPath("spec", "securityContext"))...)
|
||||
|
||||
for i := range pod.Spec.InitContainers {
|
||||
sc, scAnnotations, err := provider.CreateContainerSecurityContext(pod, &pod.Spec.InitContainers[i])
|
||||
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
|
||||
}
|
||||
pod.Spec.InitContainers[i].SecurityContext = sc
|
||||
pod.Annotations = scAnnotations
|
||||
errs = append(errs, provider.ValidateContainerSecurityContext(pod, &pod.Spec.InitContainers[i], field.NewPath("spec", "initContainers").Index(i).Child("securityContext"))...)
|
||||
}
|
||||
|
||||
for i := range pod.Spec.Containers {
|
||||
sc, scAnnotations, err := provider.CreateContainerSecurityContext(pod, &pod.Spec.Containers[i])
|
||||
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
|
||||
}
|
||||
|
||||
pod.Spec.Containers[i].SecurityContext = sc
|
||||
pod.Annotations = scAnnotations
|
||||
errs = append(errs, provider.ValidateContainerSecurityContext(pod, &pod.Spec.Containers[i], field.NewPath("spec", "containers").Index(i).Child("securityContext"))...)
|
||||
}
|
||||
|
||||
@ -352,11 +355,19 @@ func isAuthorizedForPolicy(user, sa user.Info, namespace, policyName string, aut
|
||||
}
|
||||
|
||||
// authorizedForPolicy returns true if info is authorized to perform the "use" verb on the policy resource.
|
||||
// TODO: check against only the policy group when PSP will be completely moved out of the extensions
|
||||
func authorizedForPolicy(info user.Info, namespace string, policyName string, authz authorizer.Authorizer) bool {
|
||||
// Check against extensions API group for backward compatibility
|
||||
return authorizedForPolicyInAPIGroup(info, namespace, policyName, policy.GroupName, authz) ||
|
||||
authorizedForPolicyInAPIGroup(info, namespace, policyName, extensions.GroupName, authz)
|
||||
}
|
||||
|
||||
// authorizedForPolicyInAPIGroup returns true if info is authorized to perform the "use" verb on the policy resource in the specified API group.
|
||||
func authorizedForPolicyInAPIGroup(info user.Info, namespace, policyName, apiGroupName string, authz authorizer.Authorizer) bool {
|
||||
if info == nil {
|
||||
return false
|
||||
}
|
||||
attr := buildAttributes(info, namespace, policyName)
|
||||
attr := buildAttributes(info, namespace, policyName, apiGroupName)
|
||||
decision, reason, err := authz.Authorize(attr)
|
||||
if err != nil {
|
||||
glog.V(5).Infof("cannot authorize for policy: %v,%v", reason, err)
|
||||
@ -365,14 +376,14 @@ func authorizedForPolicy(info user.Info, namespace string, policyName string, au
|
||||
}
|
||||
|
||||
// buildAttributes builds an attributes record for a SAR based on the user info and policy.
|
||||
func buildAttributes(info user.Info, namespace string, policyName string) authorizer.Attributes {
|
||||
func buildAttributes(info user.Info, namespace, policyName, apiGroupName string) authorizer.Attributes {
|
||||
// check against the namespace that the pod is being created in to allow per-namespace PSP grants.
|
||||
attr := authorizer.AttributesRecord{
|
||||
User: info,
|
||||
Verb: "use",
|
||||
Namespace: namespace,
|
||||
Name: policyName,
|
||||
APIGroup: extensions.GroupName,
|
||||
APIGroup: apiGroupName,
|
||||
Resource: "podsecuritypolicies",
|
||||
ResourceRequest: true,
|
||||
}
|
||||
|
209
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go
generated
vendored
209
vendor/k8s.io/kubernetes/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go
generated
vendored
@ -32,10 +32,12 @@ import (
|
||||
"k8s.io/apiserver/pkg/authentication/serviceaccount"
|
||||
"k8s.io/apiserver/pkg/authentication/user"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizer"
|
||||
"k8s.io/apiserver/pkg/authorization/authorizerfactory"
|
||||
"k8s.io/kubernetes/pkg/api/legacyscheme"
|
||||
kapi "k8s.io/kubernetes/pkg/apis/core"
|
||||
"k8s.io/kubernetes/pkg/apis/core/helper"
|
||||
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||
"k8s.io/kubernetes/pkg/apis/policy"
|
||||
informers "k8s.io/kubernetes/pkg/client/informers/informers_generated/internalversion"
|
||||
"k8s.io/kubernetes/pkg/controller"
|
||||
"k8s.io/kubernetes/pkg/security/apparmor"
|
||||
@ -65,11 +67,16 @@ func NewTestAdmission(psps []*extensions.PodSecurityPolicy, authz authorizer.Aut
|
||||
}
|
||||
}
|
||||
|
||||
// TestAlwaysAllowedAuthorizer is a testing struct for testing that fulfills the authorizer interface.
|
||||
// TestAuthorizer is a testing struct for testing that fulfills the authorizer interface.
|
||||
type TestAuthorizer struct {
|
||||
// usernameToNamespaceToAllowedPSPs contains the map of allowed PSPs.
|
||||
// if nil, all PSPs are allowed.
|
||||
usernameToNamespaceToAllowedPSPs map[string]map[string]map[string]bool
|
||||
// allowedAPIGroupName specifies an API Group name that contains PSP resources.
|
||||
// In order to be authorized, AttributesRecord must have this group name.
|
||||
// When empty, API Group name isn't taken into account.
|
||||
// TODO: remove this when PSP will be completely moved out of the extensions and we'll lookup only in "policy" group.
|
||||
allowedAPIGroupName string
|
||||
}
|
||||
|
||||
func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
@ -78,7 +85,8 @@ func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authoriz
|
||||
}
|
||||
allowedInNamespace := t.usernameToNamespaceToAllowedPSPs[a.GetUser().GetName()][a.GetNamespace()][a.GetName()]
|
||||
allowedClusterWide := t.usernameToNamespaceToAllowedPSPs[a.GetUser().GetName()][""][a.GetName()]
|
||||
if allowedInNamespace || allowedClusterWide {
|
||||
allowedAPIGroup := len(t.allowedAPIGroupName) == 0 || a.GetAPIGroup() == t.allowedAPIGroupName
|
||||
if allowedAPIGroup && (allowedInNamespace || allowedClusterWide) {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
return authorizer.DecisionNoOpinion, "", nil
|
||||
@ -344,15 +352,20 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
gcChangedPod.OwnerReferences = []metav1.OwnerReference{{Kind: "Foo", Name: "bar"}}
|
||||
gcChangedPod.Finalizers = []string{"foo"}
|
||||
|
||||
podWithAnnotation := unprivilegedRunAsAnyPod.DeepCopy()
|
||||
podWithAnnotation.ObjectMeta.Annotations = map[string]string{
|
||||
// "mutating2" is lexicographically behind "mutating1", so "mutating1" should be
|
||||
// chosen because it's the canonical PSP order.
|
||||
psputil.ValidatedPSPAnnotation: mutating2.Name,
|
||||
}
|
||||
|
||||
tests := map[string]struct {
|
||||
operation kadmission.Operation
|
||||
pod *kapi.Pod
|
||||
podBeforeUpdate *kapi.Pod
|
||||
psps []*extensions.PodSecurityPolicy
|
||||
shouldPassAdmit bool
|
||||
shouldPassValidate bool
|
||||
expectMutation bool
|
||||
expectedPodUser *int64
|
||||
expectedContainerUser *int64
|
||||
expectedPSP string
|
||||
}{
|
||||
@ -360,10 +373,8 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
operation: kadmission.Create,
|
||||
pod: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{privilegedPSP},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: true,
|
||||
expectMutation: false,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: nil,
|
||||
expectedPSP: privilegedPSP.Name,
|
||||
},
|
||||
@ -371,10 +382,8 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
operation: kadmission.Create,
|
||||
pod: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1, privilegedPSP},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: true,
|
||||
expectMutation: false,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: nil,
|
||||
expectedPSP: privilegedPSP.Name,
|
||||
},
|
||||
@ -382,10 +391,17 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
operation: kadmission.Create,
|
||||
pod: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: true,
|
||||
expectMutation: true,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: &mutating1.Spec.RunAsUser.Ranges[0].Min,
|
||||
expectedPSP: mutating1.Name,
|
||||
},
|
||||
"pod should use deterministic mutating PSP on create even if ValidatedPSPAnnotation is set": {
|
||||
operation: kadmission.Create,
|
||||
pod: podWithAnnotation,
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1},
|
||||
shouldPassValidate: true,
|
||||
expectMutation: true,
|
||||
expectedContainerUser: &mutating1.Spec.RunAsUser.Ranges[0].Min,
|
||||
expectedPSP: mutating1.Name,
|
||||
},
|
||||
@ -394,10 +410,8 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
pod: changedPodWithSC.DeepCopy(),
|
||||
podBeforeUpdate: podWithSC.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1, privilegedPSP},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: true,
|
||||
expectMutation: false,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: nil,
|
||||
expectedPSP: privilegedPSP.Name,
|
||||
},
|
||||
@ -406,10 +420,8 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
pod: changedPod.DeepCopy(),
|
||||
podBeforeUpdate: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: false,
|
||||
expectMutation: false,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: nil,
|
||||
expectedPSP: "",
|
||||
},
|
||||
@ -418,10 +430,8 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
pod: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
podBeforeUpdate: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: true,
|
||||
expectMutation: false,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: nil,
|
||||
expectedPSP: "",
|
||||
},
|
||||
@ -430,38 +440,32 @@ func TestAdmitPreferNonmutating(t *testing.T) {
|
||||
pod: gcChangedPod.DeepCopy(),
|
||||
podBeforeUpdate: unprivilegedRunAsAnyPod.DeepCopy(),
|
||||
psps: []*extensions.PodSecurityPolicy{mutating2, mutating1},
|
||||
shouldPassAdmit: true,
|
||||
shouldPassValidate: true,
|
||||
expectMutation: false,
|
||||
expectedPodUser: nil,
|
||||
expectedContainerUser: nil,
|
||||
expectedPSP: "",
|
||||
},
|
||||
}
|
||||
|
||||
for k, v := range tests {
|
||||
testPSPAdmitAdvanced(k, v.operation, v.psps, nil, &user.DefaultInfo{}, v.pod, v.podBeforeUpdate, v.shouldPassAdmit, v.shouldPassValidate, v.expectMutation, v.expectedPSP, t)
|
||||
testPSPAdmitAdvanced(k, v.operation, v.psps, nil, &user.DefaultInfo{}, v.pod, v.podBeforeUpdate, true, v.shouldPassValidate, v.expectMutation, v.expectedPSP, t)
|
||||
|
||||
if v.shouldPassAdmit {
|
||||
actualPodUser := (*int64)(nil)
|
||||
if v.pod.Spec.SecurityContext != nil {
|
||||
actualPodUser = v.pod.Spec.SecurityContext.RunAsUser
|
||||
}
|
||||
if (actualPodUser == nil) != (v.expectedPodUser == nil) {
|
||||
t.Errorf("%s expected pod user %v, got %v", k, v.expectedPodUser, actualPodUser)
|
||||
} else if actualPodUser != nil && *actualPodUser != *v.expectedPodUser {
|
||||
t.Errorf("%s expected pod user %v, got %v", k, *v.expectedPodUser, *actualPodUser)
|
||||
}
|
||||
actualPodUser := (*int64)(nil)
|
||||
if v.pod.Spec.SecurityContext != nil {
|
||||
actualPodUser = v.pod.Spec.SecurityContext.RunAsUser
|
||||
}
|
||||
if actualPodUser != nil {
|
||||
t.Errorf("%s expected pod user nil, got %v", k, *actualPodUser)
|
||||
}
|
||||
|
||||
actualContainerUser := (*int64)(nil)
|
||||
if v.pod.Spec.Containers[0].SecurityContext != nil {
|
||||
actualContainerUser = v.pod.Spec.Containers[0].SecurityContext.RunAsUser
|
||||
}
|
||||
if (actualContainerUser == nil) != (v.expectedContainerUser == nil) {
|
||||
t.Errorf("%s expected container user %v, got %v", k, v.expectedContainerUser, actualContainerUser)
|
||||
} else if actualContainerUser != nil && *actualContainerUser != *v.expectedContainerUser {
|
||||
t.Errorf("%s expected container user %v, got %v", k, *v.expectedContainerUser, *actualContainerUser)
|
||||
}
|
||||
actualContainerUser := (*int64)(nil)
|
||||
if v.pod.Spec.Containers[0].SecurityContext != nil {
|
||||
actualContainerUser = v.pod.Spec.Containers[0].SecurityContext.RunAsUser
|
||||
}
|
||||
if (actualContainerUser == nil) != (v.expectedContainerUser == nil) {
|
||||
t.Errorf("%s expected container user %v, got %v", k, v.expectedContainerUser, actualContainerUser)
|
||||
} else if actualContainerUser != nil && *actualContainerUser != *v.expectedContainerUser {
|
||||
t.Errorf("%s expected container user %v, got %v", k, *v.expectedContainerUser, *actualContainerUser)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1999,8 +2003,9 @@ func TestPolicyAuthorization(t *testing.T) {
|
||||
expectedPolicy string
|
||||
inPolicies []*extensions.PodSecurityPolicy
|
||||
allowed map[string]map[string]map[string]bool
|
||||
allowedGroup string
|
||||
}{
|
||||
"policy allowed by user": {
|
||||
"policy allowed by user (extensions API Group)": {
|
||||
user: &user.DefaultInfo{Name: "user"},
|
||||
sa: "sa",
|
||||
ns: "test",
|
||||
@ -2012,7 +2017,7 @@ func TestPolicyAuthorization(t *testing.T) {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{policyWithName("policy")},
|
||||
expectedPolicy: "policy",
|
||||
},
|
||||
"policy allowed by sa": {
|
||||
"policy allowed by sa (extensions API Group)": {
|
||||
user: &user.DefaultInfo{Name: "user"},
|
||||
sa: "sa",
|
||||
ns: "test",
|
||||
@ -2024,6 +2029,32 @@ func TestPolicyAuthorization(t *testing.T) {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{policyWithName("policy")},
|
||||
expectedPolicy: "policy",
|
||||
},
|
||||
"policy allowed by user (policy API Group)": {
|
||||
user: &user.DefaultInfo{Name: "user"},
|
||||
sa: "sa",
|
||||
ns: "test",
|
||||
allowed: map[string]map[string]map[string]bool{
|
||||
"user": {
|
||||
"test": {"policy": true},
|
||||
},
|
||||
},
|
||||
inPolicies: []*extensions.PodSecurityPolicy{policyWithName("policy")},
|
||||
expectedPolicy: "policy",
|
||||
allowedGroup: policy.GroupName,
|
||||
},
|
||||
"policy allowed by sa (policy API Group)": {
|
||||
user: &user.DefaultInfo{Name: "user"},
|
||||
sa: "sa",
|
||||
ns: "test",
|
||||
allowed: map[string]map[string]map[string]bool{
|
||||
serviceaccount.MakeUsername("test", "sa"): {
|
||||
"test": {"policy": true},
|
||||
},
|
||||
},
|
||||
inPolicies: []*extensions.PodSecurityPolicy{policyWithName("policy")},
|
||||
expectedPolicy: "policy",
|
||||
allowedGroup: policy.GroupName,
|
||||
},
|
||||
"no policies allowed": {
|
||||
user: &user.DefaultInfo{Name: "user"},
|
||||
sa: "sa",
|
||||
@ -2125,7 +2156,7 @@ func TestPolicyAuthorization(t *testing.T) {
|
||||
var (
|
||||
oldPod *kapi.Pod
|
||||
shouldPass = v.expectedPolicy != ""
|
||||
authz = &TestAuthorizer{usernameToNamespaceToAllowedPSPs: v.allowed}
|
||||
authz = &TestAuthorizer{usernameToNamespaceToAllowedPSPs: v.allowed, allowedAPIGroupName: v.allowedGroup}
|
||||
canMutate = true
|
||||
)
|
||||
pod := goodPod()
|
||||
@ -2150,7 +2181,6 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
|
||||
)
|
||||
|
||||
tests := map[string]struct {
|
||||
priviliged bool
|
||||
inPolicies []*extensions.PodSecurityPolicy
|
||||
allowed map[string]map[string]map[string]bool
|
||||
expectValidationErrs int
|
||||
@ -2217,7 +2247,7 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
|
||||
plugin := NewTestAdmission(tc.inPolicies, authz)
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), ns, "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Create, &user.DefaultInfo{Name: userName})
|
||||
|
||||
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true)
|
||||
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "")
|
||||
assert.Nil(t, allowedPod)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, validationErrs, tc.expectValidationErrs)
|
||||
@ -2225,6 +2255,99 @@ func TestPolicyAuthorizationErrors(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestPreferValidatedPSP(t *testing.T) {
|
||||
restrictivePSPWithName := func(name string) *extensions.PodSecurityPolicy {
|
||||
p := restrictivePSP()
|
||||
p.Name = name
|
||||
return p
|
||||
}
|
||||
|
||||
permissivePSPWithName := func(name string) *extensions.PodSecurityPolicy {
|
||||
p := permissivePSP()
|
||||
p.Name = name
|
||||
return p
|
||||
}
|
||||
|
||||
tests := map[string]struct {
|
||||
inPolicies []*extensions.PodSecurityPolicy
|
||||
expectValidationErrs int
|
||||
validatedPSPHint string
|
||||
expectedPSP string
|
||||
}{
|
||||
"no policy saved in annotations, PSPs are ordered lexicographically": {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{
|
||||
restrictivePSPWithName("001restrictive"),
|
||||
restrictivePSPWithName("002restrictive"),
|
||||
permissivePSPWithName("002permissive"),
|
||||
permissivePSPWithName("001permissive"),
|
||||
permissivePSPWithName("003permissive"),
|
||||
},
|
||||
expectValidationErrs: 0,
|
||||
validatedPSPHint: "",
|
||||
expectedPSP: "001permissive",
|
||||
},
|
||||
"policy saved in annotations is preferred": {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{
|
||||
restrictivePSPWithName("001restrictive"),
|
||||
restrictivePSPWithName("002restrictive"),
|
||||
permissivePSPWithName("001permissive"),
|
||||
permissivePSPWithName("002permissive"),
|
||||
permissivePSPWithName("003permissive"),
|
||||
},
|
||||
expectValidationErrs: 0,
|
||||
validatedPSPHint: "002permissive",
|
||||
expectedPSP: "002permissive",
|
||||
},
|
||||
"policy saved in annotations is invalid": {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{
|
||||
restrictivePSPWithName("001restrictive"),
|
||||
restrictivePSPWithName("002restrictive"),
|
||||
},
|
||||
expectValidationErrs: 2,
|
||||
validatedPSPHint: "foo",
|
||||
expectedPSP: "",
|
||||
},
|
||||
"policy saved in annotations is disallowed anymore": {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{
|
||||
restrictivePSPWithName("001restrictive"),
|
||||
restrictivePSPWithName("002restrictive"),
|
||||
},
|
||||
expectValidationErrs: 2,
|
||||
validatedPSPHint: "001restrictive",
|
||||
expectedPSP: "",
|
||||
},
|
||||
"policy saved in annotations is disallowed anymore, but find another one": {
|
||||
inPolicies: []*extensions.PodSecurityPolicy{
|
||||
restrictivePSPWithName("001restrictive"),
|
||||
restrictivePSPWithName("002restrictive"),
|
||||
permissivePSPWithName("002permissive"),
|
||||
permissivePSPWithName("001permissive"),
|
||||
},
|
||||
expectValidationErrs: 0,
|
||||
validatedPSPHint: "001restrictive",
|
||||
expectedPSP: "001permissive",
|
||||
},
|
||||
}
|
||||
for desc, tc := range tests {
|
||||
t.Run(desc, func(t *testing.T) {
|
||||
authz := authorizerfactory.NewAlwaysAllowAuthorizer()
|
||||
allowPrivilegeEscalation := true
|
||||
pod := goodPod()
|
||||
pod.Namespace = "ns"
|
||||
pod.Spec.ServiceAccountName = "sa"
|
||||
pod.Spec.Containers[0].SecurityContext.AllowPrivilegeEscalation = &allowPrivilegeEscalation
|
||||
|
||||
plugin := NewTestAdmission(tc.inPolicies, authz)
|
||||
attrs := kadmission.NewAttributesRecord(pod, nil, kapi.Kind("Pod").WithVersion("version"), "ns", "", kapi.Resource("pods").WithVersion("version"), "", kadmission.Update, &user.DefaultInfo{Name: "test"})
|
||||
|
||||
_, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, validationErrs, tc.expectValidationErrs)
|
||||
assert.Equal(t, pspName, tc.expectedPSP)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func restrictivePSP() *extensions.PodSecurityPolicy {
|
||||
return &extensions.PodSecurityPolicy{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
|
Reference in New Issue
Block a user