diff --git a/scripts/suse.sh b/scripts/suse.sh index 786e388..10c4652 100755 --- a/scripts/suse.sh +++ b/scripts/suse.sh @@ -57,13 +57,12 @@ cpu_config="{\"CPU_Sockets\": \"$cpu_sockets\", \"CPU_Cores\": \"$cpu_cores\", \ system_info["CPU_Configuration"]="$cpu_config" # Print the final JSON output +# FIXME: cpu_type omitted until filter works cat << EOF { - "CPU_Architecture": "${system_info["CPU_Architecture"]}", - "Max_Capacity_TB": "${system_info["Max_Capacity_TB"]}", - "CPU_Type": "${system_info["CPU_Type"]}", - "Max_Power_Watt": "${system_info["Max_Power_Watt"]}", - "RAM_GB": "${system_info["RAM_GB"]}", - "CPU_Configuration": ${system_info["CPU_Configuration"]} + "arch": "${system_info["CPU_Architecture"]}", + "capacity": "${system_info["Max_Capacity_TB"]}", + "max_power": "${system_info["Max_Power_Watt"]}", + "memory": "${system_info["RAM_GB"]}" } EOF diff --git a/src/collectors/pluginhandler.rs b/src/collectors/pluginhandler.rs index 9fccd07..4c55fda 100644 --- a/src/collectors/pluginhandler.rs +++ b/src/collectors/pluginhandler.rs @@ -4,8 +4,9 @@ //! //! Currently, Nazara is set to handle `bash`, `python` and `Lua` scripts. -use std::collections::HashMap; +use std::collections::{HashMap, HashSet}; use std::hash::RandomState; +use std::path::PathBuf; use std::process::Command; use std::{error::Error, path::Path}; @@ -23,38 +24,117 @@ use serde_json::{self, Value}; /// /// * `Ok(HashMap)` - Returns a HashMap if the plugin script returns valid JSON. /// * `Error` - If the execution of the plugin fails or it does not return a valid JSON. -pub fn execute( - path: Option, -) -> Result, Box> { - let script_path = match path.as_deref() { - Some(p) => Path::new(p), - None => return Err("No path provided.".into()), - }; - - println!( - "Attempting to execute plugin at path '{}'...", - script_path.display() - ); - - if !script_path.is_file() { - return Err("Provided path does not lead to a file.".into()); +pub fn execute(path: Option) -> Result, Box> { + println!("Attempting to execute plugin at path '{:?}'...", path); + + // Verify that the path is valid + if let Some(path) = path.clone() { + if !PathBuf::from(path).is_file() { + return Err("Provided path does not lead to a valid file.".into()); + } } - let output = Command::new("bash").arg(script_path).output()?; + // Execute the script + let output = Command::new("bash").arg(path.unwrap()).output()?; + // Check for execution errors if !output.status.success() { - let err = CollectorError::PluginExecutionError( - "Either you have a syntax error in your code or the file does not exist.".to_string(), - ); - return Err(err.into()); + return Err("Script execution failed.".into()); } + // Convert stdout to a string let stdout_str = String::from_utf8(output.stdout)?; - validate(&stdout_str)?; // Validate JSON format + // Parse the output JSON + let json_output: Value = serde_json::from_str(&stdout_str)?; + + // Define allowed choices for cpu_type and arch + let valid_cpu_types: HashSet<&str> = [ + "XEON X5/X7", + "XEON E7", + "XEON E7 v4", + "XEON E3 v4", + "XEON E5 v2", + "XEON Phi", + "XEON E5 v2", + "XEON-D", + "XEON E5 v3", + "XEON Gold/Platinum 81xx/82xx", + "XEON Platinum 92xx", + "XEON Gold 53xx", + "XEON Gold/platinum 63xx/83xx", + "XEON Gold/Platinum 64xx/84XX", + "XEON D 17xx/27xx", + "ATOM P 53xx/57xx/59xx", + "XEON E 23xx", + ] + .iter() + .cloned() + .collect(); + + let valid_arch: HashSet<&str> = [ + "aarch64", "i386", "ia64", "x86_64", "ppc64", "s390x", "ppc64le", + ] + .iter() + .cloned() + .collect(); + + // Convert JSON to a HashMap, filtering invalid cpu_type and arch values + let mut output_map: HashMap = json_output + .as_object() + .ok_or("Expected JSON object format")? + .clone() + .into_iter() + .collect(); + + if let Some(cpu_type) = output_map.get("CPU_Type") { + if let Some(cpu_type_str) = cpu_type.as_str() { + if !valid_cpu_types.contains(cpu_type_str) { + output_map.remove("cpu_type"); + } + } + } + + if let Some(arch) = output_map.get("CPU_Architecture") { + if let Some(arch_str) = arch.as_str() { + if !valid_arch.contains(arch_str) { + output_map.remove("arch"); + } + } + } + // Parse and adjust Max_Power_Watt, RAM_GB, and Max_Capacity_TB as integers + if let Some(max_power) = output_map.get("max_power") { + if let Some(max_power_str) = max_power.as_str() { + if let Ok(max_power_int) = max_power_str.parse::() { + output_map.insert("max_power".to_string(), Value::Number(max_power_int.into())); + } else { + output_map.remove("max_power"); // Remove if not a valid integer + } + } + } + + if let Some(ram_gb) = output_map.get("memory") { + if let Some(ram_gb_str) = ram_gb.as_str() { + if let Ok(ram_gb_int) = ram_gb_str.parse::() { + output_map.insert("memory".to_string(), Value::Number(ram_gb_int.into())); + } else { + output_map.remove("memory"); // Remove if not a valid integer + } + } + } + + if let Some(max_capacity) = output_map.get("capacity") { + if let Some(max_capacity_str) = max_capacity.as_str() { + if let Ok(max_capacity_int) = max_capacity_str.parse::() { + output_map.insert("capacity".to_string(), Value::Number(max_capacity_int.into())); + } else { + output_map.remove("capacity"); // Remove if not a valid integer + } + } + } - let json_output: HashMap = serde_json::from_str(&stdout_str)?; - Ok(json_output) + println!("{:?}", &output_map); + Ok(output_map) } /// Validate the output of the given plugin to ensure it is valid JSON.