1pub mod cfs;
2pub mod hsm;
3pub mod ims;
4pub mod kafka;
5
6use std::{collections::HashMap, str::FromStr};
7
8use serde::{Deserialize, Serialize};
9use serde_json::Value;
10use strum_macros::{AsRefStr, Display, EnumIter, EnumString, IntoStaticStr};
11
12use crate::error::Error;
13
14#[derive(Serialize, Deserialize, Debug)]
15pub enum K8sAuth {
16 Native {
17 certificate_authority_data: String,
18 client_certificate_data: String,
19 client_key_data: String,
20 },
21 Vault {
22 base_url: String,
23 },
24}
25
26#[derive(Serialize, Deserialize, Debug)]
27pub struct K8sDetails {
28 pub api_url: String,
29 pub authentication: K8sAuth,
30}
31
32#[derive(
34 Debug, EnumIter, EnumString, IntoStaticStr, AsRefStr, Display, Serialize, Deserialize, Clone,
35)]
36pub enum ArtifactType {
37 Memory,
38 Processor,
39 NodeAccel,
40 NodeHsnNic,
41 Drive,
42 CabinetPDU,
43 CabinetPDUPowerConnector,
44 CMMRectifier,
45 NodeAccelRiser,
46 NodeEnclosurePowerSupplie,
47 NodeBMC,
48 RouterBMC,
49}
50
51#[derive(Default, Debug, Serialize, Deserialize, Clone)]
52pub struct NodeSummary {
53 pub xname: String,
54 pub r#type: String,
55 pub processors: Vec<ArtifactSummary>,
56 pub memory: Vec<ArtifactSummary>,
57 pub node_accels: Vec<ArtifactSummary>,
58 pub node_hsn_nics: Vec<ArtifactSummary>,
59}
60
61impl From<HWInvByLocNode> for NodeSummary {
207 fn from(value: HWInvByLocNode) -> Self {
208 NodeSummary {
209 xname: value.id,
210 r#type: value.r#type.unwrap_or_default(),
211 processors: value
212 .processors
213 .unwrap_or_default()
214 .into_iter()
215 .map(ArtifactSummary::from)
216 .collect(),
217 memory: value
219 .memory
220 .unwrap_or_default()
221 .into_iter()
222 .map(ArtifactSummary::from)
223 .collect(),
224 node_accels: value
226 .node_accels
227 .unwrap_or_default()
228 .into_iter()
229 .map(ArtifactSummary::from)
230 .collect(),
231 node_hsn_nics: value
233 .node_hsn_nics
234 .unwrap_or_default()
235 .into_iter()
236 .map(ArtifactSummary::from)
237 .collect(),
238 }
240 }
241}
242
243impl Into<HWInvByLocNode> for NodeSummary {
244 fn into(self) -> HWInvByLocNode {
245 let redfish_system_fru_info = RedfishSystemFRUInfo {
246 asset_tag: None,
247 bios_version: None,
248 model: None,
249 manufacturer: None,
250 part_number: None,
251 serial_number: None,
252 sku: None,
253 system_type: None,
254 uuid: None,
255 };
256
257 let hw_inv_by_fr_node = HWInvByFRUNode {
258 fru_id: None,
259 r#type: None,
260 fru_sub_type: None,
261 hw_inventory_by_fru_type: self.r#type.clone(),
262 node_fru_info: redfish_system_fru_info,
263 };
264
265 HWInvByLocNode {
266 id: self.xname,
267 r#type: Some(self.r#type.clone()),
268 ordinal: None,
269 status: None,
270 hw_inventory_by_location_type: self.r#type,
271 populated_fru: Some(hw_inv_by_fr_node),
272 node_location_info: None,
273 processors: Some(
274 self.processors
275 .into_iter()
276 .map(|processor| processor.into())
277 .collect(),
278 ),
279 node_accels: Some(
280 self.node_accels
281 .into_iter()
282 .map(|node_accel| node_accel.into())
283 .collect(),
284 ),
285 drives: None,
286 memory: Some(
287 self.memory
288 .into_iter()
289 .map(|memory| memory.into())
290 .collect(),
291 ),
292 node_accel_risers: None,
293 node_hsn_nics: Some(
294 self.node_hsn_nics
295 .into_iter()
296 .map(|node_hsn_nic| node_hsn_nic.into())
297 .collect(),
298 ),
299 }
300 }
301}
302
303impl NodeSummary {
304 pub fn from_csm_value(hw_artifact_value: Value) -> Self {
305 let processors = hw_artifact_value["Processors"]
306 .as_array()
307 .unwrap_or(&Vec::new())
308 .iter()
309 .map(|processor_value| ArtifactSummary::from_processor_value(processor_value.clone()))
310 .collect();
311
312 let memory = hw_artifact_value["Memory"]
313 .as_array()
314 .unwrap_or(&Vec::new())
315 .iter()
316 .map(|memory_value| ArtifactSummary::from_memory_value(memory_value.clone()))
317 .collect();
318
319 let node_accels = hw_artifact_value["NodeAccels"]
320 .as_array()
321 .unwrap_or(&Vec::new())
322 .iter()
323 .map(|nodeaccel_value| ArtifactSummary::from_nodeaccel_value(nodeaccel_value.clone()))
324 .collect();
325
326 let node_hsn_nics = hw_artifact_value["NodeHsnNics"]
327 .as_array()
328 .unwrap_or(&Vec::new())
329 .iter()
330 .map(|nodehsnnic_value| {
331 ArtifactSummary::from_nodehsnnics_value(nodehsnnic_value.clone())
332 })
333 .collect();
334
335 Self {
336 xname: hw_artifact_value["ID"].as_str().unwrap().to_string(),
337 r#type: hw_artifact_value["Type"].as_str().unwrap().to_string(),
338 processors,
339 memory,
340 node_accels,
341 node_hsn_nics,
342 }
343 }
344}
345
346#[derive(Debug, Serialize, Deserialize, Clone)]
347pub struct ArtifactSummary {
348 pub xname: String,
349 pub r#type: ArtifactType,
350 pub info: Option<String>,
351}
352
353impl From<HWInvByLocProcessor> for ArtifactSummary {
354 fn from(value: HWInvByLocProcessor) -> Self {
355 ArtifactSummary {
356 xname: value.id,
357 r#type: ArtifactType::from_str(value.r#type.unwrap().as_str()).unwrap(),
358 info: value.populated_fru.and_then(|hw_inv_by_fru_processor| {
359 hw_inv_by_fru_processor.processor_fru_info.model
360 }),
361 }
362 }
363}
364
365impl Into<HWInvByLocProcessor> for ArtifactSummary {
366 fn into(self) -> HWInvByLocProcessor {
367 let redfish_process_fru_info = RedfishProcessorFRUInfo {
368 instruction_set: None,
369 manufacturer: None,
370 max_speed_mhz: None,
371 model: self.info,
372 processor_architecture: None,
373 processor_id: None,
374 processor_type: None,
375 total_cores: None,
376 total_threads: None,
377 };
378
379 let hw_inv_by_fru_processor = HWInvByFRUProcessor {
380 fru_id: None,
381 r#type: Some(self.r#type.to_string()),
382 fru_sub_type: None,
383 hw_inventory_by_fru_type: self.r#type.to_string(),
384 processor_fru_info: redfish_process_fru_info,
385 };
386
387 let processor_location_info = RedfishProcessorLocationInfo {
388 id: None,
389 name: None,
390 description: None,
391 socket: None,
392 };
393
394 HWInvByLocProcessor {
395 id: self.xname,
396 r#type: Some(self.r#type.to_string()),
397 ordinal: None,
398 status: None,
399 hw_inventory_by_location_type: self.r#type.to_string(),
400 populated_fru: Some(hw_inv_by_fru_processor),
401 processor_location_info,
402 }
403 }
404}
405
406impl From<HWInvByLocMemory> for ArtifactSummary {
407 fn from(value: HWInvByLocMemory) -> Self {
408 ArtifactSummary {
409 xname: value.id,
410 r#type: ArtifactType::from_str(value.r#type.unwrap().as_str()).unwrap(),
411 info: value.populated_fru.and_then(|hw_inv_by_fru_memory| {
412 hw_inv_by_fru_memory
413 .memory_fru_info
414 .capacity_mib
415 .map(|capacity_mib| capacity_mib.to_string())
416 }),
417 }
418 }
419}
420
421impl Into<HWInvByLocMemory> for ArtifactSummary {
422 fn into(self) -> HWInvByLocMemory {
423 let redfish_memory_fru_info = RedfishMemoryFRUInfo {
424 base_module_type: None,
425 bus_width_bits: None,
426 capacity_mib: self.info.map(|info| usize::from_str(&info).unwrap_or(0)), data_width_bits: None,
429 error_correction: None,
430 manufacturer: None,
431 memory_type: None,
432 memory_device_type: None,
433 operating_speed_mhz: None,
434 part_number: None,
435 rank_count: None,
436 serial_number: None,
437 };
438
439 let hw_inv_by_fru_memory = HWInvByFRUMemory {
440 fru_id: None,
441 r#type: Some(self.r#type.to_string()),
442 fru_sub_type: None,
443 hw_inventory_by_fru_type: self.r#type.to_string(),
444 memory_fru_info: redfish_memory_fru_info,
445 };
446
447 let memory_location = MemoryLocation {
448 socket: None,
449 memory_controller: None,
450 channel: None,
451 slot: None,
452 };
453
454 let redfish_memory_location_info = RedfishMemoryLocationInfo {
455 id: None,
456 name: None,
457 description: None,
458 memory_location: Some(memory_location),
459 };
460
461 HWInvByLocMemory {
462 id: self.xname,
463 r#type: Some(self.r#type.to_string()),
464 ordinal: None,
465 status: None,
466 hw_inventory_by_location_type: self.r#type.to_string(),
467 populated_fru: Some(hw_inv_by_fru_memory),
468 memory_location_info: redfish_memory_location_info,
469 }
470 }
471}
472
473impl From<HWInvByLocNodeAccel> for ArtifactSummary {
474 fn from(value: HWInvByLocNodeAccel) -> Self {
475 ArtifactSummary {
476 xname: value.id,
477 r#type: ArtifactType::from_str(value.r#type.unwrap().as_str()).unwrap(),
478 info: value.populated_fru.and_then(|hw_inv_by_fru_node_accel| {
479 hw_inv_by_fru_node_accel.node_accel_fru_info.model
480 }),
481 }
482 }
483}
484
485impl Into<HWInvByLocNodeAccel> for ArtifactSummary {
486 fn into(self) -> HWInvByLocNodeAccel {
487 let redfish_processor_fru_info = RedfishProcessorFRUInfo {
490 instruction_set: None,
491 manufacturer: None,
492 max_speed_mhz: None,
493 model: self.info,
494 processor_architecture: None,
495 processor_id: None,
496 processor_type: None,
497 total_cores: None,
498 total_threads: None,
499 };
500
501 let hw_inv_by_fru_node_accel = HWInvByFRUNodeAccel {
502 fru_id: None,
503 r#type: Some(self.r#type.to_string()),
504 fru_sub_type: None,
505 hw_inventory_by_fru_type: self.r#type.to_string(),
506 node_accel_fru_info: redfish_processor_fru_info,
507 };
508
509 HWInvByLocNodeAccel {
510 id: self.xname,
511 r#type: Some(self.r#type.to_string()),
512 ordinal: None,
513 status: None,
514 hw_inventory_by_location_type: self.r#type.to_string(),
515 populated_fru: Some(hw_inv_by_fru_node_accel),
516 node_accel_location_info: None,
517 }
518 }
519}
520
521impl From<HWInvByLocHSNNIC> for ArtifactSummary {
522 fn from(value: HWInvByLocHSNNIC) -> Self {
523 ArtifactSummary {
524 xname: value.id,
525 r#type: ArtifactType::from_str(value.r#type.unwrap().as_str()).unwrap(),
526 info: value
527 .populated_fru
528 .and_then(|hw_inv_by_fru_hsn_nic| hw_inv_by_fru_hsn_nic.hsn_nic_fru_info.model),
529 }
530 }
531}
532
533impl Into<HWInvByLocHSNNIC> for ArtifactSummary {
534 fn into(self) -> HWInvByLocHSNNIC {
535 let hsn_nic_fru_info = HSNNICFRUInfo {
538 manufacturer: None,
539 model: self.info,
540 part_number: None,
541 sku: None,
542 serial_number: None,
543 };
544
545 let hw_inv_by_fru_hsn_nic = HWInvByFRUHSNNIC {
546 fru_id: None,
547 r#type: Some(self.r#type.to_string()),
548 fru_sub_type: None,
549 hw_inventory_by_fru_type: self.r#type.to_string(),
550 hsn_nic_fru_info,
551 };
552
553 let hsn_nic_location_info = HSNNICLocationInfo {
554 id: None,
555 name: None,
556 description: None,
557 };
558
559 HWInvByLocHSNNIC {
560 id: self.xname,
561 r#type: Some(self.r#type.to_string()),
562 ordinal: None,
563 status: None,
564 hw_inventory_by_location_type: self.r#type.to_string(),
565 populated_fru: Some(hw_inv_by_fru_hsn_nic),
566 hsn_nic_location_info,
567 }
568 }
569}
570
571impl ArtifactSummary {
572 fn from_processor_value(processor_value: Value) -> Self {
573 Self {
574 xname: processor_value["ID"].as_str().unwrap().to_string(),
575 r#type: ArtifactType::from_str(processor_value["Type"].as_str().unwrap()).unwrap(),
576 info: processor_value
577 .pointer("/PopulatedFRU/ProcessorFRUInfo/Model")
578 .map(|model| model.as_str().unwrap().to_string()),
579 }
580 }
581
582 fn from_memory_value(memory_value: Value) -> Self {
583 Self {
584 xname: memory_value["ID"].as_str().unwrap().to_string(),
585 r#type: ArtifactType::from_str(memory_value["Type"].as_str().unwrap()).unwrap(),
586 info: memory_value
587 .pointer("/PopulatedFRU/MemoryFRUInfo/CapacityMiB")
588 .map(|capacity_mib| capacity_mib.as_number().unwrap().to_string() + " MiB"),
589 }
590 }
591
592 fn from_nodehsnnics_value(nodehsnnic_value: Value) -> Self {
593 Self {
594 xname: nodehsnnic_value["ID"].as_str().unwrap().to_string(),
595 r#type: ArtifactType::from_str(nodehsnnic_value["Type"].as_str().unwrap()).unwrap(),
596 info: nodehsnnic_value
597 .pointer("/NodeHsnNicLocationInfo/Description")
598 .map(|description| description.as_str().unwrap().to_string()),
599 }
600 }
601
602 fn from_nodeaccel_value(nodeaccel_value: Value) -> Self {
603 Self {
604 xname: nodeaccel_value["ID"].as_str().unwrap().to_string(),
605 r#type: ArtifactType::from_str(nodeaccel_value["Type"].as_str().unwrap()).unwrap(),
606 info: nodeaccel_value
607 .pointer("/PopulatedFRU/NodeAccelFRUInfo/Model")
608 .map(|model| model.as_str().unwrap().to_string()),
609 }
610 }
611}
612
613#[derive(Debug, Serialize, Deserialize, Clone)]
615pub struct Group {
616 pub label: String,
617 #[serde(skip_serializing_if = "Option::is_none")]
618 pub description: Option<String>,
619 #[serde(skip_serializing_if = "Option::is_none")]
620 pub tags: Option<Vec<String>>,
621 #[serde(skip_serializing_if = "Option::is_none")]
622 pub members: Option<Member>,
623 #[serde(skip_serializing_if = "Option::is_none")]
624 #[serde(rename = "exclusiveGroup")]
625 pub exclusive_group: Option<String>,
626}
627
628#[derive(Debug, Serialize, Deserialize, Default, Clone)]
629pub struct Member {
630 #[serde(skip_serializing_if = "Option::is_none")]
631 pub ids: Option<Vec<String>>,
632}
633#[derive(Debug, Serialize, Deserialize, Default, Clone)]
634pub struct XnameId {
635 #[serde(skip_serializing_if = "Option::is_none")]
636 pub id: Option<String>,
637}
638
639impl Group {
640 pub fn new(
642 label: &str,
643 description: Option<String>,
644 member_vec_opt: Option<Vec<String>>,
645 tag_vec_opt: Option<Vec<String>>,
646 exclusive_opt: Option<String>,
647 ) -> Self {
648 let members_opt = if let Some(member_vec) = member_vec_opt {
649 Some(Member {
650 ids: Some(member_vec),
651 })
652 } else {
653 None
654 };
655
656 let group = Self {
657 label: label.to_string(),
658 description,
659 tags: tag_vec_opt,
660 members: members_opt,
661 exclusive_group: exclusive_opt,
662 };
663
664 group
665 }
666
667 pub fn get_members(&self) -> Vec<String> {
669 self.members
670 .clone()
671 .map(|member| member.ids.unwrap_or_default())
672 .unwrap_or_default()
673 }
674}
675
676#[derive(Debug, Serialize, Deserialize, Clone)]
677pub struct NodeMetadataArray {
678 #[serde(skip_serializing_if = "Option::is_none")]
679 #[serde(rename = "Components")]
680 pub components: Option<Vec<Component>>,
681}
682
683#[derive(Debug, Serialize, Deserialize, Clone)]
684pub struct Component {
685 #[serde(skip_serializing_if = "Option::is_none")]
686 #[serde(rename = "ID")]
687 pub id: Option<String>,
688 #[serde(skip_serializing_if = "Option::is_none")]
689 #[serde(rename = "Type")]
690 pub r#type: Option<String>,
691 #[serde(skip_serializing_if = "Option::is_none")]
692 #[serde(rename = "State")]
693 pub state: Option<String>,
694 #[serde(skip_serializing_if = "Option::is_none")]
695 #[serde(rename = "Flag")]
696 pub flag: Option<String>,
697 #[serde(skip_serializing_if = "Option::is_none")]
698 #[serde(rename = "Enabled")]
699 pub enabled: Option<bool>,
700 #[serde(skip_serializing_if = "Option::is_none")]
701 #[serde(rename = "SoftwareStatus")]
702 pub software_status: Option<String>,
703 #[serde(skip_serializing_if = "Option::is_none")]
704 #[serde(rename = "Role")]
705 pub role: Option<String>,
706 #[serde(skip_serializing_if = "Option::is_none")]
707 #[serde(rename = "SubRole")]
708 pub sub_role: Option<String>,
709 #[serde(skip_serializing_if = "Option::is_none")]
710 #[serde(rename = "NID")]
711 pub nid: Option<usize>,
712 #[serde(skip_serializing_if = "Option::is_none")]
713 #[serde(rename = "Subtype")]
714 pub subtype: Option<String>,
715 #[serde(skip_serializing_if = "Option::is_none")]
716 #[serde(rename = "NetType")]
717 pub net_type: Option<String>,
718 #[serde(skip_serializing_if = "Option::is_none")]
719 #[serde(rename = "Arch")]
720 pub arch: Option<String>,
721 #[serde(skip_serializing_if = "Option::is_none")]
722 #[serde(rename = "Class")]
723 pub class: Option<String>,
724 #[serde(skip_serializing_if = "Option::is_none")]
725 #[serde(rename = "ReservationDisabled")]
726 pub reservation_disabled: Option<bool>,
727 #[serde(skip_serializing_if = "Option::is_none")]
728 #[serde(rename = "Locked")]
729 pub locked: Option<bool>,
730}
731
732#[derive(Debug, Serialize, Deserialize, Clone)]
733pub struct ComponentArrayPostQuery {
734 #[serde(skip_serializing_if = "Option::is_none")]
735 #[serde(rename = "ComponentIDs")]
736 pub component_ids: Option<Vec<String>>,
737 #[serde(skip_serializing_if = "Option::is_none")]
738 pub partition: Option<String>,
739 #[serde(skip_serializing_if = "Option::is_none")]
740 pub group: Option<String>,
741 #[serde(skip_serializing_if = "Option::is_none")]
742 #[serde(rename = "stateonly")]
743 pub state_only: Option<bool>,
744 #[serde(skip_serializing_if = "Option::is_none")]
745 #[serde(rename = "flagonly")]
746 pub falg_only: Option<bool>,
747 #[serde(skip_serializing_if = "Option::is_none")]
748 #[serde(rename = "roleonly")]
749 pub role_only: Option<bool>,
750 #[serde(skip_serializing_if = "Option::is_none")]
751 #[serde(rename = "nidonly")]
752 pub nid_only: Option<bool>,
753 #[serde(skip_serializing_if = "Option::is_none")]
754 pub r#type: Option<String>,
755 #[serde(skip_serializing_if = "Option::is_none")]
756 pub state: Option<String>,
757 #[serde(skip_serializing_if = "Option::is_none")]
758 pub flag: Option<String>,
759 #[serde(skip_serializing_if = "Option::is_none")]
760 pub enabled: Option<String>,
761 #[serde(skip_serializing_if = "Option::is_none")]
762 #[serde(rename = "softwarestatus")]
763 pub software_status: Option<String>,
764 #[serde(skip_serializing_if = "Option::is_none")]
765 pub role: Option<String>,
766 #[serde(skip_serializing_if = "Option::is_none")]
767 pub subrole: Option<String>,
768 #[serde(skip_serializing_if = "Option::is_none")]
769 pub subtype: Option<String>,
770 #[serde(skip_serializing_if = "Option::is_none")]
771 arch: Option<String>,
772 #[serde(skip_serializing_if = "Option::is_none")]
773 pub class: Option<String>,
774 #[serde(skip_serializing_if = "Option::is_none")]
775 pub nid: Option<String>,
776 #[serde(skip_serializing_if = "Option::is_none")]
777 pub nid_start: Option<String>,
778 #[serde(skip_serializing_if = "Option::is_none")]
779 pub nid_end: Option<String>,
780}
781
782#[derive(Debug, Serialize, Deserialize, Clone)]
783pub struct ComponentArrayPostByNidQuery {
784 #[serde(rename = "NIDRanges")]
785 pub nid_ranges: Vec<String>,
786 #[serde(skip_serializing_if = "Option::is_none")]
787 pub partition: Option<String>,
788 #[serde(skip_serializing_if = "Option::is_none")]
789 #[serde(rename = "stateonly")]
790 pub state_only: Option<bool>,
791 #[serde(skip_serializing_if = "Option::is_none")]
792 #[serde(rename = "flagonly")]
793 pub falg_only: Option<bool>,
794 #[serde(skip_serializing_if = "Option::is_none")]
795 #[serde(rename = "roleonly")]
796 pub role_only: Option<bool>,
797 #[serde(skip_serializing_if = "Option::is_none")]
798 #[serde(rename = "nidonly")]
799 pub nid_only: Option<bool>,
800}
801
802#[derive(Debug, Serialize, Deserialize, Clone)]
803pub struct ComponentArrayPostArray {
804 #[serde(rename = "Components")]
805 pub components: Vec<ComponentCreate>,
806 #[serde(skip_serializing_if = "Option::is_none")]
807 #[serde(rename = "Force")]
808 pub force: Option<bool>,
809}
810
811#[derive(Debug, Serialize, Deserialize, Clone)]
812pub struct ComponentCreate {
813 #[serde(rename = "ID")]
814 pub id: String,
815 #[serde(rename = "State")]
816 pub state: String,
817 #[serde(skip_serializing_if = "Option::is_none")]
818 #[serde(rename = "Flag")]
819 pub flag: Option<String>,
820 #[serde(skip_serializing_if = "Option::is_none")]
821 #[serde(rename = "Enabled")]
822 pub enabled: Option<bool>,
823 #[serde(skip_serializing_if = "Option::is_none")]
824 #[serde(rename = "SoftwareStatus")]
825 pub software_status: Option<String>,
826 #[serde(skip_serializing_if = "Option::is_none")]
827 #[serde(rename = "Role")]
828 pub role: Option<String>,
829 #[serde(skip_serializing_if = "Option::is_none")]
830 #[serde(rename = "SubRole")]
831 pub sub_role: Option<String>,
832 #[serde(skip_serializing_if = "Option::is_none")]
833 #[serde(rename = "NID")]
834 pub nid: Option<usize>,
835 #[serde(skip_serializing_if = "Option::is_none")]
836 #[serde(rename = "Subtype")]
837 pub subtype: Option<String>,
838 #[serde(skip_serializing_if = "Option::is_none")]
839 #[serde(rename = "NetType")]
840 pub net_type: Option<String>,
841 #[serde(skip_serializing_if = "Option::is_none")]
842 #[serde(rename = "Arch")]
843 pub arch: Option<String>,
844 #[serde(skip_serializing_if = "Option::is_none")]
845 #[serde(rename = "Class")]
846 pub class: Option<String>,
847}
848
849#[derive(Debug, Serialize, Deserialize, Clone)]
850pub struct ComponentPut {
851 pub component: ComponentCreate,
852 #[serde(skip_serializing_if = "Option::is_none")]
853 #[serde(rename = "Force")]
854 pub force: Option<bool>,
855}
856
857#[derive(Debug, Serialize, Deserialize, Default, Clone)]
858pub struct BootParameters {
859 #[serde(default)]
860 pub hosts: Vec<String>,
861 #[serde(skip_serializing_if = "Option::is_none")]
862 pub macs: Option<Vec<String>>,
863 #[serde(skip_serializing_if = "Option::is_none")]
864 pub nids: Option<Vec<u32>>,
865 #[serde(default)]
866 pub params: String, #[serde(default)]
870 pub kernel: String,
871 #[serde(default)]
872 pub initrd: String,
873 #[serde(rename = "cloud-init")]
874 #[serde(skip_serializing_if = "Option::is_none")]
875 pub cloud_init: Option<Value>,
876}
877
878impl BootParameters {
879 pub fn get_image_id_from_s3_path(s3_path: &str) -> Option<&str> {
884 s3_path.split("/").skip(3).next()
885 }
886
887 pub fn get_boot_image(&self) -> String {
890 let params: HashMap<&str, &str> = self
891 .params
892 .split_whitespace()
893 .map(|kernel_param| {
894 kernel_param
895 .split_once('=')
896 .map(|(key, value)| (key.trim(), value.trim()))
897 .unwrap_or((kernel_param, ""))
898 })
899 .collect();
900
901 let root_kernel_param_opt = params.get("root");
904 let metal_server_kernel_param_opt = params.get("metal.server");
907
908 let boot_image_id_opt: Option<&str> = if let Some(root_kernel_param) = root_kernel_param_opt
909 {
910 Self::get_image_id_from_s3_path(root_kernel_param)
911 } else if let Some(metal_server_kernel_param) = metal_server_kernel_param_opt {
912 Self::get_image_id_from_s3_path(metal_server_kernel_param)
913 } else {
914 None
915 };
916
917 boot_image_id_opt.unwrap_or("").to_string()
918
919 }
933
934 pub fn update_boot_image(&mut self, new_image_id: &str) -> Result<bool, Error> {
941 let mut changed = false;
942 let mut params: HashMap<&str, &str> = self
946 .params
947 .split_whitespace()
948 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
949 .collect();
950
951 let root_kernel_param_rslt = params.get("root");
954
955 let mut root_kernel_param: Vec<&str> = match root_kernel_param_rslt {
956 Some(root_kernel_param) => root_kernel_param.split("/").collect::<Vec<&str>>(),
957 None => {
958 return Err(Error::Message(
959 "ERROR - The 'root' kernel param is missing from user input".to_string(),
960 ));
961 }
962 };
963
964 for current_image_id in &mut root_kernel_param {
966 if uuid::Uuid::try_parse(current_image_id).is_ok() {
969 if *current_image_id != new_image_id {
970 changed = true;
971 }
972 *current_image_id = new_image_id;
974 }
975 }
976
977 let new_root_kernel_param = root_kernel_param.join("/");
979
980 params
982 .entry("root")
983 .and_modify(|root_param| *root_param = &new_root_kernel_param);
984
985 self.update_kernel_param("root", &new_root_kernel_param);
986
987 let mut params: HashMap<&str, &str> = self
991 .params
992 .split_whitespace()
993 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
994 .map(|(key, value)| (key.trim(), value.trim()))
995 .collect();
996
997 let mut metal_server_kernel_param: Vec<&str>;
999 if let Some(metal_server_data) = params.get("metal.server") {
1000 metal_server_kernel_param = metal_server_data.split("/").collect();
1001
1002 for substring in &mut metal_server_kernel_param {
1003 if uuid::Uuid::try_parse(substring).is_ok() {
1004 *substring = new_image_id;
1005 changed = true;
1006 }
1007 }
1008
1009 let new_metal_server_kernel_param = metal_server_kernel_param.join("/");
1010
1011 params
1012 .entry("metal.server")
1013 .and_modify(|metal_server_param| {
1014 *metal_server_param = &new_metal_server_kernel_param
1015 });
1016
1017 self.update_kernel_param("metal.server", &new_metal_server_kernel_param);
1018
1019 params = self
1021 .params
1022 .split_whitespace()
1023 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1024 .collect();
1025 } else {
1026 };
1027
1028 let mut nmd_kernel_param: Vec<&str>;
1030 if let Some(nmd_data) = params.get("nmd_data") {
1031 nmd_kernel_param = nmd_data.split("/").collect();
1032
1033 for substring in &mut nmd_kernel_param {
1034 if uuid::Uuid::try_parse(substring).is_ok() {
1035 *substring = new_image_id;
1036 changed = true;
1037 }
1038 }
1039
1040 let new_nmd_kernel_param = nmd_kernel_param.join("/");
1041
1042 params
1043 .entry("nmd_data")
1044 .and_modify(|nmd_param| *nmd_param = &new_nmd_kernel_param);
1045
1046 self.update_kernel_param("nmd_data", &new_nmd_kernel_param);
1047 } else {
1048 };
1049
1050 self.kernel = format!("s3://boot-images/{}/kernel", new_image_id);
1051
1052 self.initrd = format!("s3://boot-images/{}/initrd", new_image_id);
1053
1054 Ok(changed)
1055 }
1056
1057 pub fn update_kernel_params(&mut self, new_params: &str) -> bool {
1062 let mut change = false;
1063
1064 let new_params: Vec<(&str, &str)> = new_params
1065 .split_whitespace()
1066 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1067 .map(|(key, value)| (key.trim(), value.trim()))
1068 .collect();
1069
1070 let mut params: HashMap<&str, &str> = self
1071 .params
1072 .split_whitespace()
1073 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1074 .collect();
1075
1076 for (new_key, new_value) in &new_params {
1077 for (key, value) in params.iter_mut() {
1078 if *key == *new_key {
1079 log::debug!("key '{}' found", key);
1080 if value != new_value {
1081 log::info!("changing key {} from {} to {}", key, value, new_value);
1082
1083 *value = new_value;
1084 change = true
1085 } else {
1086 log::debug!("key '{}' value does not change ({})", key, value);
1087 }
1088 }
1089 }
1090 }
1091
1092 if change == false {
1093 log::debug!("No value change in kernel params. Checking is either new params have been added or removed");
1094 if new_params.len() != params.len() {
1095 log::info!("num kernel parameters have changed");
1096 change = true;
1097 }
1098 }
1099
1100 self.params = params
1101 .iter()
1102 .map(|(key, value)| {
1103 if !value.is_empty() {
1104 format!("{key}={value}")
1105 } else {
1106 key.to_string()
1107 }
1108 })
1109 .collect::<Vec<String>>()
1110 .join(" ");
1111
1112 change
1113 }
1114
1115 pub fn update_kernel_param(&mut self, new_key: &str, new_value: &str) -> bool {
1120 let mut changed = false;
1121 let mut params: HashMap<&str, &str> = self
1123 .params
1124 .split_whitespace()
1125 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1126 .map(|(key, value)| (key.trim(), value.trim()))
1127 .collect();
1128
1129 for (current_key, current_value) in params.iter_mut() {
1132 if *current_key == new_key {
1133 log::debug!("key '{}' found", new_key);
1134 if *current_value != new_value {
1135 log::info!(
1136 "changing key {} from {} to {}",
1137 new_key,
1138 current_value,
1139 new_value
1140 );
1141
1142 *current_value = new_value;
1143 changed = true
1144 } else {
1145 log::debug!(
1146 "key '{}' value does not change ({})",
1147 new_key,
1148 current_value
1149 );
1150 }
1151 }
1152 }
1157
1158 self.params = params
1160 .iter()
1161 .map(|(key, value)| {
1162 if !value.is_empty() {
1163 format!("{key}={value}")
1164 } else {
1165 key.to_string()
1166 }
1167 })
1168 .collect::<Vec<String>>()
1169 .join(" ");
1170
1171 changed
1172 }
1173
1174 pub fn add_kernel_params(&mut self, new_kernel_params: &str) -> bool {
1179 let mut changed = false;
1180 let mut params: HashMap<&str, &str> = self
1181 .params
1182 .split_whitespace()
1183 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1184 .map(|(key, value)| (key.trim(), value.trim()))
1185 .collect();
1186
1187 let new_kernel_params_tuple: HashMap<&str, &str> = new_kernel_params
1188 .split_whitespace()
1189 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1190 .collect();
1191
1192 for (key, new_value) in new_kernel_params_tuple {
1193 if params.contains_key(key) {
1196 log::info!("key '{}' already exists, the new kernel parameter won't be added since it already exists", key);
1197 } else {
1198 log::info!(
1199 "key '{}' not found, adding new kernel param with value '{}'",
1200 key,
1201 new_value
1202 );
1203 params.insert(key, new_value);
1204 changed = true
1205 }
1206 }
1207
1208 self.params = params
1209 .iter()
1210 .map(|(key, value)| {
1211 if !value.is_empty() {
1212 format!("{key}={value}")
1213 } else {
1214 key.to_string()
1215 }
1216 })
1217 .collect::<Vec<String>>()
1218 .join(" ");
1219
1220 changed
1221 }
1222
1223 pub fn delete_kernel_params(&mut self, kernel_params_to_delete: &str) -> bool {
1228 let mut changed = false;
1229 let mut params: HashMap<&str, &str> = self
1230 .params
1231 .split_whitespace()
1232 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1233 .map(|(key, value)| (key.trim(), value.trim()))
1234 .collect();
1235
1236 let kernel_params_to_delete_tuple: HashMap<&str, &str> = kernel_params_to_delete
1237 .split_whitespace()
1238 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1239 .collect();
1240
1241 for (key, _value) in kernel_params_to_delete_tuple {
1242 log::debug!("key '{}' to be removed", key);
1243
1244 changed = changed | params.remove(key).is_some();
1245
1246 if changed {
1247 log::debug!("key '{}' removed", key);
1248 } else {
1249 log::debug!("key '{}' not found", key);
1250 }
1251 }
1252
1253 self.params = params
1254 .iter()
1255 .map(|(key, value)| {
1256 if !value.is_empty() {
1257 format!("{key}={value}")
1258 } else {
1259 key.to_string()
1260 }
1261 })
1262 .collect::<Vec<String>>()
1263 .join(" ");
1264
1265 changed
1266 }
1267
1268 pub fn apply_kernel_params(&mut self, new_params: &str) -> bool {
1273 let mut change = false;
1274
1275 let new_params: Vec<(&str, &str)> = new_params
1276 .split_whitespace()
1277 .map(|kernel_param| kernel_param.split_once('=').unwrap_or((kernel_param, "")))
1278 .map(|(key, value)| (key.trim(), value.trim()))
1279 .collect();
1280
1281 let mut params: HashMap<&str, &str> = HashMap::new();
1282
1283 for (new_key, new_value) in &new_params {
1284 for (key, value) in params.iter_mut() {
1285 if *key == *new_key {
1286 log::debug!("key '{}' found", key);
1287 if value != new_value {
1288 log::info!("changing key {} from {} to {}", key, value, new_value);
1289
1290 *value = new_value;
1291 change = true
1292 } else {
1293 log::debug!("key '{}' value does not change ({})", key, value);
1294 }
1295 }
1296 }
1297 }
1298
1299 if change == false {
1300 log::debug!("No value change in kernel params. Checking is either new params have been added or removed");
1301 if new_params.len() != params.len() {
1302 log::info!("num kernel parameters have changed");
1303 change = true;
1304 }
1305 }
1306
1307 self.params = new_params
1308 .iter()
1309 .map(|(key, value)| {
1310 if !value.is_empty() {
1311 format!("{key}={value}")
1312 } else {
1313 key.to_string()
1314 }
1315 })
1316 .collect::<Vec<String>>()
1317 .join(" ");
1318
1319 change
1320 }
1321}
1322
1323#[derive(Debug, Serialize, Deserialize)]
1324pub enum ComponentType {
1325 CDU,
1326 CabinetCDU,
1327 CabinetPDU,
1328 CabinetPDUOutlet,
1329 CabinetPDUPowerConnector,
1330 CabinetPDUController,
1331 r#Cabinet,
1332 Chassis,
1333 ChassisBMC,
1334 CMMRectifier,
1335 CMMFpga,
1336 CEC,
1337 ComputeModule,
1338 RouterModule,
1339 NodeBMC,
1340 NodeEnclosure,
1341 NodeEnclosurePowerSupply,
1342 HSNBoard,
1343 Node,
1344 Processor,
1345 Drive,
1346 StorageGroup,
1347 NodeNIC,
1348 Memory,
1349 NodeAccel,
1350 NodeAccelRiser,
1351 NodeFpga,
1352 HSNAsic,
1353 RouterFpga,
1354 RouterBMC,
1355 HSNLink,
1356 HSNConnector,
1357 INVALID,
1358}
1359
1360#[derive(Debug, Serialize, Deserialize, Clone)]
1361pub struct ProcessorId {
1362 #[serde(rename = "EffectiveFamily")]
1363 #[serde(skip_serializing_if = "Option::is_none")]
1364 pub effective_family: Option<String>,
1365 #[serde(rename = "EffectiveModel")]
1366 #[serde(skip_serializing_if = "Option::is_none")]
1367 pub efffective_model: Option<String>,
1368 #[serde(rename = "IdentificationRegisters")]
1369 #[serde(skip_serializing_if = "Option::is_none")]
1370 pub identification_registers: Option<String>,
1371 #[serde(rename = "MicrocodeInfo")]
1372 #[serde(skip_serializing_if = "Option::is_none")]
1373 pub microcode_info: Option<String>,
1374 #[serde(rename = "Step")]
1375 #[serde(skip_serializing_if = "Option::is_none")]
1376 pub step: Option<String>,
1377 #[serde(rename = "VendorId")]
1378 #[serde(skip_serializing_if = "Option::is_none")]
1379 pub vendor_id: Option<String>,
1380}
1381
1382#[derive(Debug, Serialize, Deserialize, Clone)]
1383pub struct HWInvByFRUProcessor {
1384 #[serde(rename = "FRUID")]
1385 #[serde(skip_serializing_if = "Option::is_none")]
1386 pub fru_id: Option<String>,
1387 #[serde(rename = "Type")]
1388 #[serde(skip_serializing_if = "Option::is_none")]
1389 pub r#type: Option<String>,
1390 #[serde(rename = "FRUSubType")]
1391 #[serde(skip_serializing_if = "Option::is_none")]
1392 pub fru_sub_type: Option<String>,
1393 #[serde(rename = "HWInventoryByFRUType")]
1394 pub hw_inventory_by_fru_type: String,
1395 #[serde(rename = "ProcessorFRUInfo")]
1396 pub processor_fru_info: RedfishProcessorFRUInfo,
1397}
1398
1399#[derive(Debug, Serialize, Deserialize, Clone)]
1400pub struct HWInvByFRUMemory {
1401 #[serde(rename = "FRUID")]
1402 #[serde(skip_serializing_if = "Option::is_none")]
1403 pub fru_id: Option<String>,
1404 #[serde(rename = "Type")]
1405 #[serde(skip_serializing_if = "Option::is_none")]
1406 pub r#type: Option<String>,
1407 #[serde(rename = "FRUSubType")]
1408 #[serde(skip_serializing_if = "Option::is_none")]
1409 pub fru_sub_type: Option<String>,
1410 #[serde(rename = "HWInventoryByFRUType")]
1411 pub hw_inventory_by_fru_type: String,
1412 #[serde(rename = "MemoryFRUInfo")]
1413 pub memory_fru_info: RedfishMemoryFRUInfo,
1414}
1415
1416#[derive(Debug, Serialize, Deserialize, Clone)]
1417pub struct HWInvByFRUHSNNIC {
1418 #[serde(rename = "FRUID")]
1419 #[serde(skip_serializing_if = "Option::is_none")]
1420 pub fru_id: Option<String>,
1421 #[serde(rename = "Type")]
1422 #[serde(skip_serializing_if = "Option::is_none")]
1423 pub r#type: Option<String>,
1424 #[serde(rename = "FRUSubType")]
1425 #[serde(skip_serializing_if = "Option::is_none")]
1426 pub fru_sub_type: Option<String>,
1427 #[serde(rename = "HWInventoryByFRUType")]
1428 pub hw_inventory_by_fru_type: String,
1429 #[serde(rename = "HSNNICFRUInfo")]
1430 pub hsn_nic_fru_info: HSNNICFRUInfo,
1431}
1432
1433#[derive(Debug, Serialize, Deserialize, Clone)]
1434pub struct HWInvByFRUNodeAccel {
1435 #[serde(rename = "FRUID")]
1436 #[serde(skip_serializing_if = "Option::is_none")]
1437 pub fru_id: Option<String>,
1438 #[serde(rename = "Type")]
1439 #[serde(skip_serializing_if = "Option::is_none")]
1440 pub r#type: Option<String>,
1441 #[serde(rename = "FRUSubType")]
1442 #[serde(skip_serializing_if = "Option::is_none")]
1443 pub fru_sub_type: Option<String>,
1444 #[serde(rename = "HWInventoryByFRUType")]
1445 pub hw_inventory_by_fru_type: String,
1446 #[serde(rename = "NodeAccelFRUInfo")]
1447 pub node_accel_fru_info: RedfishProcessorFRUInfo, }
1450
1451#[derive(Debug, Serialize, Deserialize, Clone)]
1452pub struct RedfishProcessorFRUInfo {
1453 #[serde(rename = "InstructionSet")]
1454 #[serde(skip_serializing_if = "Option::is_none")]
1455 pub instruction_set: Option<String>,
1456 #[serde(rename = "Manufacturer")]
1457 #[serde(skip_serializing_if = "Option::is_none")]
1458 pub manufacturer: Option<String>,
1459 #[serde(rename = "MaxSpeedMHz")]
1460 #[serde(skip_serializing_if = "Option::is_none")]
1461 pub max_speed_mhz: Option<usize>,
1462 #[serde(rename = "Model")]
1463 #[serde(skip_serializing_if = "Option::is_none")]
1464 pub model: Option<String>,
1465 #[serde(rename = "ProcessorArchitecture")]
1466 #[serde(skip_serializing_if = "Option::is_none")]
1467 pub processor_architecture: Option<String>,
1468 #[serde(rename = "ProcessorId")]
1469 #[serde(skip_serializing_if = "Option::is_none")]
1470 pub processor_id: Option<ProcessorId>,
1471 #[serde(rename = "ProcessorType")]
1472 #[serde(skip_serializing_if = "Option::is_none")]
1473 pub processor_type: Option<String>,
1474 #[serde(rename = "TotalCores")]
1475 #[serde(skip_serializing_if = "Option::is_none")]
1476 pub total_cores: Option<usize>,
1477 #[serde(rename = "TotalThreads")]
1478 #[serde(skip_serializing_if = "Option::is_none")]
1479 pub total_threads: Option<usize>,
1480}
1481
1482#[derive(Debug, Serialize, Deserialize, Clone)]
1483pub struct RedfishMemoryFRUInfo {
1484 #[serde(rename = "BaseModuleType")]
1485 #[serde(skip_serializing_if = "Option::is_none")]
1486 pub base_module_type: Option<String>,
1487 #[serde(rename = "BusWidthBits")]
1488 #[serde(skip_serializing_if = "Option::is_none")]
1489 pub bus_width_bits: Option<usize>,
1490 #[serde(rename = "CapacityMiB")]
1491 #[serde(skip_serializing_if = "Option::is_none")]
1492 pub capacity_mib: Option<usize>,
1493 #[serde(rename = "DataWidthBits")]
1494 #[serde(skip_serializing_if = "Option::is_none")]
1495 pub data_width_bits: Option<usize>,
1496 #[serde(rename = "ErrorCorrection")]
1497 #[serde(skip_serializing_if = "Option::is_none")]
1498 pub error_correction: Option<String>,
1499 #[serde(rename = "Manufacturer")]
1500 #[serde(skip_serializing_if = "Option::is_none")]
1501 pub manufacturer: Option<String>,
1502 #[serde(rename = "MemoryType")]
1503 #[serde(skip_serializing_if = "Option::is_none")]
1504 pub memory_type: Option<String>,
1505 #[serde(rename = "MemoryDeviceType")]
1506 #[serde(skip_serializing_if = "Option::is_none")]
1507 pub memory_device_type: Option<String>,
1508 #[serde(rename = "OperatingSpeedMhz")]
1509 #[serde(skip_serializing_if = "Option::is_none")]
1510 pub operating_speed_mhz: Option<usize>,
1511 #[serde(rename = "PartNumber")]
1512 #[serde(skip_serializing_if = "Option::is_none")]
1513 pub part_number: Option<String>,
1514 #[serde(rename = "RankCount")]
1515 #[serde(skip_serializing_if = "Option::is_none")]
1516 pub rank_count: Option<usize>,
1517 #[serde(rename = "SerialNumber")]
1518 #[serde(skip_serializing_if = "Option::is_none")]
1519 pub serial_number: Option<String>,
1520}
1521
1522#[derive(Debug, Serialize, Deserialize, Clone)]
1523pub struct HWInventoryByFRU {
1524 #[serde(rename = "FRUID")]
1525 #[serde(skip_serializing_if = "Option::is_none")]
1526 pub fru_id: Option<String>,
1527 #[serde(rename = "Type")]
1528 #[serde(skip_serializing_if = "Option::is_none")]
1529 pub r#type: Option<String>,
1530 #[serde(rename = "FRUSubType")]
1531 #[serde(skip_serializing_if = "Option::is_none")]
1532 pub fru_sub_type: Option<String>,
1533 #[serde(rename = "HWInventoryByFRUType")]
1534 pub hw_inventory_by_fru_type: String,
1535}
1536
1537#[derive(Debug, Serialize, Deserialize, Clone)]
1538pub struct RedfishChassisLocationInfo {
1539 #[serde(rename = "Id")]
1540 #[serde(skip_serializing_if = "Option::is_none")]
1541 pub id: Option<String>,
1542 #[serde(rename = "Name")]
1543 #[serde(skip_serializing_if = "Option::is_none")]
1544 pub name: Option<String>,
1545 #[serde(rename = "Description")]
1546 #[serde(skip_serializing_if = "Option::is_none")]
1547 pub description: Option<String>,
1548 #[serde(rename = "Hostname")]
1549 #[serde(skip_serializing_if = "Option::is_none")]
1550 pub hostname: Option<String>,
1551}
1552
1553#[derive(Debug, Serialize, Deserialize, Clone)]
1554pub struct HWInvByLocChassis {
1555 #[serde(rename = "ID")]
1556 pub id: String,
1557 #[serde(rename = "Type")]
1558 #[serde(skip_serializing_if = "Option::is_none")]
1559 pub r#type: Option<String>,
1560 #[serde(rename = "Ordinal")]
1561 #[serde(skip_serializing_if = "Option::is_none")]
1562 pub ordinal: Option<u32>,
1563 #[serde(rename = "Status")]
1564 #[serde(skip_serializing_if = "Option::is_none")]
1565 pub status: Option<String>,
1566 #[serde(rename = "HWInventoryByLocationType")]
1567 pub hw_inventory_by_location_type: String,
1568 #[serde(rename = "PopulatedFRU")]
1569 #[serde(skip_serializing_if = "Option::is_none")]
1570 pub populated_fru: Option<HWInventoryByFRU>,
1571 #[serde(rename = "ChassisLocatinInfo")]
1572 #[serde(skip_serializing_if = "Option::is_none")]
1573 pub chassis_location_info: Option<RedfishChassisLocationInfo>,
1574 #[serde(rename = "ComputeModules")]
1575 #[serde(skip_serializing_if = "Option::is_none")]
1576 pub compute_modules: Option<HWInvByLocComputeModule>,
1577 #[serde(rename = "RouterModules")]
1578 #[serde(skip_serializing_if = "Option::is_none")]
1579 pub router_modules: Option<HWInvByLocRouterModule>,
1580}
1581
1582#[derive(Debug, Serialize, Deserialize, Clone)]
1583pub struct HWInvByLocNodeEnclosure {
1584 #[serde(rename = "ID")]
1585 pub id: String,
1586 #[serde(rename = "Type")]
1587 #[serde(skip_serializing_if = "Option::is_none")]
1588 pub r#type: Option<String>,
1589 #[serde(rename = "Ordinal")]
1590 #[serde(skip_serializing_if = "Option::is_none")]
1591 pub ordinal: Option<u32>,
1592 #[serde(rename = "Status")]
1593 #[serde(skip_serializing_if = "Option::is_none")]
1594 pub status: Option<String>,
1595 #[serde(rename = "HWInventoryByLocationType")]
1596 pub hw_inventory_by_location_type: String,
1597 #[serde(rename = "PopulatedFRU")]
1598 #[serde(skip_serializing_if = "Option::is_none")]
1599 pub populated_fru: Option<HWInventoryByFRU>,
1600 #[serde(rename = "NodeEnclosureLocationInfo")]
1601 #[serde(skip_serializing_if = "Option::is_none")]
1602 pub node_enclosure_location_info: Option<RedfishChassisLocationInfo>,
1603}
1604
1605#[derive(Debug, Serialize, Deserialize, Clone)]
1606pub struct HWInvByLocComputeModule {
1607 #[serde(rename = "ID")]
1608 pub id: String,
1609 #[serde(rename = "Type")]
1610 #[serde(skip_serializing_if = "Option::is_none")]
1611 pub r#type: Option<String>,
1612 #[serde(rename = "Ordinal")]
1613 #[serde(skip_serializing_if = "Option::is_none")]
1614 pub ordinal: Option<u32>,
1615 #[serde(rename = "Status")]
1616 #[serde(skip_serializing_if = "Option::is_none")]
1617 pub status: Option<String>,
1618 #[serde(rename = "HWInventoryByLocationType")]
1619 pub hw_inventory_by_location_type: String,
1620 #[serde(rename = "PopulatedFRU")]
1621 #[serde(skip_serializing_if = "Option::is_none")]
1622 pub populated_fru: Option<HWInventoryByFRU>,
1623 #[serde(rename = "ComputeModuleLocationInfo")]
1624 #[serde(skip_serializing_if = "Option::is_none")]
1625 pub compute_module_location_info: Option<RedfishChassisLocationInfo>,
1626 #[serde(rename = "NodeEnclosures")]
1627 #[serde(skip_serializing_if = "Option::is_none")]
1628 pub node_enclosures: Option<HWInvByLocNodeEnclosure>,
1629}
1630
1631#[derive(Debug, Serialize, Deserialize, Clone)]
1632pub struct HWInvByLocHSNBoard {
1633 #[serde(rename = "ID")]
1634 pub id: String,
1635 #[serde(rename = "Type")]
1636 #[serde(skip_serializing_if = "Option::is_none")]
1637 pub r#type: Option<String>,
1638 #[serde(rename = "Ordinal")]
1639 #[serde(skip_serializing_if = "Option::is_none")]
1640 pub ordinal: Option<u32>,
1641 #[serde(rename = "Status")]
1642 #[serde(skip_serializing_if = "Option::is_none")]
1643 pub status: Option<String>,
1644 #[serde(rename = "HWInventoryByLocationType")]
1645 pub hw_inventory_by_location_type: String,
1646 #[serde(rename = "PopulatedFRU")]
1647 #[serde(skip_serializing_if = "Option::is_none")]
1648 pub populated_fru: Option<HWInventoryByFRU>,
1649 #[serde(rename = "HSNBoardLocationInfo")]
1650 #[serde(skip_serializing_if = "Option::is_none")]
1651 pub hsn_board_location_info: Option<RedfishChassisLocationInfo>,
1652}
1653
1654#[derive(Debug, Serialize, Deserialize, Clone)]
1655pub struct HWInvByLocRouterModule {
1656 #[serde(rename = "ID")]
1657 pub id: String,
1658 #[serde(rename = "Type")]
1659 #[serde(skip_serializing_if = "Option::is_none")]
1660 pub r#type: Option<String>,
1661 #[serde(rename = "Ordinal")]
1662 #[serde(skip_serializing_if = "Option::is_none")]
1663 pub ordinal: Option<u32>,
1664 #[serde(rename = "Status")]
1665 #[serde(skip_serializing_if = "Option::is_none")]
1666 pub status: Option<String>,
1667 #[serde(rename = "HWInventoryByLocationType")]
1668 pub hw_inventory_by_location_type: String,
1669 #[serde(rename = "PopulatedFRU")]
1670 #[serde(skip_serializing_if = "Option::is_none")]
1671 pub populated_fru: Option<HWInventoryByFRU>,
1672 #[serde(rename = "RouterModuleLocationInfo")]
1673 #[serde(skip_serializing_if = "Option::is_none")]
1674 pub router_module_location_info: Option<RedfishChassisLocationInfo>,
1675 pub hsn_boards: Option<HWInvByLocHSNBoard>,
1676}
1677
1678#[derive(Debug, Serialize, Deserialize, Clone)]
1679pub struct HWInvByLocCabinet {
1680 #[serde(rename = "ID")]
1681 pub id: String,
1682 #[serde(rename = "Type")]
1683 #[serde(skip_serializing_if = "Option::is_none")]
1684 pub r#type: Option<String>,
1685 #[serde(rename = "Ordinal")]
1686 #[serde(skip_serializing_if = "Option::is_none")]
1687 pub ordinal: Option<u32>,
1688 #[serde(rename = "Status")]
1689 #[serde(skip_serializing_if = "Option::is_none")]
1690 pub status: Option<String>,
1691 #[serde(rename = "HWInventoryByLocationType")]
1692 pub hw_inventory_by_location_type: String,
1693 #[serde(rename = "PopulatedFRU")]
1694 #[serde(skip_serializing_if = "Option::is_none")]
1695 pub populated_fru: Option<HWInventoryByFRU>,
1696 #[serde(rename = "CabinetLocationInfo")]
1697 #[serde(skip_serializing_if = "Option::is_none")]
1698 pub cabinet_location_info: Option<RedfishChassisLocationInfo>,
1699 #[serde(rename = "Chassis")]
1700 #[serde(skip_serializing_if = "Option::is_none")]
1701 pub chassis: Option<HWInvByLocChassis>,
1702}
1703
1704#[derive(Debug, Serialize, Deserialize, Clone)]
1705pub struct HWInvByLocMgmtSwitch {
1706 #[serde(rename = "ID")]
1707 pub id: String,
1708 #[serde(rename = "Type")]
1709 #[serde(skip_serializing_if = "Option::is_none")]
1710 pub r#type: Option<String>,
1711 #[serde(rename = "Ordinal")]
1712 #[serde(skip_serializing_if = "Option::is_none")]
1713 pub ordinal: Option<u32>,
1714 #[serde(rename = "Status")]
1715 #[serde(skip_serializing_if = "Option::is_none")]
1716 pub status: Option<String>,
1717 #[serde(rename = "HWInventoryByLocationType")]
1718 pub hw_inventory_by_location_type: String,
1719 #[serde(rename = "PopulatedFRU")]
1720 #[serde(skip_serializing_if = "Option::is_none")]
1721 pub populated_fru: Option<HWInventoryByFRU>,
1722 #[serde(rename = "MgmtSwitchLocationInfo")]
1723 #[serde(skip_serializing_if = "Option::is_none")]
1724 pub mgmt_switch_location_info: Option<RedfishChassisLocationInfo>,
1725}
1726
1727#[derive(Debug, Serialize, Deserialize, Clone)]
1728pub struct HWInvByLocMgmtHLSwitch {
1729 #[serde(rename = "ID")]
1730 pub id: String,
1731 #[serde(rename = "Type")]
1732 #[serde(skip_serializing_if = "Option::is_none")]
1733 pub r#type: Option<String>,
1734 #[serde(rename = "Ordinal")]
1735 #[serde(skip_serializing_if = "Option::is_none")]
1736 pub ordinal: Option<u32>,
1737 #[serde(rename = "Status")]
1738 #[serde(skip_serializing_if = "Option::is_none")]
1739 pub status: Option<String>,
1740 #[serde(rename = "HWInventoryByLocationType")]
1741 pub hw_inventory_by_location_type: String,
1742 #[serde(rename = "PopulatedFRU")]
1743 #[serde(skip_serializing_if = "Option::is_none")]
1744 pub populated_fru: Option<HWInventoryByFRU>,
1745 #[serde(rename = "MgmtHLSwitchLocationInfo")]
1746 #[serde(skip_serializing_if = "Option::is_none")]
1747 pub mgmt_hl_switch_location_info: Option<RedfishChassisLocationInfo>,
1748}
1749
1750#[derive(Debug, Serialize, Deserialize, Clone)]
1751pub struct HWInvByLocCDUMgmtSwitch {
1752 #[serde(rename = "ID")]
1753 pub id: String,
1754 #[serde(rename = "Type")]
1755 #[serde(skip_serializing_if = "Option::is_none")]
1756 pub r#type: Option<String>,
1757 #[serde(rename = "Ordinal")]
1758 #[serde(skip_serializing_if = "Option::is_none")]
1759 pub ordinal: Option<u32>,
1760 #[serde(rename = "Status")]
1761 #[serde(skip_serializing_if = "Option::is_none")]
1762 pub status: Option<String>,
1763 #[serde(rename = "HWInventoryByLocationType")]
1764 pub hw_inventory_by_location_type: String,
1765 #[serde(rename = "PopulatedFRU")]
1766 #[serde(skip_serializing_if = "Option::is_none")]
1767 pub populated_fru: Option<HWInventoryByFRU>,
1768 #[serde(rename = "CDUMgmtSwitchLocationInfo")]
1769 #[serde(skip_serializing_if = "Option::is_none")]
1770 pub cdu_mgmt_switch_location_info: Option<RedfishChassisLocationInfo>,
1771}
1772
1773#[derive(Debug, Serialize, Deserialize, Clone)]
1774pub struct ProcessorSummary {
1775 #[serde(rename = "Count")]
1776 #[serde(skip_serializing_if = "Option::is_none")]
1777 pub count: Option<u32>,
1778 #[serde(rename = "Model")]
1779 #[serde(skip_serializing_if = "Option::is_none")]
1780 pub model: Option<String>,
1781}
1782
1783#[derive(Debug, Serialize, Deserialize, Clone)]
1784pub struct MemorySummary {
1785 #[serde(rename = "TotalSystemMemoryGiB")]
1786 #[serde(skip_serializing_if = "Option::is_none")]
1787 pub total_system_memory_gib: Option<u32>,
1788}
1789
1790#[derive(Debug, Serialize, Deserialize, Clone)]
1791pub struct RedfishSystemLocationInfo {
1792 #[serde(rename = "Id")]
1793 #[serde(skip_serializing_if = "Option::is_none")]
1794 pub id: Option<String>,
1795 #[serde(rename = "Name")]
1796 #[serde(skip_serializing_if = "Option::is_none")]
1797 pub name: Option<String>,
1798 #[serde(rename = "Description")]
1799 #[serde(skip_serializing_if = "Option::is_none")]
1800 pub description: Option<String>,
1801 #[serde(rename = "Hostname")]
1802 #[serde(skip_serializing_if = "Option::is_none")]
1803 pub hostname: Option<String>,
1804 #[serde(rename = "ProcessorSummary")]
1805 #[serde(skip_serializing_if = "Option::is_none")]
1806 pub processor_summary: Option<ProcessorSummary>,
1807 #[serde(rename = "MemorySummary")]
1808 #[serde(skip_serializing_if = "Option::is_none")]
1809 pub memory_summary: Option<MemorySummary>,
1810}
1811
1812#[derive(Debug, Serialize, Deserialize, Clone)]
1813pub struct RedfishProcessorLocationInfo {
1814 #[serde(rename = "Id")]
1815 #[serde(skip_serializing_if = "Option::is_none")]
1816 pub id: Option<String>,
1817 #[serde(rename = "Name")]
1818 #[serde(skip_serializing_if = "Option::is_none")]
1819 pub name: Option<String>,
1820 #[serde(rename = "Description")]
1821 #[serde(skip_serializing_if = "Option::is_none")]
1822 pub description: Option<String>,
1823 #[serde(rename = "Socket")]
1824 #[serde(skip_serializing_if = "Option::is_none")]
1825 pub socket: Option<String>,
1826}
1827
1828#[derive(Debug, Serialize, Deserialize, Clone)]
1829pub struct HWInvByLocProcessor {
1830 #[serde(rename = "ID")]
1831 pub id: String,
1832 #[serde(rename = "Type")]
1833 #[serde(skip_serializing_if = "Option::is_none")]
1834 pub r#type: Option<String>,
1835 #[serde(rename = "Ordinal")]
1836 #[serde(skip_serializing_if = "Option::is_none")]
1837 pub ordinal: Option<u32>,
1838 #[serde(rename = "Status")]
1839 #[serde(skip_serializing_if = "Option::is_none")]
1840 pub status: Option<String>,
1841 #[serde(rename = "HWInventoryByLocationType")]
1842 pub hw_inventory_by_location_type: String,
1843 #[serde(rename = "PopulatedFRU")]
1844 #[serde(skip_serializing_if = "Option::is_none")]
1845 pub populated_fru: Option<HWInvByFRUProcessor>,
1846 #[serde(rename = "ProcessorLocationInfo")]
1847 pub processor_location_info: RedfishProcessorLocationInfo,
1848}
1849
1850#[derive(Debug, Serialize, Deserialize, Clone)]
1851pub struct HWInvByLocNodeAccel {
1852 #[serde(rename = "ID")]
1853 pub id: String,
1854 #[serde(rename = "Type")]
1855 #[serde(skip_serializing_if = "Option::is_none")]
1856 pub r#type: Option<String>,
1857 #[serde(rename = "Ordinal")]
1858 #[serde(skip_serializing_if = "Option::is_none")]
1859 pub ordinal: Option<u32>,
1860 #[serde(rename = "Status")]
1861 #[serde(skip_serializing_if = "Option::is_none")]
1862 pub status: Option<String>,
1863 #[serde(rename = "HWInventoryByLocationType")]
1864 pub hw_inventory_by_location_type: String,
1865 #[serde(rename = "PopulatedFRU")]
1866 #[serde(skip_serializing_if = "Option::is_none")]
1867 pub populated_fru: Option<HWInvByFRUNodeAccel>,
1868 #[serde(rename = "NodeAccelLocationInfo")]
1869 #[serde(skip_serializing_if = "Option::is_none")]
1870 pub node_accel_location_info: Option<RedfishProcessorLocationInfo>,
1871}
1872
1873#[derive(Debug, Serialize, Deserialize, Clone)]
1874pub struct RedfishDriveLocationInfo {
1875 #[serde(rename = "Id")]
1876 #[serde(skip_serializing_if = "Option::is_none")]
1877 pub id: Option<String>,
1878 #[serde(rename = "Name")]
1879 #[serde(skip_serializing_if = "Option::is_none")]
1880 pub name: Option<String>,
1881 #[serde(rename = "Description")]
1882 #[serde(skip_serializing_if = "Option::is_none")]
1883 pub description: Option<String>,
1884}
1885
1886#[derive(Debug, Serialize, Deserialize, Clone)]
1887pub struct HWInvByLocDrive {
1888 #[serde(rename = "ID")]
1889 pub id: String,
1890 #[serde(rename = "Type")]
1891 #[serde(skip_serializing_if = "Option::is_none")]
1892 pub r#type: Option<String>,
1893 #[serde(rename = "Ordinal")]
1894 #[serde(skip_serializing_if = "Option::is_none")]
1895 pub ordinal: Option<u32>,
1896 #[serde(rename = "Status")]
1897 #[serde(skip_serializing_if = "Option::is_none")]
1898 pub status: Option<String>,
1899 #[serde(rename = "HWInventoryByLocationType")]
1900 pub hw_inventory_by_location_type: String,
1901 #[serde(rename = "PopulatedFRU")]
1902 #[serde(skip_serializing_if = "Option::is_none")]
1903 pub populated_fru: Option<HWInventoryByFRU>,
1904 #[serde(rename = "DriveLocationInfo")]
1905 #[serde(skip_serializing_if = "Option::is_none")]
1906 pub drive_location_info: Option<RedfishDriveLocationInfo>,
1907}
1908
1909#[derive(Debug, Serialize, Deserialize, Clone)]
1910pub struct MemoryLocation {
1911 #[serde(rename = "Socket")]
1912 #[serde(skip_serializing_if = "Option::is_none")]
1913 pub socket: Option<u32>,
1914 #[serde(rename = "MemoryController")]
1915 #[serde(skip_serializing_if = "Option::is_none")]
1916 pub memory_controller: Option<u32>,
1917 #[serde(rename = "Channel")]
1918 #[serde(skip_serializing_if = "Option::is_none")]
1919 pub channel: Option<u32>,
1920 #[serde(rename = "Slot")]
1921 #[serde(skip_serializing_if = "Option::is_none")]
1922 pub slot: Option<u32>,
1923}
1924
1925#[derive(Debug, Serialize, Deserialize, Clone)]
1926pub struct RedfishMemoryLocationInfo {
1927 #[serde(rename = "Id")]
1928 #[serde(skip_serializing_if = "Option::is_none")]
1929 pub id: Option<String>,
1930 #[serde(rename = "Name")]
1931 #[serde(skip_serializing_if = "Option::is_none")]
1932 pub name: Option<String>,
1933 #[serde(rename = "Description")]
1934 #[serde(skip_serializing_if = "Option::is_none")]
1935 pub description: Option<String>,
1936 #[serde(rename = "MemoryLocation")]
1937 #[serde(skip_serializing_if = "Option::is_none")]
1938 pub memory_location: Option<MemoryLocation>,
1939}
1940
1941#[derive(Debug, Serialize, Deserialize, Clone)]
1942pub struct HWInvByLocMemory {
1943 #[serde(rename = "ID")]
1944 pub id: String,
1945 #[serde(rename = "Type")]
1946 #[serde(skip_serializing_if = "Option::is_none")]
1947 pub r#type: Option<String>,
1948 #[serde(rename = "Ordinal")]
1949 #[serde(skip_serializing_if = "Option::is_none")]
1950 pub ordinal: Option<u32>,
1951 #[serde(rename = "Status")]
1952 #[serde(skip_serializing_if = "Option::is_none")]
1953 pub status: Option<String>,
1954 #[serde(rename = "HWInventoryByLocationType")]
1955 pub hw_inventory_by_location_type: String,
1956 #[serde(rename = "PopulatedFRU")]
1957 #[serde(skip_serializing_if = "Option::is_none")]
1958 pub populated_fru: Option<HWInvByFRUMemory>,
1959 #[serde(rename = "MemoryLocationInfo")]
1960 pub memory_location_info: RedfishMemoryLocationInfo,
1961}
1962
1963#[derive(Debug, Serialize, Deserialize, Clone)]
1964pub struct RedfishNodeAccelRiserLocationInfo {
1965 #[serde(rename = "Name")]
1966 #[serde(skip_serializing_if = "Option::is_none")]
1967 pub name: Option<String>,
1968 #[serde(rename = "Description")]
1969 #[serde(skip_serializing_if = "Option::is_none")]
1970 pub description: Option<String>,
1971}
1972
1973#[derive(Debug, Serialize, Deserialize, Clone)]
1974pub struct HWInvByLocNodeAccelRiser {
1975 #[serde(rename = "ID")]
1976 pub id: String,
1977 #[serde(rename = "Type")]
1978 #[serde(skip_serializing_if = "Option::is_none")]
1979 pub r#type: Option<String>,
1980 #[serde(rename = "Ordinal")]
1981 #[serde(skip_serializing_if = "Option::is_none")]
1982 pub ordinal: Option<u32>,
1983 #[serde(rename = "Status")]
1984 #[serde(skip_serializing_if = "Option::is_none")]
1985 pub status: Option<String>,
1986 #[serde(rename = "HWInventoryByLocationType")]
1987 pub hw_inventory_by_location_type: String,
1988 #[serde(rename = "PopulatedFRU")]
1989 #[serde(skip_serializing_if = "Option::is_none")]
1990 pub populated_fru: Option<HWInventoryByFRU>,
1991 #[serde(rename = "NodeAccelRiserLocationInfo")]
1992 #[serde(skip_serializing_if = "Option::is_none")]
1993 pub node_accel_riser_location_info: Option<RedfishNodeAccelRiserLocationInfo>,
1994}
1995
1996#[derive(Debug, Serialize, Deserialize, Clone)]
1997pub struct HSNNICLocationInfo {
1998 #[serde(rename = "Id")]
1999 #[serde(skip_serializing_if = "Option::is_none")]
2000 pub id: Option<String>,
2001 #[serde(rename = "Name")]
2002 #[serde(skip_serializing_if = "Option::is_none")]
2003 pub name: Option<String>,
2004 #[serde(rename = "Description")]
2005 #[serde(skip_serializing_if = "Option::is_none")]
2006 pub description: Option<String>,
2007}
2008
2009#[derive(Debug, Serialize, Deserialize, Clone)]
2010pub struct HWInvByLocHSNNIC {
2011 #[serde(rename = "ID")]
2012 pub id: String,
2013 #[serde(rename = "Type")]
2014 #[serde(skip_serializing_if = "Option::is_none")]
2015 pub r#type: Option<String>,
2016 #[serde(rename = "Ordinal")]
2017 #[serde(skip_serializing_if = "Option::is_none")]
2018 pub ordinal: Option<u32>,
2019 #[serde(rename = "Status")]
2020 #[serde(skip_serializing_if = "Option::is_none")]
2021 pub status: Option<String>,
2022 #[serde(rename = "HWInventoryByLocationType")]
2023 pub hw_inventory_by_location_type: String,
2024 #[serde(rename = "PopulatedFRU")]
2025 #[serde(skip_serializing_if = "Option::is_none")]
2026 pub populated_fru: Option<HWInvByFRUHSNNIC>,
2027 #[serde(rename = "HSNNICLocationInfo")]
2030 pub hsn_nic_location_info: HSNNICLocationInfo,
2031}
2032
2033#[derive(Debug, Serialize, Deserialize, Clone)]
2034pub struct RedfishSystemFRUInfo {
2035 #[serde(rename = "AssetTag")]
2036 #[serde(skip_serializing_if = "Option::is_none")]
2037 pub asset_tag: Option<String>,
2038 #[serde(rename = "BiosVersion")]
2039 #[serde(skip_serializing_if = "Option::is_none")]
2040 pub bios_version: Option<String>,
2041 #[serde(rename = "Model")]
2042 #[serde(skip_serializing_if = "Option::is_none")]
2043 pub model: Option<String>,
2044 #[serde(rename = "Manufacturer")]
2045 #[serde(skip_serializing_if = "Option::is_none")]
2046 pub manufacturer: Option<String>,
2047 #[serde(rename = "PartNumber")]
2048 #[serde(skip_serializing_if = "Option::is_none")]
2049 pub part_number: Option<String>,
2050 #[serde(rename = "SerialNumber")]
2051 #[serde(skip_serializing_if = "Option::is_none")]
2052 pub serial_number: Option<String>,
2053 #[serde(rename = "SKU")]
2054 #[serde(skip_serializing_if = "Option::is_none")]
2055 pub sku: Option<String>,
2056 #[serde(rename = "SystemType")]
2057 #[serde(skip_serializing_if = "Option::is_none")]
2058 pub system_type: Option<String>,
2059 #[serde(rename = "UUID")]
2060 #[serde(skip_serializing_if = "Option::is_none")]
2061 pub uuid: Option<String>,
2062}
2063
2064#[derive(Debug, Serialize, Deserialize, Clone)]
2065pub struct HWInvByFRUNode {
2066 #[serde(rename = "FRUID")]
2067 #[serde(skip_serializing_if = "Option::is_none")]
2068 pub fru_id: Option<String>,
2069 #[serde(rename = "Type")]
2070 #[serde(skip_serializing_if = "Option::is_none")]
2071 pub r#type: Option<String>,
2072 #[serde(rename = "FRUSubType")]
2073 #[serde(skip_serializing_if = "Option::is_none")]
2074 pub fru_sub_type: Option<String>,
2075 #[serde(rename = "HWInventoryByFRUType")]
2076 pub hw_inventory_by_fru_type: String,
2077 #[serde(rename = "NodeFRUInfo")]
2078 pub node_fru_info: RedfishSystemFRUInfo,
2079}
2080
2081#[derive(Debug, Serialize, Deserialize, Clone)]
2082pub struct HSNNICFRUInfo {
2083 #[serde(rename = "Manufacturer")]
2084 #[serde(skip_serializing_if = "Option::is_none")]
2085 pub manufacturer: Option<String>,
2086 #[serde(rename = "Model")]
2087 #[serde(skip_serializing_if = "Option::is_none")]
2088 pub model: Option<String>,
2089 #[serde(rename = "PartNumber")]
2090 #[serde(skip_serializing_if = "Option::is_none")]
2091 pub part_number: Option<String>,
2092 #[serde(rename = "SKU")]
2093 #[serde(skip_serializing_if = "Option::is_none")]
2094 pub sku: Option<String>,
2095 #[serde(rename = "SerialNumber")]
2096 #[serde(skip_serializing_if = "Option::is_none")]
2097 pub serial_number: Option<String>,
2098}
2099
2100#[derive(Debug, Serialize, Deserialize, Clone)]
2101pub struct HWInvByLocNode {
2102 #[serde(rename = "ID")]
2103 pub id: String,
2104 #[serde(rename = "Type")]
2105 #[serde(skip_serializing_if = "Option::is_none")]
2106 pub r#type: Option<String>,
2107 #[serde(rename = "Ordinal")]
2108 #[serde(skip_serializing_if = "Option::is_none")]
2109 pub ordinal: Option<u32>,
2110 #[serde(rename = "Status")]
2111 #[serde(skip_serializing_if = "Option::is_none")]
2112 pub status: Option<String>,
2113 #[serde(rename = "HWInventoryByLocationType")]
2114 pub hw_inventory_by_location_type: String,
2115 #[serde(rename = "PopulatedFRU")]
2116 #[serde(skip_serializing_if = "Option::is_none")]
2117 pub populated_fru: Option<HWInvByFRUNode>,
2118 #[serde(rename = "NodeLocationInfo")]
2119 #[serde(skip_serializing_if = "Option::is_none")]
2120 pub node_location_info: Option<RedfishSystemLocationInfo>,
2121 #[serde(rename = "Processors")]
2122 #[serde(skip_serializing_if = "Option::is_none")]
2123 pub processors: Option<Vec<HWInvByLocProcessor>>,
2124 #[serde(rename = "NodeAccels")]
2125 #[serde(skip_serializing_if = "Option::is_none")]
2126 pub node_accels: Option<Vec<HWInvByLocNodeAccel>>,
2127 #[serde(rename = "Dives")]
2128 #[serde(skip_serializing_if = "Option::is_none")]
2129 pub drives: Option<Vec<HWInvByLocDrive>>,
2130 #[serde(rename = "Memory")]
2131 #[serde(skip_serializing_if = "Option::is_none")]
2132 pub memory: Option<Vec<HWInvByLocMemory>>,
2133 #[serde(rename = "NodeAccelRisers")]
2134 #[serde(skip_serializing_if = "Option::is_none")]
2135 pub node_accel_risers: Option<Vec<HWInvByLocNodeAccelRiser>>,
2136 #[serde(rename = "NodeHsnNICs")]
2137 #[serde(skip_serializing_if = "Option::is_none")]
2138 pub node_hsn_nics: Option<Vec<HWInvByLocHSNNIC>>,
2139}
2140
2141#[derive(Debug, Serialize, Deserialize, Clone)]
2142pub struct RedfishPDULocationInfo {
2143 #[serde(rename = "Id")]
2144 #[serde(skip_serializing_if = "Option::is_none")]
2145 pub id: Option<String>,
2146 #[serde(rename = "Name")]
2147 #[serde(skip_serializing_if = "Option::is_none")]
2148 pub name: Option<String>,
2149 #[serde(rename = "Description")]
2150 #[serde(skip_serializing_if = "Option::is_none")]
2151 pub description: Option<String>,
2152 #[serde(rename = "UUID")]
2153 #[serde(skip_serializing_if = "Option::is_none")]
2154 pub uuid: Option<String>,
2155}
2156
2157#[derive(Debug, Serialize, Deserialize, Clone)]
2158pub struct RedfishOutletLocationInfo {
2159 #[serde(rename = "Id")]
2160 #[serde(skip_serializing_if = "Option::is_none")]
2161 pub id: Option<String>,
2162 #[serde(rename = "Name")]
2163 #[serde(skip_serializing_if = "Option::is_none")]
2164 pub name: Option<String>,
2165 #[serde(rename = "Description")]
2166 #[serde(skip_serializing_if = "Option::is_none")]
2167 pub description: Option<String>,
2168}
2169
2170#[derive(Debug, Serialize, Deserialize, Clone)]
2171pub struct HWInvByLocOutlet {
2172 #[serde(rename = "ID")]
2173 pub id: String,
2174 #[serde(rename = "Type")]
2175 #[serde(skip_serializing_if = "Option::is_none")]
2176 pub r#type: Option<String>,
2177 #[serde(rename = "Ordinal")]
2178 #[serde(skip_serializing_if = "Option::is_none")]
2179 pub ordinal: Option<u32>,
2180 #[serde(rename = "Status")]
2181 #[serde(skip_serializing_if = "Option::is_none")]
2182 pub status: Option<String>,
2183 #[serde(rename = "HWInventoryByLocationType")]
2184 pub hw_inventory_by_location_type: String,
2185 #[serde(rename = "PopulatedFRU")]
2186 #[serde(skip_serializing_if = "Option::is_none")]
2187 pub populated_fru: Option<HWInventoryByFRU>,
2188 #[serde(rename = "OutletLocationInfo")]
2189 #[serde(skip_serializing_if = "Option::is_none")]
2190 pub outlet_location_info: Option<RedfishOutletLocationInfo>,
2191}
2192
2193#[derive(Debug, Serialize, Deserialize, Clone)]
2194pub struct HWInvByLocPDU {
2195 #[serde(rename = "ID")]
2196 pub id: String,
2197 #[serde(rename = "Type")]
2198 #[serde(skip_serializing_if = "Option::is_none")]
2199 pub r#type: Option<String>,
2200 #[serde(rename = "Ordinal")]
2201 #[serde(skip_serializing_if = "Option::is_none")]
2202 pub ordinal: Option<u32>,
2203 #[serde(rename = "Status")]
2204 #[serde(skip_serializing_if = "Option::is_none")]
2205 pub status: Option<String>,
2206 #[serde(rename = "HWInventoryByLocationType")]
2207 pub hw_inventory_by_location_type: String,
2208 #[serde(rename = "PopulatedFRU")]
2209 #[serde(skip_serializing_if = "Option::is_none")]
2210 pub populated_fru: Option<HWInventoryByFRU>,
2211 #[serde(rename = "PDULocationInfo")]
2212 #[serde(skip_serializing_if = "Option::is_none")]
2213 pub pdu_location_info: Option<RedfishPDULocationInfo>,
2214 #[serde(rename = "CabinetPDUPowerConnectors")]
2215 #[serde(skip_serializing_if = "Option::is_none")]
2216 pub cabinet_pdu_power_connectors: Option<Vec<HWInvByLocOutlet>>,
2217}
2218
2219#[derive(Debug, Serialize, Deserialize, Clone)]
2220pub struct RedfishCMMRectifierLocationInfo {
2221 #[serde(rename = "Name")]
2222 #[serde(skip_serializing_if = "Option::is_none")]
2223 pub name: Option<String>,
2224 #[serde(rename = "FirmwareVersion")]
2225 #[serde(skip_serializing_if = "Option::is_none")]
2226 pub firmware_version: Option<String>,
2227}
2228
2229#[derive(Debug, Serialize, Deserialize, Clone)]
2230pub struct HWInvByLocCMMRectifier {
2231 #[serde(rename = "ID")]
2232 pub id: String,
2233 #[serde(rename = "Type")]
2234 #[serde(skip_serializing_if = "Option::is_none")]
2235 pub r#type: Option<String>,
2236 #[serde(rename = "Ordinal")]
2237 #[serde(skip_serializing_if = "Option::is_none")]
2238 pub ordinal: Option<u32>,
2239 #[serde(rename = "Status")]
2240 #[serde(skip_serializing_if = "Option::is_none")]
2241 pub status: Option<String>,
2242 #[serde(rename = "HWInventoryByLocationType")]
2243 pub hw_inventory_by_location_type: String,
2244 #[serde(rename = "PopulatedFRU")]
2245 #[serde(skip_serializing_if = "Option::is_none")]
2246 pub populated_fru: Option<HWInventoryByFRU>,
2247 #[serde(rename = "CMMRectifierLocationInfo")]
2248 #[serde(skip_serializing_if = "Option::is_none")]
2249 pub cmm_rectifier_location_info: Option<RedfishCMMRectifierLocationInfo>,
2250}
2251
2252#[derive(Debug, Serialize, Deserialize, Clone)]
2253pub struct RedfishNodeEnclosurePowerSupplyLocationInfo {
2254 #[serde(rename = "Name")]
2255 #[serde(skip_serializing_if = "Option::is_none")]
2256 pub name: Option<String>,
2257 #[serde(rename = "FirmwareVersion")]
2258 #[serde(skip_serializing_if = "Option::is_none")]
2259 pub firmware_version: Option<String>,
2260}
2261
2262#[derive(Debug, Serialize, Deserialize, Clone)]
2263pub struct HWInvByLocNodePowerSupply {
2264 #[serde(rename = "ID")]
2265 pub id: String,
2266 #[serde(rename = "Type")]
2267 #[serde(skip_serializing_if = "Option::is_none")]
2268 pub r#type: Option<String>,
2269 #[serde(rename = "Ordinal")]
2270 #[serde(skip_serializing_if = "Option::is_none")]
2271 pub ordinal: Option<u32>,
2272 #[serde(rename = "Status")]
2273 #[serde(skip_serializing_if = "Option::is_none")]
2274 pub status: Option<String>,
2275 #[serde(rename = "HWInventoryByLocationType")]
2276 pub hw_inventory_by_location_type: String,
2277 #[serde(rename = "PopulatedFRU")]
2278 #[serde(skip_serializing_if = "Option::is_none")]
2279 pub populated_fru: Option<HWInventoryByFRU>,
2280 #[serde(rename = "NodeEnclosurePowerSupplyLocationInfo")]
2281 #[serde(skip_serializing_if = "Option::is_none")]
2282 pub node_enclosure_power_supply_location_info:
2283 Option<RedfishNodeEnclosurePowerSupplyLocationInfo>,
2284}
2285
2286#[derive(Debug, Serialize, Deserialize, Clone)]
2287pub struct RedfishManagerLocationInfo {
2288 #[serde(rename = "Id")]
2289 #[serde(skip_serializing_if = "Option::is_none")]
2290 pub id: Option<String>,
2291 #[serde(rename = "Name")]
2292 #[serde(skip_serializing_if = "Option::is_none")]
2293 pub name: Option<String>,
2294 #[serde(rename = "Description")]
2295 #[serde(skip_serializing_if = "Option::is_none")]
2296 pub description: Option<String>,
2297 #[serde(rename = "DateTime")]
2298 #[serde(skip_serializing_if = "Option::is_none")]
2299 pub date_time: Option<String>,
2300 #[serde(rename = "DateTimeLocalOffset")]
2301 #[serde(skip_serializing_if = "Option::is_none")]
2302 pub date_time_local_offset: Option<String>,
2303 #[serde(rename = "FirmwareVersion")]
2304 #[serde(skip_serializing_if = "Option::is_none")]
2305 pub firmware_version: Option<String>,
2306}
2307
2308#[derive(Debug, Serialize, Deserialize, Clone)]
2309pub struct HWInvByLocNodeBMC {
2310 #[serde(rename = "ID")]
2311 pub id: String,
2312 #[serde(rename = "Type")]
2313 #[serde(skip_serializing_if = "Option::is_none")]
2314 pub r#type: Option<String>,
2315 #[serde(rename = "Ordinal")]
2316 #[serde(skip_serializing_if = "Option::is_none")]
2317 pub ordinal: Option<u32>,
2318 #[serde(rename = "Status")]
2319 #[serde(skip_serializing_if = "Option::is_none")]
2320 pub status: Option<String>,
2321 #[serde(rename = "HWInventoryByLocationType")]
2322 pub hw_inventory_by_location_type: String,
2323 #[serde(rename = "PopulatedFRU")]
2324 #[serde(skip_serializing_if = "Option::is_none")]
2325 pub populated_fru: Option<HWInventoryByFRU>,
2326 #[serde(rename = "NodeBMCLocationInfo")]
2327 #[serde(skip_serializing_if = "Option::is_none")]
2328 pub node_bmc_location_info: Option<RedfishManagerLocationInfo>,
2329}
2330
2331#[derive(Debug, Serialize, Deserialize, Clone)]
2332pub struct HWInvByLocRouterBMC {
2333 #[serde(rename = "ID")]
2334 pub id: String,
2335 #[serde(rename = "Type")]
2336 #[serde(skip_serializing_if = "Option::is_none")]
2337 pub r#type: Option<String>,
2338 #[serde(rename = "Ordinal")]
2339 #[serde(skip_serializing_if = "Option::is_none")]
2340 pub ordinal: Option<u32>,
2341 #[serde(rename = "Status")]
2342 #[serde(skip_serializing_if = "Option::is_none")]
2343 pub status: Option<String>,
2344 #[serde(rename = "HWInventoryByLocationType")]
2345 pub hw_inventory_by_location_type: String,
2346 #[serde(rename = "PopulatedFRU")]
2347 #[serde(skip_serializing_if = "Option::is_none")]
2348 pub populated_fru: Option<HWInventoryByFRU>,
2349 #[serde(rename = "RouterBMCLocationInfo")]
2350 #[serde(skip_serializing_if = "Option::is_none")]
2351 pub router_bmc_location_info: Option<RedfishManagerLocationInfo>,
2352}
2353
2354#[derive(Debug, Serialize, Deserialize, Clone)]
2361pub struct HWInventory {
2362 #[serde(rename = "XName")]
2363 #[serde(skip_serializing_if = "Option::is_none")]
2364 pub xname: Option<String>,
2365 #[serde(rename = "Format")]
2366 #[serde(skip_serializing_if = "Option::is_none")]
2367 pub format: Option<String>,
2368 #[serde(rename = "Cabinets")]
2369 #[serde(skip_serializing_if = "Option::is_none")]
2370 pub cabinets: Option<Vec<HWInvByLocCabinet>>,
2371 #[serde(rename = "Chassis")]
2372 #[serde(skip_serializing_if = "Option::is_none")]
2373 pub chassis: Option<Vec<HWInvByLocChassis>>,
2374 #[serde(rename = "ComputeModules")]
2375 #[serde(skip_serializing_if = "Option::is_none")]
2376 pub compute_modules: Option<Vec<HWInvByLocComputeModule>>,
2377 #[serde(rename = "RouterModules")]
2378 #[serde(skip_serializing_if = "Option::is_none")]
2379 pub router_modules: Option<Vec<HWInvByLocRouterModule>>,
2380 #[serde(rename = "NodeEnclosures")]
2381 #[serde(skip_serializing_if = "Option::is_none")]
2382 pub node_enclosures: Option<Vec<HWInvByLocNodeEnclosure>>,
2383 #[serde(rename = "HSNBoards")]
2384 #[serde(skip_serializing_if = "Option::is_none")]
2385 pub hsn_boards: Option<Vec<HWInvByLocHSNBoard>>,
2386 #[serde(rename = "MgmtSwitches")]
2387 #[serde(skip_serializing_if = "Option::is_none")]
2388 pub mgmt_switches: Option<Vec<HWInvByLocMgmtSwitch>>,
2389 #[serde(rename = "MgmtHLSwitches")]
2390 #[serde(skip_serializing_if = "Option::is_none")]
2391 pub mgmt_hl_switches: Option<Vec<HWInvByLocMgmtHLSwitch>>,
2392 #[serde(rename = "CDUMgmtSwitches")]
2393 #[serde(skip_serializing_if = "Option::is_none")]
2394 pub cdu_mgmt_switches: Option<Vec<HWInvByLocCDUMgmtSwitch>>,
2395 #[serde(rename = "Nodes")]
2396 #[serde(skip_serializing_if = "Option::is_none")]
2397 pub nodes: Option<Vec<HWInvByLocNode>>,
2398 #[serde(rename = "Processors")]
2399 #[serde(skip_serializing_if = "Option::is_none")]
2400 pub processors: Option<Vec<HWInvByLocProcessor>>,
2401 #[serde(rename = "NodeAccels")]
2402 #[serde(skip_serializing_if = "Option::is_none")]
2403 pub node_accels: Option<Vec<HWInvByLocNodeAccel>>,
2404 #[serde(rename = "Drives")]
2405 #[serde(skip_serializing_if = "Option::is_none")]
2406 pub drives: Option<Vec<HWInvByLocDrive>>,
2407 #[serde(rename = "Memory")]
2408 #[serde(skip_serializing_if = "Option::is_none")]
2409 pub memory: Option<Vec<HWInvByLocMemory>>,
2410 #[serde(rename = "CabinetPDUs")]
2411 #[serde(skip_serializing_if = "Option::is_none")]
2412 pub cabinet_pdus: Option<Vec<HWInvByLocPDU>>,
2413 #[serde(rename = "CabinetPDUPowerConnectors")]
2414 #[serde(skip_serializing_if = "Option::is_none")]
2415 pub cabinet_pdu_power_connectors: Option<Vec<HWInvByLocOutlet>>,
2416 #[serde(rename = "CMMRectifiers")]
2417 #[serde(skip_serializing_if = "Option::is_none")]
2418 pub cmm_rectifiers: Option<Vec<HWInvByLocCMMRectifier>>,
2419 #[serde(rename = "NodeAccelRisers")]
2420 #[serde(skip_serializing_if = "Option::is_none")]
2421 pub node_accel_risers: Option<Vec<HWInvByLocNodeAccelRiser>>,
2422 #[serde(rename = "NodeHsnNICs")]
2423 #[serde(skip_serializing_if = "Option::is_none")]
2424 pub node_hsn_nics: Option<Vec<HWInvByLocHSNNIC>>,
2425 #[serde(rename = "NodeEnclosurePowerSupplies")]
2426 #[serde(skip_serializing_if = "Option::is_none")]
2427 pub node_enclosure_power_supplies: Option<Vec<HWInvByLocNodePowerSupply>>,
2428 #[serde(rename = "NodeBMC")]
2429 #[serde(skip_serializing_if = "Option::is_none")]
2430 pub node_bmc: Option<Vec<HWInvByLocNodeBMC>>,
2431 #[serde(rename = "RouterBMC")]
2432 #[serde(skip_serializing_if = "Option::is_none")]
2433 pub router_bmc: Option<Vec<HWInvByLocRouterBMC>>,
2434}
2435
2436#[derive(Debug, Serialize, Deserialize, Clone)]
2437pub struct Hardware {
2438 #[serde(rename = "Hardware")]
2439 #[serde(skip_serializing_if = "Option::is_none")]
2440 pub hardware: Option<Vec<HWInvByLocNode>>,
2441}
2442
2443#[derive(Debug, Serialize, Deserialize, Clone)]
2444pub struct NodeLocationInfo {
2445 #[serde(rename = "Id")]
2446 pub id: String,
2447 #[serde(rename = "Name")]
2448 #[serde(skip_serializing_if = "Option::is_none")]
2449 pub name: Option<String>,
2450 #[serde(rename = "Description")]
2451 #[serde(skip_serializing_if = "Option::is_none")]
2452 pub description: Option<String>,
2453 #[serde(rename = "Hostname")]
2454 #[serde(skip_serializing_if = "Option::is_none")]
2455 pub hostname: Option<String>,
2456 #[serde(rename = "ProcessorSummary")]
2457 #[serde(skip_serializing_if = "Option::is_none")]
2458 pub processor_summary: Option<ProcessorSummary>,
2459 #[serde(rename = "MemorySummary")]
2460 #[serde(skip_serializing_if = "Option::is_none")]
2461 pub memory_summary: Option<MemorySummary>,
2462}
2463
2464#[derive(Debug, Serialize, Deserialize, Clone)]
2465#[serde(untagged)] pub enum HWInventoryByLocation {
2467 HWInvByLocNode(HWInvByLocNode),
2477 HWInvByLocProcessor(HWInvByLocProcessor),
2478 HWInvByLocNodeAccel(HWInvByLocNodeAccel),
2479 HWInvByLocMemory(HWInvByLocMemory),
2481 HWInvByLocHSNNIC(HWInvByLocHSNNIC),
2486 }
2490
2491#[derive(Debug, Serialize, Deserialize, Clone)]
2493pub struct HWInventoryByLocationList {
2494 #[serde(rename = "Hardware")]
2495 #[serde(skip_serializing_if = "Option::is_none")]
2496 pub hardware: Option<Vec<HWInventoryByLocation>>,
2497}
2498
2499#[derive(Debug, Serialize, Deserialize, Clone)]
2500pub struct Link {
2501 #[serde(skip_serializing_if = "Option::is_none")]
2502 pub rel: Option<String>,
2503 #[serde(skip_serializing_if = "Option::is_none")]
2504 pub href: Option<String>,
2505}
2506
2507#[derive(Debug, Serialize, Deserialize, Clone)]
2508pub struct Cfs {
2509 #[serde(skip_serializing_if = "Option::is_none")]
2510 pub configuration: Option<String>,
2511}
2512
2513#[derive(Debug, Serialize, Deserialize, Clone)]
2514pub struct BootSet {
2515 #[serde(skip_serializing_if = "Option::is_none")]
2516 pub name: Option<String>,
2517 #[serde(skip_serializing_if = "Option::is_none")]
2518 pub path: Option<String>,
2519 #[serde(skip_serializing_if = "Option::is_none")]
2520 pub cfs: Option<Cfs>,
2521 #[serde(skip_serializing_if = "Option::is_none")]
2522 pub r#type: Option<String>,
2523 #[serde(skip_serializing_if = "Option::is_none")]
2524 pub etag: Option<String>,
2525 #[serde(skip_serializing_if = "Option::is_none")]
2526 pub kernel_parameters: Option<String>,
2527 #[serde(skip_serializing_if = "Option::is_none")]
2528 pub node_list: Option<Vec<String>>,
2529 #[serde(skip_serializing_if = "Option::is_none")]
2530 pub node_roles_groups: Option<Vec<String>>,
2531 #[serde(skip_serializing_if = "Option::is_none")]
2532 pub node_groups: Option<Vec<String>>,
2533 #[serde(skip_serializing_if = "Option::is_none")]
2534 pub arch: Option<String>, #[serde(skip_serializing_if = "Option::is_none")]
2536 pub rootfs_provider: Option<String>,
2537 #[serde(skip_serializing_if = "Option::is_none")]
2538 pub rootfs_provider_passthrough: Option<String>,
2539}
2540
2541#[derive(Debug, Serialize, Deserialize, Clone)]
2542pub struct BosSessionTemplate {
2543 #[serde(skip_serializing_if = "Option::is_none")]
2544 pub name: Option<String>,
2545 #[serde(skip_serializing_if = "Option::is_none")]
2546 pub tenant: Option<String>,
2547 #[serde(skip_serializing_if = "Option::is_none")]
2548 pub description: Option<String>,
2549 #[serde(skip_serializing_if = "Option::is_none")]
2550 pub enable_cfs: Option<bool>,
2551 #[serde(skip_serializing_if = "Option::is_none")]
2552 pub cfs: Option<Cfs>,
2553 #[serde(skip_serializing_if = "Option::is_none")]
2554 pub boot_sets: Option<HashMap<String, BootSet>>,
2555 #[serde(skip_serializing_if = "Option::is_none")]
2556 pub links: Option<Vec<Link>>,
2557}