Skip to content

Commit 90fd50f

Browse files
committed
router-cli: add export command
1 parent 5ab927c commit 90fd50f

File tree

2 files changed

+84
-6
lines changed

2 files changed

+84
-6
lines changed

router-cli/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,9 @@ Initialize a new configuration file. If LOCATION is not specified, creates in th
102102
### config CONFIG
103103
Upload a configuration file to the router. CONFIG is the path to your configuration file.
104104

105+
### export [OUTPUT]
106+
Export the current configuration from the router as YAML. If OUTPUT is not specified, the file `gateway-config.yaml` will be created in the current directory.
107+
105108
## Examples
106109

107110
```bash
@@ -120,6 +123,10 @@ gwrs --osenv --config my-gateway-config.yaml
120123
# or
121124
gwrs config my-gateway-config.yaml --osenv
122125
126+
# Export current configuration
127+
gwrs export
128+
gwrs export my-export.yaml
129+
123130
# Specify custom API URL
124131
gwrs --config my-gateway-config.yaml -u admin -p password --url http://router-api:8080
125132
# or

router-cli/src/main.rs

Lines changed: 77 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,12 @@ enum Commands {
4646
/// Path to the configuration file
4747
config: PathBuf,
4848
},
49+
/// Export configuration from the router
50+
Export {
51+
/// Output file location (default: ./gateway-config.yaml)
52+
#[arg(value_name = "OUTPUT")]
53+
output: Option<PathBuf>,
54+
},
4955
}
5056

5157
#[derive(Serialize, Deserialize, Debug)]
@@ -89,10 +95,10 @@ fn main() -> Result<()> {
8995
}
9096
Some(Commands::Config { config }) => {
9197
// Get credentials
92-
let (username, password) = get_credentials(&Credentials {
93-
osenv: cli.osenv,
94-
user: cli.user,
95-
pass: cli.pass
98+
let (username, password) = get_credentials(&Credentials {
99+
osenv: cli.osenv,
100+
user: cli.user,
101+
pass: cli.pass
96102
})?;
97103

98104
debug!("Using API URL: {}", cli.url);
@@ -105,11 +111,32 @@ fn main() -> Result<()> {
105111
// Upload config
106112
upload_config(&cli.url, &token, &config)?;
107113
}
114+
Some(Commands::Export { output }) => {
115+
// Get credentials
116+
let (username, password) = get_credentials(&Credentials {
117+
osenv: cli.osenv,
118+
user: cli.user,
119+
pass: cli.pass
120+
})?;
121+
122+
let output_path = output.unwrap_or_else(|| PathBuf::from("gateway-config.yaml"));
123+
124+
debug!("Using API URL: {}", cli.url);
125+
debug!("Using username: {}", username);
126+
debug!("Exporting configuration to {}", output_path.display());
127+
128+
// Authenticate and get token
129+
let token = authenticate(&cli.url, &username, &password)?;
130+
debug!("Authentication successful, token received");
131+
132+
// Download config
133+
download_config(&cli.url, &token, &output_path)?;
134+
}
108135
None => {
109136
if let Some(config) = cli.config {
110137
// Get credentials
111-
let (username, password) = get_credentials(&Credentials {
112-
osenv: cli.osenv,
138+
let (username, password) = get_credentials(&Credentials {
139+
osenv: cli.osenv,
113140
user: cli.user,
114141
pass: cli.pass
115142
})?;
@@ -320,3 +347,47 @@ fn upload_config(
320347

321348
Ok(())
322349
}
350+
351+
fn download_config(
352+
base_url: &str,
353+
token: &str,
354+
output_path: &PathBuf,
355+
) -> Result<()> {
356+
info!("Downloading configuration to: {}", output_path.display());
357+
358+
let download_url = format!("{}/api/v1/settings/auto-config", base_url);
359+
360+
let response = ureq::get(&download_url)
361+
.set("Authorization", &format!("Bearer {}", token))
362+
.call()
363+
.context("Failed to send configuration download request")?;
364+
365+
let status = response.status();
366+
if status >= 400 {
367+
let error_text = response
368+
.into_string()
369+
.unwrap_or_else(|_| "Unknown error".to_string());
370+
error!("Download failed with status {}: {}", status, error_text);
371+
anyhow::bail!("Download failed with status {}: {}", status, error_text);
372+
}
373+
374+
let contents = response
375+
.into_string()
376+
.context("Failed to read download response")?;
377+
378+
// Validate YAML format
379+
if let Err(e) = serde_yaml::from_str::<serde_yaml::Value>(&contents) {
380+
error!("Invalid YAML format in response: {}", e);
381+
anyhow::bail!("Invalid YAML format in response: {}", e);
382+
}
383+
384+
let mut file = File::create(output_path)
385+
.context("Failed to create output file")?;
386+
file.write_all(contents.as_bytes())
387+
.context("Failed to write output file")?;
388+
389+
info!("Configuration downloaded successfully");
390+
println!("Configuration downloaded successfully to {}", output_path.display());
391+
392+
Ok(())
393+
}

0 commit comments

Comments
 (0)