use super::{BTreeMap, Deserialize, HostPath, Serialize}; pub const DOMAIN_STORE_SCHEMA_ID: &str = "lazaret-domain-store-v2"; pub const LEGACY_DOMAIN_STORE_SCHEMA_ID: &str = "lazaret-domain-store-v1"; pub const STORAGE_CATALOG_SCHEMA_ID: &str = "lazaret-storage-catalog-v1"; pub const DOMAIN_STORE_SCHEMA_VERSION: u32 = 2; pub const LEGACY_DOMAIN_STORE_SCHEMA_VERSION: u32 = 1; pub const STORAGE_CATALOG_SCHEMA_VERSION: u32 = 1; pub const TRUSTED_HOST_CONFIGURATION_SCHEMA_ID: &str = "lazaret-trusted-host-config-v1"; #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct StorageConfigurationV1 { #[serde(default)] pub data_root: Option, } #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct NetworkConfigurationV1 { #[serde(default)] pub default_allow: Vec, #[serde(default)] pub default_deny: Vec, } #[derive(Clone, Copy, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "kebab-case")] pub enum VolumeKind { File, Directory, } #[derive(Clone, Copy, Debug, Default, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] #[serde(rename_all = "kebab-case")] pub enum VolumeAccess { ReadOnly, #[default] ReadWrite, } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct VolumeConfigurationV1 { pub host: String, pub container: String, pub kind: VolumeKind, #[serde(default)] pub access: VolumeAccess, #[serde(default)] pub create: bool, } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct AutoApprovalRuleConfigurationV1 { pub executable: String, #[serde(default)] pub args: Vec, #[serde(default)] pub allow_extra_args: bool, } #[derive(Clone, Debug, Default, Deserialize, Eq, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct EscalationConfigurationV1 { #[serde(default)] pub enabled: bool, #[serde(default)] pub auto_approve: Vec, } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] #[serde(deny_unknown_fields)] pub struct ProfileConfigurationV1 { pub image: String, #[serde(default = "default_isolate_gitignored")] pub isolate_gitignored: bool, #[serde(default)] pub persistent_dirs: Vec, #[serde(default)] pub allow_egress: Vec, #[serde(default)] pub deny_egress: Vec, #[serde(default)] pub env: BTreeMap, #[serde(default)] pub volumes: Vec, #[serde(default)] pub escalation: EscalationConfigurationV1, } const fn default_isolate_gitignored() -> bool { true } #[derive(Clone, Debug, Eq, PartialEq, Serialize)] pub struct TrustedHostConfigurationV1 { #[serde(rename = "schema")] schema_id: String, storage: StorageConfigurationV1, network: NetworkConfigurationV1, profiles: BTreeMap, } impl TrustedHostConfigurationV1 { #[must_use] pub fn schema_id(&self) -> &str { &self.schema_id } #[must_use] pub const fn storage(&self) -> &StorageConfigurationV1 { &self.storage } #[must_use] pub const fn network(&self) -> &NetworkConfigurationV1 { &self.network } #[must_use] pub const fn profiles(&self) -> &BTreeMap { &self.profiles } } impl<'de> Deserialize<'de> for TrustedHostConfigurationV1 { fn deserialize(deserializer: D) -> Result where D: serde::Deserializer<'de>, { #[derive(Deserialize)] #[serde(deny_unknown_fields)] struct Fields { #[serde(rename = "schema")] schema_id: String, #[serde(default)] storage: StorageConfigurationV1, #[serde(default)] network: NetworkConfigurationV1, profiles: BTreeMap, } let fields = Fields::deserialize(deserializer)?; if fields.schema_id != TRUSTED_HOST_CONFIGURATION_SCHEMA_ID { return Err(serde::de::Error::custom( "unknown trusted-host configuration schema", )); } if fields.profiles.is_empty() { return Err(serde::de::Error::custom( "trusted-host configuration has no profiles", )); } Ok(Self { schema_id: fields.schema_id, storage: fields.storage, network: fields.network, profiles: fields.profiles, }) } } #[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub struct EnvironmentReference { pub sandbox_name: String, pub host_name: String, } #[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub struct ResolvedVolume { pub canonical_host_source: HostPath, pub container_path: String, pub kind: VolumeKind, pub access: VolumeAccess, pub create: bool, } #[derive(Clone, Debug, Deserialize, Eq, Ord, PartialEq, PartialOrd, Serialize)] pub struct ResolvedAutoApprovalRule { pub canonical_executable: HostPath, pub args: Vec, pub allow_extra_args: bool, } #[derive(Clone, Debug, Deserialize, Eq, PartialEq, Serialize)] pub struct ConfigurationFingerprintRecordV1 { pub selected_profile: String, pub storage_root: HostPath, pub runtime_root: HostPath, pub image: String, pub isolate_gitignored: bool, pub persistent_dirs: Vec, pub environment_references: Vec, pub volumes: Vec, pub effective_allow_prefixes: Vec<([u8; 4], u8)>, pub effective_deny_prefixes: Vec<([u8; 4], u8)>, pub escalation_enabled: bool, pub auto_approval_rules: Vec, }