redis_enterprise/
diagnostics.rs

1//! Diagnostics management for Redis Enterprise
2//!
3//! ## Overview
4//! - List and query resources
5//! - Create and update configurations
6//! - Monitor status and metrics
7
8use crate::client::RestClient;
9use crate::error::Result;
10use serde::{Deserialize, Serialize};
11use serde_json::Value;
12use typed_builder::TypedBuilder;
13
14/// Diagnostic check request
15#[derive(Debug, Clone, Serialize, Deserialize, TypedBuilder)]
16pub struct DiagnosticRequest {
17    /// Specific diagnostic checks to run (if not specified, runs all checks)
18    #[serde(skip_serializing_if = "Option::is_none")]
19    #[builder(default, setter(strip_option))]
20    pub checks: Option<Vec<String>>,
21    /// Node UIDs to run diagnostics on (if not specified, runs on all nodes)
22    #[serde(skip_serializing_if = "Option::is_none")]
23    #[builder(default, setter(strip_option))]
24    pub node_uids: Option<Vec<u32>>,
25    /// Database UIDs to run diagnostics on (if not specified, runs on all databases)
26    #[serde(skip_serializing_if = "Option::is_none")]
27    #[builder(default, setter(strip_option))]
28    pub bdb_uids: Option<Vec<u32>>,
29}
30
31/// Diagnostic result
32#[derive(Debug, Clone, Serialize, Deserialize)]
33pub struct DiagnosticResult {
34    /// Name of the diagnostic check performed
35    pub check_name: String,
36    /// Status of the check ('pass', 'warning', 'fail')
37    pub status: String,
38    /// Human-readable message describing the result
39    #[serde(skip_serializing_if = "Option::is_none")]
40    pub message: Option<String>,
41    /// Additional details about the check result
42    #[serde(skip_serializing_if = "Option::is_none")]
43    pub details: Option<Value>,
44    /// Recommended actions to resolve any issues found
45    #[serde(skip_serializing_if = "Option::is_none")]
46    pub recommendations: Option<Vec<String>>,
47
48    #[serde(flatten)]
49    pub extra: Value,
50}
51
52/// Diagnostic report
53#[derive(Debug, Clone, Serialize, Deserialize)]
54pub struct DiagnosticReport {
55    /// Unique identifier for this diagnostic report
56    pub report_id: String,
57    /// Timestamp when the report was generated
58    pub timestamp: String,
59    /// List of individual diagnostic check results
60    pub results: Vec<DiagnosticResult>,
61    /// Summary statistics of the diagnostic run
62    #[serde(skip_serializing_if = "Option::is_none")]
63    pub summary: Option<DiagnosticSummary>,
64
65    #[serde(flatten)]
66    pub extra: Value,
67}
68
69/// Diagnostic summary
70#[derive(Debug, Clone, Serialize, Deserialize)]
71pub struct DiagnosticSummary {
72    /// Total number of diagnostic checks performed
73    pub total_checks: u32,
74    /// Number of checks that passed
75    pub passed: u32,
76    /// Number of checks with warnings
77    pub warnings: u32,
78    /// Number of checks that failed
79    pub failures: u32,
80}
81
82/// Diagnostics handler
83pub struct DiagnosticsHandler {
84    client: RestClient,
85}
86
87impl DiagnosticsHandler {
88    pub fn new(client: RestClient) -> Self {
89        DiagnosticsHandler { client }
90    }
91
92    /// Run diagnostic checks
93    pub async fn run(&self, request: DiagnosticRequest) -> Result<DiagnosticReport> {
94        self.client.post("/v1/diagnostics", &request).await
95    }
96
97    /// Get available diagnostic checks
98    pub async fn list_checks(&self) -> Result<Vec<String>> {
99        self.client.get("/v1/diagnostics/checks").await
100    }
101
102    /// Get last diagnostic report
103    pub async fn get_last_report(&self) -> Result<DiagnosticReport> {
104        self.client.get("/v1/diagnostics/last").await
105    }
106
107    /// Get specific diagnostic report
108    pub async fn get_report(&self, report_id: &str) -> Result<DiagnosticReport> {
109        self.client
110            .get(&format!("/v1/diagnostics/reports/{}", report_id))
111            .await
112    }
113
114    /// List all diagnostic reports
115    pub async fn list_reports(&self) -> Result<Vec<DiagnosticReport>> {
116        self.client.get("/v1/diagnostics/reports").await
117    }
118
119    /// Get diagnostics configuration/state - GET /v1/diagnostics
120    pub async fn get_config(&self) -> Result<Value> {
121        self.client.get("/v1/diagnostics").await
122    }
123
124    /// Update diagnostics configuration/state - PUT /v1/diagnostics
125    pub async fn update_config(&self, body: Value) -> Result<Value> {
126        self.client.put("/v1/diagnostics", &body).await
127    }
128}