Skip to main content

elasticctl_api/value_lists/
evidence.rs

1use super::ListPlan;
2use elasticctl_core::Error;
3use serde::Serialize;
4
5#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
6#[serde(rename_all = "snake_case")]
7pub enum Outcome {
8    Applied,
9    Failed,
10    Unknown,
11    NotReached,
12}
13
14#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
15#[serde(rename_all = "snake_case")]
16pub enum Sent {
17    Accepted,
18    Refused,
19    Uncertain,
20    NotSent,
21}
22
23#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
24#[serde(rename_all = "snake_case")]
25pub enum Action {
26    CreateValueList,
27    UpdateValueList,
28    AddValues,
29    RemoveValues,
30    ReadBack,
31    NotReached,
32    DeleteValueList,
33    CheckValueList,
34}
35
36#[derive(Clone, Copy, Debug, Eq, PartialEq, Serialize)]
37#[serde(rename_all = "snake_case")]
38pub enum ReadOf {
39    Values,
40    Container,
41}
42
43#[derive(Clone, Debug, Serialize)]
44pub struct Failure {
45    pub kind: String,
46    #[serde(skip_serializing_if = "Option::is_none")]
47    pub status: Option<u16>,
48    pub message: String,
49}
50
51impl From<Error> for Failure {
52    fn from(error: Error) -> Self {
53        Self {
54            kind: error.kind.as_str().into(),
55            status: error.http_status,
56            message: error.message,
57        }
58    }
59}
60
61#[derive(Clone, Debug, Serialize)]
62pub struct Evidence {
63    pub action: Action,
64    pub rule_id: String,
65    pub name: String,
66    #[serde(skip_serializing_if = "Option::is_none")]
67    pub values: Option<Vec<String>>,
68    #[serde(skip_serializing_if = "Option::is_none")]
69    pub sent: Option<Sent>,
70    #[serde(skip_serializing_if = "Option::is_none")]
71    pub status: Option<u16>,
72    pub phase_verified: bool,
73    pub outcome: Outcome,
74    #[serde(skip_serializing_if = "Option::is_none")]
75    pub of: Option<ReadOf>,
76    #[serde(skip_serializing_if = "Option::is_none")]
77    pub observed: Option<bool>,
78    #[serde(skip_serializing_if = "Option::is_none")]
79    pub missing: Option<usize>,
80    #[serde(skip_serializing_if = "Option::is_none")]
81    pub extra: Option<usize>,
82    #[serde(skip_serializing_if = "Option::is_none")]
83    pub mismatched: Option<Vec<String>>,
84    #[serde(skip_serializing_if = "Option::is_none")]
85    pub read_error: Option<Failure>,
86    #[serde(skip_serializing_if = "Option::is_none")]
87    pub planned_adds: Option<usize>,
88    #[serde(skip_serializing_if = "Option::is_none")]
89    pub planned_removes: Option<usize>,
90    #[serde(skip_serializing_if = "Option::is_none")]
91    pub error: Option<Failure>,
92}
93
94impl Evidence {
95    pub(super) fn new(action: Action, id: &str, name: &str) -> Self {
96        Self {
97            action,
98            rule_id: id.into(),
99            name: name.into(),
100            values: Some(Vec::new()),
101            sent: Some(Sent::NotSent),
102            status: None,
103            phase_verified: false,
104            outcome: Outcome::NotReached,
105            of: None,
106            observed: None,
107            missing: None,
108            extra: None,
109            mismatched: None,
110            read_error: None,
111            planned_adds: None,
112            planned_removes: None,
113            error: None,
114        }
115    }
116}
117
118#[derive(Clone, Debug, Serialize)]
119pub struct ListOutcome {
120    pub id: String,
121    pub outcome: Outcome,
122    pub evidence: Vec<Evidence>,
123    #[serde(skip_serializing_if = "Option::is_none")]
124    pub error: Option<Failure>,
125}
126
127impl ListOutcome {
128    pub(super) fn finish(&mut self, outcome: Outcome, error: Option<Error>) {
129        self.outcome = outcome;
130        self.error = error.map(Into::into);
131        for entry in &mut self.evidence {
132            entry.outcome = outcome;
133        }
134    }
135
136    pub(super) fn not_reached(plan: &ListPlan) -> Self {
137        let c = &plan.local.container;
138        let mut entry = Evidence::new(Action::NotReached, &c.id, &c.name);
139        entry.values = None;
140        entry.planned_adds = Some(plan.adds.len());
141        entry.planned_removes = Some(plan.removes.len());
142        Self {
143            id: c.id.clone(),
144            outcome: Outcome::NotReached,
145            evidence: vec![entry],
146            error: None,
147        }
148    }
149}