#![allow(dead_code)] pub mod brain { tonic::include_proto!("brain"); } use anyhow::Result; use brain::{ brain_cli_service_client::BrainCliServiceClient, DeletedVmUpdate, ListVmContractsReq, NewVmRequest, NodeFilters, NodeListResp, VmContract, UpdateVmRequest, }; use lazy_static::lazy_static; use log::{debug, info, warn}; use rand::{distributions::Alphanumeric, thread_rng, Rng}; use tokio_stream::StreamExt; use tonic::transport::Channel; lazy_static! { static ref SECURE_PUBLIC_KEY: String = use_default_string(); } fn use_default_string() -> String { "ThisIsMyEternalClient".to_string() } fn generate_random_string() -> String { let rng = thread_rng(); rng.sample_iter(&Alphanumeric) .take(16) // Adjust the length as needed .map(char::from) .collect() } async fn get_node_list(mut client: BrainCliServiceClient) -> Result> { info!("Getting nodes from brain..."); let mut nodes = Vec::new(); let mut grpc_stream = client .list_nodes(NodeFilters { free_ports: 0, offers_ipv4: true, offers_ipv6: true, vcpus: 0, memory_mb: 0, storage_gb: 0, country: String::new(), }) .await? .into_inner(); while let Some(stream_update) = grpc_stream.next().await { match stream_update { Ok(node) => { debug!("Received node from brain: {node:?}"); nodes.push(node); } Err(e) => { warn!("Received error instead of node list: {e:?}"); } } } info!("Brain terminated list_nodes stream."); Ok(nodes) } async fn submit_vm_request( mut client: BrainCliServiceClient, node_pubkey: &str, ) -> Result<()> { let req = NewVmRequest { uuid: String::new(), admin_pubkey: SECURE_PUBLIC_KEY.clone(), node_pubkey: node_pubkey.to_string(), hostname: "cool-server".to_string(), vcpus: 4, memory_mb: 4000, disk_size_gb: 20, public_ipv4: true, public_ipv6: true, extra_ports: Vec::new(), kernel_url: "thisIsMyURL".to_string(), kernel_sha: "thisIsMySha".to_string(), dtrfs_url: "thisIsMyURL".to_string(), dtrfs_sha: "thisIsMySha".to_string(), }; info!("Creating VM {req:?}"); let result = client.create_vm_contract(req).await; match result { Ok(confirmation) => { let confirmation = confirmation.into_inner(); if confirmation.error.is_empty() { info!("Got VM confirmation: {confirmation:?}"); } else { warn!("Got VM confirmation error: {}", confirmation.error); }; } Err(e) => log::error!("Could not create vm: {e:?}"), }; Ok(()) } async fn list_contracts(mut client: BrainCliServiceClient) -> Result> { info!("Getting contracts from brain..."); let mut contracts = Vec::new(); let mut grpc_stream = client .list_vm_contracts(ListVmContractsReq { admin_pubkey: SECURE_PUBLIC_KEY.to_string(), node_pubkey: String::new(), }) .await? .into_inner(); while let Some(stream_update) = grpc_stream.next().await { match stream_update { Ok(node) => { debug!("Received contract from brain: {node:?}"); contracts.push(node); } Err(e) => { warn!("Received error instead of contracts: {e:?}"); } } } info!("Brain terminated list_contracts stream."); Ok(contracts) } async fn delete_vm(mut client: BrainCliServiceClient, uuid: &str) -> Result<()> { let req = DeletedVmUpdate { uuid: uuid.to_string(), }; info!("Creating VM {req:?}"); let result = client.delete_vm(req).await; match result { Ok(confirmation) => info!("VM deleted: {confirmation:?}"), Err(e) => log::error!("Could not delete vm: {e:?}"), }; Ok(()) } async fn update_vm_request( mut client: BrainCliServiceClient, node_pubkey: &str, uuid: &str, ) -> Result<()> { let req = UpdateVmRequest { uuid: uuid.to_string(), node_pubkey: node_pubkey.to_string(), vcpus: 4, memory_mb: 4096, disk_size_gb: 40, kernel_url: "thisIsMyNewURL".to_string(), kernel_sha: "thisIsMyNewSha".to_string(), dtrfs_url: "thisIsMyNewURL".to_string(), dtrfs_sha: "thisIsMyNewSha".to_string(), }; info!("Creating VM {req:?}"); let result = client.update_vm(req).await; match result { Ok(confirmation) => { let confirmation = confirmation.into_inner(); if confirmation.error.is_empty() { info!("Got VM confirmation: {confirmation:?}"); } else { warn!("Got VM confirmation error: {}", confirmation.error); }; } Err(e) => log::error!("Could not create vm: {e:?}"), }; Ok(()) } #[tokio::main] async fn main() -> Result<()> { env_logger::builder() .filter_level(log::LevelFilter::Debug) .init(); info!("Hello! My name is {}", SECURE_PUBLIC_KEY.clone()); let client = BrainCliServiceClient::connect("http://[::1]:31337").await?; let nodes = get_node_list(client.clone()).await?; for node in nodes { if let Err(e) = submit_vm_request(client.clone(), &node.node_pubkey).await { log::error!( "Received error when creating VM on node {}: {e:?}", &node.node_pubkey ); } } let contracts = list_contracts(client.clone()).await?; for contract in contracts { if let Err(e) = update_vm_request(client.clone(), &use_default_string(), &contract.uuid).await { log::error!("Received error when updating VM {}: {e:?}", &contract.uuid); } } if std::env::var("DELETE_VMS").is_err() { return Ok(()); } let contracts = list_contracts(client.clone()).await?; for contract in contracts { if let Err(e) = delete_vm(client.clone(), &contract.uuid).await { log::error!("Received error when deleting VM {}: {e:?}", &contract.uuid); } } Ok(()) }