From 12125455d84c75562e6dd6a183762549adff747f Mon Sep 17 00:00:00 2001 From: Mike Danese Date: Fri, 29 Sep 2017 14:21:40 -0700 Subject: [PATCH] move authorizers over to new interface --- pkg/auth/authorizer/abac/abac.go | 6 +- pkg/auth/authorizer/abac/abac_test.go | 156 +++++++++--------- pkg/kubelet/server/server.go | 4 +- pkg/kubelet/server/server_test.go | 24 +-- .../localsubjectaccessreview/rest.go | 4 +- .../selfsubjectaccessreview/rest.go | 4 +- .../authorization/subjectaccessreview/rest.go | 4 +- .../subjectaccessreview/rest_test.go | 7 +- pkg/registry/rbac/escalation_check.go | 4 +- plugin/pkg/admission/gc/gc_admission.go | 8 +- plugin/pkg/admission/gc/gc_admission_test.go | 22 +-- .../security/podsecuritypolicy/admission.go | 4 +- .../podsecuritypolicy/admission_test.go | 9 +- .../auth/authorizer/node/node_authorizer.go | 23 +-- .../authorizer/node/node_authorizer_test.go | 60 +++---- plugin/pkg/auth/authorizer/rbac/rbac.go | 6 +- plugin/pkg/auth/authorizer/rbac/rbac_test.go | 4 +- .../admission/initializer/initializer_test.go | 4 +- .../plugin/initialization/initialization.go | 4 +- .../initialization/initialization_test.go | 6 +- .../authorizerfactory/authz_test.go | 8 +- .../authorizerfactory/builtin.go | 20 +-- .../pkg/endpoints/filters/authorization.go | 2 +- .../pkg/endpoints/filters/impersonation.go | 4 +- .../endpoints/filters/impersonation_test.go | 24 +-- .../pkg/server/genericapiserver_test.go | 4 +- .../plugin/pkg/authorizer/webhook/webhook.go | 16 +- .../pkg/authorizer/webhook/webhook_test.go | 14 +- test/integration/auth/accessreview_test.go | 6 +- test/integration/auth/auth_test.go | 22 +-- test/integration/framework/master_utils.go | 5 +- test/integration/master/master_test.go | 6 +- .../serviceaccount/service_account_test.go | 10 +- 33 files changed, 261 insertions(+), 243 deletions(-) diff --git a/pkg/auth/authorizer/abac/abac.go b/pkg/auth/authorizer/abac/abac.go index 956c1f7086..f3132740d2 100644 --- a/pkg/auth/authorizer/abac/abac.go +++ b/pkg/auth/authorizer/abac/abac.go @@ -221,13 +221,13 @@ func resourceMatches(p abac.Policy, a authorizer.Attributes) bool { } // Authorizer implements authorizer.Authorize -func (pl policyList) Authorize(a authorizer.Attributes) (bool, string, error) { +func (pl policyList) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) { for _, p := range pl { if matches(*p, a) { - return true, "", nil + return authorizer.DecisionAllow, "", nil } } - return false, "No policy matched.", nil + return authorizer.DecisionNoOpinion, "No policy matched.", nil // TODO: Benchmark how much time policy matching takes with a medium size // policy file, compared to other steps such as encoding/decoding. // Then, add Caching only if needed. diff --git a/pkg/auth/authorizer/abac/abac_test.go b/pkg/auth/authorizer/abac/abac_test.go index 027943a8a3..6d73239920 100644 --- a/pkg/auth/authorizer/abac/abac_test.go +++ b/pkg/auth/authorizer/abac/abac_test.go @@ -81,46 +81,46 @@ func TestAuthorizeV0(t *testing.T) { uChuck := user.DefaultInfo{Name: "chuck", UID: "uid5", Groups: authenticatedGroup} testCases := []struct { - User user.DefaultInfo - Verb string - Resource string - NS string - APIGroup string - Path string - ExpectAllow bool + User user.DefaultInfo + Verb string + Resource string + NS string + APIGroup string + Path string + ExpectDecision authorizer.Decision }{ // Scheduler can read pods - {User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectAllow: true}, - {User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectAllow: true}, + {User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionAllow}, + {User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionAllow}, // Scheduler cannot write pods - {User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectAllow: false}, - {User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectAllow: false}, + {User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionNoOpinion}, // Scheduler can write bindings - {User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectAllow: true}, - {User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectAllow: true}, + {User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectDecision: authorizer.DecisionAllow}, + {User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectDecision: authorizer.DecisionAllow}, // Alice can read and write anything in the right namespace. - {User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "foo", NS: "projectCaribou", APIGroup: "bar", ExpectAllow: true}, + {User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "foo", NS: "projectCaribou", APIGroup: "bar", ExpectDecision: authorizer.DecisionAllow}, // .. but not the wrong namespace. - {User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false}, - {User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectAllow: false}, - {User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectAllow: false}, + {User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, // Chuck can read events, since anyone can. - {User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectAllow: true}, - {User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectAllow: true}, + {User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionAllow}, + {User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectDecision: authorizer.DecisionAllow}, // Chuck can't do other things. - {User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectAllow: false}, - {User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false}, - {User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectAllow: false}, + {User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, // Chunk can't access things with no kind or namespace - {User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectAllow: false}, + {User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion}, } for i, tc := range testCases { attr := authorizer.AttributesRecord{ @@ -133,11 +133,11 @@ func TestAuthorizeV0(t *testing.T) { ResourceRequest: len(tc.NS) > 0 || len(tc.Resource) > 0, } - authorized, _, _ := a.Authorize(attr) - if tc.ExpectAllow != authorized { + decision, _, _ := a.Authorize(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", - i, tc.ExpectAllow, authorized, tc) + i, tc.ExpectDecision, decision, tc) } } } @@ -373,72 +373,72 @@ func TestAuthorizeV1beta1(t *testing.T) { uAPIGroup := user.DefaultInfo{Name: "apigroupuser", UID: "uid8", Groups: authenticatedGroup} testCases := []struct { - User user.DefaultInfo - Verb string - Resource string - APIGroup string - NS string - Path string - ExpectAllow bool + User user.DefaultInfo + Verb string + Resource string + APIGroup string + NS string + Path string + ExpectDecision authorizer.Decision }{ // Scheduler can read pods - {User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectAllow: true}, - {User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectAllow: true}, + {User: uScheduler, Verb: "list", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionAllow}, + {User: uScheduler, Verb: "list", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionAllow}, // Scheduler cannot write pods - {User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectAllow: false}, - {User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectAllow: false}, + {User: uScheduler, Verb: "create", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uScheduler, Verb: "create", Resource: "pods", NS: "", ExpectDecision: authorizer.DecisionNoOpinion}, // Scheduler can write bindings - {User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectAllow: true}, - {User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectAllow: true}, + {User: uScheduler, Verb: "get", Resource: "bindings", NS: "ns1", ExpectDecision: authorizer.DecisionAllow}, + {User: uScheduler, Verb: "get", Resource: "bindings", NS: "", ExpectDecision: authorizer.DecisionAllow}, // Alice can read and write anything in the right namespace. - {User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectAllow: true}, - {User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectAllow: true}, + {User: uAlice, Verb: "get", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "get", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "get", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "widgets", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, + {User: uAlice, Verb: "update", Resource: "", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, // .. but not the wrong namespace. - {User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false}, - {User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectAllow: false}, - {User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectAllow: false}, + {User: uAlice, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uAlice, Verb: "get", Resource: "widgets", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uAlice, Verb: "get", Resource: "", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, // Debbie can write to pods in the right namespace - {User: uDebbie, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectAllow: true}, + {User: uDebbie, Verb: "update", Resource: "pods", NS: "projectCaribou", ExpectDecision: authorizer.DecisionAllow}, // Chuck can read events, since anyone can. - {User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectAllow: true}, - {User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectAllow: true}, + {User: uChuck, Verb: "get", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionAllow}, + {User: uChuck, Verb: "get", Resource: "events", NS: "", ExpectDecision: authorizer.DecisionAllow}, // Chuck can't do other things. - {User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectAllow: false}, - {User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectAllow: false}, - {User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectAllow: false}, + {User: uChuck, Verb: "update", Resource: "events", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uChuck, Verb: "get", Resource: "pods", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uChuck, Verb: "get", Resource: "floop", NS: "ns1", ExpectDecision: authorizer.DecisionNoOpinion}, // Chuck can't access things with no resource or namespace - {User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectAllow: false}, + {User: uChuck, Verb: "get", Path: "/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion}, // but can access /api - {User: uChuck, Verb: "get", Path: "/api", Resource: "", NS: "", ExpectAllow: true}, + {User: uChuck, Verb: "get", Path: "/api", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, // though he cannot write to it - {User: uChuck, Verb: "create", Path: "/api", Resource: "", NS: "", ExpectAllow: false}, + {User: uChuck, Verb: "create", Path: "/api", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion}, // while he can write to /custom - {User: uChuck, Verb: "update", Path: "/custom", Resource: "", NS: "", ExpectAllow: true}, + {User: uChuck, Verb: "update", Path: "/custom", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, // he cannot get "/root" - {User: uChuck, Verb: "get", Path: "/root", Resource: "", NS: "", ExpectAllow: false}, + {User: uChuck, Verb: "get", Path: "/root", Resource: "", NS: "", ExpectDecision: authorizer.DecisionNoOpinion}, // but can get any subpath - {User: uChuck, Verb: "get", Path: "/root/", Resource: "", NS: "", ExpectAllow: true}, - {User: uChuck, Verb: "get", Path: "/root/test/1/2/3", Resource: "", NS: "", ExpectAllow: true}, + {User: uChuck, Verb: "get", Path: "/root/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, + {User: uChuck, Verb: "get", Path: "/root/test/1/2/3", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, // the user "noresource" can get any non-resource request - {User: uNoResource, Verb: "get", Path: "", Resource: "", NS: "", ExpectAllow: true}, - {User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "", ExpectAllow: true}, - {User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "", NS: "", ExpectAllow: true}, + {User: uNoResource, Verb: "get", Path: "", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, + {User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, + {User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "", NS: "", ExpectDecision: authorizer.DecisionAllow}, // but cannot get any request where IsResourceRequest() == true - {User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "bar", ExpectAllow: false}, - {User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "foo", NS: "bar", ExpectAllow: false}, + {User: uNoResource, Verb: "get", Path: "/", Resource: "", NS: "bar", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uNoResource, Verb: "get", Path: "/foo/bar/baz", Resource: "foo", NS: "bar", ExpectDecision: authorizer.DecisionNoOpinion}, // Test APIGroup matching - {User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectAnyGroup", ExpectAllow: true}, - {User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectEmptyGroup", ExpectAllow: false}, - {User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectXGroup", ExpectAllow: true}, + {User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectAnyGroup", ExpectDecision: authorizer.DecisionAllow}, + {User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectEmptyGroup", ExpectDecision: authorizer.DecisionNoOpinion}, + {User: uAPIGroup, Verb: "get", APIGroup: "x", Resource: "foo", NS: "projectXGroup", ExpectDecision: authorizer.DecisionAllow}, } for i, tc := range testCases { attr := authorizer.AttributesRecord{ @@ -451,10 +451,10 @@ func TestAuthorizeV1beta1(t *testing.T) { Path: tc.Path, } // t.Logf("tc %2v: %v -> attr %v", i, tc, attr) - authorized, _, _ := a.Authorize(attr) - if tc.ExpectAllow != authorized { + decision, _, _ := a.Authorize(attr) + if tc.ExpectDecision != decision { t.Errorf("%d: Expected allowed=%v but actually allowed=%v, for case %+v & %+v", - i, tc.ExpectAllow, authorized, tc, attr) + i, tc.ExpectDecision, decision, tc, attr) } } } diff --git a/pkg/kubelet/server/server.go b/pkg/kubelet/server/server.go index 72049afd17..aed6ecb117 100644 --- a/pkg/kubelet/server/server.go +++ b/pkg/kubelet/server/server.go @@ -236,14 +236,14 @@ func (s *Server) InstallAuthFilter() { attrs := s.auth.GetRequestAttributes(u, req.Request) // Authorize - authorized, _, err := s.auth.Authorize(attrs) + decision, _, err := s.auth.Authorize(attrs) if err != nil { msg := fmt.Sprintf("Authorization error (user=%s, verb=%s, resource=%s, subresource=%s)", u.GetName(), attrs.GetVerb(), attrs.GetResource(), attrs.GetSubresource()) glog.Errorf(msg, err) resp.WriteErrorString(http.StatusInternalServerError, msg) return } - if !authorized { + if decision != authorizer.DecisionAllow { msg := fmt.Sprintf("Forbidden (user=%s, verb=%s, resource=%s, subresource=%s)", u.GetName(), attrs.GetVerb(), attrs.GetResource(), attrs.GetSubresource()) glog.V(2).Info(msg) resp.WriteErrorString(http.StatusForbidden, msg) diff --git a/pkg/kubelet/server/server_test.go b/pkg/kubelet/server/server_test.go index 7fa1753db2..daa1a91600 100644 --- a/pkg/kubelet/server/server_test.go +++ b/pkg/kubelet/server/server_test.go @@ -183,7 +183,7 @@ func (_ *fakeKubelet) GetCgroupStats(cgroupName string) (*statsapi.ContainerStat type fakeAuth struct { authenticateFunc func(*http.Request) (user.Info, bool, error) attributesFunc func(user.Info, *http.Request) authorizer.Attributes - authorizeFunc func(authorizer.Attributes) (authorized bool, reason string, err error) + authorizeFunc func(authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) } func (f *fakeAuth) AuthenticateRequest(req *http.Request) (user.Info, bool, error) { @@ -192,7 +192,7 @@ func (f *fakeAuth) AuthenticateRequest(req *http.Request) (user.Info, bool, erro 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 bool, reason string, err error) { +func (f *fakeAuth) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { return f.authorizeFunc(a) } @@ -232,8 +232,8 @@ func newServerTestWithDebug(enableDebugging bool) *serverTestFramework { attributesFunc: func(u user.Info, req *http.Request) authorizer.Attributes { return &authorizer.AttributesRecord{User: u} }, - authorizeFunc: func(a authorizer.Attributes) (authorized bool, reason string, err error) { - return true, "", nil + authorizeFunc: func(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { + return authorizer.DecisionAllow, "", nil }, } fw.criHandler = &utiltesting.FakeHandler{ @@ -688,12 +688,12 @@ Otherwise, add it to the expected list of paths that map to the "proxy" subresou } return attributesGetter.GetRequestAttributes(u, req) } - fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (authorized bool, reason string, err error) { + fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { calledAuthorize = true if a != expectedAttributes { t.Fatalf("%s: expected attributes\n\t%#v\ngot\n\t%#v", tc.Path, expectedAttributes, a) } - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } req, err := http.NewRequest(tc.Method, fw.testHTTPServer.URL+tc.Path, nil) @@ -747,9 +747,9 @@ func TestAuthenticationError(t *testing.T) { calledAttributes = true return expectedAttributes } - fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (authorized bool, reason string, err error) { + fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { calledAuthorize = true - return false, "", errors.New("Failed") + return authorizer.DecisionNoOpinion, "", errors.New("Failed") } assertHealthFails(t, fw.testHTTPServer.URL+"/healthz", http.StatusInternalServerError) @@ -785,9 +785,9 @@ func TestAuthenticationFailure(t *testing.T) { calledAttributes = true return expectedAttributes } - fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (authorized bool, reason string, err error) { + fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { calledAuthorize = true - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } assertHealthFails(t, fw.testHTTPServer.URL+"/healthz", http.StatusUnauthorized) @@ -823,9 +823,9 @@ func TestAuthorizationSuccess(t *testing.T) { calledAttributes = true return expectedAttributes } - fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (authorized bool, reason string, err error) { + fw.fakeAuth.authorizeFunc = func(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { calledAuthorize = true - return true, "", nil + return authorizer.DecisionAllow, "", nil } assertHealthIsOk(t, fw.testHTTPServer.URL+"/healthz") diff --git a/pkg/registry/authorization/localsubjectaccessreview/rest.go b/pkg/registry/authorization/localsubjectaccessreview/rest.go index 53487b310a..e00b32bb70 100644 --- a/pkg/registry/authorization/localsubjectaccessreview/rest.go +++ b/pkg/registry/authorization/localsubjectaccessreview/rest.go @@ -58,10 +58,10 @@ func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, createV } authorizationAttributes := authorizationutil.AuthorizationAttributesFrom(localSubjectAccessReview.Spec) - allowed, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes) + decision, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes) localSubjectAccessReview.Status = authorizationapi.SubjectAccessReviewStatus{ - Allowed: allowed, + Allowed: (decision == authorizer.DecisionAllow), Reason: reason, } if evaluationErr != nil { diff --git a/pkg/registry/authorization/selfsubjectaccessreview/rest.go b/pkg/registry/authorization/selfsubjectaccessreview/rest.go index 5041dddb7c..5d917753a5 100644 --- a/pkg/registry/authorization/selfsubjectaccessreview/rest.go +++ b/pkg/registry/authorization/selfsubjectaccessreview/rest.go @@ -61,10 +61,10 @@ func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, createV authorizationAttributes = authorizationutil.NonResourceAttributesFrom(userToCheck, *selfSAR.Spec.NonResourceAttributes) } - allowed, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes) + decision, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes) selfSAR.Status = authorizationapi.SubjectAccessReviewStatus{ - Allowed: allowed, + Allowed: (decision == authorizer.DecisionAllow), Reason: reason, } if evaluationErr != nil { diff --git a/pkg/registry/authorization/subjectaccessreview/rest.go b/pkg/registry/authorization/subjectaccessreview/rest.go index 1252a41ca4..10fd27b703 100644 --- a/pkg/registry/authorization/subjectaccessreview/rest.go +++ b/pkg/registry/authorization/subjectaccessreview/rest.go @@ -51,10 +51,10 @@ func (r *REST) Create(ctx genericapirequest.Context, obj runtime.Object, createV } authorizationAttributes := authorizationutil.AuthorizationAttributesFrom(subjectAccessReview.Spec) - allowed, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes) + decision, reason, evaluationErr := r.authorizer.Authorize(authorizationAttributes) subjectAccessReview.Status = authorizationapi.SubjectAccessReviewStatus{ - Allowed: allowed, + Allowed: (decision == authorizer.DecisionAllow), Reason: reason, } if evaluationErr != nil { diff --git a/pkg/registry/authorization/subjectaccessreview/rest_test.go b/pkg/registry/authorization/subjectaccessreview/rest_test.go index 697441f42f..977a437600 100644 --- a/pkg/registry/authorization/subjectaccessreview/rest_test.go +++ b/pkg/registry/authorization/subjectaccessreview/rest_test.go @@ -38,9 +38,12 @@ type fakeAuthorizer struct { err error } -func (f *fakeAuthorizer) Authorize(attrs authorizer.Attributes) (bool, string, error) { +func (f *fakeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) { f.attrs = attrs - return f.ok, f.reason, f.err + if f.ok { + return authorizer.DecisionAllow, f.reason, f.err + } + return authorizer.DecisionNoOpinion, f.reason, f.err } func TestCreate(t *testing.T) { diff --git a/pkg/registry/rbac/escalation_check.go b/pkg/registry/rbac/escalation_check.go index 4fa0d59cea..4ac1392fbb 100644 --- a/pkg/registry/rbac/escalation_check.go +++ b/pkg/registry/rbac/escalation_check.go @@ -79,12 +79,12 @@ func BindingAuthorized(ctx genericapirequest.Context, roleRef rbac.RoleRef, bind return false } - ok, _, err := a.Authorize(attrs) + decision, _, err := a.Authorize(attrs) if err != nil { utilruntime.HandleError(fmt.Errorf( "error authorizing user %#v to bind %#v in namespace %s: %v", user, roleRef, bindingNamespace, err, )) } - return ok + return decision == authorizer.DecisionAllow } diff --git a/plugin/pkg/admission/gc/gc_admission.go b/plugin/pkg/admission/gc/gc_admission.go index 2e1a53306c..7acd5cf48f 100644 --- a/plugin/pkg/admission/gc/gc_admission.go +++ b/plugin/pkg/admission/gc/gc_admission.go @@ -104,8 +104,8 @@ func (a *gcPermissionsEnforcement) Validate(attributes admission.Attributes) (er ResourceRequest: true, Path: "", } - allowed, reason, err := a.authorizer.Authorize(deleteAttributes) - if !allowed { + decision, reason, err := a.authorizer.Authorize(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)) } @@ -122,8 +122,8 @@ func (a *gcPermissionsEnforcement) Validate(attributes admission.Attributes) (er // resources. User needs to have delete permission on all the // matched Resources. for _, record := range records { - allowed, reason, err := a.authorizer.Authorize(record) - if !allowed { + decision, reason, err := a.authorizer.Authorize(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)) } } diff --git a/plugin/pkg/admission/gc/gc_admission_test.go b/plugin/pkg/admission/gc/gc_admission_test.go index 9cc118fba8..52fb665065 100644 --- a/plugin/pkg/admission/gc/gc_admission_test.go +++ b/plugin/pkg/admission/gc/gc_admission_test.go @@ -34,40 +34,40 @@ import ( type fakeAuthorizer struct{} -func (fakeAuthorizer) Authorize(a authorizer.Attributes) (bool, string, error) { +func (fakeAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) { username := a.GetUser().GetName() if username == "non-deleter" { if a.GetVerb() == "delete" { - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } if a.GetVerb() == "update" && a.GetSubresource() == "finalizers" { - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } - return true, "", nil + return authorizer.DecisionAllow, "", nil } if username == "non-pod-deleter" { if a.GetVerb() == "delete" && a.GetResource() == "pods" { - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } if a.GetVerb() == "update" && a.GetResource() == "pods" && a.GetSubresource() == "finalizers" { - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } - return true, "", nil + return authorizer.DecisionAllow, "", nil } if username == "non-rc-deleter" { if a.GetVerb() == "delete" && a.GetResource() == "replicationcontrollers" { - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } if a.GetVerb() == "update" && a.GetResource() == "replicationcontrollers" && a.GetSubresource() == "finalizers" { - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } - return true, "", nil + return authorizer.DecisionAllow, "", nil } - return true, "", nil + return authorizer.DecisionAllow, "", nil } // newGCPermissionsEnforcement returns the admission controller configured for testing. diff --git a/plugin/pkg/admission/security/podsecuritypolicy/admission.go b/plugin/pkg/admission/security/podsecuritypolicy/admission.go index fbc1cc3761..b672838a65 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/admission.go +++ b/plugin/pkg/admission/security/podsecuritypolicy/admission.go @@ -313,11 +313,11 @@ func authorizedForPolicy(info user.Info, namespace string, policy *extensions.Po return false } attr := buildAttributes(info, namespace, policy) - allowed, reason, err := authz.Authorize(attr) + decision, reason, err := authz.Authorize(attr) if err != nil { glog.V(5).Infof("cannot authorize for policy: %v,%v", reason, err) } - return allowed + return (decision == authorizer.DecisionAllow) } // buildAttributes builds an attributes record for a SAR based on the user info and policy. diff --git a/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go b/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go index e66e687bec..022a307851 100644 --- a/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go +++ b/plugin/pkg/admission/security/podsecuritypolicy/admission_test.go @@ -66,13 +66,16 @@ type TestAuthorizer struct { usernameToNamespaceToAllowedPSPs map[string]map[string]map[string]bool } -func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { +func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { if t.usernameToNamespaceToAllowedPSPs == nil { - return true, "", nil + return authorizer.DecisionAllow, "", nil } allowedInNamespace := t.usernameToNamespaceToAllowedPSPs[a.GetUser().GetName()][a.GetNamespace()][a.GetName()] allowedClusterWide := t.usernameToNamespaceToAllowedPSPs[a.GetUser().GetName()][""][a.GetName()] - return (allowedInNamespace || allowedClusterWide), "", nil + if allowedInNamespace || allowedClusterWide { + return authorizer.DecisionAllow, "", nil + } + return authorizer.DecisionNoOpinion, "", nil } var _ authorizer.Authorizer = &TestAuthorizer{} diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer.go b/plugin/pkg/auth/authorizer/node/node_authorizer.go index 01300801cb..febe7fbda3 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer.go @@ -64,16 +64,16 @@ var ( pvResource = api.Resource("persistentvolumes") ) -func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (bool, string, error) { +func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (authorizer.Decision, string, error) { nodeName, isNode := r.identifier.NodeIdentity(attrs.GetUser()) if !isNode { // reject requests from non-nodes - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } if len(nodeName) == 0 { // reject requests from unidentifiable nodes glog.V(2).Infof("NODE DENY: unknown node for user %q", attrs.GetUser().GetName()) - return false, fmt.Sprintf("unknown node for user %q", attrs.GetUser().GetName()), nil + return authorizer.DecisionNoOpinion, fmt.Sprintf("unknown node for user %q", attrs.GetUser().GetName()), nil } // subdivide access to specific resources @@ -92,31 +92,34 @@ func (r *NodeAuthorizer) Authorize(attrs authorizer.Attributes) (bool, string, e } // Access to other resources is not subdivided, so just evaluate against the statically defined node rules - return rbac.RulesAllow(attrs, r.nodeRules...), "", nil + if rbac.RulesAllow(attrs, r.nodeRules...) { + return authorizer.DecisionAllow, "", nil + } + return authorizer.DecisionNoOpinion, "", nil } // authorizeGet authorizes "get" requests to objects of the specified type if they are related to the specified node -func (r *NodeAuthorizer) authorizeGet(nodeName string, startingType vertexType, attrs authorizer.Attributes) (bool, string, error) { +func (r *NodeAuthorizer) authorizeGet(nodeName string, startingType vertexType, attrs authorizer.Attributes) (authorizer.Decision, string, error) { if attrs.GetVerb() != "get" || len(attrs.GetName()) == 0 { glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs) - return false, "can only get individual resources of this type", nil + return authorizer.DecisionNoOpinion, "can only get individual resources of this type", nil } if len(attrs.GetSubresource()) > 0 { glog.V(2).Infof("NODE DENY: %s %#v", nodeName, attrs) - return false, "cannot get subresource", nil + return authorizer.DecisionNoOpinion, "cannot get subresource", nil } ok, err := r.hasPathFrom(nodeName, startingType, attrs.GetNamespace(), attrs.GetName()) if err != nil { glog.V(2).Infof("NODE DENY: %v", err) - return false, "no path found to object", nil + return authorizer.DecisionNoOpinion, "no path found to object", nil } if !ok { glog.V(2).Infof("NODE DENY: %q %#v", nodeName, attrs) - return false, "no path found to object", nil + return authorizer.DecisionNoOpinion, "no path found to object", nil } - return ok, "", nil + return authorizer.DecisionAllow, "", nil } // hasPathFrom returns true if there is a directed path from the specified type/namespace/name to the specified Node diff --git a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go index 39f10b62ee..b4cf82d6a1 100644 --- a/plugin/pkg/auth/authorizer/node/node_authorizer_test.go +++ b/plugin/pkg/auth/authorizer/node/node_authorizer_test.go @@ -57,71 +57,71 @@ func TestAuthorizer(t *testing.T) { tests := []struct { name string attrs authorizer.AttributesRecord - expect bool + expect authorizer.Decision }{ { name: "allowed configmap", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "configmaps", Name: "configmap0-pod0-node0", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed secret via pod", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret0-pod0-node0", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed shared secret via pod", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret0-shared", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed shared secret via pvc", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret-pv0-pod0-node0-ns0", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed pvc", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "persistentvolumeclaims", Name: "pvc0-pod0-node0", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed pv", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "persistentvolumes", Name: "pv0-pod0-node0-ns0", Namespace: ""}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "disallowed configmap", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "configmaps", Name: "configmap0-pod0-node1", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed secret via pod", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret0-pod0-node1", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed shared secret via pvc", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret-pv0-pod0-node1-ns0", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed pvc", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "persistentvolumeclaims", Name: "pvc0-pod0-node1", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed pv", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "persistentvolumes", Name: "pv0-pod0-node1-ns0", Namespace: ""}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, } for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { - ok, _, _ := authz.Authorize(tc.attrs) - if ok != tc.expect { - t.Errorf("expected %v, got %v", tc.expect, ok) + decision, _, _ := authz.Authorize(tc.attrs) + if decision != tc.expect { + t.Errorf("expected %v, got %v", tc.expect, decision) } }) } @@ -186,13 +186,13 @@ func TestAuthorizerSharedResources(t *testing.T) { } for i, tc := range testcases { - ok, _, err := authz.Authorize(authorizer.AttributesRecord{User: tc.User, ResourceRequest: true, Verb: "get", Resource: "secrets", Namespace: "ns1", Name: tc.Secret}) + decision, _, err := authz.Authorize(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 } - if ok != tc.ExpectAllowed { - t.Errorf("%d: expected %v, got %v", i, tc.ExpectAllowed, ok) + if (decision == authorizer.DecisionAllow) != tc.ExpectAllowed { + t.Errorf("%d: expected %v, got %v", i, tc.ExpectAllowed, decision) } } } @@ -301,47 +301,47 @@ func BenchmarkAuthorization(b *testing.B) { tests := []struct { name string attrs authorizer.AttributesRecord - expect bool + expect authorizer.Decision }{ { name: "allowed configmap", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "configmaps", Name: "configmap0-pod0-node0", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed secret via pod", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret0-pod0-node0", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "allowed shared secret via pod", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret0-shared", Namespace: "ns0"}, - expect: true, + expect: authorizer.DecisionAllow, }, { name: "disallowed configmap", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "configmaps", Name: "configmap0-pod0-node1", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed secret via pod", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret0-pod0-node1", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed shared secret via pvc", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "secrets", Name: "secret-pv0-pod0-node1-ns0", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed pvc", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "persistentvolumeclaims", Name: "pvc0-pod0-node1", Namespace: "ns0"}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, { name: "disallowed pv", attrs: authorizer.AttributesRecord{User: node0, ResourceRequest: true, Verb: "get", Resource: "persistentvolumes", Name: "pv0-pod0-node1-ns0", Namespace: ""}, - expect: false, + expect: authorizer.DecisionNoOpinion, }, } @@ -349,9 +349,9 @@ func BenchmarkAuthorization(b *testing.B) { for _, tc := range tests { b.Run(tc.name, func(b *testing.B) { for i := 0; i < b.N; i++ { - ok, _, _ := authz.Authorize(tc.attrs) - if ok != tc.expect { - b.Errorf("expected %v, got %v", tc.expect, ok) + decision, _, _ := authz.Authorize(tc.attrs) + if decision != tc.expect { + b.Errorf("expected %v, got %v", tc.expect, decision) } } }) diff --git a/plugin/pkg/auth/authorizer/rbac/rbac.go b/plugin/pkg/auth/authorizer/rbac/rbac.go index 090c11febc..9209480763 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac.go @@ -69,12 +69,12 @@ func (v *authorizingVisitor) visit(rule *rbac.PolicyRule, err error) bool { return true } -func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (bool, string, error) { +func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (authorizer.Decision, string, error) { ruleCheckingVisitor := &authorizingVisitor{requestAttributes: requestAttributes} r.authorizationRuleResolver.VisitRulesFor(requestAttributes.GetUser(), requestAttributes.GetNamespace(), ruleCheckingVisitor.visit) if ruleCheckingVisitor.allowed { - return true, "", nil + return authorizer.DecisionAllow, "", nil } // Build a detailed log of the denial. @@ -120,7 +120,7 @@ func (r *RBACAuthorizer) Authorize(requestAttributes authorizer.Attributes) (boo if len(ruleCheckingVisitor.errors) > 0 { reason = fmt.Sprintf("%v", utilerrors.NewAggregate(ruleCheckingVisitor.errors)) } - return false, reason, nil + return authorizer.DecisionNoOpinion, reason, nil } func (r *RBACAuthorizer) RulesFor(user user.Info, namespace string) ([]authorizer.ResourceRuleInfo, []authorizer.NonResourceRuleInfo, bool, error) { diff --git a/plugin/pkg/auth/authorizer/rbac/rbac_test.go b/plugin/pkg/auth/authorizer/rbac/rbac_test.go index db8a385f0a..d4425a6047 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac_test.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac_test.go @@ -247,13 +247,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 authorized, _, _ := a.Authorize(attr); !authorized { + if decision, _, _ := a.Authorize(attr); decision != authorizer.DecisionAllow { t.Errorf("case %d: incorrectly restricted %s", i, attr) } } for _, attr := range tt.shouldFail { - if authorized, _, _ := a.Authorize(attr); authorized { + if decision, _, _ := a.Authorize(attr); decision == authorizer.DecisionAllow { t.Errorf("case %d: incorrectly passed %s", i, attr) } } diff --git a/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go b/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go index cbf0206a2f..43153b91c0 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/initializer/initializer_test.go @@ -133,8 +133,8 @@ 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 bool, reason string, err error) { - return false, "", nil +func (t *TestAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { + return authorizer.DecisionNoOpinion, "", nil } // wantClientCert is a test stub for testing that fulfulls the WantsClientCert interface. diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization.go index e5adaf2504..bf423ebb46 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization.go @@ -260,7 +260,7 @@ func (i *initializer) Admit(a admission.Attributes) (err error) { func (i *initializer) canInitialize(a admission.Attributes, message string) error { // caller must have the ability to mutate un-initialized resources - authorized, reason, err := i.authorizer.Authorize(authorizer.AttributesRecord{ + decision, reason, err := i.authorizer.Authorize(authorizer.AttributesRecord{ Name: a.GetName(), ResourceRequest: true, User: a.GetUserInfo(), @@ -273,7 +273,7 @@ func (i *initializer) canInitialize(a admission.Attributes, message string) erro if err != nil { return err } - if !authorized { + if decision != authorizer.DecisionAllow { return errors.NewForbidden(a.GetResource().GroupResource(), a.GetName(), fmt.Errorf("%s: %s", message, reason)) } return nil diff --git a/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization_test.go b/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization_test.go index 0832fe8d1b..a3bb0991b3 100644 --- a/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization_test.go +++ b/staging/src/k8s.io/apiserver/pkg/admission/plugin/initialization/initialization_test.go @@ -109,11 +109,11 @@ type fakeAuthorizer struct { accept bool } -func (f *fakeAuthorizer) Authorize(a authorizer.Attributes) (bool, string, error) { +func (f *fakeAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) { if f.accept { - return true, "", nil + return authorizer.DecisionAllow, "", nil } - return false, "denied", nil + return authorizer.DecisionNoOpinion, "denied", nil } func TestAdmitUpdate(t *testing.T) { diff --git a/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/authz_test.go b/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/authz_test.go index 73a4283488..d1de3eba70 100644 --- a/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/authz_test.go +++ b/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/authz_test.go @@ -27,7 +27,7 @@ import ( // and always return nil. func TestNewAlwaysAllowAuthorizer(t *testing.T) { aaa := NewAlwaysAllowAuthorizer() - if authorized, _, _ := aaa.Authorize(nil); !authorized { + if decision, _, _ := aaa.Authorize(nil); decision != authorizer.DecisionAllow { t.Errorf("AlwaysAllowAuthorizer.Authorize did not authorize successfully.") } } @@ -36,7 +36,7 @@ func TestNewAlwaysAllowAuthorizer(t *testing.T) { // and always return an error as everything is forbidden. func TestNewAlwaysDenyAuthorizer(t *testing.T) { ada := NewAlwaysDenyAuthorizer() - if authorized, _, _ := ada.Authorize(nil); authorized { + if decision, _, _ := ada.Authorize(nil); decision == authorizer.DecisionAllow { t.Errorf("AlwaysDenyAuthorizer.Authorize returned nil instead of error.") } } @@ -47,10 +47,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 { + if authorized, _, _ := auth.Authorize(yes); authorized != authorizer.DecisionAllow { t.Errorf("failed") } - if authorized, _, _ := auth.Authorize(no); authorized { + if authorized, _, _ := auth.Authorize(no); authorized == authorizer.DecisionAllow { t.Errorf("failed") } } diff --git a/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/builtin.go b/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/builtin.go index 8381e83f43..6f67d87b89 100644 --- a/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/builtin.go +++ b/staging/src/k8s.io/apiserver/pkg/authorization/authorizerfactory/builtin.go @@ -28,8 +28,8 @@ import ( // It is useful in tests and when using kubernetes in an open manner. type alwaysAllowAuthorizer struct{} -func (alwaysAllowAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { - return true, "", nil +func (alwaysAllowAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { + return authorizer.DecisionAllow, "", nil } func (alwaysAllowAuthorizer) RulesFor(user user.Info, namespace string) ([]authorizer.ResourceRuleInfo, []authorizer.NonResourceRuleInfo, bool, error) { @@ -56,8 +56,8 @@ 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) (authorized bool, reason string, err error) { - return false, "Everything is forbidden.", nil +func (alwaysDenyAuthorizer) Authorize(a authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { + return authorizer.DecisionNoOpinion, "Everything is forbidden.", nil } func (alwaysDenyAuthorizer) RulesFor(user user.Info, namespace string) ([]authorizer.ResourceRuleInfo, []authorizer.NonResourceRuleInfo, bool, error) { @@ -73,8 +73,8 @@ func NewAlwaysDenyAuthorizer() *alwaysDenyAuthorizer { // It is useful in unit tests to force an operation to fail with error. type alwaysFailAuthorizer struct{} -func (alwaysFailAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { - return false, "", errors.New("Authorization failure.") +func (alwaysFailAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { + return authorizer.DecisionNoOpinion, "", errors.New("Authorization failure.") } func NewAlwaysFailAuthorizer() authorizer.Authorizer { @@ -85,18 +85,18 @@ type privilegedGroupAuthorizer struct { groups []string } -func (r *privilegedGroupAuthorizer) Authorize(attr authorizer.Attributes) (bool, string, error) { +func (r *privilegedGroupAuthorizer) Authorize(attr authorizer.Attributes) (authorizer.Decision, string, error) { if attr.GetUser() == nil { - return false, "Error", errors.New("no user on request.") + return authorizer.DecisionNoOpinion, "Error", errors.New("no user on request.") } for _, attr_group := range attr.GetUser().GetGroups() { for _, priv_group := range r.groups { if priv_group == attr_group { - return true, "", nil + return authorizer.DecisionAllow, "", nil } } } - return false, "", nil + return authorizer.DecisionNoOpinion, "", nil } // NewPrivilegedGroups is for use in loopback scenarios diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go index d244257a04..f60756b6fd 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/authorization.go @@ -47,7 +47,7 @@ func WithAuthorization(handler http.Handler, requestContextMapper request.Reques return } authorized, reason, err := a.Authorize(attributes) - if authorized { + if authorized == authorizer.DecisionAllow { handler.ServeHTTP(w, req) return } diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go index 8f67caf86f..9af292e1ce 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation.go @@ -110,8 +110,8 @@ func WithImpersonation(handler http.Handler, requestContextMapper request.Reques return } - allowed, reason, err := a.Authorize(actingAsAttributes) - if err != nil || !allowed { + decision, reason, err := a.Authorize(actingAsAttributes) + if err != nil || decision != authorizer.DecisionAllow { glog.V(4).Infof("Forbidden: %#v, Reason: %s, Error: %v", req.RequestURI, reason, err) responsewriters.Forbidden(ctx, actingAsAttributes, w, req, reason, s) return diff --git a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation_test.go b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation_test.go index d43776507e..814de2a26e 100644 --- a/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation_test.go +++ b/staging/src/k8s.io/apiserver/pkg/endpoints/filters/impersonation_test.go @@ -35,50 +35,50 @@ import ( type impersonateAuthorizer struct{} -func (impersonateAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { +func (impersonateAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { user := a.GetUser() switch { case user.GetName() == "system:admin": - return true, "", nil + return authorizer.DecisionAllow, "", nil case user.GetName() == "tester": - return false, "", fmt.Errorf("works on my machine") + return authorizer.DecisionNoOpinion, "", fmt.Errorf("works on my machine") case user.GetName() == "deny-me": - return false, "denied", nil + return authorizer.DecisionNoOpinion, "denied", nil } if len(user.GetGroups()) > 0 && user.GetGroups()[0] == "wheel" && a.GetVerb() == "impersonate" && a.GetResource() == "users" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } if len(user.GetGroups()) > 0 && user.GetGroups()[0] == "sa-impersonater" && a.GetVerb() == "impersonate" && a.GetResource() == "serviceaccounts" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } if len(user.GetGroups()) > 0 && user.GetGroups()[0] == "regular-impersonater" && a.GetVerb() == "impersonate" && a.GetResource() == "users" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } if len(user.GetGroups()) > 1 && user.GetGroups()[1] == "group-impersonater" && a.GetVerb() == "impersonate" && a.GetResource() == "groups" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } if len(user.GetGroups()) > 1 && user.GetGroups()[1] == "extra-setter-scopes" && a.GetVerb() == "impersonate" && a.GetResource() == "userextras" && a.GetSubresource() == "scopes" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } if len(user.GetGroups()) > 1 && user.GetGroups()[1] == "extra-setter-particular-scopes" && a.GetVerb() == "impersonate" && a.GetResource() == "userextras" && a.GetSubresource() == "scopes" && a.GetName() == "scope-a" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } if len(user.GetGroups()) > 1 && user.GetGroups()[1] == "extra-setter-project" && a.GetVerb() == "impersonate" && a.GetResource() == "userextras" && a.GetSubresource() == "project" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } - return false, "deny by default", nil + return authorizer.DecisionNoOpinion, "deny by default", nil } func TestImpersonationFilter(t *testing.T) { diff --git a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver_test.go b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver_test.go index 54a6540fda..6923c8fc02 100644 --- a/staging/src/k8s.io/apiserver/pkg/server/genericapiserver_test.go +++ b/staging/src/k8s.io/apiserver/pkg/server/genericapiserver_test.go @@ -437,9 +437,9 @@ type mockAuthorizer struct { lastURI string } -func (authz *mockAuthorizer) Authorize(a authorizer.Attributes) (authorized bool, reason string, err error) { +func (authz *mockAuthorizer) Authorize(a authorizer.Attributes) (authorized authorizer.Decision, reason string, err error) { authz.lastURI = a.GetPath() - return true, "", nil + return authorizer.DecisionAllow, "", nil } type mockAuthenticator struct { diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go index 890845caeb..83577496ee 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook.go @@ -140,7 +140,10 @@ func newWithBackoff(subjectAccessReview authorizationclient.SubjectAccessReviewI // } // } // -func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bool, reason string, err error) { +// TODO(mikedanese): We should eventually fail closed when we encounter and +// error. We are failing open now to preserve backwards compatible behavior. +// Fix this after deprecation. +func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (decision authorizer.Decision, reason string, err error) { r := &authorization.SubjectAccessReview{} if user := attr.GetUser(); user != nil { r.Spec = authorization.SubjectAccessReviewSpec{ @@ -169,7 +172,7 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo } key, err := json.Marshal(r.Spec) if err != nil { - return false, "", err + return authorizer.DecisionNoOpinion, "", err } if entry, ok := w.responseCache.Get(string(key)); ok { r.Status = entry.(authorization.SubjectAccessReviewStatus) @@ -185,7 +188,7 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo if err != nil { // An error here indicates bad configuration or an outage. Log for debugging. glog.Errorf("Failed to make webhook authorizer request: %v", err) - return false, "", err + return authorizer.DecisionNoOpinion, "", err } r.Status = result.Status if r.Status.Allowed { @@ -194,7 +197,12 @@ func (w *WebhookAuthorizer) Authorize(attr authorizer.Attributes) (authorized bo w.responseCache.Add(string(key), r.Status, w.unauthorizedTTL) } } - return r.Status.Allowed, r.Status.Reason, nil + if r.Status.Allowed { + return authorizer.DecisionAllow, r.Status.Reason, nil + } else { + return authorizer.DecisionNoOpinion, r.Status.Reason, nil + } + } //TODO: need to finish the method to get the rules when using webhook mode diff --git a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_test.go b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_test.go index 4f5bd23312..f637af6f20 100644 --- a/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_test.go +++ b/staging/src/k8s.io/apiserver/plugin/pkg/authorizer/webhook/webhook_test.go @@ -396,13 +396,13 @@ func TestTLSConfig(t *testing.T) { // Allow all and see if we get an error. service.Allow() - authorized, _, err := wh.Authorize(attr) + decision, _, err := wh.Authorize(attr) if tt.wantAuth { - if !authorized { + if decision != authorizer.DecisionAllow { t.Errorf("expected successful authorization") } } else { - if authorized { + if decision == authorizer.DecisionAllow { t.Errorf("expected failed authorization") } } @@ -418,7 +418,7 @@ func TestTLSConfig(t *testing.T) { } service.Deny() - if authorized, _, _ := wh.Authorize(attr); authorized { + if decision, _, _ := wh.Authorize(attr); decision == authorizer.DecisionAllow { t.Errorf("%s: incorrectly authorized with DenyAll policy", tt.test) } }() @@ -522,11 +522,11 @@ func TestWebhook(t *testing.T) { } for i, tt := range tests { - authorized, _, err := wh.Authorize(tt.attr) + decision, _, err := wh.Authorize(tt.attr) if err != nil { t.Fatal(err) } - if !authorized { + if decision != authorizer.DecisionAllow { t.Errorf("case %d: authorization failed", i) continue } @@ -567,7 +567,7 @@ func testWebhookCacheCases(t *testing.T, serv *mockService, wh *WebhookAuthorize continue } - if test.expectedAuthorized != authorized { + if test.expectedAuthorized != (authorized == authorizer.DecisionAllow) { t.Errorf("%d: expected authorized=%v, got %v", i, test.expectedAuthorized, authorized) } diff --git a/test/integration/auth/accessreview_test.go b/test/integration/auth/accessreview_test.go index f26c5b2af0..3924fd61c8 100644 --- a/test/integration/auth/accessreview_test.go +++ b/test/integration/auth/accessreview_test.go @@ -39,12 +39,12 @@ import ( // TODO(etune): remove this test once a more comprehensive built-in authorizer is implemented. type sarAuthorizer struct{} -func (sarAuthorizer) Authorize(a authorizer.Attributes) (bool, string, error) { +func (sarAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) { if a.GetUser().GetName() == "dave" { - return false, "no", errors.New("I'm sorry, Dave") + return authorizer.DecisionNoOpinion, "no", errors.New("I'm sorry, Dave") } - return true, "you're not dave", nil + return authorizer.DecisionAllow, "you're not dave", nil } func alwaysAlice(req *http.Request) (user.Info, bool, error) { diff --git a/test/integration/auth/auth_test.go b/test/integration/auth/auth_test.go index 4408c2a79e..d28d54e34c 100644 --- a/test/integration/auth/auth_test.go +++ b/test/integration/auth/auth_test.go @@ -535,11 +535,11 @@ 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) (bool, string, error) { +func (allowAliceAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) { if a.GetUser() != nil && a.GetUser().GetName() == "alice" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } - return false, "I can't allow that. Go ask alice.", nil + return authorizer.DecisionNoOpinion, "I can't allow that. Go ask alice.", nil } // TestAliceNotForbiddenOrUnauthorized tests a user who is known to @@ -702,24 +702,24 @@ 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) (bool, string, error) { +func (impersonateAuthorizer) Authorize(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 true, "", nil + return authorizer.DecisionAllow, "", nil } if a.GetUser() != nil && a.GetUser().GetName() == "alice" && a.GetVerb() != "impersonate" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } // bob can impersonate anyone, but that it if a.GetUser() != nil && a.GetUser().GetName() == "bob" && a.GetVerb() == "impersonate" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } // service accounts can do everything if a.GetUser() != nil && strings.HasPrefix(a.GetUser().GetName(), serviceaccount.ServiceAccountUsernamePrefix) { - return true, "", nil + return authorizer.DecisionAllow, "", nil } - return false, "I can't allow that. Go ask alice.", nil + return authorizer.DecisionNoOpinion, "I can't allow that. Go ask alice.", nil } func TestImpersonateIsForbidden(t *testing.T) { @@ -861,9 +861,9 @@ type trackingAuthorizer struct { requestAttributes []authorizer.Attributes } -func (a *trackingAuthorizer) Authorize(attributes authorizer.Attributes) (bool, string, error) { +func (a *trackingAuthorizer) Authorize(attributes authorizer.Attributes) (authorizer.Decision, string, error) { a.requestAttributes = append(a.requestAttributes, attributes) - return true, "", nil + return authorizer.DecisionAllow, "", nil } // TestAuthorizationAttributeDetermination tests that authorization attributes are built correctly diff --git a/test/integration/framework/master_utils.go b/test/integration/framework/master_utils.go index beb035578b..7c78798824 100644 --- a/test/integration/framework/master_utils.go +++ b/test/integration/framework/master_utils.go @@ -46,6 +46,7 @@ import ( "k8s.io/apiserver/pkg/authentication/authenticatorfactory" authenticatorunion "k8s.io/apiserver/pkg/authentication/request/union" "k8s.io/apiserver/pkg/authentication/user" + "k8s.io/apiserver/pkg/authorization/authorizer" authauthorizer "k8s.io/apiserver/pkg/authorization/authorizer" "k8s.io/apiserver/pkg/authorization/authorizerfactory" authorizerunion "k8s.io/apiserver/pkg/authorization/union" @@ -148,8 +149,8 @@ func NewMasterComponents(c *Config) *MasterComponents { // alwaysAllow always allows an action type alwaysAllow struct{} -func (alwaysAllow) Authorize(requestAttributes authauthorizer.Attributes) (bool, string, error) { - return true, "always allow", nil +func (alwaysAllow) Authorize(requestAttributes authauthorizer.Attributes) (authorizer.Decision, string, error) { + return authorizer.DecisionAllow, "always allow", nil } // alwaysEmpty simulates "no authentication" for old tests diff --git a/test/integration/master/master_test.go b/test/integration/master/master_test.go index 6b13ca35ab..61294e746d 100644 --- a/test/integration/master/master_test.go +++ b/test/integration/master/master_test.go @@ -58,11 +58,11 @@ const ( type allowAliceAuthorizer struct{} -func (allowAliceAuthorizer) Authorize(a authorizer.Attributes) (bool, string, error) { +func (allowAliceAuthorizer) Authorize(a authorizer.Attributes) (authorizer.Decision, string, error) { if a.GetUser() != nil && a.GetUser().GetName() == "alice" { - return true, "", nil + return authorizer.DecisionAllow, "", nil } - return false, "I can't allow that. Go ask alice.", nil + return authorizer.DecisionNoOpinion, "I can't allow that. Go ask alice.", nil } func testPrefix(t *testing.T, prefix string) { diff --git a/test/integration/serviceaccount/service_account_test.go b/test/integration/serviceaccount/service_account_test.go index 4181fa0565..9161b47259 100644 --- a/test/integration/serviceaccount/service_account_test.go +++ b/test/integration/serviceaccount/service_account_test.go @@ -372,7 +372,7 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie // 1. The "root" user is allowed to do anything // 2. ServiceAccounts named "ro" are allowed read-only operations in their namespace // 3. ServiceAccounts named "rw" are allowed any operation in their namespace - authorizer := authorizer.AuthorizerFunc(func(attrs authorizer.Attributes) (bool, string, error) { + authorizer := authorizer.AuthorizerFunc(func(attrs authorizer.Attributes) (authorizer.Decision, string, error) { username := "" if user := attrs.GetUser(); user != nil { username = user.GetName() @@ -382,7 +382,7 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie // If the user is "root"... if username == rootUserName { // allow them to do anything - return true, "", nil + return authorizer.DecisionAllow, "", nil } // If the user is a service account... @@ -392,15 +392,15 @@ func startServiceAccountTestServer(t *testing.T) (*clientset.Clientset, restclie switch serviceAccountName { case readOnlyServiceAccountName: if attrs.IsReadOnly() { - return true, "", nil + return authorizer.DecisionAllow, "", nil } case readWriteServiceAccountName: - return true, "", nil + return authorizer.DecisionAllow, "", nil } } } - return false, fmt.Sprintf("User %s is denied (ns=%s, readonly=%v, resource=%s)", username, ns, attrs.IsReadOnly(), attrs.GetResource()), nil + return authorizer.DecisionNoOpinion, fmt.Sprintf("User %s is denied (ns=%s, readonly=%v, resource=%s)", username, ns, attrs.IsReadOnly(), attrs.GetResource()), nil }) // Set up admission plugin to auto-assign serviceaccounts to pods