Skip to content
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

Get referenced obj using dynamic GVK API #1

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 19 additions & 2 deletions knative/src/duck/v1/knative_reference.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
use crate::error::Error;
use k8s_openapi::api::core::v1::ObjectReference;
use kube::{
api::{DynamicObject, GroupVersionKind},
core::object,
discovery, Api, ResourceExt,
};
use schemars::JsonSchema;
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -42,8 +47,20 @@ impl Into<ObjectReference> for KReference {
}

impl KReference {
pub fn resolve_uri(&self, _client: kube::Client) -> Result<url::Url, Error> {
let _object_reference: ObjectReference = self.clone().into();
pub async fn resolve_uri(
&self,
client: kube::Client,
) -> Result<url::Url, Box<dyn std::error::Error>> {
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be nice to keep our error model in-line with kube's by sticking with thiserror wrappers of Error.

If we add a Variant to knative error with a #[from] kube-client::Error then it will automatically implement TryFrom which gives us back ? operator without resorting to Box<dyn std::error::Error>. We may need to drop Clone and Copy derives, but that's ok!

Our error can look like this:

use kube::error::Error as KubeError;

#[derive(Error, Debug)]
pub enum Error {
    /// Discovery errors
    #[error("Error from discovery: {0}")]
    Discovery(#[source] DiscoveryError),
    /// Kube errors
    #[error("Error from kube: {0}")]
    KubeError(#[from] KubeError),
}

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Also, the Discovery Variant is admittedly not very thought out. Feel free to scratch or rework it when we add the actual Errors that can occur during KReference uri resolution!

// let object_reference: ObjectReference = self.clone().into();
let gvk = GroupVersionKind::gvk(
self.group.as_ref().unwrap(),
self.api_version.as_ref().unwrap(),
self.kind.as_ref(),
);
let (ar, _caps) = discovery::pinned_kind(&client, &gvk).await?;
let api: Api<DynamicObject> = Api::all_with(client.clone(), &ar);
let _obj = api.get(self.name.as_ref()).await?;
// TODO: into duckv1.AddressableType is not implemented yet.
unimplemented!("see knative.dev/pkg/resolver/addressable_resolver.go")
}
}
27 changes: 16 additions & 11 deletions knative/src/duck/v1/source_types.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
#![allow(dead_code)]
use super::{
knative_reference::KReference,
status_types::{
ConditionStatus, ConditionType, Status,
},
status_types::{ConditionStatus, ConditionType, Status},
};
use crate::error::{DiscoveryError, Error};
use kube::CustomResource;
Expand Down Expand Up @@ -52,14 +50,14 @@ impl From<KReference> for Destination {
(Some(api_version), _) if api_version.contains("/") => Some(api_version),
(Some(api_version), Some(group)) => Some(group + "/" + &api_version),
(Some(api_version), None) => Some(api_version),
(None, _) => None
(None, _) => None,
},
group: None,
kind: reference.kind,
namespace: reference.namespace,
name: reference.name
name: reference.name,
}),
uri: None
uri: None,
}
}
}
Expand All @@ -68,20 +66,23 @@ impl From<url::Url> for Destination {
fn from(uri: url::Url) -> Self {
Destination {
ref_: None,
uri: Some(uri)
uri: Some(uri),
}
}
}

impl Destination {
pub fn resolve_uri(&self, client: kube::Client) -> Result<url::Url, Error> {
pub async fn resolve_uri(
&self,
client: kube::Client,
) -> Result<url::Url, Box<dyn std::error::Error>> {
match (&self.ref_, &self.uri) {
(Some(ref ref_), _) => {
let url = ref_.resolve_uri(client)?;
let url = ref_.resolve_uri(client).await?;
Ok(url)
}
(None, Some(ref uri)) => Ok(uri.clone()),
(None, None) => Err(Error::Discovery(DiscoveryError::EmptyDestination))
(None, None) => Err(Box::new(Error::Discovery(DiscoveryError::EmptyDestination))),
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can remove the box once we add the kube::Error Variant to our error

}
}
}
Expand Down Expand Up @@ -152,7 +153,11 @@ impl SourceStatus {
pub fn mark_no_sink(&mut self, reason: &str, message: String) {
self.sink_uri = None;
if let Some(ref mut cond) = &mut self.status.conditions {
cond.mark_false(ConditionType::SinkProvided, reason.to_string(), Some(message))
cond.mark_false(
ConditionType::SinkProvided,
reason.to_string(),
Some(message),
)
}
}
}
Expand Down