mirror of
https://github.com/k3s-io/kubernetes.git
synced 2026-01-29 21:29:24 +00:00
Propagate context to Authorize() calls
This commit is contained in:
@@ -126,7 +126,7 @@ func (p *Plugin) Admit(ctx context.Context, a admission.Attributes, o admission.
|
||||
pod := a.GetObject().(*api.Pod)
|
||||
|
||||
// compute the context. Mutation is allowed. ValidatedPSPAnnotation is not taken into account.
|
||||
allowedPod, pspName, validationErrs, err := p.computeSecurityContext(a, pod, true, "")
|
||||
allowedPod, pspName, validationErrs, err := p.computeSecurityContext(ctx, a, pod, true, "")
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
@@ -161,7 +161,7 @@ func (p *Plugin) Validate(ctx context.Context, a admission.Attributes, o admissi
|
||||
pod := a.GetObject().(*api.Pod)
|
||||
|
||||
// compute the context. Mutation is not allowed. ValidatedPSPAnnotation is used as a hint to gain same speed-up.
|
||||
allowedPod, pspName, validationErrs, err := p.computeSecurityContext(a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation])
|
||||
allowedPod, pspName, validationErrs, err := p.computeSecurityContext(ctx, a, pod, false, pod.ObjectMeta.Annotations[psputil.ValidatedPSPAnnotation])
|
||||
if err != nil {
|
||||
return admission.NewForbidden(a, err)
|
||||
}
|
||||
@@ -207,7 +207,7 @@ func shouldIgnore(a admission.Attributes) (bool, error) {
|
||||
// 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. validatedPSPHint is the validated psp name
|
||||
// saved in kubernetes.io/psp annotation. This psp is usually the one we are looking for.
|
||||
func (p *Plugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, specMutationAllowed bool, validatedPSPHint string) (*api.Pod, string, field.ErrorList, error) {
|
||||
func (p *Plugin) computeSecurityContext(ctx context.Context, 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
|
||||
klog.V(4).Infof("getting pod security policies for pod %s (generate: %s)", pod.Name, pod.GenerateName)
|
||||
var saInfo user.Info
|
||||
@@ -271,7 +271,7 @@ func (p *Plugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, sp
|
||||
continue
|
||||
}
|
||||
|
||||
if !isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), provider.GetPSPName(), p.authz) {
|
||||
if !isAuthorizedForPolicy(ctx, a.GetUserInfo(), saInfo, a.GetNamespace(), provider.GetPSPName(), p.authz) {
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -295,7 +295,7 @@ func (p *Plugin) computeSecurityContext(a admission.Attributes, pod *api.Pod, sp
|
||||
// Pod is rejected. Filter the validation errors to only include errors from authorized PSPs.
|
||||
aggregate := field.ErrorList{}
|
||||
for psp, errs := range validationErrs {
|
||||
if isAuthorizedForPolicy(a.GetUserInfo(), saInfo, a.GetNamespace(), psp, p.authz) {
|
||||
if isAuthorizedForPolicy(ctx, a.GetUserInfo(), saInfo, a.GetNamespace(), psp, p.authz) {
|
||||
aggregate = append(aggregate, errs...)
|
||||
}
|
||||
}
|
||||
@@ -338,27 +338,27 @@ func (p *Plugin) createProvidersFromPolicies(psps []*policyv1beta1.PodSecurityPo
|
||||
return providers, errs
|
||||
}
|
||||
|
||||
func isAuthorizedForPolicy(user, sa user.Info, namespace, policyName string, authz authorizer.Authorizer) bool {
|
||||
func isAuthorizedForPolicy(ctx context.Context, user, sa user.Info, namespace, policyName string, authz authorizer.Authorizer) bool {
|
||||
// Check the service account first, as that is the more common use case.
|
||||
return authorizedForPolicy(sa, namespace, policyName, authz) ||
|
||||
authorizedForPolicy(user, namespace, policyName, authz)
|
||||
return authorizedForPolicy(ctx, sa, namespace, policyName, authz) ||
|
||||
authorizedForPolicy(ctx, user, namespace, policyName, authz)
|
||||
}
|
||||
|
||||
// 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 {
|
||||
func authorizedForPolicy(ctx context.Context, 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)
|
||||
return authorizedForPolicyInAPIGroup(ctx, info, namespace, policyName, policy.GroupName, authz) ||
|
||||
authorizedForPolicyInAPIGroup(ctx, 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 {
|
||||
func authorizedForPolicyInAPIGroup(ctx context.Context, info user.Info, namespace, policyName, apiGroupName string, authz authorizer.Authorizer) bool {
|
||||
if info == nil {
|
||||
return false
|
||||
}
|
||||
attr := buildAttributes(info, namespace, policyName, apiGroupName)
|
||||
decision, reason, err := authz.Authorize(attr)
|
||||
decision, reason, err := authz.Authorize(ctx, attr)
|
||||
if err != nil {
|
||||
klog.V(5).Infof("cannot authorize for policy: %v,%v", reason, err)
|
||||
}
|
||||
|
||||
@@ -84,7 +84,7 @@ type TestAuthorizer struct {
|
||||
allowedAPIGroupName string
|
||||
}
|
||||
|
||||
func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
func (t *TestAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
|
||||
if t.usernameToNamespaceToAllowedPSPs == nil {
|
||||
return authorizer.DecisionAllow, "", nil
|
||||
}
|
||||
@@ -2249,7 +2249,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, &metav1.CreateOptions{}, false, &user.DefaultInfo{Name: userName})
|
||||
|
||||
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(attrs, pod, true, "")
|
||||
allowedPod, _, validationErrs, err := plugin.computeSecurityContext(context.Background(), attrs, pod, true, "")
|
||||
assert.Nil(t, allowedPod)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, validationErrs, tc.expectValidationErrs)
|
||||
@@ -2342,7 +2342,7 @@ func TestPreferValidatedPSP(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.Update, &metav1.UpdateOptions{}, false, &user.DefaultInfo{Name: "test"})
|
||||
|
||||
_, pspName, validationErrs, err := plugin.computeSecurityContext(attrs, pod, false, tc.validatedPSPHint)
|
||||
_, pspName, validationErrs, err := plugin.computeSecurityContext(context.Background(), attrs, pod, false, tc.validatedPSPHint)
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, validationErrs, tc.expectValidationErrs)
|
||||
assert.Equal(t, tc.expectedPSP, pspName)
|
||||
|
||||
Reference in New Issue
Block a user