inspect operator

This commit is contained in:
ghe0 2025-04-24 21:27:56 +03:00
parent a8cf515061
commit ee75412bb0
Signed by: ghe0
GPG Key ID: 451028EE56A0FBB4
3 changed files with 137 additions and 23 deletions

@ -75,7 +75,7 @@ DEFINE FIELD reason ON TABLE kick TYPE string;
DEFINE FIELD contract ON TABLE kick TYPE record<vm_contract|app_contract>;
DEFINE TABLE report TYPE RELATION FROM account TO vm_node|app_node;
DEFINE FIELD created_at ON TABLE ban TYPE datetime;
DEFINE FIELD reason ON TABLE ban TYPE string;
DEFINE FIELD created_at ON TABLE report TYPE datetime;
DEFINE FIELD reason ON TABLE report TYPE string;
DEFINE TABLE operator TYPE RELATION FROM account TO vm_node|app_node;

109
src/db.rs

@ -100,6 +100,26 @@ pub struct VmNode {
pub offline_minutes: u64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct VmNodeExtended {
pub id: RecordId,
pub country: String,
pub region: String,
pub city: String,
pub ip: String,
pub avail_mem_mb: u32,
pub avail_vcpus: u32,
pub avail_storage_gbs: u32,
pub avail_ipv4: u32,
pub avail_ipv6: u32,
pub avail_ports: u32,
pub max_ports_per_vm: u32,
pub price: u64,
pub offline_minutes: u64,
pub reports: Vec<Report>,
pub operator: RecordId,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct VmContract {
pub id: RecordId,
@ -221,18 +241,36 @@ impl VmContractWithNode {
#[derive(Debug, Serialize, Deserialize)]
pub struct AppNode {
id: RecordId,
country: String,
region: String,
city: String,
ip: String,
avail_mem_mb: u32,
avail_vcpus: u32,
avail_storage_gbs: u32,
avail_ports: u32,
max_ports_per_app: u32,
price: u64,
offline_minutes: u64,
pub id: RecordId,
pub country: String,
pub region: String,
pub city: String,
pub ip: String,
pub avail_mem_mb: u32,
pub avail_vcpus: u32,
pub avail_storage_gbs: u32,
pub avail_ports: u32,
pub max_ports_per_app: u32,
pub price: u64,
pub offline_minutes: u64,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct AppNodeExtended {
pub id: RecordId,
pub country: String,
pub region: String,
pub city: String,
pub ip: String,
pub avail_mem_mb: u32,
pub avail_vcpus: u32,
pub avail_storage_gbs: u32,
pub avail_ports: u32,
pub max_ports_per_app: u32,
pub price: u64,
pub offline_minutes: u64,
pub reports: Vec<Report>,
pub operator: RecordId,
}
#[derive(Debug, Serialize, Deserialize)]
@ -288,12 +326,16 @@ pub struct Report {
#[serde(rename = "out")]
to_node: RecordId,
created_at: Datetime,
reason: String,
pub reason: String,
}
impl Report {
// TODO: test this functionality and remove this comment
pub async fn create(from_account: RecordId, to_node: RecordId, reason: String) -> Result<(), Error> {
pub async fn create(
from_account: RecordId,
to_node: RecordId,
reason: String,
) -> Result<(), Error> {
let _: Vec<Self> = DB
.insert("report")
.relation(Report { from_account, to_node, created_at: Datetime::default(), reason })
@ -350,6 +392,45 @@ impl Operator {
let operators: Vec<Self> = result.take(0)?;
Ok(operators)
}
pub async fn inspect_nodes(
account: &str,
) -> Result<(Option<Self>, Vec<VmNodeExtended>, Vec<AppNodeExtended>), Error> {
let mut result = DB
.query(format!(
"select *,
in as account,
<-account.email[0] as email,
<-account.escrow[0] as escrow,
count(->vm_node) as vm_nodes,
count(->app_node) as app_nodes,
(select in from <-account->operator->vm_node<-report).len() +
(select in from <-account->operator->app_node<-report).len()
as reports
from operator where in = account:{account} group by account;"
))
.query(format!(
"select *,
(<-operator<-account)[0].id as operator,
<-report.* as reports
from vm_node
where (<-operator<-account)[0].id = account:{account};"
))
.query(format!(
"select *,
(<-operator<-account)[0].id as operator,
<-report.* as reports
from app_node
where (<-operator<-account)[0].id = account:{account};"
))
.await?;
let operator: Option<Self> = result.take(0)?;
let vm_nodes: Vec<VmNodeExtended> = result.take(1)?;
let app_nodes: Vec<AppNodeExtended> = result.take(2)?;
Ok((operator, vm_nodes, app_nodes))
}
}
// TODO: delete all of these From implementation after migration 0 gets executed

@ -1,6 +1,6 @@
#![allow(dead_code)]
use crate::db;
use detee_shared::app_proto::AppContract;
use detee_shared::app_proto::{AppContract, AppNodeListResp};
use detee_shared::{
common_proto::{Empty, Pubkey},
general_proto::{
@ -84,6 +84,36 @@ impl From<db::Operator> for ListOperatorsResp {
}
}
impl From<db::VmNodeExtended> for VmNodeListResp {
fn from(vm_node: db::VmNodeExtended) -> Self {
Self {
operator: vm_node.operator.key().to_string(),
node_pubkey: vm_node.id.key().to_string(),
country: vm_node.country,
region: vm_node.region,
city: vm_node.city,
ip: vm_node.ip,
reports: vm_node.reports.iter().map(|n| n.reason.clone()).collect(),
price: vm_node.price,
}
}
}
impl From<db::AppNodeExtended> for AppNodeListResp {
fn from(app_node: db::AppNodeExtended) -> Self {
Self {
operator: app_node.operator.key().to_string(),
node_pubkey: app_node.id.key().to_string(),
country: app_node.country,
region: app_node.region,
city: app_node.city,
ip: app_node.ip,
reports: app_node.reports.iter().map(|n| n.reason.clone()).collect(),
price: app_node.price,
}
}
}
#[tonic::async_trait]
impl BrainGeneralCli for BrainGeneralCliMock {
type ListAccountsStream = Pin<Box<dyn Stream<Item = Result<Account, Status>> + Send>>;
@ -134,13 +164,16 @@ impl BrainGeneralCli for BrainGeneralCliMock {
async fn inspect_operator(
&self,
_req: Request<Pubkey>,
req: Request<Pubkey>,
) -> Result<Response<InspectOperatorResp>, Status> {
todo!();
// match self.data.inspect_operator(&req.into_inner().pubkey) {
// Some(op) => Ok(Response::new(op.into())),
// None => Err(Status::not_found("The wallet you specified is not an operator")),
// }
match db::Operator::inspect_nodes(&req.into_inner().pubkey).await? {
(Some(op), vm_nodes, app_nodes) => Ok(Response::new(InspectOperatorResp {
operator: Some(op.into()),
vm_nodes: vm_nodes.into_iter().map(|n| n.into()).collect(),
app_nodes: app_nodes.into_iter().map(|n| n.into()).collect(),
})),
(None, _, _) => Err(Status::not_found("The wallet you specified is not an operator")),
}
}
async fn register_operator(