Browse code

expose evaluation errors for RAR

deads2k authored on 2015/09/29 23:52:51
Showing 8 changed files
... ...
@@ -505,6 +505,7 @@ func DeepCopy_api_ResourceAccessReviewResponse(in ResourceAccessReviewResponse,
505 505
 	} else {
506 506
 		out.Groups = nil
507 507
 	}
508
+	out.EvaluationError = in.EvaluationError
508 509
 	return nil
509 510
 }
510 511
 
... ...
@@ -174,6 +174,11 @@ type ResourceAccessReviewResponse struct {
174 174
 	Users sets.String
175 175
 	// Groups is the list of groups who can perform the action
176 176
 	Groups sets.String
177
+
178
+	// EvaluationError is an indication that some error occurred during resolution, but partial results can still be returned.
179
+	// It is entirely possible to get an error and be able to continue determine authorization status in spite of it.  This is
180
+	// most common when a bound role is missing, but enough roles are still present and bound to reason about the request.
181
+	EvaluationError string
177 182
 }
178 183
 
179 184
 // ResourceAccessReview is a means to request a list of which users and groups are authorized to perform the
... ...
@@ -497,6 +497,7 @@ func DeepCopy_v1_ResourceAccessReviewResponse(in ResourceAccessReviewResponse, o
497 497
 	} else {
498 498
 		out.GroupsSlice = nil
499 499
 	}
500
+	out.EvaluationError = in.EvaluationError
500 501
 	return nil
501 502
 }
502 503
 
... ...
@@ -239,10 +239,11 @@ func (ResourceAccessReview) SwaggerDoc() map[string]string {
239 239
 }
240 240
 
241 241
 var map_ResourceAccessReviewResponse = map[string]string{
242
-	"":          "ResourceAccessReviewResponse describes who can perform the action",
243
-	"namespace": "Namespace is the namespace used for the access review",
244
-	"users":     "UsersSlice is the list of users who can perform the action",
245
-	"groups":    "GroupsSlice is the list of groups who can perform the action",
242
+	"":               "ResourceAccessReviewResponse describes who can perform the action",
243
+	"namespace":      "Namespace is the namespace used for the access review",
244
+	"users":          "UsersSlice is the list of users who can perform the action",
245
+	"groups":         "GroupsSlice is the list of groups who can perform the action",
246
+	"evalutionError": "EvaluationError is an indication that some error occurred during resolution, but partial results can still be returned. It is entirely possible to get an error and be able to continue determine authorization status in spite of it.  This is most common when a bound role is missing, but enough roles are still present and bound to reason about the request.",
246 247
 }
247 248
 
248 249
 func (ResourceAccessReviewResponse) SwaggerDoc() map[string]string {
... ...
@@ -155,6 +155,11 @@ type ResourceAccessReviewResponse struct {
155 155
 	UsersSlice []string `json:"users"`
156 156
 	// GroupsSlice is the list of groups who can perform the action
157 157
 	GroupsSlice []string `json:"groups"`
158
+
159
+	// EvaluationError is an indication that some error occurred during resolution, but partial results can still be returned.
160
+	// It is entirely possible to get an error and be able to continue determine authorization status in spite of it.  This is
161
+	// most common when a bound role is missing, but enough roles are still present and bound to reason about the request.
162
+	EvaluationError string `json:"evalutionError"`
158 163
 }
159 164
 
160 165
 // ResourceAccessReview is a means to request a list of which users and groups are authorized to perform the
... ...
@@ -51,13 +51,16 @@ func (r *REST) Create(ctx kapi.Context, obj runtime.Object) (runtime.Object, err
51 51
 
52 52
 	requestContext := kapi.WithNamespace(ctx, resourceAccessReview.Action.Namespace)
53 53
 	attributes := authorizer.ToDefaultAuthorizationAttributes(resourceAccessReview.Action)
54
-	users, groups, _ := r.authorizer.GetAllowedSubjects(requestContext, attributes)
54
+	users, groups, err := r.authorizer.GetAllowedSubjects(requestContext, attributes)
55 55
 
56 56
 	response := &authorizationapi.ResourceAccessReviewResponse{
57 57
 		Namespace: resourceAccessReview.Action.Namespace,
58 58
 		Users:     users,
59 59
 		Groups:    groups,
60 60
 	}
61
+	if err != nil {
62
+		response.EvaluationError = err.Error()
63
+	}
61 64
 
62 65
 	return response, nil
63 66
 }
... ...
@@ -138,5 +138,9 @@ func (o *whoCanOptions) run() error {
138 138
 		fmt.Printf("Groups: %s\n\n", strings.Join(resourceAccessReviewResponse.Groups.List(), "\n        "))
139 139
 	}
140 140
 
141
+	if len(resourceAccessReviewResponse.EvaluationError) != 0 {
142
+		fmt.Printf("Error during evaluation, results may not be complete: %s\n", resourceAccessReviewResponse.EvaluationError)
143
+	}
144
+
141 145
 	return nil
142 146
 }
... ...
@@ -304,7 +304,10 @@ func (test resourceAccessReviewTest) run(t *testing.T) {
304 304
 			}
305 305
 		}
306 306
 
307
-		if actualResponse.Namespace != test.response.Namespace || !reflect.DeepEqual(actualResponse.Users.List(), test.response.Users.List()) || !reflect.DeepEqual(actualResponse.Groups.List(), test.response.Groups.List()) {
307
+		if actualResponse.Namespace != test.response.Namespace ||
308
+			!reflect.DeepEqual(actualResponse.Users.List(), test.response.Users.List()) ||
309
+			!reflect.DeepEqual(actualResponse.Groups.List(), test.response.Groups.List()) ||
310
+			actualResponse.EvaluationError != test.response.EvaluationError {
308 311
 			failMessage = fmt.Sprintf("%s: %#v: expected %#v, got %#v", test.description, test.review, test.response, actualResponse)
309 312
 			return false, nil
310 313
 		}
... ...
@@ -354,7 +357,10 @@ func (test localResourceAccessReviewTest) run(t *testing.T) {
354 354
 			}
355 355
 		}
356 356
 
357
-		if actualResponse.Namespace != test.response.Namespace || !reflect.DeepEqual(actualResponse.Users.List(), test.response.Users.List()) || !reflect.DeepEqual(actualResponse.Groups.List(), test.response.Groups.List()) {
357
+		if actualResponse.Namespace != test.response.Namespace ||
358
+			!reflect.DeepEqual(actualResponse.Users.List(), test.response.Users.List()) ||
359
+			!reflect.DeepEqual(actualResponse.Groups.List(), test.response.Groups.List()) ||
360
+			actualResponse.EvaluationError != test.response.EvaluationError {
358 361
 			failMessage = fmt.Sprintf("%s: %#v: expected %#v, got %#v", test.description, test.review, test.response, actualResponse)
359 362
 			return false, nil
360 363
 		}
... ...
@@ -495,9 +501,10 @@ func TestAuthorizationResourceAccessReview(t *testing.T) {
495 495
 			clientInterface: clusterAdminClient.LocalResourceAccessReviews("mallet-project"),
496 496
 			review:          localRequestWhoCanViewDeploymentConfigs,
497 497
 			response: authorizationapi.ResourceAccessReviewResponse{
498
-				Users:     sets.NewString("edgar"),
499
-				Groups:    sets.NewString(),
500
-				Namespace: "mallet-project",
498
+				Users:           sets.NewString("edgar"),
499
+				Groups:          sets.NewString(),
500
+				Namespace:       "mallet-project",
501
+				EvaluationError: `role "admin" not found`,
501 502
 			},
502 503
 		}
503 504
 		test.response.Users.Insert(globalClusterReaderUsers.List()...)