You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
To use any part of the Kubernetes api on a Resource you currently have to instantiate an Api object. In many cases, this abstraction saves some time by giving the user a type bound to a resource that you can do multiple queries on (within the same scope), but in many other instances it leads to lots of client.clone() calls to create throwaway Api instances that are used for a single query. We see this all the time in reconcilers.
It also leads to problems where people create an Api::all to perhaps query across all namespaces, and legitimately ending up with an "illegal" way to create a namespaced resource. See #1030
It's also not the first time this idea of avoiding Api has been floated around: #594. But I think we can do this in a non-breaking way, without having to rewrite so much as the original PR attempted to do (though there are some great simplifications in there).
Describe the solution you'd like
We should implement these methods directly on client:
implClient{// All of these with constraint:// where K: Resource<Scope = NamespaceResourceScope> {}fncreate_namespaced<K>(name:&str,ns:&Namespace,pp:&PostParams,data:&K) -> Result<K>fnget_namespaced<K>(name:&str,ns:&Namespace) -> Result<K>fnlist_namespaced<K>(ns:&Namespace,lp:&ListParams) -> Result<ObjectList<K>>fnlist_all<K>(lp:&ListParams) -> Result<ObjectList<K>>fndelete_namespaced<K>(name:&str,ns:&Namespace,dp:&DeleteParams) -> Result<Either<K,Status>>fndelete_namespaced_collection<K>(name:&str,ns:&Namespace,dp:&DeleteParams,lp:&ListParams) -> Result<Either<ObjectList<K>,Status>>fnpatch_namespaced<K,P>(name:&str,ns:&Namespace,pp:&PatchParams,patch:&Patch<P>) -> Result<K>fnreplace_namespaced<K>(name:&str,ns:&Namespace, pp;&PostParams,data:&K) -> Result<K>fnwatch_namespaced<K>(ns:&Namespace,lp:&ListParams,version:&str) -> Result<implStream<Item = Result<WatchEvent<K>>>>fnwatch_all<K>(lp:&ListParams,version:&str) -> Result<implStream<Item = Result<WatchEvent<K>>>>}
and near identical impls for ClusterResourceScope but without the ability to do anything namespaced (basically the same fn interfaces as on Api since they don't take a namespace.
The function bodies should leverage kube-core's Request objects and be functionally equivalent to the Api method's parallels, but without having to read namespace from self and instead get it from some newtype (to avoid two string args in a row).
Describe alternatives you've considered
We could hide some of this behind an async trait to make this stuff mockable, but then we would need to pull in async_trait (which we currently do not). Not sure what is the best solution for this. Is it a problem to have a bunch new pub methods on Client?
Documentation, Adoption, Migration Strategy
We don't need to deprecate Api I think. The abstraction is useful, just not nearly as universal as originally envisioned.
However, this does mean that more of runtime can create some of its impls directly on Client in a less or more constrained way. This might be nicer in some places, but it might be more problematic since we now force dealing with scope down to the resource.
To minimize the amount of code-duplication within kube-client, we could make the methods on Client canonical, and make Api a more empty shell that defers to these.
Less sure what to do about the subresource scope though. That requires some thought.
Target crate for feature
kube-client
Future Ideas
Future things that should be considered later on (open follow-ups):
feature gated automock derives to allow mocking the client without tower_test
Implement subresource standard methods Client::patch_status + Client::patch_status_namepaced and decide whether to make a typed variant (so you can take the Status object - e.g. Helper struct for `patch_status` with `Patch::Apply` #1465)
...more to come
generic subresources
dynamic resources
The text was updated successfully, but these errors were encountered:
What problem are you trying to solve?
To use any part of the Kubernetes api on a
Resource
you currently have to instantiate anApi
object. In many cases, this abstraction saves some time by giving the user a type bound to a resource that you can do multiple queries on (within the same scope), but in many other instances it leads to lots ofclient.clone()
calls to create throwawayApi
instances that are used for a single query. We see this all the time in reconcilers.We see users working around it by implementing these things more or less directly on the
Client
themselvesIt also leads to problems where people create an
Api::all
to perhaps query across all namespaces, and legitimately ending up with an "illegal" way to create a namespaced resource. See #1030It's also not the first time this idea of avoiding
Api
has been floated around: #594. But I think we can do this in a non-breaking way, without having to rewrite so much as the original PR attempted to do (though there are some great simplifications in there).Describe the solution you'd like
We should implement these methods directly on client:
and near identical impls for
ClusterResourceScope
but without the ability to do anything namespaced (basically the same fn interfaces as onApi
since they don't take a namespace.The function bodies should leverage kube-core's
Request
objects and be functionally equivalent to theApi
method's parallels, but without having to read namespace fromself
and instead get it from some newtype (to avoid two string args in a row).Describe alternatives you've considered
We could hide some of this behind an async trait to make this stuff mockable, but then we would need to pull in
async_trait
(which we currently do not). Not sure what is the best solution for this. Is it a problem to have a bunch new pub methods onClient
?Documentation, Adoption, Migration Strategy
We don't need to deprecate
Api
I think. The abstraction is useful, just not nearly as universal as originally envisioned.However, this does mean that more of
runtime
can create some of itsimpls
directly onClient
in a less or more constrained way. This might be nicer in some places, but it might be more problematic since we now force dealing with scope down to the resource.To minimize the amount of code-duplication within kube-client, we could make the methods on
Client
canonical, and makeApi
a more empty shell that defers to these.Less sure what to do about the subresource scope though. That requires some thought.
Target crate for feature
kube-client
Future Ideas
Future things that should be considered later on (open follow-ups):
Implementation Plan
WIP:
Client::get
andClient::list
#1375Client::list
+Client:get
- client_ext forClient::get
andClient::list
#1375Client::delete
+Client::delete_collection
Client::patch
Client::patch_status
+Client::patch_status_namepaced
and decide whether to make a typed variant (so you can take theStatus
object - e.g. Helper struct for `patch_status` with `Patch::Apply` #1465)The text was updated successfully, but these errors were encountered: