-
-
Notifications
You must be signed in to change notification settings - Fork 319
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
Add Resource
derive macro
#1565
Conversation
3219445
to
6072a33
Compare
Hey, this is a cool idea. As a quick first impression, I think it makes sense, although it does not necessarily save much in terms of user code since custom structs can re-use type information with the dynamic api: Lines 25 to 28 in 7ff120a
However, there's a reasonable argument for this in terms of complexity, by being able to just use the normal (non-dynamic api) and not have to learn about concepts of erasure. |
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #1565 +/- ##
=======================================
- Coverage 75.4% 75.3% -0.1%
=======================================
Files 80 82 +2
Lines 7284 7323 +39
=======================================
+ Hits 5489 5511 +22
- Misses 1795 1812 +17
|
a51d872
to
dae2ffa
Compare
Yes, agree, I felt that this is explored area already, but at the moment of writing this model looked natural to me. I believe |
Hmm, I actually tried using it with similar to let secret_api: Api<CertSecret> = Api::namespaced_with(
ctx.client.clone(),
"cattle-fleet-system",
ApiResource::erase::<Secret>(&()),
); and got:
Since the secret follows different model - |
8a3c468
to
85ec5af
Compare
hm, yeah. you'd actually have to use the dynamic api fully for the non-compliant core objects with let secret_api: Api<DynamicObject> = Api::namespaced_with(
ctx.client.clone(),
"cattle-fleet-system",
ApiResource::erase::<Secret>(&()),
); which means secondary |
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.
couple of minor comments. i like this, particularly after realising the dynamic api is very limited for known types. i do think we can improve the ergonomics a little bit.
(also i am not 100% sure about the name, but we can bikeshed that later)
Allows to generate Resource trait implementation for types which proxy another type internally. ConfigMaps and Secrets can be strictly typed on the client side. While using DeserializeGuard, resources can be listed and watched, skipping invalid resources. Signed-off-by: Danil-Grigorev <[email protected]>
85ec5af
to
21bae5e
Compare
- Display usage in errorbounded CM watcher Signed-off-by: Danil-Grigorev <[email protected]>
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.
two naming two minor naming things
Signed-off-by: Danil-Grigorev <[email protected]>
Signed-off-by: Danil-Grigorev <[email protected]>
Signed-off-by: Danil-Grigorev <[email protected]>
ResourceInherit
derive macroResource
derive macro
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.
minor comments on new example
let _ca: ConfigMap = client | ||
.get("kube-root-ca.crt", &Namespace::from(ns.name_any())) | ||
.await?; | ||
let _ca: CaConfigMapManual = client | ||
.get("kube-root-ca.crt", &Namespace::from(ns.name_any())) | ||
.await?; | ||
let ca: CaConfigMap = client | ||
.get("kube-root-ca.crt", &Namespace::from(ns.name_any())) | ||
.await?; |
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 a helper comment here:
let _ca: ConfigMap = client | |
.get("kube-root-ca.crt", &Namespace::from(ns.name_any())) | |
.await?; | |
let _ca: CaConfigMapManual = client | |
.get("kube-root-ca.crt", &Namespace::from(ns.name_any())) | |
.await?; | |
let ca: CaConfigMap = client | |
.get("kube-root-ca.crt", &Namespace::from(ns.name_any())) | |
.await?; | |
for namespace in namespaces { | |
let ns = Namespace::from(namespace); | |
// Equivalent ways to GET using different structs and different Resource impls | |
let _ca: ConfigMap = client.get("kube-root-ca.crt", &ns).await?; | |
let _ca: CaConfigMapManual = client.get("kube-root-ca.crt", &ns).await?; | |
let ca: CaConfigMap = client.get("kube-root-ca.crt", &ns).await?; |
Signed-off-by: Danil-Grigorev <[email protected]>
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.
last minor nit
Signed-off-by: Danil-Grigorev <[email protected]>
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.
Looks great. Thank you so much!
Motivation
When working with
ConfigMap
data, it is often expected to have a specific data structure on the inner content. While defining a CRD is the standard way of resolving the fields validation, it is sometimes not possible or desirable at the moment.This generally requires a manual conversion via
serde
, which involves creating a custom structure for thedata
content, which is only one field away from being a fully replicatedConfigMap
orSecret
definition (in the context of the problem).Choosing this direction may require implementing
Resource
trait manually, which adds to the amount of glue code.Solution
Provide a
Resource
derive macro, capable of inheritingResource
trait implementation of the specified upstream object.The resulting code can look like the following: