manta_server/service/
sat_groups.rs1use serde_json::Value;
27
28pub fn extract_image_groups(image: &Value) -> Vec<String> {
31 image
32 .get("configuration_group_names")
33 .and_then(Value::as_array)
34 .map(|arr| {
35 arr
36 .iter()
37 .filter_map(Value::as_str)
38 .map(str::to_string)
39 .collect()
40 })
41 .unwrap_or_default()
42}
43
44pub fn extract_session_template_groups(
49 session_template: &Value,
50) -> Vec<String> {
51 let Some(boot_sets) = session_template
52 .get("bos_parameters")
53 .and_then(|p| p.get("boot_sets"))
54 .and_then(Value::as_object)
55 else {
56 return Vec::new();
57 };
58
59 let mut groups: Vec<String> = boot_sets
60 .values()
61 .filter_map(|set| set.get("node_groups"))
62 .filter_map(Value::as_array)
63 .flat_map(|arr| arr.iter().filter_map(Value::as_str).map(str::to_string))
64 .collect();
65 groups.sort();
66 groups.dedup();
67 groups
68}
69
70pub fn extract_all_target_groups(sat_file: &Value) -> Vec<String> {
80 let mut groups: Vec<String> = Vec::new();
81
82 if let Some(images) = sat_file.get("images").and_then(Value::as_array) {
83 for image in images {
84 groups.extend(extract_image_groups(image));
85 }
86 }
87
88 if let Some(templates) =
89 sat_file.get("session_templates").and_then(Value::as_array)
90 {
91 for tpl in templates {
92 groups.extend(extract_session_template_groups(tpl));
93 }
94 }
95
96 groups.sort();
97 groups.dedup();
98 groups
99}
100
101#[cfg(test)]
102mod tests {
103 use super::{extract_image_groups, extract_session_template_groups};
104 use serde_json::json;
105
106 #[test]
107 fn extract_image_groups_reads_configuration_group_names() {
108 let image = json!({
109 "name": "img-v1",
110 "configuration": "cfg-v1",
111 "configuration_group_names": ["compute", "uan"],
112 });
113 assert_eq!(extract_image_groups(&image), vec!["compute", "uan"]);
114 }
115
116 #[test]
117 fn extract_image_groups_empty_when_field_absent() {
118 let image = json!({ "name": "img-v1", "configuration": "cfg-v1" });
119 assert!(extract_image_groups(&image).is_empty());
120 }
121
122 #[test]
123 fn extract_image_groups_empty_when_field_is_not_array() {
124 let image = json!({
125 "name": "img-v1",
126 "configuration_group_names": "compute",
127 });
128 assert!(extract_image_groups(&image).is_empty());
129 }
130
131 #[test]
132 fn extract_session_template_groups_reads_all_boot_sets() {
133 let template = json!({
134 "name": "st-1",
135 "bos_parameters": {
136 "boot_sets": {
137 "compute": { "node_groups": ["compute", "shared"] },
138 "uan": { "node_groups": ["uan", "shared"] },
139 }
140 }
141 });
142 let groups = extract_session_template_groups(&template);
143 assert_eq!(groups, vec!["compute", "shared", "uan"]);
144 }
145
146 #[test]
147 fn extract_session_template_groups_empty_when_bos_parameters_missing() {
148 let template = json!({ "name": "st-1" });
149 assert!(extract_session_template_groups(&template).is_empty());
150 }
151
152 #[test]
153 fn extract_session_template_groups_empty_when_boot_sets_missing() {
154 let template = json!({ "name": "st-1", "bos_parameters": {} });
155 assert!(extract_session_template_groups(&template).is_empty());
156 }
157
158 #[test]
159 fn extract_session_template_groups_skips_boot_sets_without_node_groups() {
160 let template = json!({
161 "name": "st-1",
162 "bos_parameters": {
163 "boot_sets": {
164 "compute": { "node_groups": ["compute"] },
165 "uan": { "kernel": "linux" }
166 }
167 }
168 });
169 assert_eq!(extract_session_template_groups(&template), vec!["compute"]);
170 }
171
172 #[test]
173 fn extract_all_target_groups_empty_sat_file_returns_empty() {
174 let sat = json!({});
175 assert!(super::extract_all_target_groups(&sat).is_empty());
176 }
177
178 #[test]
179 fn extract_all_target_groups_collects_from_images_and_templates() {
180 let sat = json!({
181 "images": [
182 { "name": "img-1", "configuration_group_names": ["compute", "uan"] },
183 { "name": "img-2", "configuration_group_names": ["compute"] },
184 ],
185 "session_templates": [
186 {
187 "name": "st-1",
188 "bos_parameters": {
189 "boot_sets": {
190 "compute": { "node_groups": ["compute"] },
191 "uan": { "node_groups": ["uan", "admin"] },
192 }
193 }
194 }
195 ]
196 });
197 let mut got = super::extract_all_target_groups(&sat);
198 got.sort();
199 assert_eq!(got, vec!["admin", "compute", "uan"]);
200 }
201
202 #[test]
203 fn extract_all_target_groups_handles_missing_sections() {
204 let sat = json!({ "images": [ { "name": "img", "configuration_group_names": ["g1"] } ] });
205 let got = super::extract_all_target_groups(&sat);
206 assert_eq!(got, vec!["g1"]);
207 }
208}