From 4965db6ea5a3973cb207825631e7831fedc8f3ee Mon Sep 17 00:00:00 2001 From: Simeon Romanov Date: Wed, 15 Nov 2023 17:16:16 +0300 Subject: [PATCH] add raw metrics and config methods --- backend/src/services/api.rs | 84 ++++++++++++++++++++++++++++++++++++- backend/src/services/mod.rs | 13 ++++++ 2 files changed, 95 insertions(+), 2 deletions(-) diff --git a/backend/src/services/api.rs b/backend/src/services/api.rs index 772302c3..95bab177 100644 --- a/backend/src/services/api.rs +++ b/backend/src/services/api.rs @@ -1,7 +1,13 @@ -use crate::models::bob::{DiskName, IsActive}; +use axum::extract::Path; + +use crate::{ + connector::dto::{MetricsSnapshotModel, NodeConfiguration}, + models::bob::{DiskName, IsActive}, +}; use super::{ - methods::{request_nodes, request_vdisks}, + auth::HttpClient, + methods::{request_configuration, request_metrics, request_nodes, request_vdisks}, prelude::*, }; @@ -551,3 +557,77 @@ fn disk_status_from_space(space: &dto::SpaceInfo, occupied_space: u64) -> DiskSt DiskStatus::Good } } + +/// Get Raw Metrics from Node +/// +/// # Errors +/// +/// This function will return an error if the server was unable to get node'a client or the request to get metrics fails +#[cfg_attr(feature = "swagger", utoipa::path( + get, + context_path = ApiV1::to_path(), + path = "/nodes/{node_name}/metrics", + responses( + (status = 200, body = MetricsSnapshotModel, content_type = "application/json", description = "Node's metrics"), + (status = 401, description = "Unauthorized"), + (status = 404, description = "Node Not Found") + ), + security(("api_key" = [])) + ))] +pub async fn raw_metrics_by_node( + Extension(client): Extension, + Path(node_name): Path, +) -> AxumResult> { + let client = get_client_by_node(&client, node_name).await?; + + Ok(Json(request_metrics(client.as_ref()).await?)) +} + +/// Get Configuration from Node +/// +/// # Errors +/// +/// This function will return an error if the server was unable to get node'a client or the request to get configuration fails +#[cfg_attr(feature = "swagger", utoipa::path( + get, + context_path = ApiV1::to_path(), + path = "/nodes/{node_name}/configuration", + responses( + (status = 200, body = NodeConfiguration, content_type = "application/json", description = "Node's configuration"), + (status = 401, description = "Unauthorized"), + (status = 404, description = "Node Not Found") + ), + security(("api_key" = [])) + ))] +pub async fn raw_configuration_by_node( + Extension(client): Extension, + Path(node_name): Path, +) -> AxumResult> { + let client = get_client_by_node(&client, node_name).await?; + + Ok(Json(request_configuration(client.as_ref()).await?)) +} + +async fn get_client_by_node( + client: &HttpBobClient, + node_name: NodeName, +) -> AxumResult> { + let nodes = request_nodes(client.api_main()).await?; + + let node = nodes + .iter() + .find(|node| node.name == node_name) + .ok_or_else(|| { + tracing::error!("Couldn't find specified node"); + APIError::RequestFailed + })?; + + client + .cluster_with_addr() + .get(&node.name) + .ok_or_else(|| { + tracing::error!("Couldn't find specified node"); + APIError::RequestFailed.into() + }) + .cloned() +} diff --git a/backend/src/services/mod.rs b/backend/src/services/mod.rs index 084310a8..c7887a18 100644 --- a/backend/src/services/mod.rs +++ b/backend/src/services/mod.rs @@ -27,6 +27,8 @@ use api::{get_disks_count, get_nodes_count, get_rps, get_space}; use auth::{login, logout, require_auth, AuthState, BobUser, HttpBobClient, InMemorySessionStore}; use prelude::*; +use self::api::{get_nodes, raw_configuration_by_node, raw_metrics_by_node}; + type BobAuthState = AuthState< BobUser, Uuid, @@ -48,6 +50,17 @@ pub fn api_router_v1(auth_state: BobAuthState) -> Result, R .api_route("/nodes/count", &Method::GET, get_nodes_count) .api_route("/nodes/rps", &Method::GET, get_rps) .api_route("/nodes/space", &Method::GET, get_space) + .api_route("/nodes", &Method::GET, get_nodes) + .api_route( + "/nodes/:node_name/metrics", + &Method::GET, + raw_metrics_by_node, + ) + .api_route( + "/nodes/:node_name/configuration", + &Method::GET, + raw_configuration_by_node, + ) .unwrap()? .route_layer(from_fn_with_state(auth_state, require_auth)) .with_context::()