-
Notifications
You must be signed in to change notification settings - Fork 248
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
Move pkg/clone/auth to API lib and introduce single dv.Authorize() #2636
Conversation
@@ -33,8 +33,8 @@ import ( | |||
"k8s.io/klog/v2" | |||
|
|||
cdiv1 "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1" | |||
cdiv1cloneauth "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1/clone" |
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 kubevirt.io/containerized-data-importer-api/pkg/clone
would be better. Let's keep pkg/apis
for kubernetes apis
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.
So we already have
cdiv1utils "kubevirt.io/containerized-data-importer-api/pkg/apis/core/v1beta1/utils" |
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.
That function takes a DataVolume as a parameter though so having multiple versions of the api makes sense. These funcs however do not take any api resources as parameters
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.
makes sense, was about to do this, but then realized we have #2552 which will accept a DV
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.
okay then maybe it makes to refactor to do something like:
ok, err := dv.Authorize()
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.
so Authorize()
will go in ${version}/utils, and we will be able to have different authorization logic for different version?
I am just making sure, I have no issue with moving to kubevirt.io/containerized-data-importer-api/pkg/clone
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 what I'm saying is do #2552 in this pr and have Authorize
be a DataVolume member function. All code will exist under pkg/apis...
no pkg/clone
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.
Posted a first draft just to make sure we are fine with the direction
- Still missing authorization via SA
- Feels like the logic is clunky, any pointers are greatly appreciated
- Would aggregating the proxies into one interface make sense?
be1add0
to
6bcfbde
Compare
/test all |
6bcfbde
to
3e97126
Compare
/test all |
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.
Great start! I'm not that down on this
|
||
// Authorize indicates if the creating context is authorized to create the data volume | ||
// For sources other than clone (import/upload/etc), this is a no-op | ||
func (dv *DataVolume) Authorize(requestNamespace, requestName string, sarClient SubjectAccessReviewsProxy, nsClient NamespaceProxy, dsClient DataSourceProxy, userInfo authentication.UserInfo) (bool, string, cloneSourceHandler, error) { |
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.
Maybe use the client native interfaces instead of our own proxies, so SubjectAccessReviewsGetter
, NamespacesGetter
, DataSourcesGetter
?
Is that an improvement?
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.
Scratch that, can't have DataSourcesGetter in here (circular dep). But maybe the others? Or will that make the deps situation worse?
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.
Introduced a single type AuthorizationHelperProxy interface
, hope that is fine
I'm not that down on this
I am not sure if you meant you're not down with the approach (don't like) or don't hate it too much (like~)
3e97126
to
a3deee6
Compare
/test all |
a3deee6
to
dc9e31f
Compare
/test all |
@@ -3,9 +3,11 @@ module kubevirt.io/containerized-data-importer-api | |||
go 1.19 | |||
|
|||
require ( | |||
github.com/kubernetes-csi/external-snapshotter/client/v6 v6.0.1 |
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 we get rid of this somehow?
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.
Let's keep this go.mod lean and mean. Copying string consts is fine
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.
done
dc9e31f
to
c8af204
Compare
pkg/clone/auth.go
Outdated
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.
@mhenriks do you think it's fine to delete this? should we keep for backwards compatibility?
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.
gentle ping
c8af204
to
e8d5bfd
Compare
type dsGetFunc func(string, string) (*DataSource, error) | ||
|
||
// AuthorizationHelperProxy proxies calls to APIs used for DV authorization | ||
type AuthorizationHelperProxy interface { |
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't believe I just thought of this and I'd be remiss to not bring it up, what if our api just takes a dynamic.Interface
instead of the proxy?
PRO:
Less code for clients
CON:
more code in api (translating to/from unstructured)
adding client-go
to go.mod
Don't care too much either way just want to get your opinion
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.
Would have to look up some references but the immediate concern is:
Would we still be able to restrict access to the passed client similarly to how we do with proxy?
I mean, with the proxy, external entities know that CDI doesn't have access to the client itself other than
the implemented Get/Create methods
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.
With the proxy, callers know exactly what calls we are making, and that may be nice, but ultimately there is RBAC in place to keep the SA from doing anything bad. And obviously the code is available to audit and make sure we're not reading secrets or whatever.
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.
Yes my concern is that we get passed a general SA that is probably not very limited,
unless you are suggesting to somehow reduce the SA
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 I don't think it is practical to create a special client with reduced permissions just to pass to this api. I also don't think passing the dynamic client is a security concern.
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 also don't think passing the dynamic client is a security concern.
I thought the reason we went with proxy structs in the first place was to avoid passing a full-blown client
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 also don't think passing the dynamic client is a security concern.
I thought the reason we went with proxy structs in the first place was to avoid passing a full-blown client
The issue is with the typed client here: https://github.com/kubevirt/containerized-data-importer/blob/main/pkg/client/clientset/versioned/typed/core/v1beta1/datavolume.go#L40
That would cause a circular dependency
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.
Ahh right.
I thought the reason we went with proxy structs in the first place was to avoid passing a full-blown client
We used the sarProxy prior to this PR though (and thus prior to the circular dep potential), was this^ not the main concern?
Anyway my (not 100% trustworthy) gut is telling me that whipping out a dynamic client
when we have a defined set of actions on objects we know about is not right, so I lean towards current impl
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.
All past decisions are not made with perfect information. If I could go back in time I would probably use the dynamic client. But if you like using this interface, I don't care enough to keep belaboring the discussion.
e8d5bfd
to
7bf544e
Compare
|
||
// AuthorizeUser indicates if the creating user is authorized to create the data volume | ||
// For sources other than clone (import/upload/etc), this is a no-op | ||
func (dv *DataVolume) AuthorizeUser(requestNamespace, requestName string, proxy AuthorizationHelperProxy, userInfo authentication.UserInfo) (bool, string, CloneSourceHandler, error) { |
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.
Rather than returning four vales, how about a new struct that combines the first three?
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.
Yep makes sense, added
My biggest worry is still this though:
#2636 (comment)
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 it's fine to delete auth.go. I seriously doubt any project other than kubevirt is importing it
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
This way other projects don't have to vendor in CDI, the API lib will be enough. While it's not a huge deal at this point, each existing dependency is an entry door for pulling in more stuff in the future by accident. Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com>
7bf544e
to
fabdbd1
Compare
/approve |
[APPROVALNOTIFIER] This PR is APPROVED This pull-request has been approved by: mhenriks The full list of commands accepted by this bot can be found here. The pull request process is described here
Needs approval from an approver in each of these files:
Approvers can indicate their approval by writing |
"kubevirt.io/containerized-data-importer/tests/framework" | ||
"kubevirt.io/containerized-data-importer/tests/utils" | ||
) | ||
|
||
type sarProxy struct { | ||
client kubernetes.Interface | ||
type authProxy struct { |
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.
why not using authProxy from datavolume-mutate.go?
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 it's nice that webhook_test.go will showcase all building blocks toward authorizing a data volume
plus, it feels a little "off" to export that struct from datavolume-mutate since it's not really of use to anyone but the tests
/lgtm |
This is a partial backport of kubevirt#2636 This tends to flake often, especially in OpenShift testing. Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com>
This is a partial backport of #2636 This tends to flake often, especially in OpenShift testing. Signed-off-by: Alex Kalenyuk <akalenyu@redhat.com>
What this PR does / why we need it:
This way other projects don't have to vendor in CDI, the API lib will be enough.
While it's not a huge deal at this point, each existing dependency is an entry door for pulling in more stuff in the future by accident.
Also, these are annoying
containerized-data-importer/go.mod
Lines 26 to 27 in 20dc7d4
Which issue(s) this PR fixes (optional, in
fixes #<issue number>(, fixes #<issue_number>, ...)
format, will close the issue(s) when PR gets merged):Fixes #2552
Special notes for your reviewer:
Release note: