diff --git a/Cargo.lock b/Cargo.lock index dd6da18..81b5bd8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1000,7 +1000,7 @@ dependencies = [ [[package]] name = "detee-shared" version = "0.1.0" -source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=surreal_brain_app#0d4b712fad1040dd773d2076d7b4b65b18527136" +source = "git+ssh://git@gitea.detee.cloud/testnet/proto?branch=surreal_brain_app#637610196f708475230802fa67f1b3ee4d8d0679" dependencies = [ "bincode 2.0.1", "prost", diff --git a/src/db/app.rs b/src/db/app.rs index 3080380..e610eea 100644 --- a/src/db/app.rs +++ b/src/db/app.rs @@ -1,9 +1,9 @@ -use crate::constants::{ACCOUNT, ACTIVE_APP, APP_NODE, NEW_APP_REQ}; -use crate::db::general::Report; - use super::Error; +use crate::constants::{ACCOUNT, ACTIVE_APP, APP_NODE, NEW_APP_REQ}; use crate::db; +use crate::db::general::Report; use crate::old_brain; +use detee_shared::app_proto; use serde::{Deserialize, Serialize}; use surrealdb::engine::remote::ws::Client; use surrealdb::sql::Datetime; @@ -112,6 +112,45 @@ pub struct AppNodeWithReports { pub reports: Vec, } +impl AppNodeWithReports { + pub async fn find_by_filters( + db: &Surreal, + filters: app_proto::AppNodeFilters, + ) -> Result, Error> { + let mut filter_query = format!( + "select *, <-report.* from {APP_NODE} where + avail_ports >= {} && + max_ports_per_app >= {} && + avail_vcpus >= {} && + avail_mem_mb >= {} && + avail_storage_gbs >= {}\n", + filters.free_ports, + filters.free_ports, + filters.vcpus, + filters.memory_mb, + filters.storage_mb + ); + + if !filters.city.is_empty() { + filter_query += &format!("&& city = '{}' ", filters.city); + } + if !filters.region.is_empty() { + filter_query += &format!("&& region = '{}' ", filters.region); + } + if !filters.country.is_empty() { + filter_query += &format!("&& country = '{}' ", filters.country); + } + if !filters.ip.is_empty() { + filter_query += &format!("&& ip = '{}' ", filters.ip); + } + filter_query += ";"; + dbg!(&filter_query); + let mut query_resp = db.query(filter_query).await?; + let app_nodes: Vec = query_resp.take(0)?; + Ok(app_nodes) + } +} + #[derive(Debug, Serialize, Deserialize)] pub struct ActiveApp { id: RecordId, diff --git a/src/grpc/app.rs b/src/grpc/app.rs index 91cdac4..26f9ea4 100644 --- a/src/grpc/app.rs +++ b/src/grpc/app.rs @@ -219,8 +219,15 @@ impl BrainAppCli for AppCliServer { ) -> Result::ListAppNodesStream>, tonic::Status> { let req = check_sig_from_req(req)?; info!("list_app_nodes process starting for {:?}", req); - - todo!() + let app_nodes = db::AppNodeWithReports::find_by_filters(&self.db, req).await?; + let (tx, rx) = mpsc::channel(6); + tokio::spawn(async move { + for app_node in app_nodes { + let _ = tx.send(Ok(app_node.into())).await; + } + }); + let resp_stream = ReceiverStream::new(rx); + Ok(Response::new(Box::pin(resp_stream))) } async fn get_one_app_node( diff --git a/src/grpc/mod.rs b/src/grpc/mod.rs index 1dec498..4fbf0d4 100644 --- a/src/grpc/mod.rs +++ b/src/grpc/mod.rs @@ -58,6 +58,7 @@ impl_pubkey_getter!(RegisterAppNodeReq); impl_pubkey_getter!(AppNodeFilters); pub fn check_sig_from_req(req: Request) -> Result { + log::trace!("Checking signature from request: {:?}", req); let time = match req.metadata().get("timestamp") { Some(t) => t.clone(), None => return Err(Status::unauthenticated("Timestamp not found in metadata.")), @@ -121,6 +122,9 @@ pub fn check_sig_from_req(req: Request) -> } pub fn check_sig_from_parts(pubkey: &str, time: &str, msg: &str, sig: &str) -> Result<(), Status> { + log::trace!( + "Checking signature from parts: pubkey: {pubkey}, time: {time}, msg: {msg}, sig: {sig}" + ); let now = chrono::Utc::now(); let parsed_time = chrono::DateTime::parse_from_rfc3339(time) .map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?;