| ... | ... |
@@ -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},
|