-
What I'm trying to achieve is that given a Pod, I want to find its topmost owner, and return something like that: struct Owner {
pub kind: String,
pub name: String,
pub namespace: String,
} I already have a method that checks if a resource has an owner, and if not, returns the current resource as the "owner": async fn get_owner<K>(agent: &Agent, res: &K) -> Owner
where
K: ResourceExt<DynamicType = ()>,
K::DynamicType: Default,
{
match res.owner_references() {
[] => Owner {
kind: K::kind(&()).to_string(),
name: res.name_unchecked(),
namespace: res.namespace().unwrap(),
},
[owner] => todo!("This bit here bothers me"),
_ => panic!("More than one owner found!"),
}
} Now the
|
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
I have an almost-compiling version: async fn owner_for_reference(
agent: &Agent,
ns: &str,
owner_reference: &OwnerReference,
) -> DynamicObject {
let gvk = GroupVersion::from_str(&owner_reference.api_version)
.unwrap()
.with_kind(&owner_reference.kind);
let (resource, _) = Discovery::new(agent.client.clone())
.resolve_gvk(&gvk)
.unwrap();
let api: Api<DynamicObject> = Api::namespaced_with(agent.client.clone(), ns, &resource);
api.get(&owner_reference.name).await.unwrap()
} that doesn't work however due to |
Beta Was this translation helpful? Give feedback.
-
Ah, I figured it out: First, since the only thing that prompted me to use that trait GetKind {
fn kind(&self) -> String;
}
impl GetKind for Pod {
fn kind(&self) -> String {
<Pod as Resource>::kind(&()).to_string()
}
}
impl GetKind for DynamicObject {
fn kind(&self) -> String {
self.types.as_ref().unwrap().kind.clone()
}
} I tried making it more generic but got conflicting implementations, so I just implemented it for concrete types I knew I was gonna need. Next, generic resources can be queried using async fn owner_for_reference(
agent: &Agent,
ns: &str,
owner_reference: &OwnerReference,
) -> DynamicObject {
let gvk = GroupVersion::from_str(&owner_reference.api_version)
.unwrap()
.with_kind(&owner_reference.kind);
let (resource, _) = Discovery::new(agent.client.clone())
.run()
.await
.unwrap()
.resolve_gvk(&gvk)
.unwrap();
let api: Api<DynamicObject> = Api::namespaced_with(agent.client.clone(), ns, &resource);
println!(
"GET {} / {} / {}",
owner_reference.kind, ns, owner_reference.name
);
api.get(&owner_reference.name).await.unwrap()
} (yes I realize the client is doing discovery for every single resource. Its terribly slow.) And then the last bit missing was that recursively calling fn get_owner<'a, K>(
agent: &'a Agent,
res: &'a K,
) -> Pin<Box<dyn Future<Output = Owner> + Send + 'a>>
where
K: ResourceExt + GetKind + Sync,
{
Box::pin(async move {
match res.owner_references() {
[] => Owner {
kind: res.kind(),
name: res.name_unchecked(),
namespace: res.namespace().unwrap(),
},
[owner] => {
let res =
owner_for_reference(agent, res.namespace().as_ref().unwrap(), owner).await;
get_owner(agent, &res).await
}
_ => panic!("More than one owner found!"),
}
})
} |
Beta Was this translation helpful? Give feedback.
-
You can also use kube/kube-client/src/client/client_ext.rs Line 326 in da44dd0 |
Beta Was this translation helpful? Give feedback.
Ah, I figured it out:
First, since the only thing that prompted me to use that
DynamicType = ()
bound in the first place was determining the object's kind, so I moved that to a separate trait:I tried making it more generic but got conflicting implementations, so I just implemented it for concrete types I knew I was gonna need.
Next, generic resources can be queried using
Discovery
andDynamicObject
: