Skip to main content

lenso_service/production_delivery/
mod.rs

1mod config;
2mod deployment;
3mod edge;
4mod eligibility;
5mod policy;
6mod promotion;
7mod release;
8mod resilience;
9mod rollout;
10mod trust;
11
12use schemars::JsonSchema;
13use serde::{Deserialize, Serialize};
14use utoipa::ToSchema;
15
16pub use config::*;
17pub use deployment::*;
18pub use edge::*;
19pub use eligibility::*;
20pub use policy::*;
21pub use promotion::*;
22pub use release::*;
23pub use resilience::*;
24pub use rollout::*;
25pub use trust::*;
26
27#[derive(
28    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema, ToSchema,
29)]
30#[serde(rename_all = "snake_case")]
31pub enum DeliveryDecision {
32    Passed,
33    Advisory,
34    Blocked,
35}
36
37#[derive(
38    Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize, JsonSchema, ToSchema,
39)]
40#[serde(rename_all = "snake_case")]
41pub enum DeliveryIssueCode {
42    ReleaseInputInvalid,
43    MutableArtifactReference,
44    MissingSbom,
45    MissingProvenance,
46    ProvenanceSubjectMismatch,
47    SignatureMissing,
48    SignatureInvalid,
49    SignerUntrusted,
50    SignerRevoked,
51    ReleaseTampered,
52    ConfigContractMismatch,
53    PlaintextSecretDetected,
54    SecretReferenceUnresolved,
55    StaleInput,
56    ConcurrentMutation,
57    PolicyEvidenceMissing,
58    PolicyRuleBlocked,
59    ContractIncompatible,
60    MigrationUnsafe,
61    WorkflowIncompatible,
62    RollbackUnsafe,
63    EdgeOperationUnknown,
64    EdgePathConflict,
65    EdgeExposureUnsafe,
66    DeploymentInputInvalid,
67    MigrationIncomplete,
68    ObservationStale,
69    ApprovalRequired,
70    ApprovalInvalid,
71    ReliabilityEvidenceMissing,
72    CanaryBreach,
73    RollbackIncomplete,
74    CoordinationUnavailable,
75}
76
77#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, JsonSchema, ToSchema)]
78#[serde(rename_all = "camelCase")]
79pub struct DeliveryIssue {
80    pub code: DeliveryIssueCode,
81    pub message: String,
82    #[serde(default)]
83    pub evidence_references: Vec<String>,
84    pub remediation: String,
85    #[serde(default)]
86    pub next_actions: Vec<String>,
87}
88
89#[allow(clippy::struct_excessive_bools)]
90#[derive(
91    Debug, Clone, Copy, Default, PartialEq, Eq, Serialize, Deserialize, JsonSchema, ToSchema,
92)]
93#[serde(rename_all = "camelCase")]
94pub struct DeliveryEffects {
95    pub mutates_environment: bool,
96    pub mutates_configuration: bool,
97    pub mutates_gateway: bool,
98    pub mutates_deployment: bool,
99    pub appends_ledger: bool,
100}
101
102pub(crate) fn issue(
103    code: DeliveryIssueCode,
104    message: impl Into<String>,
105    remediation: impl Into<String>,
106    next_action: impl Into<String>,
107) -> DeliveryIssue {
108    DeliveryIssue {
109        code,
110        message: message.into(),
111        evidence_references: Vec::new(),
112        remediation: remediation.into(),
113        next_actions: vec![next_action.into()],
114    }
115}
116
117pub(crate) fn valid_sha256_digest(value: &str) -> bool {
118    value.strip_prefix("sha256:").is_some_and(|digest| {
119        digest.len() == 64
120            && digest
121                .bytes()
122                .all(|byte| byte.is_ascii_digit() || (b'a'..=b'f').contains(&byte))
123    })
124}