kubus 0.6.0

Derive based kubernetes operator framework
Documentation
use std::fmt::Debug;
use std::sync::Arc;

use kube::api::{Api, Patch, PatchParams};
use kube::{Resource, ResourceExt};
use serde::de::DeserializeOwned;
use serde::ser::Serialize;
use serde_json::json;

async fn patch_object<K>(api: &Api<K>, obj: Arc<K>, patch: serde_json::Value) -> kube::Result<()>
where
    K: Resource + Clone + Debug + Serialize + DeserializeOwned,
{
    api.patch::<K>(
        &obj.meta().name.clone().unwrap(),
        &PatchParams::default(),
        &Patch::Json(serde_json::from_value(patch).unwrap()),
    )
    .await?;

    Ok(())
}

pub async fn apply_finalizer<K>(api: &Api<K>, name: &str, obj: Arc<K>) -> kube::Result<()>
where
    K: Resource + Clone + Debug + Serialize + DeserializeOwned,
{
    let patch = if obj.finalizers().is_empty() {
        json!([
            { "op": "test", "path": "/metadata/finalizers", "value": null },
            { "op": "add", "path": "/metadata/finalizers", "value": [name] }
        ])
    } else {
        json!([
            { "op": "test", "path": "/metadata/finalizers", "value": obj.finalizers() },
            { "op": "add", "path": "/metadata/finalizers", "value": [name] }
        ])
    };

    patch_object(api, obj, patch).await
}

pub async fn remove_finalizer<K>(api: &Api<K>, name: &str, obj: Arc<K>) -> kube::Result<()>
where
    K: Resource + Clone + Debug + Serialize + DeserializeOwned,
{
    let Some(idx) = obj
        .finalizers()
        .iter()
        .enumerate()
        .find(|(_, n)| n == &name)
        .map(|(idx, _)| idx)
    else {
        return Ok(());
    };

    let finalizer_path = format!("/metadata/finalizers/{idx}");

    let patch = json!([
      { "op": "test", "path": finalizer_path, "value": name },
      { "op": "remove", "path": finalizer_path }
    ]);

    patch_object(api, obj, patch).await
}