diff --git a/Cargo.lock b/Cargo.lock index 827919c..cf73330 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -419,9 +419,9 @@ dependencies = [ [[package]] name = "errno" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e" dependencies = [ "libc", "windows-sys", @@ -852,7 +852,7 @@ dependencies = [ [[package]] name = "keyweave" -version = "0.1.0" +version = "0.2.0" dependencies = [ "azure_identity", "azure_security_keyvault", diff --git a/Cargo.toml b/Cargo.toml index 138d70f..7d52ef8 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "keyweave" -version = "0.1.0" +version = "0.2.0" edition = "2021" authors = ["Bart van der Braak "] diff --git a/README.md b/README.md index 7aa1dad..a0a6308 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ -

- Cluster -

- # Keyweave +Cluster + Keyweave is an open-source tool designed to seamlessly fetch secrets from Azure Key Vault and weave them into a convenient `.env` file. Developed in Rust, Keyweave is efficient and easy to use, making it an ideal choice for managing your application's secrets. ## Features diff --git a/src/main.rs b/src/main.rs index 10a8149..6579715 100644 --- a/src/main.rs +++ b/src/main.rs @@ -4,6 +4,7 @@ use clap::Parser; use futures::stream::StreamExt; use std::fs::File; use std::io::Write; +use tokio::sync::mpsc; #[derive(Parser)] #[clap(author, version, about, long_about = None)] @@ -46,15 +47,44 @@ async fn fetch_secrets_from_key_vault( while let Some(page) = secret_pages.next().await { let page = page?; + let (tx, mut rx) = mpsc::channel(32); // Channel for concurrent secret retrieval + for secret in &page.value { if let Some(filter) = filter { if !secret.id.contains(filter) { continue; } } - let secret_name = secret.id.split('/').last().unwrap_or_default(); - let secret_bundle = client.get(secret_name).await?; - secret_values.push((secret.id.clone(), secret_bundle.value)); + let tx = tx.clone(); + + // Clone necessary data before moving into the spawned task + let secret_id = secret.id.clone(); + let client_clone = client.clone(); + + tokio::spawn(async move { + let secret_name = secret_id.split('/').last().unwrap_or_default(); + let secret_bundle = client_clone.get(secret_name).await; + + // Handle the result and send it through the channel + match secret_bundle { + Ok(bundle) => { + tx.send((secret_id, bundle.value)) + .await + .expect("Send error"); + } + Err(err) => { + eprintln!("Error fetching secret: {}", err); + // You can decide to continue or not in case of an error. + } + } + }); + } + + drop(tx); // Drop the sender to signal the end of sending tasks + + while let Some(result) = rx.recv().await { + let (key, value) = result; + secret_values.push((key, value)); } }