redis_enterprise/
shards.rs

1//! Shards 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;
12
13/// Response for a single metric query
14#[derive(Debug, Clone, Serialize, Deserialize)]
15pub struct MetricResponse {
16    pub interval: String,
17    pub timestamps: Vec<i64>,
18    pub values: Vec<Value>,
19    #[serde(flatten)]
20    pub extra: Value,
21}
22
23/// Shard information
24#[derive(Debug, Clone, Serialize, Deserialize)]
25pub struct Shard {
26    pub uid: String,
27    pub bdb_uid: u32,
28    pub node_uid: u32,
29    pub role: String,
30    pub status: String,
31    #[serde(skip_serializing_if = "Option::is_none")]
32    pub slots: Option<String>,
33    #[serde(skip_serializing_if = "Option::is_none")]
34    pub used_memory: Option<u64>,
35    #[serde(skip_serializing_if = "Option::is_none")]
36    pub backup_progress: Option<f64>,
37    #[serde(skip_serializing_if = "Option::is_none")]
38    pub import_progress: Option<f64>,
39    /// All nodes that this shard is associated with
40    pub all_nodes: Option<Vec<u32>>,
41    /// Assigned slots for this shard
42    pub assigned_slots: Option<String>,
43    /// Client certificate subject validation type
44    pub client_cert_subject_validation_type: Option<String>,
45    /// Redis info for this shard
46    pub redis_info: Option<Value>,
47    /// Roles assigned to this shard
48    pub roles: Option<Vec<String>>,
49
50    #[serde(flatten)]
51    pub extra: Value,
52}
53
54/// Shard stats information
55#[derive(Debug, Clone, Serialize, Deserialize)]
56pub struct ShardStats {
57    pub uid: String,
58    pub intervals: Vec<StatsInterval>,
59
60    #[serde(flatten)]
61    pub extra: Value,
62}
63
64#[derive(Debug, Clone, Serialize, Deserialize)]
65pub struct StatsInterval {
66    pub interval: String,
67    pub timestamps: Vec<i64>,
68    pub values: Vec<Value>,
69}
70
71/// Shard handler for managing shards
72pub struct ShardHandler {
73    client: RestClient,
74}
75
76impl ShardHandler {
77    pub fn new(client: RestClient) -> Self {
78        ShardHandler { client }
79    }
80
81    /// List all shards
82    pub async fn list(&self) -> Result<Vec<Shard>> {
83        self.client.get("/v1/shards").await
84    }
85
86    /// Get specific shard information
87    pub async fn get(&self, uid: &str) -> Result<Shard> {
88        self.client.get(&format!("/v1/shards/{}", uid)).await
89    }
90
91    /// Get shard statistics
92    pub async fn stats(&self, uid: &str) -> Result<ShardStats> {
93        self.client.get(&format!("/v1/shards/{}/stats", uid)).await
94    }
95
96    /// Get shard statistics for a specific metric
97    pub async fn stats_metric(&self, uid: &str, metric: &str) -> Result<MetricResponse> {
98        self.client
99            .get(&format!("/v1/shards/{}/stats/{}", uid, metric))
100            .await
101    }
102
103    // raw variant removed: use stats_metric()
104
105    /// Get shards for a specific database
106    pub async fn list_by_database(&self, bdb_uid: u32) -> Result<Vec<Shard>> {
107        self.client
108            .get(&format!("/v1/bdbs/{}/shards", bdb_uid))
109            .await
110    }
111
112    /// Get shards for a specific node
113    pub async fn list_by_node(&self, node_uid: u32) -> Result<Vec<Shard>> {
114        self.client
115            .get(&format!("/v1/nodes/{}/shards", node_uid))
116            .await
117    }
118
119    // Aggregate raw helpers removed; use StatsHandler for aggregates
120
121    /// Global failover - POST /v1/shards/actions/failover
122    pub async fn failover_all(&self, body: ShardActionRequest) -> Result<Action> {
123        self.client.post("/v1/shards/actions/failover", &body).await
124    }
125
126    /// Global migrate - POST /v1/shards/actions/migrate
127    pub async fn migrate_all(&self, body: ShardActionRequest) -> Result<Action> {
128        self.client.post("/v1/shards/actions/migrate", &body).await
129    }
130
131    /// Per-shard failover - POST /v1/shards/{uid}/actions/failover
132    pub async fn failover(&self, uid: &str, body: ShardActionRequest) -> Result<Action> {
133        self.client
134            .post(&format!("/v1/shards/{}/actions/failover", uid), &body)
135            .await
136    }
137
138    /// Per-shard migrate - POST /v1/shards/{uid}/actions/migrate
139    pub async fn migrate(&self, uid: &str, body: ShardActionRequest) -> Result<Action> {
140        self.client
141            .post(&format!("/v1/shards/{}/actions/migrate", uid), &body)
142            .await
143    }
144}
145
146#[derive(Debug, Clone, Serialize, Deserialize)]
147pub struct ShardActionRequest {
148    #[serde(skip_serializing_if = "Option::is_none")]
149    pub shard_uids: Option<Vec<String>>,
150    #[serde(flatten)]
151    pub extra: Value,
152}
153
154#[derive(Debug, Clone, Serialize, Deserialize)]
155pub struct Action {
156    pub action_uid: String,
157    #[serde(skip_serializing_if = "Option::is_none")]
158    pub status: Option<String>,
159    #[serde(flatten)]
160    pub extra: Value,
161}