canic-cli 0.35.11

Operator CLI for Canic fleet backup and restore workflows
Documentation
use super::{
    BackupCommandError, BackupInspectOperation, BackupInspectOptions, BackupInspectReport,
    BackupInspectTarget,
};
use crate::backup::{
    labels::{
        backup_scope_label, control_authority_source_label, execution_layout_status,
        format_authority, operation_kind_label, operation_state_label,
        snapshot_read_authority_source_label,
    },
    reference::resolve_backup_dir,
};
use canic_backup::{
    execution::BackupExecutionJournalOperation, persistence::BackupLayout, plan::BackupTarget,
};

pub(super) fn backup_inspect(
    options: &BackupInspectOptions,
) -> Result<BackupInspectReport, BackupCommandError> {
    let layout = BackupLayout::new(resolve_backup_dir(
        options.dir.as_deref(),
        options.backup_ref.as_deref(),
    )?);
    let plan = layout.read_backup_plan()?;
    let journal = layout.read_execution_journal()?;
    layout.verify_execution_integrity()?;

    Ok(BackupInspectReport {
        layout_status: execution_layout_status(&journal, layout.manifest_path().is_file()),
        plan_id: plan.plan_id.clone(),
        run_id: plan.run_id.clone(),
        fleet: plan.fleet.clone(),
        network: plan.network.clone(),
        scope: backup_scope_label(&plan),
        targets: plan.targets.iter().map(inspect_target).collect(),
        operations: journal.operations.iter().map(inspect_operation).collect(),
        execution: journal.resume_summary(),
    })
}

fn inspect_target(target: &BackupTarget) -> BackupInspectTarget {
    BackupInspectTarget {
        role: target.role.clone().unwrap_or_else(|| "-".to_string()),
        canister_id: target.canister_id.clone(),
        parent_canister_id: target
            .parent_canister_id
            .clone()
            .unwrap_or_else(|| "-".to_string()),
        expected_module_hash: target
            .expected_module_hash
            .clone()
            .unwrap_or_else(|| "-".to_string()),
        depth: target.depth,
        control_authority: format_authority(
            control_authority_source_label(&target.control_authority.source),
            &target.control_authority.evidence,
        ),
        snapshot_read_authority: format_authority(
            snapshot_read_authority_source_label(&target.snapshot_read_authority.source),
            &target.snapshot_read_authority.evidence,
        ),
    }
}

fn inspect_operation(operation: &BackupExecutionJournalOperation) -> BackupInspectOperation {
    BackupInspectOperation {
        sequence: operation.sequence,
        kind: operation_kind_label(&operation.kind).to_string(),
        target_canister_id: operation
            .target_canister_id
            .clone()
            .unwrap_or_else(|| "-".to_string()),
        state: operation_state_label(&operation.state).to_string(),
        blocking_reasons: operation.blocking_reasons.clone(),
    }
}