use crate::client::RestClient;
use crate::error::Result;
use serde::{Deserialize, Serialize};
use serde_json::Value;
use typed_builder::TypedBuilder;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeActionResponse {
pub action_uid: String,
pub description: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct Node {
pub uid: u32,
#[serde(rename = "addr")]
pub addr: Option<String>,
pub status: String,
pub accept_servers: Option<bool>,
pub architecture: Option<String>,
#[serde(rename = "cores")]
pub cores: Option<u32>,
pub external_addr: Option<Vec<String>>,
pub total_memory: Option<u64>,
pub os_version: Option<String>,
pub os_name: Option<String>,
pub os_family: Option<String>,
pub os_semantic_version: Option<String>,
pub ephemeral_storage_size: Option<f64>,
pub persistent_storage_size: Option<f64>,
pub ephemeral_storage_path: Option<String>,
pub persistent_storage_path: Option<String>,
pub bigredis_storage_path: Option<String>,
pub rack_id: Option<String>,
pub second_rack_id: Option<String>,
pub shard_count: Option<u32>,
pub shard_list: Option<Vec<u32>>,
pub ram_shard_count: Option<u32>,
pub flash_shard_count: Option<u32>,
pub bigstore_enabled: Option<bool>,
pub fips_enabled: Option<bool>,
pub use_internal_ipv6: Option<bool>,
pub max_listeners: Option<u32>,
pub max_redis_servers: Option<u32>,
pub max_redis_forks: Option<i32>,
pub max_slave_full_syncs: Option<i32>,
pub uptime: Option<u64>,
pub software_version: Option<String>,
pub supported_database_versions: Option<Vec<Value>>,
pub bigstore_driver: Option<String>,
pub bigstore_size: Option<u64>,
pub public_addr: Option<String>,
pub recovery_path: Option<String>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct NodeStats {
pub uid: u32,
pub cpu_user: Option<f64>,
pub cpu_system: Option<f64>,
pub cpu_idle: Option<f64>,
pub free_memory: Option<u64>,
pub network_bytes_in: Option<u64>,
pub network_bytes_out: Option<u64>,
pub persistent_storage_free: Option<u64>,
pub ephemeral_storage_free: Option<u64>,
}
#[derive(Debug, Serialize, TypedBuilder)]
pub struct NodeActionRequest {
#[builder(setter(into))]
pub action: String,
#[serde(skip_serializing_if = "Option::is_none")]
#[builder(default, setter(strip_option))]
pub node_uid: Option<u32>,
}
pub struct NodeHandler {
client: RestClient,
}
pub type NodesHandler = NodeHandler;
impl NodeHandler {
pub fn new(client: RestClient) -> Self {
NodeHandler { client }
}
pub async fn list(&self) -> Result<Vec<Node>> {
self.client.get("/v1/nodes").await
}
pub async fn get(&self, uid: u32) -> Result<Node> {
self.client.get(&format!("/v1/nodes/{}", uid)).await
}
pub async fn update(&self, uid: u32, updates: Value) -> Result<Node> {
self.client
.put(&format!("/v1/nodes/{}", uid), &updates)
.await
}
pub async fn remove(&self, uid: u32) -> Result<()> {
self.client.delete(&format!("/v1/nodes/{}", uid)).await
}
pub async fn stats(&self, uid: u32) -> Result<NodeStats> {
self.client.get(&format!("/v1/nodes/{}/stats", uid)).await
}
pub async fn actions(&self, uid: u32) -> Result<Value> {
self.client.get(&format!("/v1/nodes/{}/actions", uid)).await
}
pub async fn execute_action(&self, uid: u32, action: &str) -> Result<NodeActionResponse> {
let request = NodeActionRequest {
action: action.to_string(),
node_uid: Some(uid),
};
self.client
.post(&format!("/v1/nodes/{}/actions", uid), &request)
.await
}
pub async fn list_actions(&self) -> Result<Value> {
self.client.get("/v1/nodes/actions").await
}
pub async fn action_detail(&self, uid: u32, action: &str) -> Result<Value> {
self.client
.get(&format!("/v1/nodes/{}/actions/{}", uid, action))
.await
}
pub async fn action_execute(&self, uid: u32, action: &str, body: Value) -> Result<Value> {
self.client
.post(&format!("/v1/nodes/{}/actions/{}", uid, action), &body)
.await
}
pub async fn action_delete(&self, uid: u32, action: &str) -> Result<()> {
self.client
.delete(&format!("/v1/nodes/{}/actions/{}", uid, action))
.await
}
pub async fn snapshots(&self, uid: u32) -> Result<Value> {
self.client
.get(&format!("/v1/nodes/{}/snapshots", uid))
.await
}
pub async fn snapshot_create(&self, uid: u32, name: &str) -> Result<Value> {
self.client
.post(
&format!("/v1/nodes/{}/snapshots/{}", uid, name),
&serde_json::json!({}),
)
.await
}
pub async fn snapshot_delete(&self, uid: u32, name: &str) -> Result<()> {
self.client
.delete(&format!("/v1/nodes/{}/snapshots/{}", uid, name))
.await
}
pub async fn status_all(&self) -> Result<Value> {
self.client.get("/v1/nodes/status").await
}
pub async fn wd_status_all(&self) -> Result<Value> {
self.client.get("/v1/nodes/wd_status").await
}
pub async fn status(&self, uid: u32) -> Result<Value> {
self.client.get(&format!("/v1/nodes/{}/status", uid)).await
}
pub async fn wd_status(&self, uid: u32) -> Result<Value> {
self.client
.get(&format!("/v1/nodes/{}/wd_status", uid))
.await
}
pub async fn alerts_all(&self) -> Result<Value> {
self.client.get("/v1/nodes/alerts").await
}
pub async fn alerts_for(&self, uid: u32) -> Result<Value> {
self.client.get(&format!("/v1/nodes/alerts/{}", uid)).await
}
pub async fn alert_detail(&self, uid: u32, alert: &str) -> Result<Value> {
self.client
.get(&format!("/v1/nodes/alerts/{}/{}", uid, alert))
.await
}
}