Merge pull request #83064 from liggitt/propagate-context

Propagate context to remote authorize/authenticate webhook calls
This commit is contained in:
Kubernetes Prow Robot 2019-09-25 09:32:01 -07:00 committed by GitHub
commit 327f53ba57
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
61 changed files with 270 additions and 93 deletions

View File

@ -19,6 +19,7 @@ package abac
import (
"bufio"
"context"
"fmt"
"os"
"strings"
@ -224,7 +225,7 @@ func resourceMatches(p abac.Policy, a authorizer.Attributes) bool {
}
// Authorize implements authorizer.Authorize
func (pl PolicyList) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (pl PolicyList) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
for _, p := range pl {
if matches(*p, a) {
return authorizer.DecisionAllow, "", nil

View File

@ -17,6 +17,7 @@ limitations under the License.
package abac
import (
"context"
"io/ioutil"
"os"
"reflect"
@ -133,7 +134,7 @@ func TestAuthorizeV0(t *testing.T) {
ResourceRequest: len(tc.NS) > 0 || len(tc.Resource) > 0,
}
decision, _, _ := a.Authorize(attr)
decision, _, _ := a.Authorize(context.Background(), attr)
if tc.ExpectDecision != decision {
t.Logf("tc: %v -> attr %v", tc, attr)
t.Errorf("%d: Expected allowed=%v but actually allowed=%v\n\t%v",
@ -451,7 +452,7 @@ func TestAuthorizeV1beta1(t *testing.T) {
Path: tc.Path,
}
// t.Logf("tc %2v: %v -> attr %v", i, tc, attr)
decision, _, _ := a.Authorize(attr)
decision, _, _ := a.Authorize(context.Background(), attr)
if tc.ExpectDecision != decision {
t.Errorf("%d: Expected allowed=%v but actually allowed=%v, for case %+v & %+v",
i, tc.ExpectDecision, decision, tc, attr)

View File

@ -260,7 +260,7 @@ func (s *Server) InstallAuthFilter() {
attrs := s.auth.GetRequestAttributes(info.User, req.Request)
// Authorize
decision, _, err := s.auth.Authorize(attrs)
decision, _, err := s.auth.Authorize(req.Request.Context(), attrs)
if err != nil {
msg := fmt.Sprintf("Authorization error (user=%s, verb=%s, resource=%s, subresource=%s)", attrs.GetUser().GetName(), attrs.GetVerb(), attrs.GetResource(), attrs.GetSubresource())
klog.Errorf(msg, err)

View File

@ -284,7 +284,7 @@ func (f *fakeAuth) AuthenticateRequest(req *http.Request) (*authenticator.Respon
func (f *fakeAuth) GetRequestAttributes(u user.Info, req *http.Request) authorizer.Attributes {
return f.attributesFunc(u, req)
}
func (f *fakeAuth) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
func (f *fakeAuth) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
return f.authorizeFunc(a)
}

View File

@ -70,7 +70,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
}
authorizationAttributes := authorizationutil.AuthorizationAttributesFrom(localSubjectAccessReview.Spec)
decision, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes)
decision, reason, evaluationErr := r.authorizer.Authorize(ctx, authorizationAttributes)
localSubjectAccessReview.Status = authorizationapi.SubjectAccessReviewStatus{
Allowed: (decision == authorizer.DecisionAllow),

View File

@ -73,7 +73,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
authorizationAttributes = authorizationutil.NonResourceAttributesFrom(userToCheck, *selfSAR.Spec.NonResourceAttributes)
}
decision, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes)
decision, reason, evaluationErr := r.authorizer.Authorize(ctx, authorizationAttributes)
selfSAR.Status = authorizationapi.SubjectAccessReviewStatus{
Allowed: (decision == authorizer.DecisionAllow),

View File

@ -62,7 +62,7 @@ func (r *REST) Create(ctx context.Context, obj runtime.Object, createValidation
}
authorizationAttributes := authorizationutil.AuthorizationAttributesFrom(subjectAccessReview.Spec)
decision, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes)
decision, reason, evaluationErr := r.authorizer.Authorize(ctx, authorizationAttributes)
subjectAccessReview.Status = authorizationapi.SubjectAccessReviewStatus{
Allowed: (decision == authorizer.DecisionAllow),

View File

@ -17,6 +17,7 @@ limitations under the License.
package subjectaccessreview
import (
"context"
"errors"
"strings"
"testing"
@ -39,7 +40,7 @@ type fakeAuthorizer struct {
err error
}
func (f *fakeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) {
func (f *fakeAuthorizer) Authorize(ctx context.Context, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
f.attrs = attrs
return f.decision, f.reason, f.err
}

View File

@ -87,7 +87,7 @@ func RoleEscalationAuthorized(ctx context.Context, a authorizer.Authorizer) bool
ResourceRequest: true,
}
decision, _, err := a.Authorize(attrs)
decision, _, err := a.Authorize(ctx, attrs)
if err != nil {
utilruntime.HandleError(fmt.Errorf(
"error authorizing user %#v to escalate %#v named %q in namespace %q: %v",
@ -135,7 +135,7 @@ func BindingAuthorized(ctx context.Context, roleRef rbac.RoleRef, bindingNamespa
return false
}
decision, _, err := a.Authorize(attrs)
decision, _, err := a.Authorize(ctx, attrs)
if err != nil {
utilruntime.HandleError(fmt.Errorf(
"error authorizing user %#v to bind %#v in namespace %s: %v",

View File

@ -112,7 +112,7 @@ func (a *gcPermissionsEnforcement) Validate(ctx context.Context, attributes admi
ResourceRequest: true,
Path: "",
}
decision, reason, err := a.authorizer.Authorize(deleteAttributes)
decision, reason, err := a.authorizer.Authorize(ctx, deleteAttributes)
if decision != authorizer.DecisionAllow {
return admission.NewForbidden(attributes, fmt.Errorf("cannot set an ownerRef on a resource you can't delete: %v, %v", reason, err))
}
@ -131,7 +131,7 @@ func (a *gcPermissionsEnforcement) Validate(ctx context.Context, attributes admi
// resources. User needs to have delete permission on all the
// matched Resources.
for _, record := range records {
decision, reason, err := a.authorizer.Authorize(record)
decision, reason, err := a.authorizer.Authorize(ctx, record)
if decision != authorizer.DecisionAllow {
return admission.NewForbidden(attributes, fmt.Errorf("cannot set blockOwnerDeletion if an ownerReference refers to a resource you can't set finalizers on: %v, %v", reason, err))
}

View File

@ -40,7 +40,7 @@ import (
type fakeAuthorizer struct{}
func (fakeAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (fakeAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
username := a.GetUser().GetName()
if username == "non-deleter" {

View File

@ -160,13 +160,13 @@ func (a *Plugin) Validate(ctx context.Context, attributes admission.Attributes,
Namespace: attributes.GetNamespace(),
},
}
if err := a.admitPod(pod, attributes, &imageReview); err != nil {
if err := a.admitPod(ctx, pod, attributes, &imageReview); err != nil {
return admission.NewForbidden(attributes, err)
}
return nil
}
func (a *Plugin) admitPod(pod *api.Pod, attributes admission.Attributes, review *v1alpha1.ImageReview) error {
func (a *Plugin) admitPod(ctx context.Context, pod *api.Pod, attributes admission.Attributes, review *v1alpha1.ImageReview) error {
cacheKey, err := json.Marshal(review.Spec)
if err != nil {
return err
@ -174,8 +174,8 @@ func (a *Plugin) admitPod(pod *api.Pod, attributes admission.Attributes, review
if entry, ok := a.responseCache.Get(string(cacheKey)); ok {
review.Status = entry.(v1alpha1.ImageReviewStatus)
} else {
result := a.webhook.WithExponentialBackoff(func() rest.Result {
return a.webhook.RestClient.Post().Body(review).Do()
result := a.webhook.WithExponentialBackoff(ctx, func() rest.Result {
return a.webhook.RestClient.Post().Context(ctx).Body(review).Do()
})
if err := result.Error(); err != nil {

View File

@ -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)
}

View File

@ -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)

View File

@ -17,6 +17,7 @@ limitations under the License.
package node
import (
"context"
"fmt"
"k8s.io/klog"
@ -78,7 +79,7 @@ var (
csiNodeResource = storageapi.Resource("csinodes")
)
func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) {
func (r *NodeAuthorizer) Authorize(ctx context.Context, attrs authorizer.Attributes) (authorizer.Decision, string, error) {
nodeName, isNode := r.identifier.NodeIdentity(attrs.GetUser())
if !isNode {
// reject requests from non-nodes

View File

@ -17,6 +17,7 @@ limitations under the License.
package node
import (
"context"
"fmt"
"runtime"
"runtime/pprof"
@ -414,7 +415,7 @@ func TestAuthorizer(t *testing.T) {
} else {
authz.features = tc.features
}
decision, _, _ := authz.Authorize(tc.attrs)
decision, _, _ := authz.Authorize(context.Background(), tc.attrs)
if decision != tc.expect {
t.Errorf("expected %v, got %v", tc.expect, decision)
}
@ -504,13 +505,13 @@ func TestAuthorizerSharedResources(t *testing.T) {
)
if len(tc.Secret) > 0 {
decision, _, err = authz.Authorize(authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "secrets", Namespace: "ns1", Name: tc.Secret})
decision, _, err = authz.Authorize(context.Background(), authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "secrets", Namespace: "ns1", Name: tc.Secret})
if err != nil {
t.Errorf("%d: unexpected error: %v", i, err)
continue
}
} else if len(tc.ConfigMap) > 0 {
decision, _, err = authz.Authorize(authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "configmaps", Namespace: "ns1", Name: tc.ConfigMap})
decision, _, err = authz.Authorize(context.Background(), authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "configmaps", Namespace: "ns1", Name: tc.ConfigMap})
if err != nil {
t.Errorf("%d: unexpected error: %v", i, err)
continue
@ -527,7 +528,7 @@ func TestAuthorizerSharedResources(t *testing.T) {
{
node3SharedSecretGet := authorizer.AttributesRecord{User: node3, ResourceRequest: true, Verb: "get", Resource: "secrets", Namespace: "ns1", Name: "shared-all"}
decision, _, err := authz.Authorize(node3SharedSecretGet)
decision, _, err := authz.Authorize(context.Background(), node3SharedSecretGet)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -539,7 +540,7 @@ func TestAuthorizerSharedResources(t *testing.T) {
pod3.Spec.Volumes = nil
g.AddPod(pod3)
decision, _, err = authz.Authorize(node3SharedSecretGet)
decision, _, err = authz.Authorize(context.Background(), node3SharedSecretGet)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
@ -833,7 +834,7 @@ func BenchmarkAuthorization(b *testing.B) {
b.SetParallelism(5000)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
decision, _, _ := authz.Authorize(tc.attrs)
decision, _, _ := authz.Authorize(context.Background(), tc.attrs)
if decision != tc.expect {
b.Errorf("expected %v, got %v", tc.expect, decision)
}

View File

@ -19,6 +19,7 @@ package rbac
import (
"bytes"
"context"
"fmt"
"k8s.io/klog"
@ -71,7 +72,7 @@ func (v *authorizingVisitor) visit(source fmt.Stringer, rule *rbacv1.PolicyRule,
return true
}
func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {
func (r *RBACAuthorizer) Authorize(ctx context.Context, requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {
ruleCheckingVisitor := &authorizingVisitor{requestAttributes: requestAttributes}
r.authorizationRuleResolver.VisitRulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace(), ruleCheckingVisitor.visit)

View File

@ -17,6 +17,7 @@ limitations under the License.
package rbac
import (
"context"
"fmt"
"strings"
"testing"
@ -248,13 +249,13 @@ func TestAuthorizer(t *testing.T) {
ruleResolver, _ := rbacregistryvalidation.NewTestRuleResolver(tt.roles, tt.roleBindings, tt.clusterRoles, tt.clusterRoleBindings)
a := RBACAuthorizer{ruleResolver}
for _, attr := range tt.shouldPass {
if decision, _, _ := a.Authorize(attr); decision != authorizer.DecisionAllow {
if decision, _, _ := a.Authorize(context.Background(), attr); decision != authorizer.DecisionAllow {
t.Errorf("case %d: incorrectly restricted %s", i, attr)
}
}
for _, attr := range tt.shouldFail {
if decision, _, _ := a.Authorize(attr); decision == authorizer.DecisionAllow {
if decision, _, _ := a.Authorize(context.Background(), attr); decision == authorizer.DecisionAllow {
t.Errorf("case %d: incorrectly passed %s", i, attr)
}
}
@ -516,7 +517,7 @@ func BenchmarkAuthorize(b *testing.B) {
for _, request := range requests {
b.Run(request.name, func(b *testing.B) {
for i := 0; i < b.N; i++ {
authz.Authorize(request.attrs)
authz.Authorize(context.Background(), request.attrs)
}
})
}

View File

@ -115,7 +115,7 @@ var _ initializer.WantsAuthorizer = &WantAuthorizerAdmission{}
// TestAuthorizer is a test stub that fulfills the WantsAuthorizer interface.
type TestAuthorizer struct{}
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) {
return authorizer.DecisionNoOpinion, "", nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package authorizer
import (
"context"
"net/http"
"k8s.io/apiserver/pkg/authentication/user"
@ -67,12 +68,12 @@ type Attributes interface {
// zero or more calls to methods of the Attributes interface. It returns nil when an action is
// authorized, otherwise it returns an error.
type Authorizer interface {
Authorize(a Attributes) (authorized Decision, reason string, err error)
Authorize(ctx context.Context, a Attributes) (authorized Decision, reason string, err error)
}
type AuthorizerFunc func(a Attributes) (Decision, string, error)
func (f AuthorizerFunc) Authorize(a Attributes) (Decision, string, error) {
func (f AuthorizerFunc) Authorize(ctx context.Context, a Attributes) (Decision, string, error) {
return f(a)
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package authorizerfactory
import (
"context"
"errors"
"k8s.io/apiserver/pkg/authentication/user"
@ -28,7 +29,7 @@ import (
// It is useful in tests and when using kubernetes in an open manner.
type alwaysAllowAuthorizer struct{}
func (alwaysAllowAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
func (alwaysAllowAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
return authorizer.DecisionAllow, "", nil
}
@ -56,7 +57,7 @@ func NewAlwaysAllowAuthorizer() *alwaysAllowAuthorizer {
// It is useful in unit tests to force an operation to be forbidden.
type alwaysDenyAuthorizer struct{}
func (alwaysDenyAuthorizer) Authorize(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) {
func (alwaysDenyAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) {
return authorizer.DecisionNoOpinion, "Everything is forbidden.", nil
}
@ -72,7 +73,7 @@ type privilegedGroupAuthorizer struct {
groups []string
}
func (r *privilegedGroupAuthorizer) Authorize(attr authorizer.Attributes) (authorizer.Decision, string, error) {
func (r *privilegedGroupAuthorizer) Authorize(ctx context.Context, attr authorizer.Attributes) (authorizer.Decision, string, error) {
if attr.GetUser() == nil {
return authorizer.DecisionNoOpinion, "Error", errors.New("no user on request.")
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package authorizerfactory
import (
"context"
"testing"
"k8s.io/apiserver/pkg/authentication/user"
@ -25,14 +26,14 @@ import (
func TestNewAlwaysAllowAuthorizer(t *testing.T) {
aaa := NewAlwaysAllowAuthorizer()
if decision, _, _ := aaa.Authorize(nil); decision != authorizer.DecisionAllow {
if decision, _, _ := aaa.Authorize(context.Background(), nil); decision != authorizer.DecisionAllow {
t.Errorf("AlwaysAllowAuthorizer.Authorize did not authorize successfully.")
}
}
func TestNewAlwaysDenyAuthorizer(t *testing.T) {
ada := NewAlwaysDenyAuthorizer()
if decision, _, _ := ada.Authorize(nil); decision == authorizer.DecisionAllow {
if decision, _, _ := ada.Authorize(context.Background(), nil); decision == authorizer.DecisionAllow {
t.Errorf("AlwaysDenyAuthorizer.Authorize returned nil instead of error.")
}
}
@ -43,10 +44,10 @@ func TestPrivilegedGroupAuthorizer(t *testing.T) {
yes := authorizer.AttributesRecord{User: &user.DefaultInfo{Groups: []string{"no", "allow-01"}}}
no := authorizer.AttributesRecord{User: &user.DefaultInfo{Groups: []string{"no", "deny-01"}}}
if authorized, _, _ := auth.Authorize(yes); authorized != authorizer.DecisionAllow {
if authorized, _, _ := auth.Authorize(context.Background(), yes); authorized != authorizer.DecisionAllow {
t.Errorf("failed")
}
if authorized, _, _ := auth.Authorize(no); authorized == authorizer.DecisionAllow {
if authorized, _, _ := auth.Authorize(context.Background(), no); authorized == authorizer.DecisionAllow {
t.Errorf("failed")
}
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package path
import (
"context"
"testing"
"k8s.io/apiserver/pkg/authorization/authorizer"
@ -65,7 +66,7 @@ func TestNewAuthorizer(t *testing.T) {
info := authorizer.AttributesRecord{
Path: pth,
}
if got, _, err := a.Authorize(info); err != nil {
if got, _, err := a.Authorize(context.Background(), info); err != nil {
t.Errorf("NewAuthorizer(%v).Authorize(%q) return unexpected error: %v", tt.excludedPaths, pth, err)
} else if got != cases.want {
t.Errorf("NewAuthorizer(%v).Authorize(%q) = %v, want %v", tt.excludedPaths, pth, got, cases.want)

View File

@ -25,6 +25,7 @@ limitations under the License.
package union
import (
"context"
"strings"
utilerrors "k8s.io/apimachinery/pkg/util/errors"
@ -41,14 +42,14 @@ func New(authorizationHandlers ...authorizer.Authorizer) authorizer.Authorizer {
}
// Authorizes against a chain of authorizer.Authorizer objects and returns nil if successful and returns error if unsuccessful
func (authzHandler unionAuthzHandler) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (authzHandler unionAuthzHandler) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
var (
errlist []error
reasonlist []string
)
for _, currAuthzHandler := range authzHandler {
decision, reason, err := currAuthzHandler.Authorize(a)
decision, reason, err := currAuthzHandler.Authorize(ctx, a)
if err != nil {
errlist = append(errlist, err)

View File

@ -17,6 +17,7 @@ limitations under the License.
package union
import (
"context"
"errors"
"fmt"
"reflect"
@ -31,7 +32,7 @@ type mockAuthzHandler struct {
err error
}
func (mock *mockAuthzHandler) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (mock *mockAuthzHandler) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
return mock.decision, "", mock.err
}
@ -40,7 +41,7 @@ func TestAuthorizationSecondPasses(t *testing.T) {
handler2 := &mockAuthzHandler{decision: authorizer.DecisionAllow}
authzHandler := New(handler1, handler2)
authorized, _, _ := authzHandler.Authorize(nil)
authorized, _, _ := authzHandler.Authorize(context.Background(), nil)
if authorized != authorizer.DecisionAllow {
t.Errorf("Unexpected authorization failure")
}
@ -51,7 +52,7 @@ func TestAuthorizationFirstPasses(t *testing.T) {
handler2 := &mockAuthzHandler{decision: authorizer.DecisionNoOpinion}
authzHandler := New(handler1, handler2)
authorized, _, _ := authzHandler.Authorize(nil)
authorized, _, _ := authzHandler.Authorize(context.Background(), nil)
if authorized != authorizer.DecisionAllow {
t.Errorf("Unexpected authorization failure")
}
@ -62,7 +63,7 @@ func TestAuthorizationNonePasses(t *testing.T) {
handler2 := &mockAuthzHandler{decision: authorizer.DecisionNoOpinion}
authzHandler := New(handler1, handler2)
authorized, _, _ := authzHandler.Authorize(nil)
authorized, _, _ := authzHandler.Authorize(context.Background(), nil)
if authorized == authorizer.DecisionAllow {
t.Errorf("Expected failed authorization")
}
@ -73,7 +74,7 @@ func TestAuthorizationError(t *testing.T) {
handler2 := &mockAuthzHandler{err: fmt.Errorf("foo")}
authzHandler := New(handler1, handler2)
_, _, err := authzHandler.Authorize(nil)
_, _, err := authzHandler.Authorize(context.Background(), nil)
if err == nil {
t.Errorf("Expected error: %v", err)
}
@ -257,7 +258,7 @@ func TestAuthorizationUnequivocalDeny(t *testing.T) {
t.Run(fmt.Sprintf("case %v", i), func(t *testing.T) {
authzHandler := New(c.authorizers...)
decision, _, _ := authzHandler.Authorize(nil)
decision, _, _ := authzHandler.Authorize(context.Background(), nil)
if decision != c.decision {
t.Errorf("Unexpected authorization failure: %v, expected: %v", decision, c.decision)
}

View File

@ -56,7 +56,7 @@ func WithAuthorization(handler http.Handler, a authorizer.Authorizer, s runtime.
responsewriters.InternalError(w, req, err)
return
}
authorized, reason, err := a.Authorize(attributes)
authorized, reason, err := a.Authorize(ctx, attributes)
// an authorizer like RBAC could encounter evaluation errors and still allow the request, so authorizer decision is checked before error here.
if authorized == authorizer.DecisionAllow {
audit.LogAnnotation(ae, decisionAnnotationKey, decisionAllow)

View File

@ -17,6 +17,7 @@ limitations under the License.
package filters
import (
"context"
"errors"
"net/http"
"net/http/httptest"
@ -129,7 +130,7 @@ type fakeAuthorizer struct {
err error
}
func (f fakeAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (f fakeAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
return f.decision, f.reason, f.err
}

View File

@ -109,7 +109,7 @@ func WithImpersonation(handler http.Handler, a authorizer.Authorizer, s runtime.
return
}
decision, reason, err := a.Authorize(actingAsAttributes)
decision, reason, err := a.Authorize(ctx, actingAsAttributes)
if err != nil || decision != authorizer.DecisionAllow {
klog.V(4).Infof("Forbidden: %#v, Reason: %s, Error: %v", req.RequestURI, reason, err)
responsewriters.Forbidden(ctx, actingAsAttributes, w, req, reason, s)

View File

@ -36,7 +36,7 @@ import (
type impersonateAuthorizer struct{}
func (impersonateAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
func (impersonateAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
user := a.GetUser()
switch {

View File

@ -210,7 +210,7 @@ func withAuthorization(validate rest.ValidateObjectFunc, a authorizer.Authorizer
return errors.NewInternalError(fmt.Errorf("no authorizer provided, unable to authorize a create on update"))
}
once.Do(func() {
authorizerDecision, authorizerReason, authorizerErr = a.Authorize(attributes)
authorizerDecision, authorizerReason, authorizerErr = a.Authorize(ctx, attributes)
})
// an authorizer like RBAC could encounter evaluation errors and still allow the request, so authorizer decision is checked before error here.
if authorizerDecision == authorizer.DecisionAllow {

View File

@ -477,7 +477,7 @@ type mockAuthorizer struct {
lastURI string
}
func (authz *mockAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
func (authz *mockAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) {
authz.lastURI = a.GetPath()
return authorizer.DecisionAllow, "", nil
}

View File

@ -18,6 +18,7 @@ limitations under the License.
package webhook
import (
"context"
"fmt"
"time"
@ -81,9 +82,9 @@ func newGenericWebhook(scheme *runtime.Scheme, codecFactory serializer.CodecFact
// WithExponentialBackoff will retry webhookFn() up to 5 times with exponentially increasing backoff when
// it returns an error for which apierrors.SuggestsClientDelay() or apierrors.IsInternalError() returns true.
func (g *GenericWebhook) WithExponentialBackoff(webhookFn func() rest.Result) rest.Result {
func (g *GenericWebhook) WithExponentialBackoff(ctx context.Context, webhookFn func() rest.Result) rest.Result {
var result rest.Result
WithExponentialBackoff(g.InitialBackoff, func() error {
WithExponentialBackoff(ctx, g.InitialBackoff, func() error {
result = webhookFn()
return result.Error()
})
@ -92,7 +93,7 @@ func (g *GenericWebhook) WithExponentialBackoff(webhookFn func() rest.Result) re
// WithExponentialBackoff will retry webhookFn() up to 5 times with exponentially increasing backoff when
// it returns an error for which apierrors.SuggestsClientDelay() or apierrors.IsInternalError() returns true.
func WithExponentialBackoff(initialBackoff time.Duration, webhookFn func() error) error {
func WithExponentialBackoff(ctx context.Context, initialBackoff time.Duration, webhookFn func() error) error {
backoff := wait.Backoff{
Duration: initialBackoff,
Factor: 1.5,
@ -103,6 +104,12 @@ func WithExponentialBackoff(initialBackoff time.Duration, webhookFn func() error
var err error
wait.ExponentialBackoff(backoff, func() (bool, error) {
err = webhookFn()
if ctx.Err() != nil {
// we timed out or were cancelled, we should not retry
return true, err
}
// these errors indicate a transient error that should be retried.
if net.IsConnectionReset(err) || apierrors.IsInternalError(err) || apierrors.IsTimeout(err) || apierrors.IsTooManyRequests(err) {
return false, nil

View File

@ -17,6 +17,7 @@ limitations under the License.
package webhook
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
@ -550,7 +551,7 @@ func TestWithExponentialBackoff(t *testing.T) {
t.Fatalf("failed to create the webhook: %v", err)
}
result := wh.WithExponentialBackoff(func() rest.Result {
result := wh.WithExponentialBackoff(context.Background(), func() rest.Result {
return wh.RestClient.Get().Do()
})
@ -562,7 +563,7 @@ func TestWithExponentialBackoff(t *testing.T) {
t.Errorf("unexpected status code: %d", statusCode)
}
result = wh.WithExponentialBackoff(func() rest.Result {
result = wh.WithExponentialBackoff(context.Background(), func() rest.Result {
return wh.RestClient.Get().Do()
})

View File

@ -18,6 +18,7 @@ limitations under the License.
package webhook
import (
"context"
"fmt"
"time"
@ -95,7 +96,7 @@ func (b *backend) processEvents(ev ...*auditinternal.Event) error {
for _, e := range ev {
list.Items = append(list.Items, *e)
}
return b.w.WithExponentialBackoff(func() rest.Result {
return b.w.WithExponentialBackoff(context.Background(), func() rest.Result {
trace := utiltrace.New("Call Audit Events webhook",
utiltrace.Field{"name", b.name},
utiltrace.Field{"event-count", len(list.Items)})

View File

@ -98,8 +98,8 @@ func (w *WebhookTokenAuthenticator) AuthenticateToken(ctx context.Context, token
err error
auds authenticator.Audiences
)
webhook.WithExponentialBackoff(w.initialBackoff, func() error {
result, err = w.tokenReview.Create(r)
webhook.WithExponentialBackoff(ctx, w.initialBackoff, func() error {
result, err = w.tokenReview.CreateContext(ctx, r)
return err
})
if err != nil {
@ -171,7 +171,11 @@ type tokenReviewClient struct {
}
func (t *tokenReviewClient) Create(tokenReview *authentication.TokenReview) (*authentication.TokenReview, error) {
return t.CreateContext(context.Background(), tokenReview)
}
func (t *tokenReviewClient) CreateContext(ctx context.Context, tokenReview *authentication.TokenReview) (*authentication.TokenReview, error) {
result := &authentication.TokenReview{}
err := t.w.RestClient.Post().Body(tokenReview).Do().Into(result)
err := t.w.RestClient.Post().Context(ctx).Body(tokenReview).Do().Into(result)
return result, err
}

View File

@ -18,6 +18,7 @@ limitations under the License.
package webhook
import (
"context"
"encoding/json"
"fmt"
"time"
@ -149,7 +150,7 @@ func newWithBackoff(subjectAccessReview authorizationclient.SubjectAccessReviewI
// TODO(mikedanese): We should eventually support failing closed when we
// encounter an error. We are failing open now to preserve backwards compatible
// behavior.
func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (decision authorizer.Decision, reason string, err error) {
func (w *WebhookAuthorizer) Authorize(ctx context.Context, attr authorizer.Attributes) (decision authorizer.Decision, reason string, err error) {
r := &authorization.SubjectAccessReview{}
if user := attr.GetUser(); user != nil {
r.Spec = authorization.SubjectAccessReviewSpec{
@ -187,8 +188,8 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (decision auth
result *authorization.SubjectAccessReview
err error
)
webhook.WithExponentialBackoff(w.initialBackoff, func() error {
result, err = w.subjectAccessReview.Create(r)
webhook.WithExponentialBackoff(ctx, w.initialBackoff, func() error {
result, err = w.subjectAccessReview.CreateContext(ctx, r)
return err
})
if err != nil {
@ -264,8 +265,12 @@ type subjectAccessReviewClient struct {
}
func (t *subjectAccessReviewClient) Create(subjectAccessReview *authorization.SubjectAccessReview) (*authorization.SubjectAccessReview, error) {
return t.CreateContext(context.Background(), subjectAccessReview)
}
func (t *subjectAccessReviewClient) CreateContext(ctx context.Context, subjectAccessReview *authorization.SubjectAccessReview) (*authorization.SubjectAccessReview, error) {
result := &authorization.SubjectAccessReview{}
err := t.w.RestClient.Post().Body(subjectAccessReview).Do().Into(result)
err := t.w.RestClient.Post().Context(ctx).Body(subjectAccessReview).Do().Into(result)
return result, err
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package webhook
import (
"context"
"crypto/tls"
"crypto/x509"
"encoding/json"
@ -397,7 +398,7 @@ func TestTLSConfig(t *testing.T) {
// Allow all and see if we get an error.
service.Allow()
decision, _, err := wh.Authorize(attr)
decision, _, err := wh.Authorize(context.Background(), attr)
if tt.wantAuth {
if decision != authorizer.DecisionAllow {
t.Errorf("expected successful authorization")
@ -419,7 +420,7 @@ func TestTLSConfig(t *testing.T) {
}
service.Deny()
if decision, _, _ := wh.Authorize(attr); decision == authorizer.DecisionAllow {
if decision, _, _ := wh.Authorize(context.Background(), attr); decision == authorizer.DecisionAllow {
t.Errorf("%s: incorrectly authorized with DenyAll policy", tt.test)
}
}()
@ -523,7 +524,7 @@ func TestWebhook(t *testing.T) {
}
for i, tt := range tests {
decision, _, err := wh.Authorize(tt.attr)
decision, _, err := wh.Authorize(context.Background(), tt.attr)
if err != nil {
t.Fatal(err)
}
@ -627,7 +628,7 @@ func TestWebhookCache(t *testing.T) {
serv.called = 0
serv.allow = test.allow
serv.statusCode = test.statusCode
authorized, _, err := wh.Authorize(test.attr)
authorized, _, err := wh.Authorize(context.Background(), test.attr)
if test.expectedErr && err == nil {
t.Fatalf("%d: Expected error", i)
} else if !test.expectedErr && err != nil {

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authenticationapi "k8s.io/api/authentication/v1"
core "k8s.io/client-go/testing"
)
func (c *FakeTokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
return c.CreateContext(context.Background(), tokenReview)
}
func (c *FakeTokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authenticationapi.SchemeGroupVersion.WithResource("tokenreviews"), tokenReview), &authenticationapi.TokenReview{})
return obj.(*authenticationapi.TokenReview), err
}

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1
import (
"context"
authenticationapi "k8s.io/api/authentication/v1"
)
type TokenReviewExpansion interface {
Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
}
func (c *tokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
return c.CreateContext(context.Background(), tokenReview)
}
func (c *tokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
result = &authenticationapi.TokenReview{}
err = c.client.Post().
Context(ctx).
Resource("tokenreviews").
Body(tokenReview).
Do().

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authenticationapi "k8s.io/api/authentication/v1beta1"
core "k8s.io/client-go/testing"
)
func (c *FakeTokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
return c.CreateContext(context.Background(), tokenReview)
}
func (c *FakeTokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authenticationapi.SchemeGroupVersion.WithResource("tokenreviews"), tokenReview), &authenticationapi.TokenReview{})
return obj.(*authenticationapi.TokenReview), err
}

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1beta1
import (
"context"
authenticationapi "k8s.io/api/authentication/v1beta1"
)
type TokenReviewExpansion interface {
Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error)
}
func (c *tokenReviews) Create(tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
return c.CreateContext(context.Background(), tokenReview)
}
func (c *tokenReviews) CreateContext(ctx context.Context, tokenReview *authenticationapi.TokenReview) (result *authenticationapi.TokenReview, err error) {
result = &authenticationapi.TokenReview{}
err = c.client.Post().
Context(ctx).
Resource("tokenreviews").
Body(tokenReview).
Do().

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
core "k8s.io/client-go/testing"
)
func (c *FakeLocalSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *FakeLocalSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewCreateAction(authorizationapi.SchemeGroupVersion.WithResource("localsubjectaccessreviews"), c.ns, sar), &authorizationapi.SubjectAccessReview{})
return obj.(*authorizationapi.LocalSubjectAccessReview), err
}

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
core "k8s.io/client-go/testing"
)
func (c *FakeSelfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *FakeSelfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectaccessreviews"), sar), &authorizationapi.SelfSubjectAccessReview{})
return obj.(*authorizationapi.SelfSubjectAccessReview), err
}

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
core "k8s.io/client-go/testing"
)
func (c *FakeSelfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
return c.CreateContext(context.Background(), srr)
}
func (c *FakeSelfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectrulesreviews"), srr), &authorizationapi.SelfSubjectRulesReview{})
return obj.(*authorizationapi.SelfSubjectRulesReview), err
}

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
core "k8s.io/client-go/testing"
)
func (c *FakeSubjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *FakeSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("subjectaccessreviews"), sar), &authorizationapi.SubjectAccessReview{})
if obj == nil {
return nil, err

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
)
type LocalSubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
}
func (c *localSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *localSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
result = &authorizationapi.LocalSubjectAccessReview{}
err = c.client.Post().
Context(ctx).
Namespace(c.ns).
Resource("localsubjectaccessreviews").
Body(sar).

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
)
type SelfSubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
}
func (c *selfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *selfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
result = &authorizationapi.SelfSubjectAccessReview{}
err = c.client.Post().
Context(ctx).
Resource("selfsubjectaccessreviews").
Body(sar).
Do().

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
)
type SelfSubjectRulesReviewExpansion interface {
Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
}
func (c *selfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
return c.CreateContext(context.Background(), srr)
}
func (c *selfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
result = &authorizationapi.SelfSubjectRulesReview{}
err = c.client.Post().
Context(ctx).
Resource("selfsubjectrulesreviews").
Body(srr).
Do().

View File

@ -17,17 +17,25 @@ limitations under the License.
package v1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1"
)
// The SubjectAccessReviewExpansion interface allows manually adding extra methods to the AuthorizationInterface.
type SubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
}
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *subjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
result = &authorizationapi.SubjectAccessReview{}
err = c.client.Post().
Context(ctx).
Resource("subjectaccessreviews").
Body(sar).
Do().

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
core "k8s.io/client-go/testing"
)
func (c *FakeLocalSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *FakeLocalSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewCreateAction(authorizationapi.SchemeGroupVersion.WithResource("localsubjectaccessreviews"), c.ns, sar), &authorizationapi.SubjectAccessReview{})
return obj.(*authorizationapi.LocalSubjectAccessReview), err
}

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
core "k8s.io/client-go/testing"
)
func (c *FakeSelfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *FakeSelfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectaccessreviews"), sar), &authorizationapi.SelfSubjectAccessReview{})
return obj.(*authorizationapi.SelfSubjectAccessReview), err
}

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
core "k8s.io/client-go/testing"
)
func (c *FakeSelfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
return c.CreateContext(context.Background(), srr)
}
func (c *FakeSelfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("selfsubjectrulesreviews"), srr), &authorizationapi.SelfSubjectRulesReview{})
return obj.(*authorizationapi.SelfSubjectRulesReview), err
}

View File

@ -17,11 +17,17 @@ limitations under the License.
package fake
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
core "k8s.io/client-go/testing"
)
func (c *FakeSubjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *FakeSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
obj, err := c.Fake.Invokes(core.NewRootCreateAction(authorizationapi.SchemeGroupVersion.WithResource("subjectaccessreviews"), sar), &authorizationapi.SubjectAccessReview{})
return obj.(*authorizationapi.SubjectAccessReview), err
}

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1beta1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
)
type LocalSubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error)
}
func (c *localSubjectAccessReviews) Create(sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *localSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.LocalSubjectAccessReview) (result *authorizationapi.LocalSubjectAccessReview, err error) {
result = &authorizationapi.LocalSubjectAccessReview{}
err = c.client.Post().
Context(ctx).
Namespace(c.ns).
Resource("localsubjectaccessreviews").
Body(sar).

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1beta1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
)
type SelfSubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error)
}
func (c *selfSubjectAccessReviews) Create(sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *selfSubjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SelfSubjectAccessReview) (result *authorizationapi.SelfSubjectAccessReview, err error) {
result = &authorizationapi.SelfSubjectAccessReview{}
err = c.client.Post().
Context(ctx).
Resource("selfsubjectaccessreviews").
Body(sar).
Do().

View File

@ -17,16 +17,24 @@ limitations under the License.
package v1beta1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
)
type SelfSubjectRulesReviewExpansion interface {
Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error)
}
func (c *selfSubjectRulesReviews) Create(srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
return c.CreateContext(context.Background(), srr)
}
func (c *selfSubjectRulesReviews) CreateContext(ctx context.Context, srr *authorizationapi.SelfSubjectRulesReview) (result *authorizationapi.SelfSubjectRulesReview, err error) {
result = &authorizationapi.SelfSubjectRulesReview{}
err = c.client.Post().
Context(ctx).
Resource("selfsubjectrulesreviews").
Body(srr).
Do().

View File

@ -17,17 +17,25 @@ limitations under the License.
package v1beta1
import (
"context"
authorizationapi "k8s.io/api/authorization/v1beta1"
)
// The SubjectAccessReviewExpansion interface allows manually adding extra methods to the AuthorizationInterface.
type SubjectAccessReviewExpansion interface {
Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error)
}
func (c *subjectAccessReviews) Create(sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
return c.CreateContext(context.Background(), sar)
}
func (c *subjectAccessReviews) CreateContext(ctx context.Context, sar *authorizationapi.SubjectAccessReview) (result *authorizationapi.SubjectAccessReview, err error) {
result = &authorizationapi.SubjectAccessReview{}
err = c.client.Post().
Context(ctx).
Resource("subjectaccessreviews").
Body(sar).
Do().

View File

@ -17,6 +17,7 @@ limitations under the License.
package auth
import (
"context"
"errors"
"net/http"
"strings"
@ -38,7 +39,7 @@ import (
// TODO(etune): remove this test once a more comprehensive built-in authorizer is implemented.
type sarAuthorizer struct{}
func (sarAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (sarAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
if a.GetUser().GetName() == "dave" {
return authorizer.DecisionNoOpinion, "no", errors.New("I'm sorry, Dave")
}

View File

@ -22,6 +22,7 @@ package auth
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
@ -539,7 +540,7 @@ func TestAuthModeAlwaysDeny(t *testing.T) {
// TODO(etune): remove this test once a more comprehensive built-in authorizer is implemented.
type allowAliceAuthorizer struct{}
func (allowAliceAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (allowAliceAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
if a.GetUser() != nil && a.GetUser().GetName() == "alice" {
return authorizer.DecisionAllow, "", nil
}
@ -705,7 +706,7 @@ func TestUnknownUserIsUnauthorized(t *testing.T) {
type impersonateAuthorizer struct{}
// alice can't act as anyone and bob can't do anything but act-as someone
func (impersonateAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (impersonateAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
// alice can impersonate service accounts and do other actions
if a.GetUser() != nil && a.GetUser().GetName() == "alice" && a.GetVerb() == "impersonate" && a.GetResource() == "serviceaccounts" {
return authorizer.DecisionAllow, "", nil
@ -864,7 +865,7 @@ type trackingAuthorizer struct {
requestAttributes []authorizer.Attributes
}
func (a *trackingAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) {
func (a *trackingAuthorizer) Authorize(ctx context.Context, attributes authorizer.Attributes) (authorizer.Decision, string, error) {
a.requestAttributes = append(a.requestAttributes, attributes)
return authorizer.DecisionAllow, "", nil
}

View File

@ -17,6 +17,7 @@ limitations under the License.
package framework
import (
"context"
"flag"
"net"
"net/http"
@ -69,7 +70,7 @@ type Config struct {
// alwaysAllow always allows an action
type alwaysAllow struct{}
func (alwaysAllow) Authorize(requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {
func (alwaysAllow) Authorize(ctx context.Context, requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) {
return authorizer.DecisionAllow, "always allow", nil
}

View File

@ -18,6 +18,7 @@ package master
import (
"bytes"
"context"
"encoding/json"
"fmt"
"io/ioutil"
@ -59,7 +60,7 @@ const (
type allowAliceAuthorizer struct{}
func (allowAliceAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) {
func (allowAliceAuthorizer) Authorize(ctx context.Context, a authorizer.Attributes) (authorizer.Decision, string, error) {
if a.GetUser() != nil && a.GetUser().GetName() == "alice" {
return authorizer.DecisionAllow, "", nil
}