Skip to content

[Merged by Bors] - Expose Client::get_opt using Api::get_opt #451

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

Closed
wants to merge 2 commits into from
Closed
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
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,15 @@ All notable changes to this project will be documented in this file.

- Cluster resources can be added to a struct which determines the orphaned
resources and deletes them ([#436]).
- Added `Client::get_opt` for trying to get an object that may not exist ([#451]).

### Changed

- BREAKING: The `managed_by` label must be passed explicitly to the
`ObjectMetaBuilder::with_recommended_labels` function ([#436]).

[#436]: https://github.com/stackabletech/operator-rs/pull/436
[#451]: https://github.com/stackabletech/operator-rs/pull/451

## [0.23.0] - 2022-07-26

Expand Down
33 changes: 21 additions & 12 deletions src/client.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::error::{Error, OperatorResult};
use crate::error::OperatorResult;
use crate::label_selector;

use backoff::backoff::Backoff;
Expand All @@ -9,7 +9,6 @@ use k8s_openapi::apimachinery::pkg::apis::meta::v1::LabelSelector;
use kube::api::{DeleteParams, ListParams, Patch, PatchParams, PostParams, Resource, ResourceExt};
use kube::client::Client as KubeClient;
use kube::core::Status;
use kube::error::ErrorResponse;
use kube::runtime::WatchStreamExt;
use kube::{Api, Config};
use serde::de::DeserializeOwned;
Expand Down Expand Up @@ -78,12 +77,26 @@ impl Client {
Ok(self.get_api(namespace).get(resource_name).await?)
}

/// Retrieves a single instance of the requested resource type with the given name, if it exists.
pub async fn get_opt<T>(
&self,
resource_name: &str,
namespace: Option<&str>,
) -> OperatorResult<Option<T>>
where
T: Clone + Debug + DeserializeOwned + Resource,
<T as Resource>::DynamicType: Default,
{
Ok(self.get_api(namespace).get_opt(resource_name).await?)
}

/// Returns Ok(true) if the resource has been registered in Kubernetes, Ok(false) if it could
/// not be found and Error in any other case (e.g. connection to Kubernetes failed in some way).
/// Kubernetes does not offer a pure exists check. Therefore we currently use the get() method
/// and ignore the (in case of existing) returned resource. We should replace this with a pure
/// exists method as soon as it becomes available (e.g. only returning Ok/Success) to reduce
/// network traffic.
#[deprecated(since = "0.24.0", note = "Replaced by `get_opt`")]
pub async fn exists<T>(
&self,
resource_name: &str,
Expand All @@ -93,14 +106,9 @@ impl Client {
T: Clone + Debug + DeserializeOwned + Resource,
<T as Resource>::DynamicType: Default,
{
let resource: OperatorResult<T> = self.get(resource_name, namespace).await;
match resource {
Ok(_) => Ok(true),
Err(Error::KubeError {
source: kube::error::Error::Api(ErrorResponse { reason, .. }),
}) if reason == "NotFound" => Ok(false),
Err(err) => Err(err),
}
self.get_opt::<T>(resource_name, namespace)
.await
.map(|obj| obj.is_some())
}

/// Retrieves all instances of the requested resource type.
Expand Down Expand Up @@ -373,9 +381,10 @@ impl Client {
self.delete(&resource).await?;

loop {
if !self
.exists::<T>(&resource.name_any(), resource.namespace().as_deref())
if self
.get_opt::<T>(&resource.name_any(), resource.namespace().as_deref())
.await?
.is_none()
{
return Ok(());
}
Expand Down