Browse code

Allow POST access to node stats for cluster-reader and system:node-reader

Jordan Liggitt authored on 2015/10/10 02:13:28
Showing 3 changed files
... ...
@@ -90,13 +90,13 @@ var (
90 90
 		OpenshiftStatusGroupName: {"imagestreams/status", "routes/status"},
91 91
 
92 92
 		QuotaGroupName:         {"limitranges", "resourcequotas", "resourcequotausages"},
93
-		KubeInternalsGroupName: {"minions", "nodes", NodeMetricsResource, NodeStatsResource, NodeLogResource, "bindings", "events", "namespaces"},
93
+		KubeInternalsGroupName: {"minions", "nodes", "bindings", "events", "namespaces"},
94 94
 		KubeExposedGroupName:   {"pods", "replicationcontrollers", "serviceaccounts", "services", "endpoints", "persistentvolumeclaims", "pods/log"},
95 95
 		KubeAllGroupName:       {KubeInternalsGroupName, KubeExposedGroupName, QuotaGroupName},
96 96
 		KubeStatusGroupName:    {"pods/status", "resourcequotas/status", "namespaces/status"},
97 97
 
98 98
 		OpenshiftEscalatingViewableGroupName: {"oauthauthorizetokens", "oauthaccesstokens"},
99
-		KubeEscalatingViewableGroupName:      {"secrets", NodeLogResource}, // consider NodeLogResource a potentially escalating resource since it proxies to /var/log on the nodes
99
+		KubeEscalatingViewableGroupName:      {"secrets"},
100 100
 		EscalatingResourcesGroupName:         {OpenshiftEscalatingViewableGroupName, KubeEscalatingViewableGroupName},
101 101
 
102 102
 		NonEscalatingResourcesGroupName: {OpenshiftNonEscalatingViewableGroupName, KubeNonEscalatingViewableGroupName},
... ...
@@ -59,6 +59,17 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
59 59
 					Verbs:     sets.NewString("create"),
60 60
 					Resources: sets.NewString("resourceaccessreviews", "subjectaccessreviews"),
61 61
 				},
62
+				// Allow read access to node metrics
63
+				{
64
+					Verbs:     sets.NewString("get"),
65
+					Resources: sets.NewString(authorizationapi.NodeMetricsResource),
66
+				},
67
+				// Allow read access to stats
68
+				// Node stats requests are submitted as POSTs.  These creates are non-mutating
69
+				{
70
+					Verbs:     sets.NewString("get", "create"),
71
+					Resources: sets.NewString(authorizationapi.NodeStatsResource),
72
+				},
62 73
 				{
63 74
 					Verbs:           sets.NewString("get"),
64 75
 					NonResourceURLs: sets.NewString(authorizationapi.NonResourceAll),
... ...
@@ -407,12 +418,18 @@ func GetBootstrapClusterRoles() []authorizationapi.ClusterRole {
407 407
 					Verbs:     sets.NewString("get", "list", "watch"),
408 408
 					Resources: sets.NewString("nodes"),
409 409
 				},
410
-				// Allow read access to metrics and stats
411
-				// TODO: expose other things like /healthz on the node once we figure out non-resource URL policy across systems
410
+				// Allow read access to node metrics
412 411
 				{
413 412
 					Verbs:     sets.NewString("get"),
414
-					Resources: sets.NewString(authorizationapi.NodeMetricsResource, authorizationapi.NodeStatsResource),
413
+					Resources: sets.NewString(authorizationapi.NodeMetricsResource),
415 414
 				},
415
+				// Allow read access to stats
416
+				// Node stats requests are submitted as POSTs.  These creates are non-mutating
417
+				{
418
+					Verbs:     sets.NewString("get", "create"),
419
+					Resources: sets.NewString(authorizationapi.NodeStatsResource),
420
+				},
421
+				// TODO: expose other things like /healthz on the node once we figure out non-resource URL policy across systems
416 422
 			},
417 423
 		},
418 424
 		{
... ...
@@ -178,15 +178,18 @@ func TestNodeAuth(t *testing.T) {
178 178
 			// Responses to invalid paths are the same for all users
179 179
 			{"GET", "/", http.StatusNotFound},
180 180
 			{"GET", "/stats", http.StatusMovedPermanently}, // ServeMux redirects to the directory
181
+			{"GET", "/logs", http.StatusMovedPermanently},  // ServeMux redirects to the directory
181 182
 			{"GET", "/invalid", http.StatusNotFound},
182 183
 
183 184
 			// viewer requests
184 185
 			{"GET", "/metrics", viewResult},
185 186
 			{"GET", "/stats/", viewResult},
187
+			{"POST", "/stats/", viewResult}, // stats requests can be POSTs which contain query options
186 188
 
187 189
 			// successful admin requests
188 190
 			{"GET", "/healthz", adminResultOK},
189 191
 			{"GET", "/pods", adminResultOK},
192
+			{"GET", "/logs/", adminResultOK},
190 193
 
191 194
 			// not found admin requests
192 195
 			{"GET", "/containerLogs/mynamespace/mypod/mycontainer", adminResultMissing},