use super::*;
use crate::ops_health_diagnostics::{ops_scope_and_target, scoped_buckets};
impl BucketWarden {
pub fn ops_config_report(
&mut self,
principal: &str,
bucket: Option<&str>,
) -> Result<RuntimeConfigReport, RuntimeError> {
let (scope, target) = ops_scope_and_target(bucket);
self.require_operator_action(
principal,
OperatorAction::ReadDiagnostics,
&target,
"ops:GetConfigReport",
)?;
self.require_ops_bucket_scope(bucket)?;
let buckets = scoped_buckets(self, bucket);
let mut bucket_regions = BTreeMap::new();
let mut buckets_with_logging = Vec::new();
let mut buckets_with_website = Vec::new();
let mut buckets_with_lifecycle = Vec::new();
let mut buckets_with_notifications = Vec::new();
let mut buckets_with_replication = Vec::new();
let mut buckets_with_object_lock = Vec::new();
let mut buckets_with_encryption = Vec::new();
for (bucket_name, bucket_state) in &buckets {
bucket_regions.insert((*bucket_name).clone(), bucket_state.region.clone());
if bucket_state.logging.is_some() {
buckets_with_logging.push((*bucket_name).clone());
}
if bucket_state.website.is_some() {
buckets_with_website.push((*bucket_name).clone());
}
if !bucket_state.lifecycle_rules.is_empty() {
buckets_with_lifecycle.push((*bucket_name).clone());
}
if !bucket_state.notification_rules.is_empty() {
buckets_with_notifications.push((*bucket_name).clone());
}
if !bucket_state.replication.rules.is_empty() {
buckets_with_replication.push((*bucket_name).clone());
}
if bucket_state.object_lock.enabled {
buckets_with_object_lock.push((*bucket_name).clone());
}
if bucket_state.encryption.is_some() {
buckets_with_encryption.push((*bucket_name).clone());
}
}
let mut tenant_quota_targets = self.tenant_quotas.keys().cloned().collect::<Vec<_>>();
tenant_quota_targets.sort();
let storage_backend_report = self.storage_backend_support_report();
let replication_strategy_report = self.replication_strategy_support_report();
let erasure_coding_report = self.erasure_coding_support_report();
let placement_domain_report = self.placement_domain_support_report();
let consistency_model_report = self.consistency_model_support_report();
let metadata_architecture_report = self.metadata_architecture_support_report();
let object_layout_report = self.object_layout_support_report();
let small_object_report = self.small_object_optimization_report();
let large_object_report = self.large_object_optimization_report();
let report = RuntimeConfigReport {
scope: scope.to_string(),
target: target.to_string(),
generated_at_epoch_seconds: self.clock_epoch_seconds,
key_id: self.kms.key_id().to_string(),
clock_epoch_seconds: self.clock_epoch_seconds,
default_bucket_region: DEFAULT_BUCKET_REGION.to_string(),
bucket_regions,
tenant_quota_targets,
buckets_with_logging,
buckets_with_website,
buckets_with_lifecycle,
buckets_with_notifications,
buckets_with_replication,
buckets_with_object_lock,
buckets_with_encryption,
active_storage_backend: storage_backend_report.active_backend.to_string(),
supported_storage_backends: storage_backend_report
.supported_backends
.iter()
.map(|backend| (*backend).to_string())
.collect(),
unsupported_storage_backends: storage_backend_report
.unsupported_backends
.iter()
.map(|backend| (*backend).to_string())
.collect(),
storage_backend_caveats: storage_backend_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_replication_strategy: replication_strategy_report.active_strategy.to_string(),
supported_replication_strategies: replication_strategy_report
.supported_strategies
.iter()
.map(|strategy| (*strategy).to_string())
.collect(),
unsupported_replication_strategies: replication_strategy_report
.unsupported_strategies
.iter()
.map(|strategy| (*strategy).to_string())
.collect(),
replication_strategy_caveats: replication_strategy_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_erasure_coding_profile: erasure_coding_report.active_profile.to_string(),
supported_erasure_coding_profiles: erasure_coding_report
.supported_profiles
.iter()
.map(|profile| (*profile).to_string())
.collect(),
unsupported_erasure_coding_profiles: erasure_coding_report
.unsupported_profiles
.iter()
.map(|profile| (*profile).to_string())
.collect(),
erasure_coding_k: erasure_coding_report.k,
erasure_coding_m: erasure_coding_report.m,
erasure_coding_small_object_threshold_bytes: erasure_coding_report
.small_object_threshold_bytes,
erasure_coding_caveats: erasure_coding_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_placement_profile: placement_domain_report.active_profile.to_string(),
supported_placement_domains: placement_domain_report
.supported_domains
.iter()
.map(|domain| (*domain).to_string())
.collect(),
unsupported_placement_domains: placement_domain_report
.unsupported_domains
.iter()
.map(|domain| (*domain).to_string())
.collect(),
default_placement_failure_domain: placement_domain_report
.default_failure_domain
.to_string(),
placement_affinity_policy: placement_domain_report.affinity_policy.to_string(),
placement_domain_caveats: placement_domain_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_consistency_model: consistency_model_report.active_model.to_string(),
supported_consistency_models: consistency_model_report
.supported_models
.iter()
.map(|model| (*model).to_string())
.collect(),
unsupported_consistency_models: consistency_model_report
.unsupported_models
.iter()
.map(|model| (*model).to_string())
.collect(),
consistency_model_caveats: consistency_model_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_metadata_architecture: metadata_architecture_report
.active_architecture
.to_string(),
supported_metadata_architectures: metadata_architecture_report
.supported_architectures
.iter()
.map(|architecture| (*architecture).to_string())
.collect(),
unsupported_metadata_architectures: metadata_architecture_report
.unsupported_architectures
.iter()
.map(|architecture| (*architecture).to_string())
.collect(),
metadata_namespace_model: metadata_architecture_report.namespace_model.to_string(),
metadata_persistence_model: metadata_architecture_report.persistence_model.to_string(),
metadata_architecture_caveats: metadata_architecture_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_object_layout: object_layout_report.active_layout.to_string(),
supported_object_layouts: object_layout_report
.supported_layouts
.iter()
.map(|layout| (*layout).to_string())
.collect(),
unsupported_object_layouts: object_layout_report
.unsupported_layouts
.iter()
.map(|layout| (*layout).to_string())
.collect(),
object_layout_chunk_policy: object_layout_report.default_chunk_policy.to_string(),
object_layout_caveats: object_layout_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_small_object_mode: small_object_report.active_mode.to_string(),
small_object_threshold_bytes: small_object_report.small_object_threshold_bytes,
supported_small_object_modes: small_object_report
.supported_modes
.iter()
.map(|mode| (*mode).to_string())
.collect(),
unsupported_small_object_modes: small_object_report
.unsupported_modes
.iter()
.map(|mode| (*mode).to_string())
.collect(),
small_object_optimization_caveats: small_object_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
active_large_object_mode: large_object_report.active_mode.to_string(),
large_object_multipart_threshold_bytes: large_object_report.multipart_threshold_bytes,
supported_large_object_modes: large_object_report
.supported_modes
.iter()
.map(|mode| (*mode).to_string())
.collect(),
unsupported_large_object_modes: large_object_report
.unsupported_modes
.iter()
.map(|mode| (*mode).to_string())
.collect(),
large_object_optimization_caveats: large_object_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
};
self.audit.append(
principal,
"ops:GetConfigReport",
&target,
AuditOutcome::Allowed,
Some(format!(
"buckets={},tenant_quotas={}",
report.bucket_regions.len(),
report.tenant_quota_targets.len()
)),
);
Ok(report)
}
}