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::{ | use detee_cli::general::cli_handler::{ | ||||||
|     handle_account, handle_completion, handle_operators, handle_packagers, |     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::snp::cli_handler::{handle_vm, handle_vm_nodes}; | ||||||
| use detee_cli::*; | use detee_cli::*; | ||||||
| 
 | 
 | ||||||
| @ -33,6 +33,7 @@ fn main() { | |||||||
|     match matches.subcommand() { |     match matches.subcommand() { | ||||||
|         Some(("completion", subcom_args)) => handle_completion(subcom_args, cmd), |         Some(("completion", subcom_args)) => handle_completion(subcom_args, cmd), | ||||||
|         Some(("app", subcom_args)) => handle_app(subcom_args), |         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", subcom_args)) => handle_vm(subcom_args), | ||||||
|         Some(("vm-node", subcom_args)) => handle_vm_nodes(subcom_args), |         Some(("vm-node", subcom_args)) => handle_vm_nodes(subcom_args), | ||||||
|         Some(("operator", subcom_args)) => handle_operators(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") |                     .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") |         .subcommand(Command::new("vm") | ||||||
|             .about("virtual machines that run on AMD SEV-SNP nodes") |             .about("virtual machines that run on AMD SEV-SNP nodes") | ||||||
|             .subcommand(Command::new("deploy").about("deploy a VM on the DeTEE network") |             .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>> { | fn handle_package(package_match: &ArgMatches) -> Result<SimpleOutput, Box<dyn std::error::Error>> { | ||||||
|     if let Some(file_paths) = package_match.get_many::<String>("files") { |     if let Some(file_paths) = package_match.get_many::<String>("files") { | ||||||
|         let packaging_items = file_paths.cloned().collect::<Vec<String>>(); |         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()) |     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::{ | use detee_shared::{ | ||||||
|     app_proto::{ |     app_proto::{ | ||||||
|         AppContract as AppContractPB, AppNodeFilters, AppNodeListResp, AppResource, NewAppRes, |         AppContract as AppContractPB, AppNodeFilters, AppNodeListResp, AppResource, NewAppRes, | ||||||
| @ -5,19 +14,9 @@ use detee_shared::{ | |||||||
|     sgx::types::brain::Resource, |     sgx::types::brain::Resource, | ||||||
| }; | }; | ||||||
| use grpc_brain::get_one_app_node; | use grpc_brain::get_one_app_node; | ||||||
| 
 |  | ||||||
| use serde::{Deserialize, Serialize}; | use serde::{Deserialize, Serialize}; | ||||||
| use tabled::Tabled; | 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)] | #[derive(Tabled, Debug, Serialize, Deserialize)] | ||||||
| pub struct AppContract { | pub struct AppContract { | ||||||
|     #[tabled(rename = "Location")] |     #[tabled(rename = "Location")] | ||||||
| @ -150,7 +149,8 @@ impl crate::HumanOutput for AppDeleteResponse { | |||||||
| 
 | 
 | ||||||
| pub async fn get_app_node( | pub async fn get_app_node( | ||||||
|     resource: Resource, |     resource: Resource, | ||||||
|     location: crate::snp::deploy::Location, |     // TODO: change this to utils or something
 | ||||||
|  |     location: snp::deploy::Location, | ||||||
| ) -> Result<AppNodeListResp, grpc_brain::Error> { | ) -> Result<AppNodeListResp, grpc_brain::Error> { | ||||||
|     let app_node_filter = AppNodeFilters { |     let app_node_filter = AppNodeFilters { | ||||||
|         vcpus: resource.vcpu, |         vcpus: resource.vcpu, | ||||||
| @ -164,3 +164,45 @@ pub async fn get_app_node( | |||||||
|     }; |     }; | ||||||
|     get_one_app_node(app_node_filter).await |     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)) |             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, |     PublicIPv4, | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | //  TODO: push this out of snp module
 | ||||||
| #[derive(Serialize, Deserialize, Default)] | #[derive(Serialize, Deserialize, Default)] | ||||||
| pub struct Location { | pub struct Location { | ||||||
|     pub node_ip: Option<String>, |     pub node_ip: Option<String>, | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user