signstar_config/nethsm/
state.rs1use crate::{
4 nethsm::{NetHsmConfigState, backend::NetHsmBackendState},
5 state::{StateDiff, StateDiffFailure, StateDiffFailureTarget, StateDiffReport},
6};
7
8#[derive(Debug)]
10pub struct NetHsmDiff<'config_state, 'backend_state, 'config_items> {
11 pub config: &'config_state NetHsmConfigState<'config_items>,
13
14 pub backend: &'backend_state NetHsmBackendState,
16}
17
18impl<'config_state, 'backend_state, 'config_items> StateDiff<'config_state, 'backend_state>
19 for NetHsmDiff<'config_state, 'backend_state, 'config_items>
20{
21 fn diff(&self) -> StateDiffReport<'config_state, 'backend_state> {
22 if self.config == self.backend {
23 return StateDiffReport::Success;
24 }
25
26 let user_state_discrepancies = {
27 let mut matched_config_states = Vec::new();
28 let mut state_discrepancies = Vec::new();
29
30 'outer: for backend_user_state in self.backend.user_states.iter() {
31 for config_user_state in self.config.user_data.iter() {
32 if config_user_state == backend_user_state {
34 matched_config_states.push(config_user_state);
35 continue 'outer;
36 }
37
38 if &backend_user_state.name == config_user_state.user {
40 matched_config_states.push(config_user_state);
41 state_discrepancies.push(StateDiffFailure::Mismatch {
42 one: Box::new(self.config),
43 other: Box::new(self.backend),
44 one_state: config_user_state.to_string(),
45 other_state: backend_user_state.to_string(),
46 });
47 continue 'outer;
48 }
49 }
50
51 state_discrepancies.push(StateDiffFailure::DoesNotExist {
53 one: Box::new(self.config),
54 other: Box::new(self.backend),
55 target: StateDiffFailureTarget::One,
56 state: backend_user_state.to_string(),
57 });
58 }
59
60 self.config
62 .user_data
63 .iter()
64 .filter(|state| !matched_config_states.contains(state))
65 .for_each(|config_user_state| {
66 state_discrepancies.push(StateDiffFailure::DoesNotExist {
67 one: Box::new(self.config),
68 other: Box::new(self.backend),
69 target: StateDiffFailureTarget::Other,
70 state: config_user_state.to_string(),
71 })
72 });
73
74 state_discrepancies
75 };
76
77 let key_state_discrepancies = {
78 let mut matched_config_states = Vec::new();
79 let mut state_discrepancies = Vec::new();
80
81 'outer: for backend_key_state in self.backend.key_states.iter() {
82 for config_key_state in self.config.key_data.iter() {
83 if config_key_state == backend_key_state {
85 matched_config_states.push(config_key_state);
86 continue 'outer;
87 }
88
89 if &backend_key_state.name == config_key_state.key_id
91 && backend_key_state.namespace.as_ref() == config_key_state.user.namespace()
92 {
93 matched_config_states.push(config_key_state);
94 state_discrepancies.push(StateDiffFailure::Mismatch {
95 one: Box::new(self.config),
96 other: Box::new(self.backend),
97 one_state: config_key_state.to_string(),
98 other_state: backend_key_state.to_string(),
99 });
100 continue 'outer;
101 }
102 }
103
104 state_discrepancies.push(StateDiffFailure::DoesNotExist {
106 one: Box::new(self.config),
107 other: Box::new(self.backend),
108 target: StateDiffFailureTarget::One,
109 state: backend_key_state.to_string(),
110 });
111 }
112
113 self.config
115 .key_data
116 .iter()
117 .filter(|state| !matched_config_states.contains(state))
118 .for_each(|key_state| {
119 state_discrepancies.push(StateDiffFailure::DoesNotExist {
120 one: Box::new(self.config),
121 other: Box::new(self.backend),
122 target: StateDiffFailureTarget::Other,
123 state: key_state.to_string(),
124 })
125 });
126
127 state_discrepancies
128 };
129
130 let messages = {
131 let mut output = Vec::new();
132 output.extend(user_state_discrepancies);
133 output.extend(key_state_discrepancies);
134 output
135 };
136
137 if messages.is_empty() {
138 return StateDiffReport::Success;
139 }
140
141 StateDiffReport::Failure { messages }
142 }
143}