use super::*;
pub const PLACEMENT_DOMAIN_LOCAL_DISK: &str = "local-disk";
pub const PLACEMENT_DOMAIN_LOCAL_NODE: &str = "local-node";
pub const PLACEMENT_DOMAIN_RACK: &str = "rack";
pub const PLACEMENT_DOMAIN_ZONE: &str = "zone";
pub const PLACEMENT_DOMAIN_REGION: &str = "region";
const PLACEMENT_DOMAIN_CAPABILITIES: &[&str] = &[
"disk-placement",
"node-placement",
"rack-placement",
"zone-placement",
"region-placement",
"failure-domain",
"affinity",
"anti-affinity",
"native-support-state",
"semantic-parity",
"configuration-admin-surface",
"security-governance-impact",
"observability-evidence",
"failure-mode-behavior",
"validation-test-coverage",
"product-specific-caveats",
];
const PLACEMENT_DOMAIN_CAVEATS: &[&str] = &[
"BucketWarden supports deterministic local disk and local node placement metadata for runtime proof.",
"Rack, zone, and region placement are tracked but fail closed outside the current single-runtime boundary.",
"Affinity and anti-affinity are validated as placement policy metadata before placement decisions are accepted.",
"Placement-domain proof is local runtime behavior and does not claim Kubernetes, cloud-region, rack-aware, or multi-node scheduling semantics.",
];
const PLACEMENT_DOMAIN_FAILURE_MODES: &[&str] = &[
"unsupported-domain-rejected",
"invalid-affinity-policy-rejected",
"conflicting-affinity-anti-affinity-rejected",
"out-of-bound-region-zone-rack-rejected",
];
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct PlacementDomainSupportEntry {
pub domain: &'static str,
pub native_support: bool,
pub semantic_parity: &'static str,
pub failure_domain: &'static str,
pub affinity_behavior: &'static str,
pub failure_mode: &'static str,
pub caveat: &'static str,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct PlacementDomainSupportReport {
pub active_profile: &'static str,
pub supported_domains: Vec<&'static str>,
pub unsupported_domains: Vec<&'static str>,
pub default_failure_domain: &'static str,
pub affinity_policy: &'static str,
pub capabilities: Vec<&'static str>,
pub failure_modes: Vec<&'static str>,
pub caveats: Vec<&'static str>,
pub entries: Vec<PlacementDomainSupportEntry>,
}
#[derive(Clone, Debug, Default, Eq, PartialEq, Serialize)]
pub struct PlacementPolicy {
pub domain: String,
pub disk_id: Option<String>,
pub node_id: Option<String>,
pub rack_id: Option<String>,
pub zone_id: Option<String>,
pub region_id: Option<String>,
pub affinity_group: Option<String>,
pub anti_affinity_groups: Vec<String>,
}
#[derive(Clone, Debug, Eq, PartialEq, Serialize)]
pub struct PlacementDecision {
pub domain: String,
pub failure_domain: String,
pub disk_id: Option<String>,
pub node_id: Option<String>,
pub affinity_group: Option<String>,
pub anti_affinity_groups: Vec<String>,
}
impl BucketWarden {
pub fn placement_domain_support_report(&self) -> PlacementDomainSupportReport {
PlacementDomainSupportReport {
active_profile: "local-single-node",
supported_domains: vec![PLACEMENT_DOMAIN_LOCAL_DISK, PLACEMENT_DOMAIN_LOCAL_NODE],
unsupported_domains: vec![
PLACEMENT_DOMAIN_RACK,
PLACEMENT_DOMAIN_ZONE,
PLACEMENT_DOMAIN_REGION,
],
default_failure_domain: PLACEMENT_DOMAIN_LOCAL_NODE,
affinity_policy: "metadata-validated-local-placement",
capabilities: PLACEMENT_DOMAIN_CAPABILITIES.to_vec(),
failure_modes: PLACEMENT_DOMAIN_FAILURE_MODES.to_vec(),
caveats: PLACEMENT_DOMAIN_CAVEATS.to_vec(),
entries: vec![
PlacementDomainSupportEntry {
domain: PLACEMENT_DOMAIN_LOCAL_DISK,
native_support: true,
semantic_parity: "Object versions are assigned deterministic local disk placement metadata.",
failure_domain: "local disk within the active BucketWarden runtime.",
affinity_behavior: "Affinity labels are preserved and validated as local placement metadata.",
failure_mode: "Invalid local disk placement metadata is rejected.",
caveat: "Local disk placement does not claim RAID, JBOD, or cloud block-device semantics.",
},
PlacementDomainSupportEntry {
domain: PLACEMENT_DOMAIN_LOCAL_NODE,
native_support: true,
semantic_parity: "Object versions are assigned deterministic local node placement metadata.",
failure_domain: "single local node runtime boundary.",
affinity_behavior: "Anti-affinity conflicts are rejected before placement is accepted.",
failure_mode: "Conflicting affinity and anti-affinity policy is rejected.",
caveat: "Local node support does not claim cluster scheduling or multi-node availability.",
},
PlacementDomainSupportEntry {
domain: PLACEMENT_DOMAIN_RACK,
native_support: false,
semantic_parity: "No rack topology, rack IDs, or rack spread semantics are claimed.",
failure_domain: "rack placement is out of the current runtime boundary.",
affinity_behavior: "Rack affinity policy is rejected as unsupported.",
failure_mode: "Rack placement selection is rejected as unsupported.",
caveat: "Rack-aware placement needs inventory and scheduler integration before support.",
},
PlacementDomainSupportEntry {
domain: PLACEMENT_DOMAIN_ZONE,
native_support: false,
semantic_parity: "No availability-zone placement, zone spread, or zone failure semantics are claimed.",
failure_domain: "zone placement is out of the current runtime boundary.",
affinity_behavior: "Zone affinity policy is rejected as unsupported.",
failure_mode: "Zone placement selection is rejected as unsupported.",
caveat: "Zone-aware placement needs multi-zone topology and durability policy integration.",
},
PlacementDomainSupportEntry {
domain: PLACEMENT_DOMAIN_REGION,
native_support: false,
semantic_parity: "No cross-region placement or regional durability SLA semantics are claimed.",
failure_domain: "region placement is out of the current runtime boundary.",
affinity_behavior: "Region affinity policy is rejected as unsupported.",
failure_mode: "Region placement selection is rejected as unsupported.",
caveat: "Region placement belongs to a future distributed deployment boundary.",
},
],
}
}
pub fn ensure_placement_domain_supported(&self, domain: &str) -> Result<(), RuntimeError> {
let report = self.placement_domain_support_report();
if report.supported_domains.contains(&domain) {
Ok(())
} else {
Err(RuntimeError::UnsupportedPlacementDomain(domain.to_string()))
}
}
pub fn evaluate_placement_policy(
&self,
policy: PlacementPolicy,
) -> Result<PlacementDecision, RuntimeError> {
self.ensure_placement_domain_supported(&policy.domain)?;
if let Some(affinity_group) = &policy.affinity_group {
if policy
.anti_affinity_groups
.iter()
.any(|group| group == affinity_group)
{
return Err(RuntimeError::InvalidPlacementPolicy(
"affinity group cannot also be anti-affinity".to_string(),
));
}
}
if matches!(policy.domain.as_str(), PLACEMENT_DOMAIN_LOCAL_DISK)
&& policy.disk_id.as_deref().unwrap_or_default().is_empty()
{
return Err(RuntimeError::InvalidPlacementPolicy(
"local disk placement requires disk_id".to_string(),
));
}
if matches!(policy.domain.as_str(), PLACEMENT_DOMAIN_LOCAL_NODE)
&& policy.node_id.as_deref().unwrap_or_default().is_empty()
{
return Err(RuntimeError::InvalidPlacementPolicy(
"local node placement requires node_id".to_string(),
));
}
Ok(PlacementDecision {
domain: policy.domain,
failure_domain: policy
.node_id
.clone()
.unwrap_or_else(|| "local-node".to_string()),
disk_id: policy.disk_id,
node_id: policy.node_id,
affinity_group: policy.affinity_group,
anti_affinity_groups: policy.anti_affinity_groups,
})
}
}