Compare commits

...

3 Commits

Author SHA1 Message Date
b9963dcb16
Use compact formatting for tracing if running through cargo
All checks were successful
Build and deploy / Build container and manifests (push) Successful in 7m23s
2025-03-22 04:58:56 +01:00
31354f8a83
Added demo yaml 2025-03-22 04:58:56 +01:00
5a254164cf
Added Group controller (#8) 2025-03-22 04:58:54 +01:00
5 changed files with 44 additions and 18 deletions

View File

@ -4,6 +4,7 @@ use kube::{Resource, ResourceExt};
use crate::lldap::LldapConfig; use crate::lldap::LldapConfig;
#[derive(Clone)]
pub struct Context { pub struct Context {
pub client: kube::Client, pub client: kube::Client,
pub lldap_config: LldapConfig, pub lldap_config: LldapConfig,

View File

@ -42,6 +42,7 @@ fn check_graphql_errors<T>(response: GraphQlResponse<T>) -> Result<T> {
.expect("Data should be valid if there are no error")) .expect("Data should be valid if there are no error"))
} }
#[derive(Clone)]
pub struct LldapConfig { pub struct LldapConfig {
username: String, username: String,
password: String, password: String,

View File

@ -3,30 +3,47 @@ use std::time::Duration;
use futures::StreamExt; use futures::StreamExt;
use k8s_openapi::api::core::v1::Secret; use k8s_openapi::api::core::v1::Secret;
use kube::runtime::Controller; use kube::runtime::controller::{self, Action};
use kube::runtime::controller::Action; use kube::runtime::reflector::ObjectRef;
use kube::{Api, Client as KubeClient}; use kube::runtime::{Controller, watcher};
use kube::{Api, Client as KubeClient, Resource};
use lldap_controller::context::Context; use lldap_controller::context::Context;
use lldap_controller::lldap::LldapConfig; use lldap_controller::lldap::LldapConfig;
use lldap_controller::resources::{self, ServiceUser, reconcile}; use lldap_controller::resources::{self, Error, Group, ServiceUser, reconcile};
use tracing::{debug, info, warn}; use tracing::{debug, info, warn};
use tracing_subscriber::layer::SubscriberExt; use tracing_subscriber::layer::SubscriberExt;
use tracing_subscriber::util::SubscriberInitExt; use tracing_subscriber::util::SubscriberInitExt;
use tracing_subscriber::{EnvFilter, Registry}; use tracing_subscriber::{EnvFilter, Registry};
fn error_policy(_obj: Arc<ServiceUser>, err: &resources::Error, _ctx: Arc<Context>) -> Action { fn error_policy<T>(_obj: Arc<T>, err: &resources::Error, _ctx: Arc<Context>) -> Action {
warn!("error: {}", err); warn!("error: {}", err);
Action::requeue(Duration::from_secs(5)) Action::requeue(Duration::from_secs(5))
} }
async fn log_status<T>(
res: Result<(ObjectRef<T>, Action), controller::Error<Error, watcher::Error>>,
) where
T: Resource,
{
match res {
Ok(obj) => debug!("reconciled {:?}", obj.0.name),
Err(err) => warn!("reconcile failed: {}", err),
}
}
#[tokio::main] #[tokio::main]
async fn main() -> anyhow::Result<()> { async fn main() -> anyhow::Result<()> {
let logger = tracing_subscriber::fmt::layer().json();
let env_filter = EnvFilter::try_from_default_env() let env_filter = EnvFilter::try_from_default_env()
.or_else(|_| EnvFilter::try_new("info")) .or_else(|_| EnvFilter::try_new("info"))
.expect("Fallback should be valid"); .expect("Fallback should be valid");
if std::env::var("CARGO").is_ok() {
let logger = tracing_subscriber::fmt::layer().compact();
Registry::default().with(logger).with(env_filter).init(); Registry::default().with(logger).with(env_filter).init();
} else {
let logger = tracing_subscriber::fmt::layer().json();
Registry::default().with(logger).with(env_filter).init();
}
info!("Starting controller"); info!("Starting controller");
@ -41,17 +58,20 @@ async fn main() -> anyhow::Result<()> {
let service_users = Api::<ServiceUser>::all(client.clone()); let service_users = Api::<ServiceUser>::all(client.clone());
let secrets = Api::<Secret>::all(client.clone()); let secrets = Api::<Secret>::all(client.clone());
Controller::new(service_users.clone(), Default::default()) let service_user_controller = Controller::new(service_users, Default::default())
.owns(secrets, Default::default()) .owns(secrets, Default::default())
.shutdown_on_signal()
.run(reconcile, error_policy, Arc::new(data.clone()))
.for_each(log_status);
let groups = Api::<Group>::all(client.clone());
let group_controller = Controller::new(groups, Default::default())
.shutdown_on_signal() .shutdown_on_signal()
.run(reconcile, error_policy, Arc::new(data)) .run(reconcile, error_policy, Arc::new(data))
.for_each(|res| async move { .for_each(log_status);
match res {
Ok(obj) => debug!("reconciled {:?}", obj.0.name), tokio::join!(service_user_controller, group_controller);
Err(err) => warn!("reconcile failed: {}", err),
}
})
.await;
Ok(()) Ok(())
} }

5
yaml/group.yaml Normal file
View File

@ -0,0 +1,5 @@
apiVersion: lldap.huizinga.dev/v1
kind: Group
metadata:
name: test-group
spec: {}

View File

@ -1,6 +1,5 @@
apiVersion: lldap.huizinga.dev/v1 apiVersion: lldap.huizinga.dev/v1
kind: ServiceUser kind: ServiceUser
metadata: metadata:
name: authelia name: test-user
spec: spec: {}
passwordManager: false