-
Notifications
You must be signed in to change notification settings - Fork 4.7k
Add conversions from RBAC resources to origin resources #13334
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
[test] |
pkg/authorization/util/util.go
Outdated
} | ||
} | ||
|
||
func ConvertRBACClusterRole(in *rbac.ClusterRole) *api.ClusterRole { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think detection is fine
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we still working with v1alpha1 RBAC here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
are we still working with v1alpha1 RBAC here?
Internal to internal.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
ah, but before kubernetes/kubernetes#41184
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This won't match up.
pkg/authorization/util/util.go
Outdated
} | ||
|
||
func convertRBACRoleRef(in *rbac.RoleRef) kapi.ObjectReference { | ||
return kapi.ObjectReference{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No. Inline into callers.
} | ||
} | ||
|
||
func unsetUnpreservedFields(subjects []api.ObjectReference, roleRef *api.ObjectReference) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, that would have been unfortunate. Annotation to roundtrip through the rbac role maybe?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
do we allow mixing resource and non-resource bits in the same rule? upstream does not, so we potentially need to split rules
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We do not allow mixing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
awesome
@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.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 <[email protected]>
Signed-off-by: Monis Khan <[email protected]>
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
unsetUnpreservedFields
andsortAndDeduplicateRulesFields
do not invalidate the tests.cc @liggitt
Signed-off-by: Monis Khan [email protected]