From e8a703b651d4ae3145ea027a9256547cb59667cb Mon Sep 17 00:00:00 2001 From: David Eads Date: Wed, 11 Oct 2017 10:06:37 -0400 Subject: [PATCH] allow */subresource in rbac policy rules --- api/openapi-spec/swagger.json | 6 +- api/swagger-spec/authorization.k8s.io_v1.json | 2 +- .../authorization.k8s.io_v1beta1.json | 2 +- .../rbac.authorization.k8s.io_v1beta1.json | 2 +- .../authorization.k8s.io/v1/definitions.html | 3 +- .../v1beta1/definitions.html | 3 +- .../v1beta1/definitions.html | 2 +- pkg/apis/authorization/types.go | 3 +- pkg/apis/rbac/helpers.go | 19 +++- pkg/apis/rbac/helpers_test.go | 105 ++++++++++++++++++ pkg/apis/rbac/types.go | 3 +- .../rbac/validation/policy_comparator.go | 27 ++++- .../rbac/validation/policy_comparator_test.go | 14 +++ .../rbac/bootstrappolicy/controller_policy.go | 5 +- .../testdata/controller-roles.yaml | 20 +--- plugin/pkg/auth/authorizer/rbac/rbac.go | 6 +- plugin/pkg/auth/authorizer/rbac/rbac_test.go | 8 +- .../api/authorization/v1/generated.proto | 3 +- .../src/k8s.io/api/authorization/v1/types.go | 3 +- .../v1/types_swagger_doc_generated.go | 2 +- .../api/authorization/v1beta1/generated.proto | 3 +- .../k8s.io/api/authorization/v1beta1/types.go | 3 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- .../k8s.io/api/rbac/v1beta1/generated.proto | 3 +- staging/src/k8s.io/api/rbac/v1beta1/types.go | 3 +- .../v1beta1/types_swagger_doc_generated.go | 2 +- 26 files changed, 205 insertions(+), 49 deletions(-) diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 214870b7404..38bed12b0b4 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -64461,7 +64461,7 @@ } }, "resources": { - "description": "Resources is a list of resources this rule applies to. ResourceAll represents all resources. \"*\" means all.", + "description": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", "type": "array", "items": { "type": "string" @@ -64812,7 +64812,7 @@ } }, "resources": { - "description": "Resources is a list of resources this rule applies to. ResourceAll represents all resources. \"*\" means all.", + "description": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", "type": "array", "items": { "type": "string" @@ -73180,7 +73180,7 @@ } }, "resources": { - "description": "Resources is a list of resources this rule applies to. ResourceAll represents all resources.", + "description": "Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups.", "type": "array", "items": { "type": "string" diff --git a/api/swagger-spec/authorization.k8s.io_v1.json b/api/swagger-spec/authorization.k8s.io_v1.json index 46f957024cf..32e4bf20266 100644 --- a/api/swagger-spec/authorization.k8s.io_v1.json +++ b/api/swagger-spec/authorization.k8s.io_v1.json @@ -785,7 +785,7 @@ "items": { "type": "string" }, - "description": "Resources is a list of resources this rule applies to. ResourceAll represents all resources. \"*\" means all." + "description": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups." }, "resourceNames": { "type": "array", diff --git a/api/swagger-spec/authorization.k8s.io_v1beta1.json b/api/swagger-spec/authorization.k8s.io_v1beta1.json index dcc02d2b092..8e617ff497f 100644 --- a/api/swagger-spec/authorization.k8s.io_v1beta1.json +++ b/api/swagger-spec/authorization.k8s.io_v1beta1.json @@ -785,7 +785,7 @@ "items": { "type": "string" }, - "description": "Resources is a list of resources this rule applies to. ResourceAll represents all resources. \"*\" means all." + "description": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups." }, "resourceNames": { "type": "array", diff --git a/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json b/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json index b52fcc084ed..025cf93e360 100644 --- a/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json +++ b/api/swagger-spec/rbac.authorization.k8s.io_v1beta1.json @@ -3818,7 +3818,7 @@ "items": { "type": "string" }, - "description": "Resources is a list of resources this rule applies to. ResourceAll represents all resources." + "description": "Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups." }, "resourceNames": { "type": "array", diff --git a/docs/api-reference/authorization.k8s.io/v1/definitions.html b/docs/api-reference/authorization.k8s.io/v1/definitions.html index 2c79a973817..99c586f6eb2 100755 --- a/docs/api-reference/authorization.k8s.io/v1/definitions.html +++ b/docs/api-reference/authorization.k8s.io/v1/definitions.html @@ -1432,7 +1432,8 @@ When an object is created, the system will populate this list with the current s

resources

-

Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all.

+

Resources is a list of resources this rule applies to. "" means all in the specified apiGroups.
+ "
/foo" represents the subresource foo for all resources in the specified apiGroups.

false

string array

diff --git a/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html b/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html index 9d10ac19a3f..517acc34a70 100755 --- a/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/authorization.k8s.io/v1beta1/definitions.html @@ -1452,7 +1452,8 @@ When an object is created, the system will populate this list with the current s

resources

-

Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all.

+

Resources is a list of resources this rule applies to. "" means all in the specified apiGroups.
+ "
/foo" represents the subresource foo for all resources in the specified apiGroups.

false

string array

diff --git a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html index cf5169590b2..1b3d229a60d 100755 --- a/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html +++ b/docs/api-reference/rbac.authorization.k8s.io/v1beta1/definitions.html @@ -1682,7 +1682,7 @@ Examples:

resources

-

Resources is a list of resources this rule applies to. ResourceAll represents all resources.

+

Resources is a list of resources this rule applies to. represents all resources in the specified apiGroups. /foo represents the subresource foo for all resources in the specified apiGroups.

false

string array

diff --git a/pkg/apis/authorization/types.go b/pkg/apis/authorization/types.go index 4920913c59e..c4140b6d1cc 100644 --- a/pkg/apis/authorization/types.go +++ b/pkg/apis/authorization/types.go @@ -205,7 +205,8 @@ type ResourceRule struct { // APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of // the enumerated resources in any API group will be allowed. "*" means all. APIGroups []string - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all. + // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. Resources []string // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. ResourceNames []string diff --git a/pkg/apis/rbac/helpers.go b/pkg/apis/rbac/helpers.go index efc4c61c569..4b1a1d3a0c7 100644 --- a/pkg/apis/rbac/helpers.go +++ b/pkg/apis/rbac/helpers.go @@ -55,14 +55,29 @@ func APIGroupMatches(rule *PolicyRule, requestedGroup string) bool { return false } -func ResourceMatches(rule *PolicyRule, requestedResource string) bool { +func ResourceMatches(rule *PolicyRule, combinedRequestedResource, requestedSubresource string) bool { for _, ruleResource := range rule.Resources { + // if everything is allowed, we match if ruleResource == ResourceAll { return true } - if ruleResource == requestedResource { + // if we have an exact match, we match + if ruleResource == combinedRequestedResource { return true } + + // We can also match a */subresource. + // if there isn't a subresource, then continue + if len(requestedSubresource) == 0 { + continue + } + // if the rule isn't in the format */subresource, then we don't match, continue + if len(ruleResource) == len(requestedSubresource)+2 && + strings.HasPrefix(ruleResource, "*/") && + strings.HasSuffix(ruleResource, requestedSubresource) { + return true + + } } return false diff --git a/pkg/apis/rbac/helpers_test.go b/pkg/apis/rbac/helpers_test.go index de9f24a090a..a81fb2f5718 100644 --- a/pkg/apis/rbac/helpers_test.go +++ b/pkg/apis/rbac/helpers_test.go @@ -70,3 +70,108 @@ func TestHelpersRoundTrip(t *testing.T) { } } } + +func TestResourceMatches(t *testing.T) { + tests := []struct { + name string + ruleResources []string + combinedRequestedResource string + requestedSubresource string + expected bool + }{ + { + name: "all matches 01", + ruleResources: []string{"*"}, + combinedRequestedResource: "foo", + expected: true, + }, + { + name: "checks all rules", + ruleResources: []string{"doesn't match", "*"}, + combinedRequestedResource: "foo", + expected: true, + }, + { + name: "matches exact rule", + ruleResources: []string{"foo/bar"}, + combinedRequestedResource: "foo/bar", + requestedSubresource: "bar", + expected: true, + }, + { + name: "matches exact rule 02", + ruleResources: []string{"foo/bar"}, + combinedRequestedResource: "foo", + expected: false, + }, + { + name: "matches subresource", + ruleResources: []string{"*/scale"}, + combinedRequestedResource: "foo/scale", + requestedSubresource: "scale", + expected: true, + }, + { + name: "doesn't match partial subresource hit", + ruleResources: []string{"foo/bar", "*/other"}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: false, + }, + { + name: "matches subresource with multiple slashes", + ruleResources: []string{"*/other/segment"}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: true, + }, + { + name: "doesn't fail on empty", + ruleResources: []string{""}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: false, + }, + { + name: "doesn't fail on slash", + ruleResources: []string{"/"}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: false, + }, + { + name: "doesn't fail on missing subresource", + ruleResources: []string{"*/"}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: false, + }, + { + name: "doesn't match on not star", + ruleResources: []string{"*something/other/segment"}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: false, + }, + { + name: "doesn't match on something else", + ruleResources: []string{"something/other/segment"}, + combinedRequestedResource: "foo/other/segment", + requestedSubresource: "other/segment", + expected: false, + }, + } + + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + rule := &rbac.PolicyRule{ + Resources: tc.ruleResources, + } + actual := rbac.ResourceMatches(rule, tc.combinedRequestedResource, tc.requestedSubresource) + if tc.expected != actual { + t.Errorf("expected %v, got %v", tc.expected, actual) + } + + }) + } +} diff --git a/pkg/apis/rbac/types.go b/pkg/apis/rbac/types.go index 6e5ce60fb88..9ce2985f027 100644 --- a/pkg/apis/rbac/types.go +++ b/pkg/apis/rbac/types.go @@ -48,7 +48,8 @@ type PolicyRule struct { // APIGroups is the name of the APIGroup that contains the resources. // If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. APIGroups []string - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. + // Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. + // '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups. Resources []string // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. ResourceNames []string diff --git a/pkg/registry/rbac/validation/policy_comparator.go b/pkg/registry/rbac/validation/policy_comparator.go index 6c69c24fb22..4b2ba515814 100644 --- a/pkg/registry/rbac/validation/policy_comparator.go +++ b/pkg/registry/rbac/validation/policy_comparator.go @@ -105,6 +105,31 @@ func hasAll(set, contains []string) bool { return true } +func resourceCoversAll(setResources, coversResources []string) bool { + // if we have a star or an exact match on all resources, then we match + if has(setResources, rbac.ResourceAll) || hasAll(setResources, coversResources) { + return true + } + + for _, path := range coversResources { + // if we have an exact match, then we match. + if has(setResources, path) { + continue + } + // if we're not a subresource, then we definitely don't match. fail. + if !strings.Contains(path, "/") { + return false + } + tokens := strings.SplitN(path, "/", 2) + resourceToCheck := "*/" + tokens[1] + if !has(setResources, resourceToCheck) { + return false + } + } + + return true +} + func nonResourceURLsCoversAll(set, covers []string) bool { for _, path := range covers { covered := false @@ -133,7 +158,7 @@ func nonResourceURLCovers(ownerPath, subPath string) bool { func ruleCovers(ownerRule, subRule rbac.PolicyRule) bool { verbMatches := has(ownerRule.Verbs, rbac.VerbAll) || hasAll(ownerRule.Verbs, subRule.Verbs) groupMatches := has(ownerRule.APIGroups, rbac.APIGroupAll) || hasAll(ownerRule.APIGroups, subRule.APIGroups) - resourceMatches := has(ownerRule.Resources, rbac.ResourceAll) || hasAll(ownerRule.Resources, subRule.Resources) + resourceMatches := resourceCoversAll(ownerRule.Resources, subRule.Resources) nonResourceURLMatches := nonResourceURLsCoversAll(ownerRule.NonResourceURLs, subRule.NonResourceURLs) resourceNameMatches := false diff --git a/pkg/registry/rbac/validation/policy_comparator_test.go b/pkg/registry/rbac/validation/policy_comparator_test.go index fd892bf372e..b8b947f72ea 100644 --- a/pkg/registry/rbac/validation/policy_comparator_test.go +++ b/pkg/registry/rbac/validation/policy_comparator_test.go @@ -45,6 +45,20 @@ func TestCoversExactMatch(t *testing.T) { }.test(t) } +func TestCoversSubresourceWildcard(t *testing.T) { + escalationTest{ + ownerRules: []rbac.PolicyRule{ + {APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"*/scale"}}, + }, + servantRules: []rbac.PolicyRule{ + {APIGroups: []string{"v1"}, Verbs: []string{"get"}, Resources: []string{"foo/scale"}}, + }, + + expectedCovered: true, + expectedUncoveredRules: []rbac.PolicyRule{}, + }.test(t) +} + func TestCoversMultipleRulesCoveringSingleRule(t *testing.T) { escalationTest{ ownerRules: []rbac.PolicyRule{ diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go index f81abc720c2..f6294125631 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/controller_policy.go @@ -156,10 +156,7 @@ func buildControllerRoles() ([]rbac.ClusterRole, []rbac.ClusterRoleBinding) { Rules: []rbac.PolicyRule{ rbac.NewRule("get", "list", "watch").Groups(autoscalingGroup).Resources("horizontalpodautoscalers").RuleOrDie(), rbac.NewRule("update").Groups(autoscalingGroup).Resources("horizontalpodautoscalers/status").RuleOrDie(), - rbac.NewRule("get", "update").Groups(legacyGroup).Resources("replicationcontrollers/scale").RuleOrDie(), - // TODO this should be removable when the HPA contoller is fixed - rbac.NewRule("get", "update").Groups(extensionsGroup).Resources("replicationcontrollers/scale").RuleOrDie(), - rbac.NewRule("get", "update").Groups(extensionsGroup, appsGroup).Resources("deployments/scale", "replicasets/scale").RuleOrDie(), + rbac.NewRule("get", "update").Groups("*").Resources("*/scale").RuleOrDie(), rbac.NewRule("list").Groups(legacyGroup).Resources("pods").RuleOrDie(), // TODO: restrict this to the appropriate namespace rbac.NewRule("get").Groups(legacyGroup).Resources("services/proxy").Names("https:heapster:", "http:heapster:").RuleOrDie(), diff --git a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml index bc24fa3cf25..0c7e5ea019d 100644 --- a/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml +++ b/plugin/pkg/auth/authorizer/rbac/bootstrappolicy/testdata/controller-roles.yaml @@ -445,25 +445,9 @@ items: verbs: - update - apiGroups: - - "" + - '*' resources: - - replicationcontrollers/scale - verbs: - - get - - update - - apiGroups: - - extensions - resources: - - replicationcontrollers/scale - verbs: - - get - - update - - apiGroups: - - apps - - extensions - resources: - - deployments/scale - - replicasets/scale + - '*/scale' verbs: - get - update diff --git a/plugin/pkg/auth/authorizer/rbac/rbac.go b/plugin/pkg/auth/authorizer/rbac/rbac.go index 68ef7b2567f..090c11febc4 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac.go @@ -174,14 +174,14 @@ func RulesAllow(requestAttributes authorizer.Attributes, rules ...rbac.PolicyRul func RuleAllows(requestAttributes authorizer.Attributes, rule *rbac.PolicyRule) bool { if requestAttributes.IsResourceRequest() { - resource := requestAttributes.GetResource() + combinedResource := requestAttributes.GetResource() if len(requestAttributes.GetSubresource()) > 0 { - resource = requestAttributes.GetResource() + "/" + requestAttributes.GetSubresource() + combinedResource = requestAttributes.GetResource() + "/" + requestAttributes.GetSubresource() } return rbac.VerbMatches(rule, requestAttributes.GetVerb()) && rbac.APIGroupMatches(rule, requestAttributes.GetAPIGroup()) && - rbac.ResourceMatches(rule, resource) && + rbac.ResourceMatches(rule, combinedResource, requestAttributes.GetSubresource()) && rbac.ResourceNameMatches(rule, requestAttributes.GetName()) } diff --git a/plugin/pkg/auth/authorizer/rbac/rbac_test.go b/plugin/pkg/auth/authorizer/rbac/rbac_test.go index 16a21241ce8..db8a385f0af 100644 --- a/plugin/pkg/auth/authorizer/rbac/rbac_test.go +++ b/plugin/pkg/auth/authorizer/rbac/rbac_test.go @@ -224,13 +224,19 @@ func TestAuthorizer(t *testing.T) { { // test subresource resolution clusterRoles: []*rbac.ClusterRole{ - newClusterRole("admin", newRule("*", "*", "pods/status", "*")), + newClusterRole("admin", + newRule("*", "*", "pods/status", "*"), + newRule("*", "*", "*/scale", "*"), + ), }, roleBindings: []*rbac.RoleBinding{ newRoleBinding("ns1", "admin", bindToClusterRole, "User:admin", "Group:admins"), }, shouldPass: []authorizer.Attributes{ &defaultAttributes{"admin", "", "get", "pods", "status", "ns1", ""}, + &defaultAttributes{"admin", "", "get", "pods", "scale", "ns1", ""}, + &defaultAttributes{"admin", "", "get", "deployments", "scale", "ns1", ""}, + &defaultAttributes{"admin", "", "get", "anything", "scale", "ns1", ""}, }, shouldFail: []authorizer.Attributes{ &defaultAttributes{"admin", "", "get", "pods", "", "ns1", ""}, diff --git a/staging/src/k8s.io/api/authorization/v1/generated.proto b/staging/src/k8s.io/api/authorization/v1/generated.proto index 7f31d599a81..de8323fc14a 100644 --- a/staging/src/k8s.io/api/authorization/v1/generated.proto +++ b/staging/src/k8s.io/api/authorization/v1/generated.proto @@ -121,7 +121,8 @@ message ResourceRule { // +optional repeated string apiGroups = 2; - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all. + // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional repeated string resources = 3; diff --git a/staging/src/k8s.io/api/authorization/v1/types.go b/staging/src/k8s.io/api/authorization/v1/types.go index 99ec3bcbf7f..23b5ae7051c 100644 --- a/staging/src/k8s.io/api/authorization/v1/types.go +++ b/staging/src/k8s.io/api/authorization/v1/types.go @@ -241,7 +241,8 @@ type ResourceRule struct { // the enumerated resources in any API group will be allowed. "*" means all. // +optional APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all. + // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. diff --git a/staging/src/k8s.io/api/authorization/v1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/authorization/v1/types_swagger_doc_generated.go index 8a0fb8a857b..1e3f780d908 100644 --- a/staging/src/k8s.io/api/authorization/v1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/authorization/v1/types_swagger_doc_generated.go @@ -76,7 +76,7 @@ var map_ResourceRule = map[string]string{ "": "ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", "verbs": "Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"*\" means all.", - "resources": "Resources is a list of resources this rule applies to. ResourceAll represents all resources. \"*\" means all.", + "resources": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. \"*\" means all.", } diff --git a/staging/src/k8s.io/api/authorization/v1beta1/generated.proto b/staging/src/k8s.io/api/authorization/v1beta1/generated.proto index 9e9942f367a..2c940f27306 100644 --- a/staging/src/k8s.io/api/authorization/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/authorization/v1beta1/generated.proto @@ -121,7 +121,8 @@ message ResourceRule { // +optional repeated string apiGroups = 2; - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all. + // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional repeated string resources = 3; diff --git a/staging/src/k8s.io/api/authorization/v1beta1/types.go b/staging/src/k8s.io/api/authorization/v1beta1/types.go index a0659d519c0..f62f59569ca 100644 --- a/staging/src/k8s.io/api/authorization/v1beta1/types.go +++ b/staging/src/k8s.io/api/authorization/v1beta1/types.go @@ -241,7 +241,8 @@ type ResourceRule struct { // the enumerated resources in any API group will be allowed. "*" means all. // +optional APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. "*" means all. + // Resources is a list of resources this rule applies to. "*" means all in the specified apiGroups. + // "*/foo" represents the subresource 'foo' for all resources in the specified apiGroups. // +optional Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. "*" means all. diff --git a/staging/src/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go index 1d8bb9849ba..544c2fa4333 100644 --- a/staging/src/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/authorization/v1beta1/types_swagger_doc_generated.go @@ -76,7 +76,7 @@ var map_ResourceRule = map[string]string{ "": "ResourceRule is the list of actions the subject is allowed to perform on resources. The list ordering isn't significant, may contain duplicates, and possibly be incomplete.", "verbs": "Verb is a list of kubernetes resource API verbs, like: get, list, watch, create, update, delete, proxy. \"*\" means all.", "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed. \"*\" means all.", - "resources": "Resources is a list of resources this rule applies to. ResourceAll represents all resources. \"*\" means all.", + "resources": "Resources is a list of resources this rule applies to. \"*\" means all in the specified apiGroups.\n \"*/foo\" represents the subresource 'foo' for all resources in the specified apiGroups.", "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. \"*\" means all.", } diff --git a/staging/src/k8s.io/api/rbac/v1beta1/generated.proto b/staging/src/k8s.io/api/rbac/v1beta1/generated.proto index 6469de720a5..fa4418771eb 100644 --- a/staging/src/k8s.io/api/rbac/v1beta1/generated.proto +++ b/staging/src/k8s.io/api/rbac/v1beta1/generated.proto @@ -85,7 +85,8 @@ message PolicyRule { // +optional repeated string apiGroups = 2; - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. + // Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. + // '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups. // +optional repeated string resources = 3; diff --git a/staging/src/k8s.io/api/rbac/v1beta1/types.go b/staging/src/k8s.io/api/rbac/v1beta1/types.go index 30f95a77405..ee3964a3c0e 100644 --- a/staging/src/k8s.io/api/rbac/v1beta1/types.go +++ b/staging/src/k8s.io/api/rbac/v1beta1/types.go @@ -54,7 +54,8 @@ type PolicyRule struct { // the enumerated resources in any API group will be allowed. // +optional APIGroups []string `json:"apiGroups,omitempty" protobuf:"bytes,2,rep,name=apiGroups"` - // Resources is a list of resources this rule applies to. ResourceAll represents all resources. + // Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. + // '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups. // +optional Resources []string `json:"resources,omitempty" protobuf:"bytes,3,rep,name=resources"` // ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed. diff --git a/staging/src/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go b/staging/src/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go index 1463d8feac0..16a265c5a9c 100644 --- a/staging/src/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go +++ b/staging/src/k8s.io/api/rbac/v1beta1/types_swagger_doc_generated.go @@ -72,7 +72,7 @@ var map_PolicyRule = map[string]string{ "": "PolicyRule holds information that describes a policy rule, but does not contain information about who the rule applies to or which namespace the rule applies to.", "verbs": "Verbs is a list of Verbs that apply to ALL the ResourceKinds and AttributeRestrictions contained in this rule. VerbAll represents all kinds.", "apiGroups": "APIGroups is the name of the APIGroup that contains the resources. If multiple API groups are specified, any action requested against one of the enumerated resources in any API group will be allowed.", - "resources": "Resources is a list of resources this rule applies to. ResourceAll represents all resources.", + "resources": "Resources is a list of resources this rule applies to. '*' represents all resources in the specified apiGroups. '*/foo' represents the subresource 'foo' for all resources in the specified apiGroups.", "resourceNames": "ResourceNames is an optional white list of names that the rule applies to. An empty set means that everything is allowed.", "nonResourceURLs": "NonResourceURLs is a set of partial urls that a user should have access to. *s are allowed, but only as the full, final step in the path Since non-resource URLs are not namespaced, this field is only applicable for ClusterRoles referenced from a ClusterRoleBinding. Rules can either apply to API resources (such as \"pods\" or \"secrets\") or non-resource URL paths (such as \"/api\"), but not both.", }