confium_operator/main.rs
1//! `confium-operator` — Kubernetes operator for Confium threshold
2//! signing ceremonies.
3//!
4//! Watches for `ConfiumSigningCeremony` Custom Resources and
5//! orchestrates the threshold DKG + sign lifecycle. The operator
6//! runs as a Kubernetes Deployment; each ceremony is a CRD instance.
7//!
8//! ## CRD shape
9//!
10//! ```yaml
11//! apiVersion: confium.org/v1alpha1
12//! kind: ConfiumSigningCeremony
13//! metadata:
14//! name: release-v2-signing
15//! spec:
16//! scheme: cmp20
17//! threshold: 3
18//! partyCount: 5
19//! messageRef:
20//! configMap: release-artifact
21//! key: release.tar.gz
22//! outputRef:
23//! secret: release-signature
24//! ```
25//!
26//! ## Status
27//!
28//! Scaffold: the CRD definition + controller loop are defined but
29//! the actual Kubernetes client integration is stubbed. The scaffold
30//! lets teams design their ceremony workflow against a stable API.
31
32#![forbid(unsafe_code)]
33#![allow(missing_docs)] // TODO: document before 1.0
34#![allow(dead_code)] // CRD/controller types not yet wired into the reconcile loop
35
36mod controller;
37mod crd;
38
39use clap::Parser;
40
41#[derive(Parser, Debug)]
42#[command(
43 name = "confium-operator",
44 version,
45 about = "Kubernetes operator for Confium threshold signing"
46)]
47pub struct Args {
48 /// Path to the kubeconfig file. Defaults to in-cluster config.
49 #[arg(long)]
50 pub kubeconfig: Option<String>,
51
52 /// Namespace to watch. Defaults to all namespaces.
53 #[arg(long)]
54 pub namespace: Option<String>,
55
56 /// Run once and exit (don't reconcile loop).
57 #[arg(long)]
58 pub once: bool,
59}
60
61#[tokio::main]
62async fn main() -> anyhow::Result<()> {
63 tracing_subscriber::fmt()
64 .with_env_filter(
65 tracing_subscriber::EnvFilter::try_from_default_env()
66 .unwrap_or_else(|_| "confium_operator=info".into()),
67 )
68 .init();
69
70 let args = Args::parse();
71 tracing::info!("starting confium-operator");
72
73 let controller = controller::CeremonyController::new(args.namespace.clone());
74
75 if args.once {
76 controller.reconcile_once().await?;
77 } else {
78 controller.run().await?;
79 }
80
81 Ok(())
82}