libstorage/
xtremio.rs

1/**
2* Copyright 2019 Comcast Cable Communications Management, LLC
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*
16* SPDX-License-Identifier: Apache-2.0
17*/
18use crate::deserialize_string_or_float;
19use crate::deserialize_string_or_int;
20use crate::error::MetricsResult;
21use crate::IntoPoint;
22
23use std::collections::HashMap;
24use std::fmt::Debug;
25use std::str;
26
27use crate::ir::{TsPoint, TsValue};
28use serde::de::DeserializeOwned;
29use serde_json::Value;
30
31#[derive(Clone, Deserialize, Debug)]
32pub struct XtremIOConfig {
33    /// The scaleio endpoint to use
34    pub endpoint: String,
35    pub user: String,
36    /// This gets replaced with the token at runtime
37    pub password: String,
38    /// Optional certificate file to use against the server
39    /// der encoded
40    pub certificate: Option<String>,
41    /// Optional root certificate file to use against the server
42    /// der encoded
43    pub root_certificate: Option<String>,
44    /// The region this cluster is located in
45    pub region: String,
46}
47
48pub struct XtremIo {
49    client: reqwest::Client,
50    config: XtremIOConfig,
51}
52
53impl XtremIo {
54    pub fn new(client: &reqwest::Client, config: XtremIOConfig) -> Self {
55        XtremIo {
56            client: client.clone(),
57            config,
58        }
59    }
60}
61
62#[test]
63fn test_get_xtremio_volumes() {
64    use std::fs::File;
65    use std::io::Read;
66
67    let mut f = File::open("tests/xtremio/volumes.json").unwrap();
68    let mut buff = String::new();
69    f.read_to_string(&mut buff).unwrap();
70
71    let i: Volumes = serde_json::from_str(&buff).unwrap();
72    println!("result: {:#?}", i);
73}
74
75#[derive(Deserialize, Debug)]
76pub struct Link {
77    pub href: String,
78    pub rel: String,
79}
80
81#[derive(Deserialize, Debug)]
82#[serde(rename_all = "lowercase")]
83pub enum SmallIOAlert {
84    Enabled,
85    Disabled,
86}
87
88#[derive(Deserialize, Debug)]
89pub struct Volumes {
90    pub params: HashMap<String, String>,
91    pub volumes: Vec<Volume>,
92    pub links: Vec<Link>,
93}
94
95impl IntoPoint for Volumes {
96    fn into_point(&self, name: Option<&str>, is_time_series: bool) -> Vec<TsPoint> {
97        let mut points: Vec<TsPoint> = Vec::new();
98        let n = name.unwrap_or("volume");
99
100        for v in &self.volumes {
101            points.extend(v.into_point(Some(n), is_time_series));
102        }
103
104        points
105    }
106}
107
108#[derive(Deserialize, Debug, IntoPoint)]
109#[serde(rename_all = "kebab-case")]
110pub struct Volume {
111    pub small_io_alerts: SmallIOAlert,
112    pub created_by_app: Option<String>,
113    #[serde(deserialize_with = "deserialize_string_or_int")]
114    pub small_iops: i64,
115    #[serde(deserialize_with = "deserialize_string_or_int")]
116    pub wr_latency: i64,
117    pub vol_id: Vec<Value>,
118    pub obj_severity: String,
119    pub unaligned_io_alerts: String,
120    #[serde(deserialize_with = "deserialize_string_or_int")]
121    pub unaligned_rd_bw: i64,
122    pub num_of_dest_snaps: i64,
123    #[serde(deserialize_with = "deserialize_string_or_int")]
124    pub acc_size_of_wr: i64,
125    #[serde(deserialize_with = "deserialize_string_or_int")]
126    pub iops: i64,
127    pub small_io_ratio_level: String,
128    pub dest_snap_list: Vec<Value>,
129    pub guid: String,
130    pub snapshot_type: String,
131    #[serde(deserialize_with = "deserialize_string_or_int")]
132    pub logical_space_in_use: i64,
133    pub unaligned_io_ratio_level: String,
134    #[serde(deserialize_with = "deserialize_string_or_int")]
135    pub acc_num_of_rd: i64,
136    pub index: i64,
137    pub lb_size: i64,
138    pub naa_name: String,
139    pub snapset_list: Vec<Value>,
140    #[serde(deserialize_with = "deserialize_string_or_int")]
141    pub unaligned_wr_bw: i64,
142    #[serde(deserialize_with = "deserialize_string_or_int")]
143    pub acc_num_of_small_rd: i64,
144    #[serde(deserialize_with = "deserialize_string_or_int")]
145    pub unaligned_rd_iops: i64,
146    pub snapgrp_id: Vec<Value>,
147    #[serde(deserialize_with = "deserialize_string_or_int")]
148    pub acc_num_of_small_wr: i64,
149    pub created_from_volume: String,
150    pub ancestor_vol_id: Vec<Value>,
151    #[serde(deserialize_with = "deserialize_string_or_int")]
152    pub small_wr_iops: i64,
153    pub creation_time: String,
154    #[serde(deserialize_with = "deserialize_string_or_int")]
155    pub rd_bw: i64,
156    pub xms_id: Vec<Value>,
157    #[serde(deserialize_with = "deserialize_string_or_int")]
158    pub acc_num_of_unaligned_rd: i64,
159    #[serde(deserialize_with = "deserialize_string_or_int")]
160    pub small_wr_bw: i64,
161    pub tag_list: Vec<Value>,
162    #[serde(deserialize_with = "deserialize_string_or_int")]
163    pub unaligned_iops: i64,
164    pub num_of_lun_mappings: i64,
165    pub vol_access: String,
166    #[serde(deserialize_with = "deserialize_string_or_int")]
167    pub small_rd_iops: i64,
168    #[serde(deserialize_with = "deserialize_string_or_int")]
169    pub unaligned_io_ratio: i64,
170    pub lun_mapping_list: Vec<Value>,
171    #[serde(deserialize_with = "deserialize_string_or_int")]
172    pub vol_size: i64,
173    #[serde(deserialize_with = "deserialize_string_or_int")]
174    pub wr_iops: i64,
175    pub manager_guid: Option<String>,
176    pub sys_id: Vec<Value>,
177    #[serde(deserialize_with = "deserialize_string_or_int")]
178    pub avg_latency: i64,
179    pub name: String,
180    pub vaai_tp_alerts: String,
181    #[serde(deserialize_with = "deserialize_string_or_int")]
182    pub rd_iops: i64,
183    #[serde(deserialize_with = "deserialize_string_or_int")]
184    pub rd_latency: i64,
185    #[serde(deserialize_with = "deserialize_string_or_int")]
186    pub unaligned_bw: i64,
187    pub related_consistency_groups: Vec<Value>,
188    pub certainty: String,
189    #[serde(deserialize_with = "deserialize_string_or_int")]
190    pub acc_num_of_unaligned_wr: i64,
191    pub vol_type: String,
192    #[serde(deserialize_with = "deserialize_string_or_int")]
193    pub acc_num_of_wr: i64,
194    #[serde(deserialize_with = "deserialize_string_or_int")]
195    pub small_io_ratio: i64,
196    #[serde(deserialize_with = "deserialize_string_or_int")]
197    pub acc_size_of_rd: i64,
198    #[serde(deserialize_with = "deserialize_string_or_int")]
199    pub unaligned_wr_iops: i64,
200    #[serde(deserialize_with = "deserialize_string_or_int")]
201    pub bw: i64,
202    #[serde(deserialize_with = "deserialize_string_or_int")]
203    pub small_rd_bw: i64,
204    pub alignment_offset: i64,
205    #[serde(deserialize_with = "deserialize_string_or_int")]
206    pub small_bw: i64,
207    #[serde(deserialize_with = "deserialize_string_or_int")]
208    pub wr_bw: i64,
209}
210
211#[derive(Deserialize, Debug)]
212pub struct Ssds {
213    pub ssds: Vec<Ssd>,
214    pub params: HashMap<String, String>,
215    pub links: Vec<Link>,
216}
217
218impl IntoPoint for Ssds {
219    fn into_point(&self, name: Option<&str>, is_time_series: bool) -> Vec<TsPoint> {
220        let mut points: Vec<TsPoint> = Vec::new();
221        let n = name.unwrap_or("ssd");
222
223        for v in &self.ssds {
224            points.extend(v.into_point(Some(n), is_time_series));
225        }
226
227        points
228    }
229}
230
231#[test]
232fn test_get_xtremio_ssds() {
233    use std::fs::File;
234    use std::io::Read;
235
236    let mut f = File::open("tests/xtremio/ssds.json").unwrap();
237    let mut buff = String::new();
238    f.read_to_string(&mut buff).unwrap();
239
240    let i: Ssds = serde_json::from_str(&buff).unwrap();
241    println!("result: {:#?}", i);
242}
243
244#[derive(Deserialize, Debug, IntoPoint)]
245#[serde(rename_all = "kebab-case")]
246pub struct Ssd {
247    #[serde(deserialize_with = "deserialize_string_or_int")]
248    pub ssd_size: i64,
249    pub fru_lifecycle_state: String,
250    pub smart_error_ascq: i64,
251    pub ssd_failure_reason: String,
252    pub percent_endurance_remaining: i64,
253    pub obj_severity: String,
254    #[serde(deserialize_with = "deserialize_string_or_int")]
255    pub rd_bw: i64,
256    pub part_number: String,
257    pub serial_number: String,
258    pub rg_id: Vec<Value>,
259    pub health_state: Option<Value>,
260    pub guid: String,
261    pub index: i64,
262    pub ssd_id: Vec<Value>,
263    pub model_name: String,
264    pub fw_version_error: String,
265    #[serde(deserialize_with = "deserialize_string_or_int")]
266    pub ssd_space_in_use: i64,
267    pub last_io_error_timestamp: i64,
268    pub slot_num: i64,
269    pub identify_led: String,
270    pub io_error_ascq: i64,
271    pub hw_revision: String,
272    pub ssd_link2_health_state: String,
273    pub io_error_asc: i64,
274    pub num_bad_sectors: i64,
275    pub xms_id: Vec<Value>,
276    pub ssd_link1_health_state: String,
277    pub percent_endurance_remaining_level: String,
278    pub io_error_vendor_specific: i64,
279    pub tag_list: Vec<Value>,
280    pub io_error_sense_code: i64,
281    #[serde(deserialize_with = "deserialize_string_or_int")]
282    pub bw: i64,
283    pub ssd_uid: String,
284    pub smart_error_asc: i64,
285    #[serde(deserialize_with = "deserialize_string_or_int")]
286    pub wr_iops: i64,
287    pub swap_led: String,
288    pub sys_id: Vec<Value>,
289    pub last_io_error_type: String,
290    #[serde(deserialize_with = "deserialize_string_or_int")]
291    pub iops: i64,
292    pub diagnostic_health_state: String,
293    pub name: String,
294    pub brick_id: Vec<Value>,
295    pub ssd_size_in_kb: i64,
296    pub certainty: String,
297    pub status_led: String,
298    pub enabled_state: String,
299    pub encryption_status: String,
300    pub ssd_rg_state: String,
301    pub fw_version: String,
302    #[serde(deserialize_with = "deserialize_string_or_int")]
303    pub rd_iops: i64,
304    #[serde(deserialize_with = "deserialize_string_or_int")]
305    pub wr_bw: i64,
306    #[serde(deserialize_with = "deserialize_string_or_int")]
307    pub useful_ssd_space: i64,
308}
309
310#[derive(Deserialize, Debug)]
311pub struct Psus {
312    #[serde(rename = "storage-controller-psus")]
313    pub storage_controller_psus: Vec<Psu>,
314    pub params: HashMap<String, String>,
315    pub links: Vec<Link>,
316}
317
318impl IntoPoint for Psus {
319    fn into_point(&self, name: Option<&str>, is_time_series: bool) -> Vec<TsPoint> {
320        let mut points: Vec<TsPoint> = Vec::new();
321        let n = name.unwrap_or("psu");
322
323        for v in &self.storage_controller_psus {
324            points.extend(v.into_point(Some(n), is_time_series));
325        }
326
327        points
328    }
329}
330
331#[test]
332fn test_get_xtremio_psus() {
333    use std::fs::File;
334    use std::io::Read;
335
336    let mut f = File::open("tests/xtremio/psus.json").unwrap();
337    let mut buff = String::new();
338    f.read_to_string(&mut buff).unwrap();
339
340    let i: Psus = serde_json::from_str(&buff).unwrap();
341    println!("result: {:#?}", i);
342}
343
344#[derive(Deserialize, Debug, IntoPoint)]
345#[serde(rename_all = "kebab-case")]
346pub struct Psu {
347    pub index: i64,
348    pub guid: String,
349    pub name: String,
350    pub brick_id: Vec<Value>,
351    pub node_psu_id: Vec<Value>,
352    pub obj_severity: String,
353    pub fw_version_error: String,
354    pub status_led: String,
355    pub enabled_state: String,
356    pub node_id: Vec<Value>,
357    pub power_feed: String,
358    pub serial_number: String,
359    pub fru_lifecycle_state: String,
360    pub location: String,
361    pub part_number: String,
362    pub input: String,
363    pub fru_replace_failure_reason: String,
364    pub model_name: String,
365    pub hw_revision: String,
366    pub sys_id: Vec<Value>,
367    pub power_failure: String,
368}
369
370#[test]
371fn test_get_xtremio_clusters() {
372    use std::fs::File;
373    use std::io::Read;
374
375    let mut f = File::open("tests/xtremio/clusters.json").unwrap();
376    let mut buff = String::new();
377    f.read_to_string(&mut buff).unwrap();
378
379    let i: Clusters = serde_json::from_str(&buff).unwrap();
380    println!("result: {:#?}", i);
381}
382
383#[derive(Deserialize, Debug)]
384pub struct Clusters {
385    pub clusters: Vec<Cluster>,
386    pub params: HashMap<String, String>,
387    pub links: Vec<Link>,
388}
389
390impl IntoPoint for Clusters {
391    fn into_point(&self, name: Option<&str>, is_time_series: bool) -> Vec<TsPoint> {
392        let mut points: Vec<TsPoint> = Vec::new();
393        let n = name.unwrap_or("cluster");
394
395        for v in &self.clusters {
396            points.extend(v.into_point(Some(n), is_time_series));
397        }
398
399        points
400    }
401}
402
403#[derive(Deserialize, Debug, IntoPoint)]
404#[serde(rename_all = "kebab-case")]
405pub struct Cluster {
406    pub compression_factor_text: String,
407    pub os_upgrade_in_progress: String,
408    pub ssh_firewall_mode: String,
409    #[serde(deserialize_with = "deserialize_string_or_int")]
410    pub wr_bw_64kb: i64,
411    #[serde(deserialize_with = "deserialize_string_or_int")]
412    pub rd_iops_64kb: i64,
413    pub free_ud_ssd_space_level: String,
414    #[serde(deserialize_with = "deserialize_string_or_int")]
415    pub wr_iops_by_block: i64,
416    pub num_of_rgs: i64,
417    pub total_memory_in_use_in_percent: i64,
418    #[serde(deserialize_with = "deserialize_string_or_int")]
419    pub iops: i64,
420    pub last_upgrade_attempt_version: String,
421    #[serde(deserialize_with = "deserialize_string_or_int")]
422    pub wr_latency_64kb: i64,
423    #[serde(deserialize_with = "deserialize_string_or_int")]
424    pub avg_latency_512kb: i64,
425    #[serde(deserialize_with = "deserialize_string_or_int")]
426    pub rd_latency_8kb: i64,
427    #[serde(deserialize_with = "deserialize_string_or_int")]
428    pub wr_bw_32kb: i64,
429    #[serde(deserialize_with = "deserialize_string_or_int")]
430    pub acc_num_of_small_rd: i64,
431    pub num_of_nodes: i64,
432    #[serde(deserialize_with = "deserialize_string_or_int")]
433    pub wr_bw_by_block: i64,
434    #[serde(deserialize_with = "deserialize_string_or_int")]
435    pub rd_latency_512b: i64,
436    #[serde(deserialize_with = "deserialize_string_or_int")]
437    pub rd_iops_1kb: i64,
438    pub iscsi_port_speed: String,
439    pub memory_recovery_status: String,
440    pub debug_create_timeout: String,
441    pub num_of_minor_alerts: i64,
442    pub gates_open: Option<bool>,
443    pub compression_factor: f64,
444    #[serde(deserialize_with = "deserialize_string_or_int")]
445    pub unaligned_rd_iops: i64,
446    pub shared_memory_in_use_recoverable_ratio_level: String,
447    #[serde(deserialize_with = "deserialize_string_or_int")]
448    pub wr_latency_2kb: i64,
449    pub obj_severity: String,
450    #[serde(deserialize_with = "deserialize_string_or_int")]
451    pub wr_bw_2kb: i64,
452    #[serde(deserialize_with = "deserialize_string_or_int")]
453    pub rd_iops_8kb: i64,
454    #[serde(deserialize_with = "deserialize_string_or_int")]
455    pub wr_latency_16kb: i64,
456    #[serde(deserialize_with = "deserialize_string_or_int")]
457    pub rd_bw: i64,
458    #[serde(deserialize_with = "deserialize_string_or_int")]
459    pub wr_iops_64kb: i64,
460    #[serde(deserialize_with = "deserialize_string_or_int")]
461    pub avg_latency_256kb: i64,
462    #[serde(deserialize_with = "deserialize_string_or_int")]
463    pub wr_latency_512kb: i64,
464    pub tag_list: Vec<Value>,
465    #[serde(deserialize_with = "deserialize_string_or_int")]
466    pub rd_bw_128kb: i64,
467    #[serde(deserialize_with = "deserialize_string_or_int")]
468    pub unaligned_rd_bw: i64,
469    #[serde(deserialize_with = "deserialize_string_or_int")]
470    pub wr_iops: i64,
471    pub sys_start_timestamp: i64,
472    pub cluster_expansion_in_progress: String,
473    #[serde(deserialize_with = "deserialize_string_or_int")]
474    pub wr_bw_gt1mb: i64,
475    pub num_of_ib_switches: i64,
476    pub num_of_tars: i64,
477    pub name: String,
478    #[serde(deserialize_with = "deserialize_string_or_int")]
479    pub acc_num_of_unaligned_wr: i64,
480    pub dedup_ratio_text: String,
481    #[serde(deserialize_with = "deserialize_string_or_int")]
482    pub rd_iops_4kb: i64,
483    #[serde(deserialize_with = "deserialize_string_or_int")]
484    pub wr_iops_16kb: i64,
485    #[serde(deserialize_with = "deserialize_string_or_int")]
486    pub wr_latency_1mb: i64,
487    #[serde(deserialize_with = "deserialize_string_or_int")]
488    pub acc_size_of_rd: i64,
489    #[serde(deserialize_with = "deserialize_string_or_int")]
490    pub wr_latency_4kb: i64,
491    pub dedup_ratio: f64,
492    #[serde(deserialize_with = "deserialize_string_or_int")]
493    pub rd_latency_1mb: i64,
494    #[serde(deserialize_with = "deserialize_string_or_int")]
495    pub wr_bw_8kb: i64,
496    #[serde(deserialize_with = "deserialize_string_or_int")]
497    pub avg_latency_512b: i64,
498    pub brick_list: Vec<Value>,
499    pub sys_sw_version: String,
500    #[serde(deserialize_with = "deserialize_string_or_int")]
501    pub rd_latency_16kb: i64,
502    #[serde(deserialize_with = "deserialize_string_or_int")]
503    pub rd_bw_512b: i64,
504    pub max_data_transfer_percent_done: i64,
505    pub fc_port_speed: String,
506    pub shared_memory: i64,
507    #[serde(deserialize_with = "deserialize_string_or_int")]
508    pub acc_num_of_wr: i64,
509    #[serde(deserialize_with = "deserialize_string_or_int")]
510    pub avg_latency_2kb: i64,
511    #[serde(deserialize_with = "deserialize_string_or_int")]
512    pub wr_bw_128kb: i64,
513    pub free_ud_ssd_space_in_percent: i64,
514    pub index: i64,
515    #[serde(deserialize_with = "deserialize_string_or_int")]
516    pub rd_iops_256kb: i64,
517    #[serde(deserialize_with = "deserialize_string_or_int")]
518    pub rd_latency_gt1mb: i64,
519    #[serde(deserialize_with = "deserialize_string_or_int")]
520    pub wr_latency_8kb: i64,
521    #[serde(deserialize_with = "deserialize_string_or_int")]
522    pub wr_latency_256kb: i64,
523    pub upgrade_failure_reason: String,
524    #[serde(deserialize_with = "deserialize_string_or_int")]
525    pub wr_bw_1kb: i64,
526    #[serde(deserialize_with = "deserialize_string_or_int")]
527    pub wr_iops_gt1mb: i64,
528    pub last_upgrade_attempt_timestamp: String,
529    #[serde(deserialize_with = "deserialize_string_or_int")]
530    pub rd_latency_256kb: i64,
531    #[serde(deserialize_with = "deserialize_string_or_int")]
532    pub rd_latency_32kb: i64,
533    pub num_of_xenvs: i64,
534    pub sys_stop_type: String,
535    pub stopped_reason: String,
536    #[serde(deserialize_with = "deserialize_string_or_int")]
537    pub wr_iops_32kb: i64,
538    pub configurable_vol_type_capability: String,
539    pub xms_id: Vec<Value>,
540    #[serde(deserialize_with = "deserialize_string_or_int")]
541    pub rd_iops_gt1mb: i64,
542    #[serde(deserialize_with = "deserialize_string_or_int")]
543    pub wr_latency_gt1mb: i64,
544    #[serde(deserialize_with = "deserialize_string_or_int")]
545    pub small_wr_bw: i64,
546    pub num_of_ssds: i64,
547    pub mode_switch_status: String,
548    #[serde(deserialize_with = "deserialize_string_or_int")]
549    pub wr_bw_512b: i64,
550    #[serde(deserialize_with = "deserialize_string_or_int")]
551    pub bw: i64,
552    #[serde(deserialize_with = "deserialize_string_or_int")]
553    pub avg_latency_64kb: i64,
554    #[serde(deserialize_with = "deserialize_string_or_int")]
555    pub wr_bw_512kb: i64,
556    pub send_snmp_heartbeat: Option<bool>,
557    #[serde(deserialize_with = "deserialize_string_or_int")]
558    pub avg_latency: i64,
559    pub total_memory_in_use: i64,
560    #[serde(deserialize_with = "deserialize_string_or_int")]
561    pub rd_iops_128kb: i64,
562    #[serde(deserialize_with = "deserialize_string_or_int")]
563    pub rd_latency_1kb: i64,
564    #[serde(deserialize_with = "deserialize_string_or_int")]
565    pub unaligned_bw: i64,
566    #[serde(deserialize_with = "deserialize_string_or_int")]
567    pub ud_ssd_space_in_use: i64,
568    pub num_of_jbods: i64,
569    pub license_id: String,
570    pub sys_health_state: String,
571    #[serde(deserialize_with = "deserialize_string_or_int")]
572    pub avg_latency_8kb: i64,
573    #[serde(deserialize_with = "deserialize_string_or_int")]
574    pub wr_iops_128kb: i64,
575    #[serde(deserialize_with = "deserialize_string_or_int")]
576    pub unaligned_wr_iops: i64,
577    pub data_reduction_ratio_text: String,
578    #[serde(deserialize_with = "deserialize_string_or_int")]
579    pub wr_bw: i64,
580    #[serde(deserialize_with = "deserialize_string_or_int")]
581    pub rd_bw_1kb: i64,
582    #[serde(deserialize_with = "deserialize_string_or_int")]
583    pub rd_iops_32kb: i64,
584    pub obfuscate_debug: String,
585    #[serde(deserialize_with = "deserialize_string_or_int")]
586    pub wr_latency: i64,
587    pub psnt_part_number: String,
588    #[serde(deserialize_with = "deserialize_string_or_int")]
589    pub small_iops: i64,
590    #[serde(deserialize_with = "deserialize_string_or_int")]
591    pub wr_bw_16kb: i64,
592    #[serde(deserialize_with = "deserialize_string_or_int")]
593    pub avg_latency_1kb: i64,
594    pub odx_mode: Option<String>,
595    #[serde(deserialize_with = "deserialize_string_or_int")]
596    pub rd_bw_by_block: i64,
597    #[serde(deserialize_with = "deserialize_string_or_int")]
598    pub ud_ssd_space: i64,
599    pub num_of_vols: i64,
600    #[serde(deserialize_with = "deserialize_string_or_int")]
601    pub wr_iops_512b: i64,
602    #[serde(deserialize_with = "deserialize_string_or_int")]
603    pub rd_iops_512b: i64,
604    #[serde(deserialize_with = "deserialize_string_or_int")]
605    pub acc_num_of_small_wr: i64,
606    pub guid: String,
607    #[serde(deserialize_with = "deserialize_string_or_int")]
608    pub useful_ssd_space_per_ssd: i64,
609    pub space_saving_ratio: f64,
610    #[serde(deserialize_with = "deserialize_string_or_int")]
611    pub acc_num_of_rd: i64,
612    pub data_reduction_ratio: f64,
613    #[serde(deserialize_with = "deserialize_string_or_int")]
614    pub wr_bw_1mb: i64,
615    pub ssd_very_high_utilization_thld_crossing: String,
616    pub vaai_tp_limit_crossing: String,
617    #[serde(deserialize_with = "deserialize_string_or_int")]
618    pub acc_size_of_wr: i64,
619    pub shared_memory_in_use_ratio_level: String,
620    pub num_of_internal_vols: i64,
621    #[serde(deserialize_with = "deserialize_string_or_int")]
622    pub rd_bw_2kb: i64,
623    #[serde(deserialize_with = "deserialize_string_or_int")]
624    pub rd_iops_by_block: i64,
625    pub under_maintenance: bool,
626    pub chap_authentication_mode: String,
627    #[serde(deserialize_with = "deserialize_string_or_int")]
628    pub bw_by_block: i64,
629    pub num_of_tgs: i64,
630    #[serde(deserialize_with = "deserialize_string_or_int")]
631    pub small_wr_iops: i64,
632    pub chap_discovery_mode: String,
633    #[serde(deserialize_with = "deserialize_string_or_int")]
634    pub wr_iops_1mb: i64,
635    pub device_connectivity_mode: Option<String>,
636    #[serde(deserialize_with = "deserialize_string_or_int")]
637    pub rd_bw_16kb: i64,
638    #[serde(deserialize_with = "deserialize_string_or_int")]
639    pub acc_num_of_unaligned_rd: i64,
640    pub iscsi_tcp_port: Option<i64>,
641    #[serde(deserialize_with = "deserialize_string_or_int")]
642    pub wr_iops_2kb: i64,
643    #[serde(deserialize_with = "deserialize_string_or_int")]
644    pub wr_iops_8kb: i64,
645    #[serde(deserialize_with = "deserialize_string_or_int")]
646    pub rd_bw_512kb: i64,
647    #[serde(deserialize_with = "deserialize_string_or_int")]
648    pub dedup_space_in_use: i64,
649    #[serde(deserialize_with = "deserialize_string_or_int")]
650    pub wr_latency_128kb: i64,
651    #[serde(deserialize_with = "deserialize_string_or_int")]
652    pub rd_latency_512kb: i64,
653    #[serde(deserialize_with = "deserialize_string_or_int")]
654    pub rd_bw_64kb: i64,
655    pub sys_id: Vec<Value>,
656    pub size_and_capacity: String,
657    pub is_any_c_mdl_lazy_load_in_progress: bool,
658    #[serde(deserialize_with = "deserialize_string_or_int")]
659    pub rd_bw_1mb: i64,
660    #[serde(deserialize_with = "deserialize_string_or_int")]
661    pub rd_latency_4kb: i64,
662    #[serde(deserialize_with = "deserialize_string_or_int")]
663    pub avg_latency_4kb: i64,
664    pub sys_activation_timestamp: i64,
665    #[serde(deserialize_with = "deserialize_string_or_int")]
666    pub wr_latency_512b: i64,
667    #[serde(deserialize_with = "deserialize_string_or_int")]
668    pub wr_iops_256kb: i64,
669    #[serde(deserialize_with = "deserialize_string_or_int")]
670    pub unaligned_wr_bw: i64,
671    #[serde(deserialize_with = "deserialize_string_or_int")]
672    pub rd_bw_4kb: i64,
673    #[serde(deserialize_with = "deserialize_string_or_int")]
674    pub small_rd_bw: i64,
675    #[serde(deserialize_with = "deserialize_string_or_int")]
676    pub rd_latency_64kb: i64,
677    #[serde(deserialize_with = "deserialize_string_or_int")]
678    pub rd_bw_32kb: i64,
679    #[serde(deserialize_with = "deserialize_string_or_int")]
680    pub wr_bw_256kb: i64,
681    #[serde(deserialize_with = "deserialize_string_or_int")]
682    pub rd_latency_2kb: i64,
683    #[serde(deserialize_with = "deserialize_string_or_int")]
684    pub rd_latency_128kb: i64,
685    pub ssd_high_utilization_thld_crossing: String,
686    pub compression_mode: String,
687    #[serde(deserialize_with = "deserialize_string_or_int")]
688    pub rd_iops_16kb: i64,
689    pub sc_fp_temperature_monitor_mode: String,
690    pub is_any_d_mdl_lazy_load_in_progress: bool,
691    pub upgrade_state: String,
692    #[serde(deserialize_with = "deserialize_string_or_int")]
693    pub wr_iops_512kb: i64,
694    #[serde(deserialize_with = "deserialize_string_or_int")]
695    pub avg_latency_128kb: i64,
696    pub space_in_use: i64,
697    #[serde(deserialize_with = "deserialize_string_or_int")]
698    pub logical_space_in_use: i64,
699    pub vaai_tp_limit: Option<i64>,
700    #[serde(deserialize_with = "deserialize_string_or_int")]
701    pub rd_iops_1mb: i64,
702    pub ib_switch_list: Vec<Value>,
703    pub sys_psnt_serial_number: String,
704    #[serde(deserialize_with = "deserialize_string_or_int")]
705    pub wr_iops_1kb: i64,
706    #[serde(deserialize_with = "deserialize_string_or_int")]
707    pub rd_iops_2kb: i64,
708    pub encryption_mode: String,
709    #[serde(deserialize_with = "deserialize_string_or_int")]
710    pub rd_bw_8kb: i64,
711    #[serde(deserialize_with = "deserialize_string_or_int")]
712    pub avg_latency_gt1mb: i64,
713    #[serde(deserialize_with = "deserialize_string_or_int")]
714    pub rd_bw_256kb: i64,
715    pub thin_provisioning_ratio: f64,
716    pub sys_mgr_conn_error_reason: String,
717    pub num_of_upses: i64,
718    #[serde(deserialize_with = "deserialize_string_or_int")]
719    pub avg_latency_1mb: i64,
720    pub num_of_major_alerts: i64,
721    pub num_of_initiators: i64,
722    pub sys_mgr_conn_state: String,
723    pub naa_sys_id: String,
724    #[serde(deserialize_with = "deserialize_string_or_int")]
725    pub wr_iops_4kb: i64,
726    #[serde(deserialize_with = "deserialize_string_or_int")]
727    pub unaligned_iops: i64,
728    #[serde(deserialize_with = "deserialize_string_or_int")]
729    pub rd_bw_gt1mb: i64,
730    pub encryption_supported: bool,
731    #[serde(deserialize_with = "deserialize_string_or_int")]
732    pub small_rd_iops: i64,
733    #[serde(deserialize_with = "deserialize_string_or_int")]
734    pub vol_size: i64,
735    #[serde(deserialize_with = "deserialize_string_or_int")]
736    pub rd_iops_512kb: i64,
737    pub thin_provisioning_savings: Option<f64>,
738    #[serde(deserialize_with = "deserialize_string_or_int")]
739    pub wr_bw_4kb: i64,
740    #[serde(deserialize_with = "deserialize_string_or_int")]
741    pub rd_iops: i64,
742    pub num_of_bricks: i64,
743    #[serde(deserialize_with = "deserialize_string_or_int")]
744    pub rd_latency: i64,
745    #[serde(deserialize_with = "deserialize_string_or_int")]
746    pub avg_latency_32kb: i64,
747    pub max_num_of_ssds_per_rg: i64,
748    #[serde(deserialize_with = "deserialize_string_or_int")]
749    pub wr_latency_32kb: i64,
750    #[serde(deserialize_with = "deserialize_string_or_int")]
751    pub iops_by_block: i64,
752    pub mode_switch_new_mode: String,
753    pub sys_state: String,
754    #[serde(deserialize_with = "deserialize_string_or_int")]
755    pub avg_latency_16kb: i64,
756    pub consistency_state: String,
757    pub num_of_critical_alerts: i64,
758    #[serde(deserialize_with = "deserialize_string_or_int")]
759    pub wr_latency_1kb: i64,
760    #[serde(deserialize_with = "deserialize_string_or_int")]
761    pub small_bw: i64,
762}
763
764#[test]
765fn test_get_xtremio_xmss() {
766    use std::fs::File;
767    use std::io::Read;
768
769    let mut f = File::open("tests/xtremio/xmss.json").unwrap();
770    let mut buff = String::new();
771    f.read_to_string(&mut buff).unwrap();
772
773    let i: Xmss = serde_json::from_str(&buff).unwrap();
774    println!("result: {:#?}", i);
775}
776
777#[derive(Deserialize, Debug)]
778pub struct Xmss {
779    pub xmss: Vec<Xms>,
780    pub params: HashMap<String, String>,
781    pub links: Vec<Link>,
782}
783
784impl IntoPoint for Xmss {
785    fn into_point(&self, name: Option<&str>, is_time_series: bool) -> Vec<TsPoint> {
786        let mut points: Vec<TsPoint> = Vec::new();
787        let n = name.unwrap_or("xms");
788
789        for xms in &self.xmss {
790            points.extend(xms.into_point(Some(n), is_time_series));
791        }
792
793        points
794    }
795}
796
797#[derive(Deserialize, Debug, IntoPoint)]
798#[serde(rename_all = "kebab-case")]
799pub struct Xms {
800    pub max_repeating_alert: Option<i64>,
801    #[serde(deserialize_with = "deserialize_string_or_int")]
802    pub wr_latency: i64,
803    pub max_recs_in_event_log: i64,
804    pub top_n_igs_by_iops: Vec<Value>,
805    pub xms_gw: String,
806    pub datetime: String,
807    #[serde(deserialize_with = "deserialize_string_or_int")]
808    pub rd_bw_by_block: i64,
809    #[serde(deserialize_with = "deserialize_string_or_int")]
810    pub iops: i64,
811    #[serde(deserialize_with = "deserialize_string_or_int")]
812    pub logs_size: i64,
813    pub guid: String,
814    #[serde(deserialize_with = "deserialize_string_or_int")]
815    pub wr_iops_by_block: i64,
816    pub index: i64,
817    pub uptime: String,
818    #[serde(deserialize_with = "deserialize_string_or_int")]
819    pub wr_bw_by_block: i64,
820    pub db_version: String,
821    pub server_name: Option<String>,
822    pub num_of_iscsi_routes: i64,
823    pub allow_empty_password: bool,
824    pub ip_version: String,
825    pub name: String,
826    pub xms_num_of_volumes_level: Option<String>,
827    pub top_n_volumes_by_latency: Vec<Value>,
828    #[serde(deserialize_with = "deserialize_string_or_int")]
829    pub rd_iops_by_block: i64,
830    pub version: String,
831    pub obj_severity: String,
832    pub top_n_igs_by_bw: Vec<Value>,
833    pub max_xms_tags_per_object: Option<i64>,
834    pub disk_space_secondary_utilization_level: String,
835    #[serde(deserialize_with = "deserialize_string_or_float")]
836    pub overall_efficiency_ratio: f64,
837    #[serde(deserialize_with = "deserialize_string_or_int")]
838    pub bw_by_block: i64,
839    #[serde(deserialize_with = "deserialize_string_or_int")]
840    pub build: i64,
841    pub num_of_igs: i64,
842    #[serde(deserialize_with = "deserialize_string_or_int")]
843    pub rd_bw: i64,
844    pub xms_id: Vec<Value>,
845    pub max_xms_clusters: Option<i64>,
846    pub sw_version: String,
847    pub num_of_systems: i64,
848    pub recs_in_event_log: i64,
849    pub num_of_user_accounts: i64,
850    pub disk_space_utilization_level: String,
851    pub default_user_inactivity_timeout: i64,
852    pub restapi_protocol_version: String,
853    #[serde(deserialize_with = "deserialize_string_or_int")]
854    pub wr_iops: i64,
855    #[serde(deserialize_with = "deserialize_string_or_int")]
856    pub thin_provisioning_savings: i64,
857    pub memory_utilization_level: String,
858    pub xms_ip_sn: String,
859    #[serde(deserialize_with = "deserialize_string_or_int")]
860    pub avg_latency: i64,
861    #[serde(deserialize_with = "deserialize_string_or_int")]
862    pub ram_usage: i64,
863    pub xms_ip: String,
864    pub max_xms_objects_per_tag: Option<i64>,
865    #[serde(deserialize_with = "deserialize_string_or_int")]
866    pub rd_latency: i64,
867    pub days_in_num_event: i64,
868    pub wrong_cn_in_csr: bool,
869    pub mgmt_interface: String,
870    #[serde(deserialize_with = "deserialize_string_or_int")]
871    pub iops_by_block: i64,
872    #[serde(deserialize_with = "deserialize_string_or_int")]
873    pub bw: i64,
874    #[serde(deserialize_with = "deserialize_string_or_int")]
875    pub ram_total: i64,
876    pub mode: String,
877    pub ntp_servers: Vec<Value>,
878    pub max_xms_volumes: Option<i64>,
879    #[serde(deserialize_with = "deserialize_string_or_int")]
880    pub rd_iops: i64,
881    #[serde(deserialize_with = "deserialize_string_or_int")]
882    pub wr_bw: i64,
883    #[serde(deserialize_with = "deserialize_string_or_float")]
884    pub cpu: f64,
885}
886
887impl XtremIo {
888    fn get_data<T>(&self, api_endpoint: &str, point_name: &str) -> MetricsResult<Vec<TsPoint>>
889    where
890        T: DeserializeOwned + Debug + IntoPoint,
891    {
892        let url = format!(
893            "https://{}/api/json/v2/types/{}?full=1",
894            self.config.endpoint, api_endpoint,
895        );
896        let j: T = crate::get(
897            &self.client,
898            &url,
899            &self.config.user,
900            Some(&self.config.password),
901        )?;
902
903        Ok(j.into_point(Some(point_name), true))
904    }
905
906    pub fn get_clusters(&self) -> MetricsResult<Vec<TsPoint>> {
907        let points = self.get_data::<Clusters>("clusters", "cluster")?;
908        Ok(points)
909    }
910
911    pub fn get_psus(&self) -> MetricsResult<Vec<TsPoint>> {
912        let points = self.get_data::<Psus>("storage-controller-psus", "psu")?;
913        Ok(points)
914    }
915    pub fn get_ssds(&self) -> MetricsResult<Vec<TsPoint>> {
916        let points = self.get_data::<Ssds>("ssds", "ssd")?;
917        Ok(points)
918    }
919
920    pub fn get_xms(&self) -> MetricsResult<Vec<TsPoint>> {
921        let points = self.get_data::<Xmss>("xms", "xms")?;
922        Ok(points)
923    }
924
925    pub fn get_volumes(&self) -> MetricsResult<Vec<TsPoint>> {
926        let points = self.get_data::<Volumes>("volumes", "volume")?;
927        Ok(points)
928    }
929}