feat: add app-node search
tabled list of app nodes fix handler docs some todos
This commit is contained in:
		
							parent
							
								
									88d3207cb5
								
							
						
					
					
						commit
						bf8a4f3a8b
					
				| @ -2,7 +2,7 @@ use clap::{builder::PossibleValue, Arg, Command}; | ||||
| use detee_cli::general::cli_handler::{ | ||||
|     handle_account, handle_completion, handle_operators, handle_packagers, | ||||
| }; | ||||
| use detee_cli::sgx::cli_handler::handle_app; | ||||
| use detee_cli::sgx::cli_handler::{handle_app, handle_app_nodes}; | ||||
| use detee_cli::snp::cli_handler::{handle_vm, handle_vm_nodes}; | ||||
| use detee_cli::*; | ||||
| 
 | ||||
| @ -33,6 +33,7 @@ fn main() { | ||||
|     match matches.subcommand() { | ||||
|         Some(("completion", subcom_args)) => handle_completion(subcom_args, cmd), | ||||
|         Some(("app", subcom_args)) => handle_app(subcom_args), | ||||
|         Some(("app-node", subcom_args)) => handle_app_nodes(subcom_args), | ||||
|         Some(("vm", subcom_args)) => handle_vm(subcom_args), | ||||
|         Some(("vm-node", subcom_args)) => handle_vm_nodes(subcom_args), | ||||
|         Some(("operator", subcom_args)) => handle_operators(subcom_args), | ||||
| @ -265,6 +266,39 @@ fn clap_cmd() -> Command { | ||||
|                     .long_about("List all the deployed apps in the enclave") | ||||
|                 ) | ||||
|         ) | ||||
|         .subcommand(Command::new("app-node") | ||||
|             .about("info about Intel SGX servers registerd to DeTEE") | ||||
|             .subcommand(Command::new("search").about("search nodes based on filters")) | ||||
|             /* | ||||
|             .subcommand(Command::new("inspect").about("get detailed information about a node") | ||||
|                 .arg( | ||||
|                     Arg::new("ip") | ||||
|                     .long("ip") | ||||
|                     .help("main IP of the node your want to inspect") | ||||
|                     .required(true) | ||||
|                 ) | ||||
|             ) | ||||
|             .subcommand(Command::new("report").about("report a node for poor performance") | ||||
|                 .arg( | ||||
|                     Arg::new("pubkey") | ||||
|                     .long("pubkey") | ||||
|                     .help("public key of the node you are reporting") | ||||
|                     .required(true) | ||||
|                 ) | ||||
|                 .arg( | ||||
|                     Arg::new("contract") | ||||
|                     .long("contract") | ||||
|                     .help("UUID of the active contract with this node") | ||||
|                     .required(true) | ||||
|                 ) | ||||
|                 .arg( | ||||
|                     Arg::new("reason") | ||||
|                     .long("reason") | ||||
|                     .help("detail the performance issue you experienced") | ||||
|                 ) | ||||
|             ) | ||||
|             */ | ||||
|         ) | ||||
|         .subcommand(Command::new("vm") | ||||
|             .about("virtual machines that run on AMD SEV-SNP nodes") | ||||
|             .subcommand(Command::new("deploy").about("deploy a VM on the DeTEE network") | ||||
|  | ||||
| @ -26,6 +26,22 @@ pub fn handle_app(app_matche: &ArgMatches) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn handle_app_nodes(matches: &ArgMatches) { | ||||
|     match matches.subcommand() { | ||||
|         Some(("search", _)) => cli_print(crate::sgx::print_nodes().map_err(Into::into)), | ||||
|         Some(("inspect", _)) => todo!(), | ||||
|         Some(("report", _)) => { | ||||
|             // let node_pubkey: String = path_subcommand.get_one::<String>("pubkey").unwrap().clone();
 | ||||
|             // let contract_uuid: String = path_subcommand.get_one::<String>("contract").unwrap().clone();
 | ||||
|             // let reason: String = path_subcommand.get_one::<String>("reason").unwrap().clone();
 | ||||
|             todo!() | ||||
|         } | ||||
|         _ => { | ||||
|             println!("Available commands are search, inspec and report. Use --help for more information.") | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| fn handle_package(package_match: &ArgMatches) -> Result<SimpleOutput, Box<dyn std::error::Error>> { | ||||
|     if let Some(file_paths) = package_match.get_many::<String>("files") { | ||||
|         let packaging_items = file_paths.cloned().collect::<Vec<String>>(); | ||||
|  | ||||
| @ -83,3 +83,24 @@ pub async fn get_one_app_node(req: AppNodeFilters) -> Result<AppNodeListResp> { | ||||
| 
 | ||||
|     Ok(res.into_inner()) | ||||
| } | ||||
| 
 | ||||
| pub async fn get_app_node_list(req: AppNodeFilters) -> Result<Vec<AppNodeListResp>> { | ||||
|     log::debug!("Getting app nodes from brain..."); | ||||
|     let mut daemon_serivce = BrainAppCliClient::connect(Config::get_brain_url()).await?; | ||||
|     let mut nodes = Vec::new(); | ||||
|     let mut grpc_stream = daemon_serivce.list_app_nodes(sign_request(req)?).await?.into_inner(); | ||||
| 
 | ||||
|     while let Some(stream_update) = grpc_stream.next().await { | ||||
|         match stream_update { | ||||
|             Ok(node) => { | ||||
|                 log::debug!("Received node from brain: {node:?}"); | ||||
|                 nodes.push(node); | ||||
|             } | ||||
|             Err(e) => { | ||||
|                 log::warn!("Received error instead of node list: {e:?}"); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     log::debug!("Brain terminated list_nodes stream."); | ||||
|     Ok(nodes) | ||||
| } | ||||
|  | ||||
| @ -1,3 +1,12 @@ | ||||
| pub mod cli_handler; | ||||
| pub mod config; | ||||
| pub mod grpc_brain; | ||||
| pub mod grpc_dtpm; | ||||
| pub mod packaging; | ||||
| pub mod utils; | ||||
| 
 | ||||
| use crate::snp; | ||||
| use crate::{constants::HRATLS_APP_PORT, utils::block_on}; | ||||
| use detee_shared::{ | ||||
|     app_proto::{ | ||||
|         AppContract as AppContractPB, AppNodeFilters, AppNodeListResp, AppResource, NewAppRes, | ||||
| @ -5,19 +14,9 @@ use detee_shared::{ | ||||
|     sgx::types::brain::Resource, | ||||
| }; | ||||
| use grpc_brain::get_one_app_node; | ||||
| 
 | ||||
| use serde::{Deserialize, Serialize}; | ||||
| use tabled::Tabled; | ||||
| 
 | ||||
| use crate::{constants::HRATLS_APP_PORT, utils::block_on}; | ||||
| 
 | ||||
| pub mod cli_handler; | ||||
| pub mod config; | ||||
| pub mod grpc_brain; | ||||
| pub mod grpc_dtpm; | ||||
| pub mod packaging; | ||||
| pub mod utils; | ||||
| 
 | ||||
| #[derive(Tabled, Debug, Serialize, Deserialize)] | ||||
| pub struct AppContract { | ||||
|     #[tabled(rename = "Location")] | ||||
| @ -150,7 +149,8 @@ impl crate::HumanOutput for AppDeleteResponse { | ||||
| 
 | ||||
| pub async fn get_app_node( | ||||
|     resource: Resource, | ||||
|     location: crate::snp::deploy::Location, | ||||
|     // TODO: change this to utils or something
 | ||||
|     location: snp::deploy::Location, | ||||
| ) -> Result<AppNodeListResp, grpc_brain::Error> { | ||||
|     let app_node_filter = AppNodeFilters { | ||||
|         vcpus: resource.vcpu, | ||||
| @ -164,3 +164,45 @@ pub async fn get_app_node( | ||||
|     }; | ||||
|     get_one_app_node(app_node_filter).await | ||||
| } | ||||
| 
 | ||||
| #[derive(Tabled, Debug, Serialize, Deserialize)] | ||||
| pub struct TabledAppNode { | ||||
|     #[tabled(rename = "Operator")] | ||||
|     pub operator: String, | ||||
|     #[tabled(rename = "City, Region, Country")] | ||||
|     pub location: String, | ||||
|     #[tabled(rename = "IP")] | ||||
|     pub public_ip: String, | ||||
|     #[tabled(rename = "Price per unit")] | ||||
|     pub price: String, | ||||
|     #[tabled(rename = "Reports")] | ||||
|     pub reports: usize, | ||||
| } | ||||
| 
 | ||||
| impl From<AppNodeListResp> for TabledAppNode { | ||||
|     fn from(brain_node: AppNodeListResp) -> Self { | ||||
|         Self { | ||||
|             operator: brain_node.operator, | ||||
|             location: brain_node.city + ", " + &brain_node.region + ", " + &brain_node.country, | ||||
|             public_ip: brain_node.ip, | ||||
|             price: format!("{} nanoLP/min", brain_node.price), | ||||
|             reports: brain_node.reports.len(), | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| impl super::HumanOutput for Vec<AppNodeListResp> { | ||||
|     fn human_cli_print(&self) { | ||||
|         let nodes: Vec<TabledAppNode> = self.iter().map(|n| n.clone().into()).collect(); | ||||
|         let style = tabled::settings::Style::rounded(); | ||||
|         let mut table = tabled::Table::new(nodes); | ||||
|         table.with(style); | ||||
|         println!("{table}"); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| pub fn print_nodes() -> Result<Vec<AppNodeListResp>, grpc_brain::Error> { | ||||
|     log::debug!("This will support flags in the future, but we have only one node atm."); | ||||
|     let req = AppNodeFilters { ..Default::default() }; | ||||
|     Ok(block_on(grpc_brain::get_app_node_list(req))?) | ||||
| } | ||||
|  | ||||
| @ -41,7 +41,7 @@ pub fn handle_vm_nodes(matches: &ArgMatches) { | ||||
|             cli_print(general::report_node(node_pubkey, contract_uuid, reason).map_err(Into::into)) | ||||
|         } | ||||
|         _ => { | ||||
|             println!("Available commands are search and report. Use --help for more information.") | ||||
|             println!("Available commands are search, inspect and report. Use --help for more information.") | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| @ -13,6 +13,7 @@ pub enum IPv4Config { | ||||
|     PublicIPv4, | ||||
| } | ||||
| 
 | ||||
| //  TODO: push this out of snp module
 | ||||
| #[derive(Serialize, Deserialize, Default)] | ||||
| pub struct Location { | ||||
|     pub node_ip: Option<String>, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user