Add conversions from RBAC resources to origin resources#13334
Add conversions from RBAC resources to origin resources#13334openshift-bot merged 2 commits intoopenshift:masterfrom
Conversation
|
[test] |
pkg/authorization/util/util.go
Outdated
| } | ||
| } | ||
|
|
||
| func ConvertRBACClusterRole(in *rbac.ClusterRole) *api.ClusterRole { |
There was a problem hiding this comment.
Make the names look like the generated ones: Convert_rbac_ClusterRole_To_api_ClusterRole and actually register these with other pkg/authorization/api conversions.
pkg/authorization/util/util.go
Outdated
| } | ||
| } | ||
|
|
||
| func convertRBACPolicyRules(in []rbac.PolicyRule) []api.PolicyRule { |
There was a problem hiding this comment.
you need a comment about AttributeRestrictions
pkg/authorization/util/util.go
Outdated
| } | ||
| } | ||
|
|
||
| func convertOriginPolicyRule(in []api.PolicyRule) []rbac.PolicyRule { |
There was a problem hiding this comment.
I guess that comment goes here.
pkg/authorization/util/util.go
Outdated
| subjects := make([]rbac.Subject, 0, len(in)) | ||
| for _, subject := range in { | ||
| s := rbac.Subject{ | ||
| Kind: subject.Kind, |
There was a problem hiding this comment.
origin kinds collapse down to just User and Group from SystemUser and SystemGroup.
pkg/authorization/util/util.go
Outdated
|
|
||
| func convertOriginRoleRef(in *kapi.ObjectReference) rbac.RoleRef { | ||
| return rbac.RoleRef{ | ||
| APIGroup: in.APIVersion, |
There was a problem hiding this comment.
This is fixed in kube to rbac.authorization.k8s.io.
pkg/authorization/util/util.go
Outdated
| func convertOriginRoleRef(in *kapi.ObjectReference) rbac.RoleRef { | ||
| return rbac.RoleRef{ | ||
| APIGroup: in.APIVersion, | ||
| Kind: in.Kind, |
There was a problem hiding this comment.
I didn't think we filled in a Kind. I thought we triggered on empty namespace or not.
pkg/authorization/util/util.go
Outdated
| return subjects | ||
| } | ||
|
|
||
| func convertOriginRoleRef(in *kapi.ObjectReference) rbac.RoleRef { |
There was a problem hiding this comment.
If we reference a role (not clusterrole) from a different namespace this needs to return an error so we can catch it.
Also, we'll want an upgrade preflight check or at least warning about the condition. We may have to provide a script for a cluster-admin to denormalize automatically. @liggitt necessary to make the script?
pkg/authorization/util/util.go
Outdated
| for _, subject := range in { | ||
| s := rbac.Subject{ | ||
| Kind: subject.Kind, | ||
| APIVersion: subject.APIVersion, |
There was a problem hiding this comment.
@liggitt want to specify our group here? It's what its for and it should work... Alternatively, we could avoid rocking the boat.
There was a problem hiding this comment.
if we want to use the upstream authorizer eventually, I don't want want to have to rewrite these into subjects it recognizes
There was a problem hiding this comment.
are we still working with v1alpha1 RBAC here?
There was a problem hiding this comment.
are we still working with v1alpha1 RBAC here?
Internal to internal.
pkg/authorization/util/util.go
Outdated
| for _, subject := range in { | ||
| s := kapi.ObjectReference{ | ||
| Kind: subject.Kind, | ||
| APIVersion: subject.APIVersion, |
There was a problem hiding this comment.
This shouldn't carry through.
pkg/authorization/util/util.go
Outdated
| subjects := make([]kapi.ObjectReference, 0, len(in)) | ||
| for _, subject := range in { | ||
| s := kapi.ObjectReference{ | ||
| Kind: subject.Kind, |
There was a problem hiding this comment.
You'll need to use the subject determination code. Take a look at the conversions we have from Users and Groups to Subjects and you'll find the helpers to determine SystemUser and SystemGroup
pkg/authorization/util/util.go
Outdated
| func convertRBACRoleRef(in *rbac.RoleRef) kapi.ObjectReference { | ||
| return kapi.ObjectReference{ | ||
| APIVersion: in.APIGroup, | ||
| Kind: in.Kind, |
pkg/authorization/util/util.go
Outdated
| } | ||
|
|
||
| func convertRBACRoleRef(in *rbac.RoleRef) kapi.ObjectReference { | ||
| return kapi.ObjectReference{ |
There was a problem hiding this comment.
You'll need to fill in a namespace for the local role reference
|
@deads2k PTAL Fuzzing tests are failing right now because they do not follow the kind requirements - I will update those soon. |
pkg/authorization/api/conversion.go
Outdated
| func convertOriginRoleRef(in *api.ObjectReference) rbac.RoleRef { | ||
| return rbac.RoleRef{ | ||
| APIGroup: in.APIVersion, | ||
| Kind: in.Kind, // TODO leave empty? |
There was a problem hiding this comment.
When the origin roleref namespace is empty, the rbacRoleRef kind should be "ClusterRole". Otherwise, it should be "Role"
pkg/authorization/api/conversion.go
Outdated
|
|
||
| func convertOriginRoleRef(in *api.ObjectReference) rbac.RoleRef { | ||
| return rbac.RoleRef{ | ||
| APIGroup: in.APIVersion, |
There was a problem hiding this comment.
I'm expecting the APIGroup to pinned to the correct rbac value.
pkg/authorization/api/conversion.go
Outdated
| func convertOriginRoleRef(in *api.ObjectReference) rbac.RoleRef { | ||
| return rbac.RoleRef{ | ||
| APIGroup: in.APIVersion, | ||
| Kind: in.Kind, // TODO leave empty? |
There was a problem hiding this comment.
When the origin roleref namespace equals the current namespace, then the Kind should be "Role"
pkg/authorization/api/conversion.go
Outdated
| for _, subject := range in { | ||
| s := rbac.Subject{ | ||
| Name: subject.Name, | ||
| APIVersion: rbac.GroupName, // TODO what to use here? |
There was a problem hiding this comment.
It's pinned. Look it up in the rbac code.
pkg/authorization/api/conversion.go
Outdated
| subjects := make([]api.ObjectReference, 0, len(in)) | ||
| for _, subject := range in { | ||
| s := api.ObjectReference{ | ||
| APIVersion: rbac.GroupName, // TODO what do we want here? |
There was a problem hiding this comment.
This is empty. You really should read the existing code that builds origin subject references.
pkg/authorization/api/helpers.go
Outdated
| return determineKind(GroupKind, SystemGroupKind, group, groupNameValidator) | ||
| } | ||
|
|
||
| func determineKind(base, fallback, name string, nameValidator validation.ValidateNameFunc) string { |
| } | ||
| } | ||
|
|
||
| func unsetUnpreservedFields(subjects []api.ObjectReference, roleRef *api.ObjectReference) { |
There was a problem hiding this comment.
Fix the fuzz functions instead to create values that could actually exist.
|
@deads2k PTAL |
pkg/authorization/api/conversion.go
Outdated
| } | ||
| } | ||
|
|
||
| func getKind(namespace string) string { |
There was a problem hiding this comment.
originRoleRefKind? Something to demonstrate how specific it is.
pkg/authorization/api/conversion.go
Outdated
|
|
||
| func convertRBACRoleRef(in *rbac.RoleRef, namespace string) api.ObjectReference { | ||
| return api.ObjectReference{ | ||
| Kind: getKind(namespace), |
There was a problem hiding this comment.
I didn't think that origin rolerefs respected kind.
pkg/authorization/api/conversion.go
Outdated
| return subjects, nil | ||
| } | ||
|
|
||
| func convertRBACRoleRef(in *rbac.RoleRef, namespace string) api.ObjectReference { |
There was a problem hiding this comment.
Can you name these functions as Convert_foo_to_bar? Obviously the signature won't match, but it will help remind me as I read it. Also, godoc on for the args. namespace isn't obvious.
|
|
||
| case rbac.UserKind: | ||
| if len(uservalidation.ValidateUserName(subject.Name, false)) != 0 { | ||
| subject.Name = fmt.Sprintf("validusername%d", i) |
There was a problem hiding this comment.
we want some user names that are SystemUsers too.
| } | ||
|
|
||
| case rbac.ServiceAccountKind: | ||
| if len(validation.ValidateNamespaceName(subject.Namespace, false)) != 0 { |
There was a problem hiding this comment.
RBAC service account references aren't required to have namespaces. Some shouldn't have them.
| subject.Name = ":" + subject.Name | ||
|
|
||
| case ServiceAccountKind: | ||
| if len(validation.ValidateNamespaceName(subject.Namespace, false)) != 0 { |
There was a problem hiding this comment.
some SA subject namespaces should be empty.
1e8cc68 to
054bab7
Compare
|
@liggitt Any comments? |
pkg/authorization/api/conversion.go
Outdated
| func convert_api_PolicyRules_To_rbac_PolicyRules(in []PolicyRule) []rbac.PolicyRule { | ||
| rules := make([]rbac.PolicyRule, 0, len(in)) | ||
| for _, rule := range in { | ||
| r := rbac.PolicyRule{ // AttributeRestrictions is lost, but our authorizor ignores that field now |
There was a problem hiding this comment.
it ignores it, but only after converting subjectaccessreviews with an IsSelfSubjectAccessReview restriction to selfsubjectaccessreviews.authorization.k8s.io... just dropping it escalates that permission
There was a problem hiding this comment.
if we see a rule with that restriction, we need to limit the rule to the things that restriction would allow, and convert subjectaccessreviews resources to selfsubjectaccessreviews.authorization.k8s.io resources
There was a problem hiding this comment.
Ah, that would have been unfortunate. Annotation to roundtrip through the rbac role maybe?
There was a problem hiding this comment.
if we round-trip and end up with a rule that allows selfsubjectaccessreviews.authorization.k8s.io, that's sufficient
| Verbs: rule.Verbs.List(), | ||
| Resources: rule.Resources.List(), | ||
| ResourceNames: rule.ResourceNames.List(), | ||
| NonResourceURLs: rule.NonResourceURLs.List(), |
There was a problem hiding this comment.
do we allow mixing resource and non-resource bits in the same rule? upstream does not, so we potentially need to split rules
|
@deads2k did we fix up mixed-case resources in conversion or in the authorizer? do we need to downcase on our way out to kube? |
No such luck.
apiVersion: v1
kind: ClusterRole
metadata:
name: foobar
rules:
- apiGroups:
- ""
resources:
- configmapS
- Endpoints
- persistentvolumeclAIms
- PODS
verbs:
- GET
- lIst
- wAtch
apiVersion: v1
kind: ClusterRole
metadata:
creationTimestamp: 2017-03-15T22:09:25Z
name: foobar
resourceVersion: "986"
selfLink: /oapi/v1/clusterrolesfoobar
uid: 0cc20af8-09cc-11e7-8ccc-507b9dac97ff
rules:
- apiGroups:
- ""
attributeRestrictions: null
resources:
- Endpoints
- PODS
- configmapS
- persistentvolumeclAIms
verbs:
- GET
- lIst
- wAtch |
|
So in the |
| } | ||
|
|
||
| // rules with AttributeRestrictions should not be preserved during conversion | ||
| func TestAttributeRestrictionsRuleLoss(t *testing.T) { |
There was a problem hiding this comment.
Shouldn't this function be using a two way covers check? Also, that probably needs checking come to think of it.
|
@liggitt as I recall, we did the tolower thing because in 3.0, we had mixed case paths. I think we're far enough out that I'd be willing to say, "those clients need to be fixed" at this point. I'm thinking we tolower everything as a migration step ( |
|
Oh, and we stop tolowering in our authorizer for 3.6. |
|
@enj We're going with the |
|
@enj I think you should remove the normalization commit and remind me to look at this on Monday. |
Signed-off-by: Monis Khan <mkhan@redhat.com>
Signed-off-by: Monis Khan <mkhan@redhat.com>
65ffbdf to
bf34a59
Compare
|
Evaluated for origin test up to bf34a59 |
|
continuous-integration/openshift-jenkins/test SUCCESS (https://ci.openshift.redhat.com/jenkins/job/test_pull_request_origin/293/) (Base Commit: 9e19032) |
|
@deads2k @liggitt I opened #13429 #13430 #13432 to track the remaining issues. RBAC conversions no longer normalize and use Let me know if you want to merge this as-is and have separate PRs for each of those fixes or if you want me to add some of the fixes here. |
|
lgtm [merge] |
|
Evaluated for origin merge up to bf34a59 |
|
continuous-integration/openshift-jenkins/merge SUCCESS (https://ci.openshift.redhat.com/jenkins/job/merge_pull_request_origin/149/) (Base Commit: 612dcfb) (Image: devenv-rhel7_6087) |
|
@enj add validation for a role and cluster role that makes including any attributerestrictions invalid. It may frustrate some people who have serialized roles that include these, but it also forces them to look at why and see that their rule won't work. Other paths that I decided against:
|
Trello ref: https://trello.com/c/viECLnNa
@deads2k It would probably take ~3 conversions to build a semantic compare function - assuming
unsetUnpreservedFieldsandsortAndDeduplicateRulesFieldsdo not invalidate the tests.cc @liggitt
Signed-off-by: Monis Khan mkhan@redhat.com