features: app engine #1

Merged
ghe0 merged 11 commits from app_engine into main 2025-05-15 01:39:06 +00:00
4 changed files with 56 additions and 6 deletions
Showing only changes of commit 0ccaa4840c - Show all commits

2
Cargo.lock generated

@ -1000,7 +1000,7 @@ dependencies = [
[[package]] [[package]]
name = "detee-shared" name = "detee-shared"
version = "0.1.0" 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 = [ dependencies = [
"bincode 2.0.1", "bincode 2.0.1",
"prost", "prost",

@ -1,9 +1,9 @@
use crate::constants::{ACCOUNT, ACTIVE_APP, APP_NODE, NEW_APP_REQ};
use crate::db::general::Report;
use super::Error; use super::Error;
use crate::constants::{ACCOUNT, ACTIVE_APP, APP_NODE, NEW_APP_REQ};
use crate::db; use crate::db;
use crate::db::general::Report;
use crate::old_brain; use crate::old_brain;
use detee_shared::app_proto;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use surrealdb::engine::remote::ws::Client; use surrealdb::engine::remote::ws::Client;
use surrealdb::sql::Datetime; use surrealdb::sql::Datetime;
@ -112,6 +112,45 @@ pub struct AppNodeWithReports {
pub reports: Vec<Report>, pub reports: Vec<Report>,
} }
impl AppNodeWithReports {
pub async fn find_by_filters(
db: &Surreal<Client>,
filters: app_proto::AppNodeFilters,
) -> Result<Vec<Self>, 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<Self> = query_resp.take(0)?;
Ok(app_nodes)
}
}
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Serialize, Deserialize)]
pub struct ActiveApp { pub struct ActiveApp {
id: RecordId, id: RecordId,

@ -219,8 +219,15 @@ impl BrainAppCli for AppCliServer {
) -> Result<tonic::Response<<Self as BrainAppCli>::ListAppNodesStream>, tonic::Status> { ) -> Result<tonic::Response<<Self as BrainAppCli>::ListAppNodesStream>, tonic::Status> {
let req = check_sig_from_req(req)?; let req = check_sig_from_req(req)?;
info!("list_app_nodes process starting for {:?}", req); info!("list_app_nodes process starting for {:?}", req);
let app_nodes = db::AppNodeWithReports::find_by_filters(&self.db, req).await?;
todo!() 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( async fn get_one_app_node(

@ -58,6 +58,7 @@ impl_pubkey_getter!(RegisterAppNodeReq);
impl_pubkey_getter!(AppNodeFilters); impl_pubkey_getter!(AppNodeFilters);
pub fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Result<T, Status> { pub fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) -> Result<T, Status> {
log::trace!("Checking signature from request: {:?}", req);
let time = match req.metadata().get("timestamp") { let time = match req.metadata().get("timestamp") {
Some(t) => t.clone(), Some(t) => t.clone(),
None => return Err(Status::unauthenticated("Timestamp not found in metadata.")), None => return Err(Status::unauthenticated("Timestamp not found in metadata.")),
@ -121,6 +122,9 @@ pub fn check_sig_from_req<T: std::fmt::Debug + PubkeyGetter>(req: Request<T>) ->
} }
pub fn check_sig_from_parts(pubkey: &str, time: &str, msg: &str, sig: &str) -> Result<(), Status> { 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 now = chrono::Utc::now();
let parsed_time = chrono::DateTime::parse_from_rfc3339(time) let parsed_time = chrono::DateTime::parse_from_rfc3339(time)
.map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?; .map_err(|_| Status::unauthenticated("Coult not parse timestamp"))?;