Moved ServiceUser into separate file
This commit is contained in:
parent
f085bf1088
commit
13ddc853fb
75
src/resources/mod.rs
Normal file
75
src/resources/mod.rs
Normal file
|
@ -0,0 +1,75 @@
|
||||||
|
mod service_user;
|
||||||
|
|
||||||
|
use core::fmt;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
|
use async_trait::async_trait;
|
||||||
|
use k8s_openapi::NamespaceResourceScope;
|
||||||
|
use kube::runtime::controller::Action;
|
||||||
|
use kube::runtime::finalizer;
|
||||||
|
use kube::{Api, Resource, ResourceExt};
|
||||||
|
use serde::de::DeserializeOwned;
|
||||||
|
use serde::Serialize;
|
||||||
|
use tracing::{debug, instrument};
|
||||||
|
|
||||||
|
use crate::context::Context;
|
||||||
|
use crate::lldap;
|
||||||
|
|
||||||
|
pub use service_user::ServiceUser;
|
||||||
|
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Failed to commit: {0}")]
|
||||||
|
Commit(#[from] kube::api::entry::CommitError),
|
||||||
|
#[error("Kube api error: {0}")]
|
||||||
|
Kube(#[from] kube::Error),
|
||||||
|
#[error("LLDAP error: {0}")]
|
||||||
|
Lldap(#[from] lldap::Error),
|
||||||
|
#[error("Finalizer error: {0}")]
|
||||||
|
Finalizer(#[source] Box<finalizer::Error<Self>>),
|
||||||
|
#[error("MissingObjectKey: {0}")]
|
||||||
|
MissingObjectKey(&'static str),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl From<finalizer::Error<Self>> for Error {
|
||||||
|
fn from(error: finalizer::Error<Self>) -> Self {
|
||||||
|
Self::Finalizer(Box::new(error))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
type Result<T, E = Error> = std::result::Result<T, E>;
|
||||||
|
|
||||||
|
#[async_trait]
|
||||||
|
trait Reconcile {
|
||||||
|
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
||||||
|
|
||||||
|
async fn cleanup(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[instrument(skip(obj, ctx))]
|
||||||
|
pub async fn reconcile<T>(obj: Arc<T>, ctx: Arc<Context>) -> Result<Action>
|
||||||
|
where
|
||||||
|
T: Resource<Scope = NamespaceResourceScope>
|
||||||
|
+ ResourceExt
|
||||||
|
+ Clone
|
||||||
|
+ Serialize
|
||||||
|
+ DeserializeOwned
|
||||||
|
+ fmt::Debug
|
||||||
|
+ Reconcile,
|
||||||
|
<T as Resource>::DynamicType: Default,
|
||||||
|
{
|
||||||
|
debug!(name = obj.name_any(), "Reconcile");
|
||||||
|
|
||||||
|
let namespace = obj.namespace().expect("Resource is namespace scoped");
|
||||||
|
let service_users = Api::<T>::namespaced(ctx.client.clone(), &namespace);
|
||||||
|
|
||||||
|
Ok(
|
||||||
|
finalizer(&service_users, &ctx.controller_name, obj, |event| async {
|
||||||
|
match event {
|
||||||
|
finalizer::Event::Apply(obj) => obj.reconcile(ctx.clone()).await,
|
||||||
|
finalizer::Event::Cleanup(obj) => obj.cleanup(ctx.clone()).await,
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.await?,
|
||||||
|
)
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
use core::fmt;
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::str::from_utf8;
|
use std::str::from_utf8;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -8,43 +7,19 @@ use async_trait::async_trait;
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use k8s_openapi::api::core::v1::Secret;
|
use k8s_openapi::api::core::v1::Secret;
|
||||||
use k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference;
|
use k8s_openapi::apimachinery::pkg::apis::meta::v1::OwnerReference;
|
||||||
use k8s_openapi::NamespaceResourceScope;
|
|
||||||
use kube::api::{ObjectMeta, Patch, PatchParams, PostParams};
|
use kube::api::{ObjectMeta, Patch, PatchParams, PostParams};
|
||||||
use kube::runtime::controller::Action;
|
use kube::runtime::controller::Action;
|
||||||
use kube::runtime::finalizer;
|
use kube::{Api, CustomResource, Resource};
|
||||||
use kube::{Api, CustomResource, Resource, ResourceExt};
|
|
||||||
use passwords::PasswordGenerator;
|
use passwords::PasswordGenerator;
|
||||||
use schemars::JsonSchema;
|
use schemars::JsonSchema;
|
||||||
use serde::de::DeserializeOwned;
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use serde_json::json;
|
use serde_json::json;
|
||||||
use tracing::{debug, instrument, trace, warn};
|
use tracing::{debug, trace, warn};
|
||||||
|
|
||||||
|
use super::{Error, Reconcile, Result};
|
||||||
use crate::context::{Context, ControllerEvents};
|
use crate::context::{Context, ControllerEvents};
|
||||||
use crate::lldap;
|
use crate::lldap;
|
||||||
|
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Failed to commit: {0}")]
|
|
||||||
Commit(#[from] kube::api::entry::CommitError),
|
|
||||||
#[error("Kube api error: {0}")]
|
|
||||||
Kube(#[from] kube::Error),
|
|
||||||
#[error("LLDAP error: {0}")]
|
|
||||||
Lldap(#[from] lldap::Error),
|
|
||||||
#[error("Finalizer error: {0}")]
|
|
||||||
Finalizer(#[source] Box<finalizer::Error<Self>>),
|
|
||||||
#[error("MissingObjectKey: {0}")]
|
|
||||||
MissingObjectKey(&'static str),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<finalizer::Error<Self>> for Error {
|
|
||||||
fn from(error: finalizer::Error<Self>) -> Self {
|
|
||||||
Self::Finalizer(Box::new(error))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type Result<T, E = Error> = std::result::Result<T, E>;
|
|
||||||
|
|
||||||
#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
|
#[derive(CustomResource, Deserialize, Serialize, Clone, Debug, JsonSchema)]
|
||||||
#[kube(
|
#[kube(
|
||||||
kind = "ServiceUser",
|
kind = "ServiceUser",
|
||||||
|
@ -97,41 +72,6 @@ fn new_secret(username: &str, oref: OwnerReference) -> Secret {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[async_trait]
|
|
||||||
trait Reconcile {
|
|
||||||
async fn reconcile(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
|
||||||
|
|
||||||
async fn cleanup(self: Arc<Self>, ctx: Arc<Context>) -> Result<Action>;
|
|
||||||
}
|
|
||||||
|
|
||||||
#[instrument(skip(obj, ctx))]
|
|
||||||
pub async fn reconcile<T>(obj: Arc<T>, ctx: Arc<Context>) -> Result<Action>
|
|
||||||
where
|
|
||||||
T: Resource<Scope = NamespaceResourceScope>
|
|
||||||
+ ResourceExt
|
|
||||||
+ Clone
|
|
||||||
+ Serialize
|
|
||||||
+ DeserializeOwned
|
|
||||||
+ fmt::Debug
|
|
||||||
+ Reconcile,
|
|
||||||
<T as Resource>::DynamicType: Default,
|
|
||||||
{
|
|
||||||
debug!(name = obj.name_any(), "Reconcile");
|
|
||||||
|
|
||||||
let namespace = obj.namespace().expect("Resource is namespace scoped");
|
|
||||||
let service_users = Api::<T>::namespaced(ctx.client.clone(), &namespace);
|
|
||||||
|
|
||||||
Ok(
|
|
||||||
finalizer(&service_users, &ctx.controller_name, obj, |event| async {
|
|
||||||
match event {
|
|
||||||
finalizer::Event::Apply(obj) => obj.reconcile(ctx.clone()).await,
|
|
||||||
finalizer::Event::Cleanup(obj) => obj.cleanup(ctx.clone()).await,
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.await?,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn format_username(name: &str, namespace: &str) -> String {
|
fn format_username(name: &str, namespace: &str) -> String {
|
||||||
format!("{name}.{namespace}")
|
format!("{name}.{namespace}")
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user