use super::*;
use crate::ops_health_diagnostics::{
ops_scope_and_target, scoped_audit_events, scoped_notification_events,
scoped_replication_records,
};
impl BucketWarden {
pub fn ops_evidence_export_report(
&mut self,
principal: &str,
bucket: Option<&str>,
) -> Result<OpsEvidenceExportReport, RuntimeError> {
let (scope, target) = ops_scope_and_target(bucket);
self.require_operator_action(
principal,
OperatorAction::ReadAudit,
&target,
"ops:GetEvidenceExportReport",
)?;
self.require_ops_bucket_scope(bucket)?;
let audit_events = scoped_audit_events(self, bucket);
let notification_events = scoped_notification_events(self, bucket);
let replication_records = scoped_replication_records(self, bucket);
let report = OpsEvidenceExportReport {
scope: scope.to_string(),
target: target.to_string(),
generated_at_epoch_seconds: self.clock_epoch_seconds,
audit_event_count: audit_events.len(),
notification_event_count: notification_events.len(),
replication_record_count: replication_records.len(),
first_audit_sequence: audit_events.first().map(|event| event.sequence),
last_audit_sequence: audit_events.last().map(|event| event.sequence),
first_notification_event_id: notification_events
.first()
.map(|event| event.event_id.clone()),
last_notification_event_id: notification_events
.last()
.map(|event| event.event_id.clone()),
first_replication_sequence: replication_records.first().map(|record| record.sequence),
last_replication_sequence: replication_records.last().map(|record| record.sequence),
snapshot_json: self.snapshot_json()?,
audit_json_lines: audit_events_json_lines(&audit_events)?,
notification_json_lines: notification_events_json_lines_scoped(¬ification_events)?,
replication_json_lines: replication_records_json_lines(&replication_records)?,
storage_backend_evidence_json: serde_json::to_string(
&self.storage_backend_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
replication_strategy_evidence_json: serde_json::to_string(
&self.replication_strategy_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
erasure_coding_evidence_json: serde_json::to_string(
&self.erasure_coding_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
placement_domain_evidence_json: serde_json::to_string(
&self.placement_domain_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
consistency_model_evidence_json: serde_json::to_string(
&self.consistency_model_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
metadata_architecture_evidence_json: serde_json::to_string(
&self.metadata_architecture_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
object_layout_evidence_json: serde_json::to_string(
&self.object_layout_support_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
small_object_optimization_evidence_json: serde_json::to_string(
&self.small_object_optimization_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
large_object_optimization_evidence_json: serde_json::to_string(
&self.large_object_optimization_report(),
)
.map_err(RuntimeError::SnapshotSerialize)?,
};
self.audit.append(
principal,
"ops:GetEvidenceExportReport",
&target,
AuditOutcome::Allowed,
Some(format!(
"audit={},notification={},replication={}",
report.audit_event_count,
report.notification_event_count,
report.replication_record_count
)),
);
Ok(report)
}
}
fn audit_events_json_lines(events: &[&AuditEvent]) -> Result<String, RuntimeError> {
let mut lines = Vec::with_capacity(events.len());
for event in events {
lines.push(serde_json::to_string(event).map_err(RuntimeError::SnapshotSerialize)?);
}
Ok(lines.join("\n"))
}
fn notification_events_json_lines_scoped(
events: &[&NotificationEvent],
) -> Result<String, RuntimeError> {
let mut lines = Vec::with_capacity(events.len());
for event in events {
lines.push(serde_json::to_string(event).map_err(RuntimeError::SnapshotSerialize)?);
}
Ok(lines.join("\n"))
}
fn replication_records_json_lines(events: &[&ReplicationRecord]) -> Result<String, RuntimeError> {
let mut lines = Vec::with_capacity(events.len());
for event in events {
lines.push(serde_json::to_string(event).map_err(RuntimeError::SnapshotSerialize)?);
}
Ok(lines.join("\n"))
}