use std::sync::Arc;
use async_trait::async_trait;
use k8s_openapi::api::core::v1::ConfigMap;
use kube::runtime::controller::Action;
use kube::runtime::watcher::Config;
use kube::{Api, Client};
use kuberator::cache::{CachingStrategy, StaticApiProvider};
use kuberator::error::Result as KubeResult;
use kuberator::k8s::K8sRepository;
use kuberator::{Context, Reconcile, TryResource};
type MyK8sRepo = K8sRepository<ConfigMap, StaticApiProvider<ConfigMap>>;
struct MyContext {
repo: Arc<MyK8sRepo>,
}
#[async_trait]
impl Context<ConfigMap, MyK8sRepo, StaticApiProvider<ConfigMap>> for MyContext {
fn k8s_repository(&self) -> Arc<MyK8sRepo> {
Arc::clone(&self.repo)
}
fn finalizer(&self) -> &'static str {
"example.kuberator.io/basic-operator"
}
async fn handle_apply(&self, object: Arc<ConfigMap>) -> KubeResult<Action> {
let name = object.try_name()?;
let namespace = object.try_namespace()?;
tracing::info!("ConfigMap {}/{} was created or updated", namespace, name);
Ok(Action::await_change())
}
async fn handle_cleanup(&self, object: Arc<ConfigMap>) -> KubeResult<Action> {
let name = object.try_name()?;
let namespace = object.try_namespace()?;
tracing::info!("ConfigMap {}/{} is being deleted - cleaning up", namespace, name);
Ok(Action::await_change())
}
}
struct MyReconciler {
context: Arc<MyContext>,
crd_api: Api<ConfigMap>,
}
#[async_trait]
impl Reconcile<ConfigMap, MyContext, MyK8sRepo, StaticApiProvider<ConfigMap>> for MyReconciler {
fn destruct(self) -> (Api<ConfigMap>, Config, Arc<MyContext>) {
(self.crd_api, Config::default(), self.context)
}
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(
tracing_subscriber::EnvFilter::try_from_default_env()
.unwrap_or_else(|_| tracing_subscriber::EnvFilter::new("info")),
)
.init();
tracing::info!("Starting Basic Operator");
let client = Client::try_default().await?;
let api_provider = StaticApiProvider::new(client.clone(), vec!["default"], CachingStrategy::Strict);
let k8s_repo = K8sRepository::new(api_provider);
let context = MyContext {
repo: Arc::new(k8s_repo),
};
let reconciler = MyReconciler {
context: Arc::new(context),
crd_api: Api::namespaced(client, "default"),
};
tracing::info!("Watching ConfigMaps in 'default' namespace");
reconciler.start::<futures::future::Ready<()>>(None).await;
Ok(())
}