1pub mod audit;
7pub mod credentials;
8pub mod providers;
9pub mod tenants;
10pub mod tokens;
11
12use std::sync::Arc;
13use std::time::{SystemTime, UNIX_EPOCH};
14
15pub use audit::{AuditSink, FileAudit, InMemoryAudit, TracingAudit};
16pub use credentials::{CredentialStore, InMemoryCredentials, Secret};
17pub use providers::{
18 CachingCredentials, CredentialProvider, EksGetTokenProvider, GitHubAppProvider, MintedSecret,
19 pkcs8_from_pem, spawn_refresher,
20};
21pub use tenants::Tenants;
22pub use tokens::{SigV4Mint, Tokens};
23
24pub fn now_ms() -> u64 {
27 SystemTime::now()
28 .duration_since(UNIX_EPOCH)
29 .map_or(0, |d| d.as_millis() as u64)
30}
31
32pub struct ControlPlane {
36 pub tokens: Tokens,
37 pub tenants: Tenants,
38 pub credentials: Arc<dyn CredentialStore>,
39 pub audit: Arc<dyn AuditSink>,
40}
41
42impl ControlPlane {
43 pub fn new(credentials: Arc<dyn CredentialStore>, audit: Arc<dyn AuditSink>) -> Self {
45 Self {
46 tokens: Tokens::new(),
47 tenants: Tenants::new(),
48 credentials,
49 audit,
50 }
51 }
52
53 pub fn with_defaults() -> (Self, Arc<InMemoryCredentials>) {
57 let credentials = Arc::new(InMemoryCredentials::new());
58 let plane = Self::new(credentials.clone(), Arc::new(TracingAudit));
59 (plane, credentials)
60 }
61}
62
63#[cfg(test)]
64#[allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)]
65mod tests {
66 use super::*;
67
68 #[test]
69 fn now_ms_is_nonzero() {
70 assert!(now_ms() > 0);
71 }
72
73 #[test]
74 fn with_defaults_wires_components() {
75 let (plane, creds) = ControlPlane::with_defaults();
76 creds.insert("github-app", Secret::new("tok"));
77 assert!(plane.credentials.resolve("github-app").is_some());
78 }
79}