-
-
Notifications
You must be signed in to change notification settings - Fork 323
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
Change Resource trait #486
Conversation
MikailBag
commented
Apr 2, 2021
- add a meta_mut method for mutable access to the metadata
- move some methods to ResourceExt trait
- add a meta_mut method for mutable access to the metadata - move some methods to ResourceExt trait
kube/src/api/metadata.rs
Outdated
/// when resource was received from the apiserver. | ||
/// Because of `.metadata.generateName` field, in other contexts name | ||
/// may be missing. | ||
fn expect_name(&self) -> 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.
Maybe name_unchecked
?
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 was going to advocate for hiding it like we did before, but after testing it against quick generateName
variants, and seeing that it's a common thing (and not just an api wart that could have been an admission controller), we kind of have to deal with it.
The response back when you create withgenerateName
does not havemetadata.name
The first ADDED event from watch withgenerateName
does not havemetadata.name
(so our runtime machinery can crash pretty quickly, will find a minimal case and open a bug)
EDIT: i might be wrong, unwrap was on something else, actually cannot reproduce the missing name 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.
I think this is a very good way forward. Thank you for this.
I think the trait can cover more of ObjectMeta's foundational types, and I think kazk's naming makes more sense.
Also think we should be using o.name_unchecked()
over ResourceExt::name_unchecked(&o)
in examples insofar as it's possible.
|
||
fn resource_ver(&self) -> Option<String> { | ||
self.meta().resource_version.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 we can have a lot more helpers in here if we are uncoupling the more foundational Resource
trait, with a more user-friendly one.
This should be a helper trait for dealing with ObjectMeta
, it needs to cover at least the basics: stuff like, labels, annotations, ownerrefs, finalizers, managedfields, where we can unpack optional vectors into empty vectors.
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 will add labels, annotations, ownerrefs, and annotations (getters and setters), and also getter for UID.
I don't think we should add managedfields to the trait - AFAIU one does not need to look at .metadata.managedFields
or modify it unless one is writing an alternative apiserver implementation.
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.
ok, fair point on managedFields
.
btw, i am not sure about setters, because most of the time people change metadata fields with apply
patches, or more awkward json patches, and setters kind of encourage use of api.replace
which is awkward, and can run into idempotency issues.
i think maybe some patchbuilder utils for changing metadata fields might be more appropriate.
} | ||
|
||
fn labels_mut(&mut self) -> &mut BTreeMap<String, String> { | ||
self.meta_mut().labels.get_or_insert_with(BTreeMap::new) |
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.
oh, actually, this is a really nice use of get_or_insert_with
!
yeah, I like these mut accessors.
I've reproduced CI failure locally: deployment does not have |
I'll fix up the CI later in the week. Thanks for the diagnosis. The only thing left here is whether or not to call it |
On the other hand, a resource instance can be constructed by the application, and in this case, it can have For example, following code will panic: let p = Pod {spec: make_pod_spec(), ..Default::default()}
println!("{}", p.name()); That's why I have initially decided to guard against such panics. However, I understand this makes API less ergonomic, and this mistake is not too easy to make. Given that this is just a helper function, it really makes sense to allow panicking, so I'm going to rename Ideally, it should be separated at type level, but it requires serious changes to |
Ah, interesting! Yeah, that makes it a bit more ambiguous. It's not like it's even invalid to not have a name, it's just invalid to not have both. Alternatively, we could sidestep the issue by having |
While such a fallback feels natural, I'm afraid it can be too surprising. So now my proposal is to keep current behavior (i.e. panicking name() function) and leave better type safety as a future extension. |
Released in 0.53.0. |