use super::*;
use crate::ops_health_diagnostics::{ops_scope_and_target, scoped_buckets};
use std::collections::BTreeSet;
impl BucketWarden {
pub fn ops_admin_surface_report(
&mut self,
principal: &str,
bucket: Option<&str>,
) -> Result<OpsAdminSurfaceReport, RuntimeError> {
let (scope, target) = ops_scope_and_target(bucket);
self.require_operator_action(
principal,
OperatorAction::ReadDiagnostics,
&target,
"ops:GetAdminSurfaceReport",
)?;
self.require_ops_bucket_scope(bucket)?;
let buckets = scoped_buckets(self, bucket);
let mut tenant_ids = BTreeSet::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();
let mut bucket_quota_target_count = 0usize;
for (bucket_name, bucket_state) in &buckets {
tenant_ids.insert(bucket_state.tenant_id.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());
}
if bucket_state.quota.max_objects.is_some() || bucket_state.quota.max_requests.is_some()
{
bucket_quota_target_count += 1;
}
}
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 = OpsAdminSurfaceReport {
scope: scope.to_string(),
target: target.to_string(),
generated_at_epoch_seconds: self.clock_epoch_seconds,
bucket_count: buckets.len(),
tenant_count: tenant_ids.len(),
identity_provider_count: self.identity_provider_count(),
tenant_quota_target_count: self.tenant_quotas.len(),
bucket_quota_target_count,
buckets_with_logging,
buckets_with_website,
buckets_with_lifecycle,
buckets_with_notifications,
buckets_with_replication,
buckets_with_object_lock,
buckets_with_encryption,
storage_backend_admin_surfaces: storage_backend_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
storage_backend_caveats: storage_backend_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
replication_strategy_admin_surfaces: replication_strategy_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
replication_strategy_caveats: replication_strategy_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
erasure_coding_admin_surfaces: erasure_coding_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
erasure_coding_caveats: erasure_coding_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
placement_domain_admin_surfaces: placement_domain_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
placement_domain_caveats: placement_domain_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
consistency_model_admin_surfaces: consistency_model_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
consistency_model_caveats: consistency_model_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
metadata_architecture_admin_surfaces: metadata_architecture_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
metadata_architecture_caveats: metadata_architecture_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
object_layout_admin_surfaces: object_layout_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
object_layout_caveats: object_layout_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
small_object_optimization_admin_surfaces: small_object_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
small_object_optimization_caveats: small_object_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
large_object_optimization_admin_surfaces: large_object_report
.capabilities
.iter()
.map(|capability| (*capability).to_string())
.collect(),
large_object_optimization_caveats: large_object_report
.caveats
.iter()
.map(|caveat| (*caveat).to_string())
.collect(),
};
self.audit.append(
principal,
"ops:GetAdminSurfaceReport",
&target,
AuditOutcome::Allowed,
Some(format!(
"buckets={},tenants={},providers={}",
report.bucket_count, report.tenant_count, report.identity_provider_count
)),
);
Ok(report)
}
}