mirror of
https://mirror.suhoan.cn/https://github.com/EasyTier/EasyTier.git
synced 2025-12-12 20:57:26 +08:00
Add commands to manage configuations
This commit is contained in:
@@ -109,6 +109,8 @@ enum SubCommand {
|
||||
Stats(StatsArgs),
|
||||
#[command(about = "manage logger configuration")]
|
||||
Logger(LoggerArgs),
|
||||
#[command(about = "manage network instance configuration")]
|
||||
Config(ConfigArgs),
|
||||
#[command(about = t!("core_clap.generate_completions").to_string())]
|
||||
GenAutocomplete { shell: Shell },
|
||||
}
|
||||
@@ -293,6 +295,23 @@ enum LoggerSubCommand {
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
struct ConfigArgs {
|
||||
#[command(subcommand)]
|
||||
sub_command: Option<ConfigSubCommand>,
|
||||
}
|
||||
|
||||
#[derive(Subcommand, Debug)]
|
||||
enum ConfigSubCommand {
|
||||
/// List network instances and their configurations
|
||||
List,
|
||||
/// Get configuration for a specific instance
|
||||
Get {
|
||||
#[arg(help = "Instance ID")]
|
||||
inst_id: String,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Args, Debug)]
|
||||
struct ServiceArgs {
|
||||
#[arg(short, long, default_value = env!("CARGO_PKG_NAME"), help = "service name")]
|
||||
@@ -1286,6 +1305,68 @@ impl CommandHandler<'_> {
|
||||
}
|
||||
Ok(ports)
|
||||
}
|
||||
|
||||
async fn handle_config_list(&self) -> Result<(), Error> {
|
||||
let client = self.get_peer_manager_client().await?;
|
||||
let node_info = client
|
||||
.show_node_info(BaseController::default(), ShowNodeInfoRequest::default())
|
||||
.await?
|
||||
.node_info
|
||||
.ok_or(anyhow::anyhow!("node info not found"))?;
|
||||
|
||||
if self.verbose || *self.output_format == OutputFormat::Json {
|
||||
println!("{}", serde_json::to_string_pretty(&node_info)?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
#[derive(tabled::Tabled, serde::Serialize)]
|
||||
struct ConfigTableItem {
|
||||
#[tabled(rename = "Instance ID")]
|
||||
inst_id: String,
|
||||
#[tabled(rename = "Virtual IP")]
|
||||
ipv4: String,
|
||||
#[tabled(rename = "Hostname")]
|
||||
hostname: String,
|
||||
#[tabled(rename = "Network Name")]
|
||||
network_name: String,
|
||||
}
|
||||
|
||||
let items = vec![ConfigTableItem {
|
||||
inst_id: node_info.peer_id.to_string(),
|
||||
ipv4: node_info.ipv4_addr,
|
||||
hostname: node_info.hostname,
|
||||
network_name: node_info.network_name,
|
||||
}];
|
||||
|
||||
print_output(&items, self.output_format)?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_config_get(&self, inst_id: &str) -> Result<(), Error> {
|
||||
let client = self.get_peer_manager_client().await?;
|
||||
let node_info = client
|
||||
.show_node_info(BaseController::default(), ShowNodeInfoRequest::default())
|
||||
.await?
|
||||
.node_info
|
||||
.ok_or(anyhow::anyhow!("node info not found"))?;
|
||||
|
||||
// Check if the requested instance ID matches the current node
|
||||
if node_info.peer_id.to_string() != inst_id {
|
||||
return Err(anyhow::anyhow!(
|
||||
"Instance ID {} not found. Current instance ID is {}",
|
||||
inst_id,
|
||||
node_info.peer_id
|
||||
));
|
||||
}
|
||||
|
||||
if self.verbose || *self.output_format == OutputFormat::Json {
|
||||
println!("{}", serde_json::to_string_pretty(&node_info)?);
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
println!("{}", node_info.config);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
@@ -2097,6 +2178,14 @@ async fn main() -> Result<(), Error> {
|
||||
handler.handle_logger_set(level).await?;
|
||||
}
|
||||
},
|
||||
SubCommand::Config(config_args) => match &config_args.sub_command {
|
||||
Some(ConfigSubCommand::List) | None => {
|
||||
handler.handle_config_list().await?;
|
||||
}
|
||||
Some(ConfigSubCommand::Get { inst_id }) => {
|
||||
handler.handle_config_get(inst_id).await?;
|
||||
}
|
||||
},
|
||||
SubCommand::GenAutocomplete { shell } => {
|
||||
let mut cmd = Cli::command();
|
||||
easytier::print_completions(shell, &mut cmd, "easytier-cli");
|
||||
|
||||
@@ -140,6 +140,12 @@ impl NetworkInstanceManager {
|
||||
.and_then(|instance| instance.value().get_running_info())
|
||||
}
|
||||
|
||||
pub fn get_network_config(&self, instance_id: &uuid::Uuid) -> Option<TomlConfigLoader> {
|
||||
self.instance_map
|
||||
.get(instance_id)
|
||||
.map(|instance| instance.value().get_config())
|
||||
}
|
||||
|
||||
pub fn list_network_instance_ids(&self) -> Vec<uuid::Uuid> {
|
||||
self.instance_map.iter().map(|item| *item.key()).collect()
|
||||
}
|
||||
|
||||
@@ -460,6 +460,10 @@ impl NetworkInstance {
|
||||
None
|
||||
}
|
||||
}
|
||||
|
||||
pub fn get_config(&self) -> TomlConfigLoader {
|
||||
self.config.clone()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_proxy_network_to_config(
|
||||
|
||||
@@ -178,6 +178,15 @@ message DeleteNetworkInstanceResponse {
|
||||
repeated common.UUID remain_inst_ids = 1;
|
||||
}
|
||||
|
||||
message GetConfigRequest {
|
||||
common.UUID inst_id = 1;
|
||||
}
|
||||
|
||||
message GetConfigResponse {
|
||||
NetworkConfig config = 1;
|
||||
string toml_config = 2;
|
||||
}
|
||||
|
||||
service WebClientService {
|
||||
rpc ValidateConfig(ValidateConfigRequest) returns (ValidateConfigResponse) {}
|
||||
rpc RunNetworkInstance(RunNetworkInstanceRequest) returns (RunNetworkInstanceResponse) {}
|
||||
@@ -185,4 +194,5 @@ service WebClientService {
|
||||
rpc CollectNetworkInfo(CollectNetworkInfoRequest) returns (CollectNetworkInfoResponse) {}
|
||||
rpc ListNetworkInstance(ListNetworkInstanceRequest) returns (ListNetworkInstanceResponse) {}
|
||||
rpc DeleteNetworkInstance(DeleteNetworkInstanceRequest) returns (DeleteNetworkInstanceResponse) {}
|
||||
rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {}
|
||||
}
|
||||
|
||||
@@ -6,10 +6,11 @@ use crate::{
|
||||
rpc_types::{self, controller::BaseController},
|
||||
web::{
|
||||
CollectNetworkInfoRequest, CollectNetworkInfoResponse, DeleteNetworkInstanceRequest,
|
||||
DeleteNetworkInstanceResponse, ListNetworkInstanceRequest, ListNetworkInstanceResponse,
|
||||
NetworkInstanceRunningInfoMap, RetainNetworkInstanceRequest,
|
||||
RetainNetworkInstanceResponse, RunNetworkInstanceRequest, RunNetworkInstanceResponse,
|
||||
ValidateConfigRequest, ValidateConfigResponse, WebClientService,
|
||||
DeleteNetworkInstanceResponse, GetConfigRequest, GetConfigResponse,
|
||||
ListNetworkInstanceRequest, ListNetworkInstanceResponse, NetworkInstanceRunningInfoMap,
|
||||
RetainNetworkInstanceRequest, RetainNetworkInstanceResponse, RunNetworkInstanceRequest,
|
||||
RunNetworkInstanceResponse, ValidateConfigRequest, ValidateConfigResponse,
|
||||
WebClientService,
|
||||
},
|
||||
},
|
||||
};
|
||||
@@ -153,4 +154,37 @@ impl WebClientService for Controller {
|
||||
remain_inst_ids: remain_inst_ids.into_iter().map(Into::into).collect(),
|
||||
})
|
||||
}
|
||||
|
||||
// rpc GetConfig(GetConfigRequest) returns (GetConfigResponse) {}
|
||||
async fn get_config(
|
||||
&self,
|
||||
_: BaseController,
|
||||
req: GetConfigRequest,
|
||||
) -> Result<GetConfigResponse, rpc_types::error::Error> {
|
||||
let inst_id = req.inst_id.ok_or_else(|| {
|
||||
rpc_types::error::Error::ExecutionError(
|
||||
anyhow::anyhow!("instance_id is required").into(),
|
||||
)
|
||||
})?;
|
||||
|
||||
let config = self
|
||||
.manager
|
||||
.get_network_config(&inst_id.into())
|
||||
.ok_or_else(|| {
|
||||
rpc_types::error::Error::ExecutionError(
|
||||
anyhow::anyhow!("instance {} not found", inst_id).into(),
|
||||
)
|
||||
})?;
|
||||
|
||||
// Get the NetworkConfig from the instance
|
||||
let network_config = crate::launcher::NetworkConfig::new_from_config(&config)?;
|
||||
|
||||
// Get the TOML config string
|
||||
let toml_config = config.dump();
|
||||
|
||||
Ok(GetConfigResponse {
|
||||
config: Some(network_config),
|
||||
toml_config,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user