use std::collections::BTreeMap; use clusterflux_core::{ AgentId, CredentialKind, Digest, NodeId, ProjectId, SourceProviderKind, TenantId, UserId, }; use serde::{Deserialize, Serialize}; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct TenantRecord { pub id: TenantId, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct UserRecord { pub id: UserId, pub tenant: TenantId, pub credential_kind: CredentialKind, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ProjectRecord { pub id: ProjectId, pub tenant: TenantId, pub name: String, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct NodeIdentityRecord { pub id: NodeId, pub tenant: TenantId, pub project: ProjectId, pub public_key: String, pub enrollment_scope: String, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct CredentialRecord { pub subject: String, pub tenant: TenantId, pub project: Option, pub kind: CredentialKind, pub public_key_fingerprint: Option, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct CliSessionRecord { pub session_digest: Digest, pub tenant: TenantId, pub project: ProjectId, pub user: UserId, pub credential_kind: CredentialKind, pub expires_at_epoch_seconds: Option, pub revoked: bool, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct SourceProviderConfigRecord { pub tenant: TenantId, pub project: ProjectId, pub provider: SourceProviderKind, pub manifest_digest: Digest, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ServicePolicyRecord { pub tenant: TenantId, pub name: String, pub digest: Digest, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct AccountPolicyState { pub account_status: String, pub suspended: bool, pub disabled: bool, pub deleted: bool, pub manual_review: bool, pub sanitized_reason: Option, pub next_actions: Vec, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct ProjectPermissionRecord { pub tenant: TenantId, pub project: ProjectId, pub user: UserId, pub can_debug: bool, } #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] pub struct AgentPublicKeyRecord { pub tenant: TenantId, pub project: ProjectId, pub user: UserId, pub agent: AgentId, pub public_key: String, pub public_key_fingerprint: Digest, pub version: u64, pub revoked: bool, pub scopes: Vec, pub human_account_creation_privilege: bool, pub browser_interaction_required_each_run: bool, } #[derive(Clone, Debug, Default, Serialize, Deserialize)] pub struct DurableState { pub tenants: BTreeMap, pub users: BTreeMap, pub projects: BTreeMap, pub node_identities: BTreeMap, pub credentials: BTreeMap, pub cli_sessions: BTreeMap, pub source_provider_configs: BTreeMap<(TenantId, ProjectId, String), SourceProviderConfigRecord>, pub service_policy_records: BTreeMap<(TenantId, String), ServicePolicyRecord>, pub project_permissions: BTreeMap<(TenantId, ProjectId, UserId), ProjectPermissionRecord>, pub agent_public_keys: BTreeMap<(TenantId, ProjectId, AgentId), AgentPublicKeyRecord>, } pub trait DurableStore { fn load(&self) -> DurableState; fn save(&mut self, state: DurableState); } pub trait FallibleDurableStore { type Error; fn load_state(&mut self) -> Result; fn save_state(&mut self, state: &DurableState) -> Result<(), Self::Error>; } #[derive(Clone, Debug, Default)] pub struct InMemoryDurableStore { state: DurableState, } impl DurableStore for InMemoryDurableStore { fn load(&self) -> DurableState { self.state.clone() } fn save(&mut self, state: DurableState) { self.state = state; } }