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 214870b740..38bed12b0b 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 46f957024c..32e4bf2026 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 dcc02d2b09..8e617ff497 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 b52fcc084e..025cf93e36 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 2c79a97381..99c586f6eb 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 9d10ac19a3..517acc34a7 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 cf5169590b..1b3d229a60 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 4920913c59..c4140b6d1c 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 efc4c61c56..4b1a1d3a0c 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 de9f24a090..a81fb2f571 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 6e5ce60fb8..9ce2985f02 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 6c69c24fb2..4b2ba51581 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 fd892bf372..b8b947f72e 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 f81abc720c..f629412563 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 bc24fa3cf2..0c7e5ea019 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 68ef7b2567..090c11febc 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 16a21241ce..db8a385f0a 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 7f31d599a8..de8323fc14 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 99ec3bcbf7..23b5ae7051 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 8a0fb8a857..1e3f780d90 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 9e9942f367..2c940f2730 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 a0659d519c..f62f59569c 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 1d8bb9849b..544c2fa433 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 6469de720a..fa4418771e 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 30f95a7740..ee3964a3c0 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 1463d8feac..16a265c5a9 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.", }