canic-host 0.70.1

Host-side build, install, deployment, and fleet-template library for Canic workspaces
Documentation
use super::group::{promotion_artifact_identity_groups, promotion_artifact_identity_summary};
use super::roles::role_promotion_artifact_identity;
use super::validation::validate_promotion_artifact_identity_report;
use crate::deployment_truth::{
    DEPLOYMENT_TRUTH_SCHEMA_VERSION, PromotionArtifactIdentityReportV1, PromotionReadinessStatusV1,
    RolePromotionInputV1, SafetySeverityV1,
};

use super::super::digest::promotion_artifact_identity_report_digest;
use super::super::ensure::ensure_identity_report_field;
use super::super::error::PromotionArtifactIdentityReportError;
use super::super::request::PromotionArtifactIdentityReportRequest;

pub fn promotion_artifact_identity_report_from_inputs(
    request: PromotionArtifactIdentityReportRequest,
) -> Result<PromotionArtifactIdentityReportV1, PromotionArtifactIdentityReportError> {
    ensure_identity_report_field("report_id", &request.report_id)?;
    let report = promotion_artifact_identity_report(&request.report_id, &request.inputs);
    validate_promotion_artifact_identity_report(&report)?;
    Ok(report)
}

#[must_use]
pub fn promotion_artifact_identity_report(
    report_id: impl Into<String>,
    inputs: &[RolePromotionInputV1],
) -> PromotionArtifactIdentityReportV1 {
    let mut roles = Vec::with_capacity(inputs.len());
    let mut blockers = Vec::new();
    for input in inputs {
        if let Err(err) = super::super::transform::validate_role_artifact_source(&input.source) {
            blockers.push(super::super::promotion_finding(
                "promotion_artifact_source_invalid",
                err.to_string(),
                SafetySeverityV1::HardFailure,
                &input.role,
            ));
        }
        if input.role != input.source.role {
            blockers.push(super::super::promotion_finding(
                "promotion_source_role_mismatch",
                format!(
                    "promotion input role {} does not match artifact source role {}",
                    input.role, input.source.role
                ),
                SafetySeverityV1::HardFailure,
                &input.role,
            ));
        }
        roles.push(role_promotion_artifact_identity(input));
    }
    let identity_groups = promotion_artifact_identity_groups(&roles);
    let summary = promotion_artifact_identity_summary(&roles, &identity_groups);

    let mut report = PromotionArtifactIdentityReportV1 {
        schema_version: DEPLOYMENT_TRUTH_SCHEMA_VERSION,
        report_id: report_id.into(),
        artifact_identity_report_digest: String::new(),
        status: if blockers.is_empty() {
            PromotionReadinessStatusV1::Ready
        } else {
            PromotionReadinessStatusV1::Blocked
        },
        summary,
        identity_groups,
        roles,
        blockers,
    };
    report.artifact_identity_report_digest = promotion_artifact_identity_report_digest(&report);
    report
}