@@ -4,6 +4,7 @@ extern crate serde;
44extern crate serde_json;
55
66use error:: MetricsResult ;
7+ use ChildPoint ;
78use IntoPoint ;
89
910use std:: fmt:: Debug ;
@@ -39,16 +40,16 @@ fn get_data<T>(
3940where
4041 T : DeserializeOwned + Debug + IntoPoint ,
4142{
42- let j : T = client
43+ let mut j = client
4344 . get ( & format ! (
4445 "https://{}/univmax/restapi/{}" ,
4546 config. endpoint, api_endpoint,
4647 ) )
4748 . basic_auth ( config. user . clone ( ) , Some ( config. password . clone ( ) ) )
4849 . send ( ) ?
49- . error_for_status ( ) ?
50- . json ( ) ?;
51- Ok ( j . into_point ( Some ( point_name) ) )
50+ . error_for_status ( ) ?;
51+ let deserialized : T = j . json ( ) ?;
52+ Ok ( deserialized . into_point ( Some ( point_name) ) )
5253}
5354
5455/* Changed the GET to POST and added body parameter to pass additional fields to
@@ -962,4 +963,196 @@ fn test_get_per_array_storagegroup_metrics() {
962963 let i: StorageGroupArrayMetrics = serde_json:: from_str ( & buff) . unwrap ( ) ;
963964 println ! ( "result: {:#?}" , i) ;
964965}
965- //END Section for Test Functions
966+
967+ //For Collecting the VMAX Array System Properties Metrics. This includes the RAW array values for capacity
968+ //which is found in the GUI Unisphere --> Array --> System --> Symmetrix Properties
969+ //https://[username]:[password]@[Unisphere Server]:8443/univmax/restapi/90/sloprovisioning/symmetrix/[Array S/N]
970+ #[ test]
971+ fn test_get_slo_provisioning_system_properties ( ) {
972+ use std:: fs:: File ;
973+ use std:: io:: Read ;
974+
975+ let mut f = File :: open ( "tests/vmax/slo_provisioning_system_properties.json" ) . unwrap ( ) ;
976+ let mut buff = String :: new ( ) ;
977+ f. read_to_string ( & mut buff) . unwrap ( ) ;
978+
979+ let i: VmaxSystemCapacity = serde_json:: from_str ( & buff) . unwrap ( ) ;
980+ println ! ( "result: {:#?}" , i) ;
981+ }
982+ // END Section for Test Functions
983+
984+ // This function is for get_data only, the get_list was not needed. Note the '90' for v9 of the EMC Unisphere software
985+ pub fn get_vmax_array_raw (
986+ client : & reqwest:: Client ,
987+ config : & VmaxConfig ,
988+ symmetrixid : & str ,
989+ ) -> MetricsResult < Vec < TsPoint > > {
990+ let vmax_raw = get_data :: < VmaxSystemCapacity > (
991+ client,
992+ config,
993+ & format ! ( "90/sloprovisioning/symmetrix/{}" , symmetrixid) ,
994+ "vmax_array_raw" ,
995+ ) ?;
996+ debug ! ( "result: {:#?}" , vmax_raw) ;
997+ Ok ( vmax_raw)
998+ }
999+
1000+ // This is split into objects and sub-objects based upon the new Unisphere release v9
1001+ #[ derive( Debug , Deserialize ) ]
1002+ pub struct VmaxSystemCapacity {
1003+ #[ serde( rename = "symmetrixId" ) ]
1004+ pub symmetrix_id : String ,
1005+ pub device_count : u64 ,
1006+ pub ucode : String ,
1007+ pub model : String ,
1008+ pub local : bool ,
1009+ pub default_fba_srp : String ,
1010+ pub host_visible_device_count : u64 ,
1011+ pub system_capacity : SystemCapacity ,
1012+ pub system_efficiency : SystemEfficiency ,
1013+ pub meta_data_usage : MetaDataUsage ,
1014+ #[ serde( rename = "sloCompliance" ) ]
1015+ pub slo_compliance : SloComplianceSys ,
1016+ #[ serde( rename = "physicalCapacity" ) ]
1017+ pub physical_capacity : PhysicalCapacity ,
1018+ }
1019+
1020+ impl IntoPoint for VmaxSystemCapacity {
1021+ fn into_point ( & self , name : Option < & str > ) -> Vec < TsPoint > {
1022+ let mut p = TsPoint :: new ( name. unwrap_or ( "unknown" ) ) ;
1023+ p. add_tag ( "symmetrix_id" , TsValue :: String ( self . symmetrix_id . clone ( ) ) ) ;
1024+ p. add_field ( "device_count" , TsValue :: Long ( self . device_count ) ) ;
1025+ p. add_field ( "ucode" , TsValue :: String ( self . ucode . clone ( ) ) ) ;
1026+ p. add_field ( "model" , TsValue :: String ( self . model . clone ( ) ) ) ;
1027+ p. add_field ( "local" , TsValue :: Boolean ( self . local . clone ( ) ) ) ;
1028+ p. add_tag (
1029+ "default_fba_srp" ,
1030+ TsValue :: String ( self . default_fba_srp . clone ( ) ) ,
1031+ ) ;
1032+ p. add_field (
1033+ "host_visible_device_count" ,
1034+ TsValue :: Long ( self . host_visible_device_count ) ,
1035+ ) ;
1036+ self . system_capacity . sub_point ( & mut p) ;
1037+ self . system_efficiency . sub_point ( & mut p) ;
1038+ self . meta_data_usage . sub_point ( & mut p) ;
1039+ self . slo_compliance . sub_point ( & mut p) ;
1040+ self . physical_capacity . sub_point ( & mut p) ;
1041+ vec ! [ p]
1042+ }
1043+ }
1044+
1045+ #[ allow( non_snake_case) ]
1046+ #[ derive( Debug , Deserialize ) ]
1047+ pub struct SystemCapacity {
1048+ pub subscribed_allocated_tb : f64 ,
1049+ pub subscribed_total_tb : f64 ,
1050+ pub snapshot_modified_tb : f64 ,
1051+ pub snapshot_total_tb : f64 ,
1052+ pub usable_used_tb : f64 ,
1053+ pub usable_total_tb : f64 ,
1054+ pub subscribed_usable_capacity_percent : f64 ,
1055+ }
1056+
1057+ // This implements a new impl for sub_point based upon EMC metrics
1058+ // Use a tags for the those metrics defined as String value and field for the remaining, but not both
1059+ impl ChildPoint for SystemCapacity {
1060+ fn sub_point ( & self , p : & mut TsPoint ) {
1061+ p. add_field (
1062+ "subscribed_allocated_tb" ,
1063+ TsValue :: Float ( self . subscribed_allocated_tb ) ,
1064+ ) ;
1065+ p. add_field (
1066+ "subscribed_total_tb" ,
1067+ TsValue :: Float ( self . subscribed_total_tb ) ,
1068+ ) ;
1069+ p. add_field (
1070+ "snapshot_modified_tb" ,
1071+ TsValue :: Float ( self . snapshot_modified_tb ) ,
1072+ ) ;
1073+ p. add_field ( "snapshot_total_tb" , TsValue :: Float ( self . snapshot_total_tb ) ) ;
1074+ p. add_field ( "usable_used_tb" , TsValue :: Float ( self . usable_used_tb ) ) ;
1075+ p. add_field ( "usable_total_tb" , TsValue :: Float ( self . usable_total_tb ) ) ;
1076+ p. add_field (
1077+ "subscribed_usable_capacity_percent" ,
1078+ TsValue :: Float ( self . subscribed_usable_capacity_percent ) ,
1079+ ) ;
1080+ }
1081+ }
1082+
1083+ #[ allow( non_snake_case) ]
1084+ #[ derive( Debug , Deserialize ) ]
1085+ pub struct SystemEfficiency {
1086+ pub overall_efficiency_ratio_to_one : f64 ,
1087+ pub data_reduction_enabled_percent : f64 ,
1088+ pub virtual_provisioning_savings_ratio_to_one : f64 ,
1089+ }
1090+
1091+ impl ChildPoint for SystemEfficiency {
1092+ fn sub_point ( & self , p : & mut TsPoint ) {
1093+ p. add_field (
1094+ "overall_efficiency_ratio_to_one" ,
1095+ TsValue :: Float ( self . overall_efficiency_ratio_to_one ) ,
1096+ ) ;
1097+ p. add_field (
1098+ "data_reduction_enabled_percent" ,
1099+ TsValue :: Float ( self . data_reduction_enabled_percent ) ,
1100+ ) ;
1101+ p. add_field (
1102+ "virtual_provisioning_savings_ratio_to_one" ,
1103+ TsValue :: Float ( self . virtual_provisioning_savings_ratio_to_one ) ,
1104+ ) ;
1105+ }
1106+ }
1107+
1108+ #[ allow( non_snake_case) ]
1109+ #[ derive( Debug , Deserialize ) ]
1110+ pub struct MetaDataUsage {
1111+ pub system_meta_data_used_percent : f64 ,
1112+ pub replication_cache_used_percent : u64 ,
1113+ }
1114+
1115+ impl ChildPoint for MetaDataUsage {
1116+ fn sub_point ( & self , p : & mut TsPoint ) {
1117+ p. add_field (
1118+ "system_meta_data_used_percent" ,
1119+ TsValue :: Float ( self . system_meta_data_used_percent ) ,
1120+ ) ;
1121+ p. add_field (
1122+ "replication_cache_used_percent" ,
1123+ TsValue :: Long ( self . replication_cache_used_percent ) ,
1124+ ) ;
1125+ }
1126+ }
1127+
1128+ #[ allow( non_snake_case) ]
1129+ #[ derive( Debug , Deserialize ) ]
1130+ pub struct SloComplianceSys {
1131+ pub slo_stable : i64 ,
1132+ pub slo_marginal : i64 ,
1133+ pub slo_critical : i64 ,
1134+ pub no_slo : i64 ,
1135+ }
1136+
1137+ impl ChildPoint for SloComplianceSys {
1138+ fn sub_point ( & self , p : & mut TsPoint ) {
1139+ p. add_field ( "slo_stable" , TsValue :: SignedLong ( self . slo_stable ) ) ;
1140+ p. add_field ( "slo_marginal" , TsValue :: SignedLong ( self . slo_marginal ) ) ;
1141+ p. add_field ( "slo_critical" , TsValue :: SignedLong ( self . slo_critical ) ) ;
1142+ p. add_field ( "no_slo" , TsValue :: SignedLong ( self . no_slo ) ) ;
1143+ }
1144+ }
1145+
1146+ #[ allow( non_snake_case) ]
1147+ #[ derive( Debug , Deserialize ) ]
1148+ pub struct PhysicalCapacity {
1149+ pub used_capacity_gb : f64 ,
1150+ pub total_capacity_gb : f64 ,
1151+ }
1152+
1153+ impl ChildPoint for PhysicalCapacity {
1154+ fn sub_point ( & self , p : & mut TsPoint ) {
1155+ p. add_field ( "used_capacity_gb" , TsValue :: Float ( self . used_capacity_gb ) ) ;
1156+ p. add_field ( "total_capacity_gb" , TsValue :: Float ( self . total_capacity_gb ) ) ;
1157+ }
1158+ }
0 commit comments