-
Notifications
You must be signed in to change notification settings - Fork 41
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
Improve Name and Namespace optionality #134
Comments
First, is there any resource type for which Second, the third and fourth versions still have The real problem is that creating a resource might have For example, a more accurate representation would be to replace enum ObjectMetaName {
Name { inner: String },
Generated { prefix: String },
}
struct ObjectMeta {
name: ObjectMetaName,
...
} But this still has the issue as Instead of an enum we could have separate types determined by a type parameter:
Then |
I feel splitting On the |
Some background maybe; we're currently having a debate in our team because I want to add: pub trait NamespaceUnchecked {
fn namespace_unchecked(&self) -> String;
}
impl<K: kube::Resource<Scope = k8s_openapi::NamespaceResourceScope>> NamespaceUnchecked for K {
fn namespace_unchecked(&self) -> String {
#[allow(clippy::expect_used)]
self.meta()
.namespace
.clone()
.expect(".metadata.namespace missing")
}
} While other team members want to go the other way and remove all references to Obviously I'm largely on the side of "just use the unchecked stuff, it will never error"; but it is slightly nasty to have code that potentially could (it won't, be it technically could) throw an exception littered around the code base. It feels like it sort of breaks that contract of safety that Rust usually offers. It looks like |
yeah, for sure this is awkward. We could maybe have a |
Ideally I'd prefer not to have to handle a result once I have an object from the API, I know it has a As @Arnavion states the real problem is that the types you put into Kubernetes is subtly different to the type you get out of Kubernetes ... so maybe they really are just different types? As an alternative to making every type take a generic, would it be horrible to simply have two versions of every type? e.g. // Not convinced by the name `create` maybe `pending` or `pre`?
mod create {
struct Pod {
metadata: ObjectMetaCreate,
...
}
mod read {
struct Pod {
metadata: ObjectMetaRead,
...
}
}
impl TryFrom<crate::Pod> for read::Pod {
...
} This adds a complexity to code generation, and to importing, but then accurately represents the type model from Kubernetes. This could also potentially not export both types by default and hide the Or on the idea of an enum type for I must admit on the |
well, it's really just apiserver bugs you are catering for. you can unwrap, or you can propagate the error to whatever upstream thing you have via
yes, it does feel like that, but we have no guarantee on what upstream wants to evolve their naming conveniences to, and it's architecting ourselves into a corner by assuming invariants that upstream is not beholden to (and if you've listened in on sig apimachinery they do still propose generic metadata changes).
yeah, you are kind of describing ApplyConfigurations (variants where everything is optional so that it's easy to construct and use with server-side apply. See kube-rs/kube#649 for some context and links. TL;DR: it makes it easier to use created structs, but it does not make it more ergonomic to deal with optionals from the apiserver. Their schema is ultimately as open as they say it is. |
For One problem is that determining the scope of the resource happens while emitting its operations using the operation URLs, but the field needs to be known before-hand when the struct definition is emitted, or ideally even before that at spec fixup time so that the generator itself doesn't need to change the metadata type based on the scope. I'm still trying to think of a nice way to write the code that doesn't require duplicating the logic for determining the scope. |
Having
.metadata.name
and.metadata.namespace
as optional causes us headaches all over our code. We either have to decideunwrap
because we know the value will be there, or implementResult
for the case of a missing value that will never be missing.In reality a Kubernetes object without a name (baring the edge case of asking Kubernetes to generate the name) is invalid; likewise a namespace scoped Kubernetes object without a namespace is invalid. As mentioned above this means unnecessary error handle, and allows the creation of resources without a
name
and/ornamespace
which appear to be perfectly valid until you attempt to submit them to Kubernetes.I propose that there should be four versions of
ObjectMeta
to cover the valid cases and simplify the 99% usage cases.For namespaced resources:
For cluster resources:
For namespaced resources which can take
generate_name
Alternatively each resource could generate its own version of
ObjectMeta
which is valid and correct for that resource.The text was updated successfully, but these errors were encountered: