redis_enterprise/
nodes.rs

1//! Node management for Redis Enterprise
2
3use crate::client::RestClient;
4use crate::error::Result;
5use serde::{Deserialize, Serialize};
6use serde_json::Value;
7
8/// Node information
9#[derive(Debug, Clone, Serialize, Deserialize)]
10pub struct Node {
11    pub uid: u32,
12
13    /// IP address of the node (renamed from 'address' to match API)
14    #[serde(rename = "addr")]
15    pub addr: Option<String>,
16
17    pub status: String,
18
19    /// Whether node accepts new shards
20    pub accept_servers: Option<bool>,
21
22    /// System architecture (e.g., "aarch64", "x86_64")
23    pub architecture: Option<String>,
24
25    /// CPU cores (renamed from 'cpu_cores' to match API)
26    #[serde(rename = "cores")]
27    pub cores: Option<u32>,
28
29    /// External IP addresses
30    pub external_addr: Option<Vec<String>>,
31
32    /// Total memory in bytes
33    pub total_memory: Option<u64>,
34
35    /// OS version information
36    pub os_version: Option<String>,
37    pub os_name: Option<String>,
38    pub os_family: Option<String>,
39    pub os_semantic_version: Option<String>,
40
41    /// Storage sizes (API returns f64, not u64)
42    pub ephemeral_storage_size: Option<f64>,
43    pub persistent_storage_size: Option<f64>,
44
45    /// Storage paths
46    pub ephemeral_storage_path: Option<String>,
47    pub persistent_storage_path: Option<String>,
48    pub bigredis_storage_path: Option<String>,
49
50    /// Rack configuration
51    pub rack_id: Option<String>,
52    pub second_rack_id: Option<String>,
53
54    /// Shard information
55    pub shard_count: Option<u32>,
56    pub shard_list: Option<Vec<u32>>,
57    pub ram_shard_count: Option<u32>,
58    pub flash_shard_count: Option<u32>,
59
60    /// Features and capabilities
61    pub bigstore_enabled: Option<bool>,
62    pub fips_enabled: Option<bool>,
63    pub use_internal_ipv6: Option<bool>,
64
65    /// Limits and settings
66    pub max_listeners: Option<u32>,
67    pub max_redis_servers: Option<u32>,
68    pub max_redis_forks: Option<i32>,
69    pub max_slave_full_syncs: Option<i32>,
70
71    /// Runtime information
72    pub uptime: Option<u64>,
73    pub software_version: Option<String>,
74
75    /// Supported Redis versions
76    pub supported_database_versions: Option<Vec<Value>>,
77
78    /// Capture any additional fields not explicitly defined
79    #[serde(flatten)]
80    pub extra: Value,
81}
82
83/// Node stats
84#[derive(Debug, Clone, Serialize, Deserialize)]
85pub struct NodeStats {
86    pub uid: u32,
87    pub cpu_user: Option<f64>,
88    pub cpu_system: Option<f64>,
89    pub cpu_idle: Option<f64>,
90    pub free_memory: Option<u64>,
91    pub network_bytes_in: Option<u64>,
92    pub network_bytes_out: Option<u64>,
93    pub persistent_storage_free: Option<u64>,
94    pub ephemeral_storage_free: Option<u64>,
95
96    #[serde(flatten)]
97    pub extra: Value,
98}
99
100/// Node action request
101#[derive(Debug, Serialize)]
102pub struct NodeActionRequest {
103    pub action: String,
104    #[serde(skip_serializing_if = "Option::is_none")]
105    pub node_uid: Option<u32>,
106}
107
108/// Node handler for executing node commands
109pub struct NodeHandler {
110    client: RestClient,
111}
112
113impl NodeHandler {
114    pub fn new(client: RestClient) -> Self {
115        NodeHandler { client }
116    }
117
118    /// List all nodes
119    pub async fn list(&self) -> Result<Vec<Node>> {
120        self.client.get("/v1/nodes").await
121    }
122
123    /// Get specific node info
124    pub async fn get(&self, uid: u32) -> Result<Node> {
125        self.client.get(&format!("/v1/nodes/{}", uid)).await
126    }
127
128    /// Update node configuration
129    pub async fn update(&self, uid: u32, updates: Value) -> Result<Node> {
130        self.client
131            .put(&format!("/v1/nodes/{}", uid), &updates)
132            .await
133    }
134
135    /// Remove node from cluster
136    pub async fn remove(&self, uid: u32) -> Result<()> {
137        self.client.delete(&format!("/v1/nodes/{}", uid)).await
138    }
139
140    /// Get node stats
141    pub async fn stats(&self, uid: u32) -> Result<NodeStats> {
142        self.client.get(&format!("/v1/nodes/{}/stats", uid)).await
143    }
144
145    /// Get node actions
146    pub async fn actions(&self, uid: u32) -> Result<Value> {
147        self.client.get(&format!("/v1/nodes/{}/actions", uid)).await
148    }
149
150    /// Execute node action (e.g., "maintenance_on", "maintenance_off")
151    pub async fn execute_action(&self, uid: u32, action: &str) -> Result<Value> {
152        let request = NodeActionRequest {
153            action: action.to_string(),
154            node_uid: Some(uid),
155        };
156        self.client
157            .post(&format!("/v1/nodes/{}/actions", uid), &request)
158            .await
159    }
160}