mirror of
https://github.com/bartvdbraak/keyweave.git
synced 2025-04-29 07:41:21 +00:00
Merge pull request #26 from bartvdbraak/feat/improve-verbosity
Add useful and pretty logging using `paris`
This commit is contained in:
commit
63d9aedd75
3 changed files with 56 additions and 12 deletions
7
Cargo.lock
generated
7
Cargo.lock
generated
|
@ -860,6 +860,7 @@ dependencies = [
|
||||||
"clap",
|
"clap",
|
||||||
"futures",
|
"futures",
|
||||||
"openssl",
|
"openssl",
|
||||||
|
"paris",
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -1063,6 +1064,12 @@ dependencies = [
|
||||||
"vcpkg",
|
"vcpkg",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "paris"
|
||||||
|
version = "1.5.15"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8fecab3723493c7851f292cb060f3ee1c42f19b8d749345d0d7eaf3fd19aa62d"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "parking"
|
name = "parking"
|
||||||
version = "2.2.0"
|
version = "2.2.0"
|
||||||
|
|
|
@ -15,6 +15,7 @@ azure_identity = "0.17.0"
|
||||||
azure_security_keyvault = "0.17.0"
|
azure_security_keyvault = "0.17.0"
|
||||||
clap = { version = "4.4.8", features = ["derive"] }
|
clap = { version = "4.4.8", features = ["derive"] }
|
||||||
futures = "0.3.29"
|
futures = "0.3.29"
|
||||||
|
paris = { version = "1.5.15", features = ["macros"] }
|
||||||
tokio = {version = "1.34.0", features = ["full"]}
|
tokio = {version = "1.34.0", features = ["full"]}
|
||||||
|
|
||||||
[target.'cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "arm", target_arch = "aarch64")))'.dependencies]
|
[target.'cfg(all(target_os = "linux", any(target_env = "musl", target_arch = "arm", target_arch = "aarch64")))'.dependencies]
|
||||||
|
|
60
src/main.rs
60
src/main.rs
|
@ -1,9 +1,10 @@
|
||||||
use anyhow::{Context, Result};
|
use anyhow::Result;
|
||||||
use azure_identity::DefaultAzureCredential;
|
use azure_identity::DefaultAzureCredential;
|
||||||
use azure_security_keyvault::prelude::KeyVaultGetSecretsResponse;
|
use azure_security_keyvault::prelude::KeyVaultGetSecretsResponse;
|
||||||
use azure_security_keyvault::KeyvaultClient;
|
use azure_security_keyvault::KeyvaultClient;
|
||||||
use clap::Parser;
|
use clap::Parser;
|
||||||
use futures::stream::StreamExt;
|
use futures::stream::StreamExt;
|
||||||
|
use paris::{error, Logger};
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
@ -34,7 +35,13 @@ async fn fetch_secrets_from_key_vault(
|
||||||
let mut secret_pages = client.secret_client().list_secrets().into_stream();
|
let mut secret_pages = client.secret_client().list_secrets().into_stream();
|
||||||
|
|
||||||
while let Some(page) = secret_pages.next().await {
|
while let Some(page) = secret_pages.next().await {
|
||||||
let page = page.context("Failed to fetch secrets page")?;
|
let page = match page {
|
||||||
|
Ok(p) => p,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Failed to fetch secrets page: {}", err);
|
||||||
|
return Err(err.into()); // Convert the error into anyhow::Error
|
||||||
|
}
|
||||||
|
};
|
||||||
secret_values
|
secret_values
|
||||||
.extend(fetch_secrets_from_page(&client.secret_client(), &page, filter).await?);
|
.extend(fetch_secrets_from_page(&client.secret_client(), &page, filter).await?);
|
||||||
}
|
}
|
||||||
|
@ -75,6 +82,8 @@ async fn fetch_secrets_from_page(
|
||||||
for handle in handles {
|
for handle in handles {
|
||||||
if let Ok(result) = handle.await {
|
if let Ok(result) = handle.await {
|
||||||
secrets.push(result);
|
secrets.push(result);
|
||||||
|
} else {
|
||||||
|
error!("Error occurred while fetching a secret.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -97,20 +106,30 @@ async fn fetch_and_send_secret(
|
||||||
(secret_id, bundle.value)
|
(secret_id, bundle.value)
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
eprintln!("Error fetching secret: {}", err);
|
error!("Error fetching secret: {}", err);
|
||||||
(secret_id, String::new())
|
(secret_id, String::new())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn create_env_file(secrets: Vec<(String, String)>, output_file: &str) -> Result<()> {
|
fn create_env_file(secrets: Vec<(String, String)>, output_file: &str) -> Result<()> {
|
||||||
let mut file = File::create(output_file).context("Failed to create output file")?;
|
let mut file = match File::create(output_file) {
|
||||||
|
Ok(f) => f,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Failed to create output file: {}", err);
|
||||||
|
return Err(err.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
for (key, value) in secrets {
|
for (key, value) in secrets {
|
||||||
if let Some(secret_name) = key.split('/').last() {
|
if let Some(secret_name) = key.split('/').last() {
|
||||||
writeln!(file, "{}={}", secret_name, value)
|
if let Err(err) = writeln!(file, "{}={}", secret_name, value) {
|
||||||
.with_context(|| format!("Failed to write to output file: {}", output_file))?;
|
error!("Failed to write to output file: {}: {}", output_file, err);
|
||||||
|
return Err(err.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -147,18 +166,35 @@ mod tests {
|
||||||
#[tokio::main]
|
#[tokio::main]
|
||||||
async fn main() -> Result<()> {
|
async fn main() -> Result<()> {
|
||||||
let opts: Opts = Opts::parse();
|
let opts: Opts = Opts::parse();
|
||||||
|
let mut log = Logger::new();
|
||||||
|
|
||||||
let vault_url = format!("https://{}.vault.azure.net", opts.vault_name);
|
let vault_url = format!("https://{}.vault.azure.net", opts.vault_name);
|
||||||
println!("Fetching secrets from Key Vault: {}", opts.vault_name);
|
|
||||||
|
|
||||||
|
log.loading("Detecting credentials.");
|
||||||
let credential = DefaultAzureCredential::default();
|
let credential = DefaultAzureCredential::default();
|
||||||
let client = KeyvaultClient::new(&vault_url, std::sync::Arc::new(credential))
|
let client = match KeyvaultClient::new(&vault_url, std::sync::Arc::new(credential)) {
|
||||||
.context("Failed to create KeyvaultClient")?;
|
Ok(c) => c,
|
||||||
|
Err(err) => {
|
||||||
|
error!("Failed to create KeyvaultClient: {}", err);
|
||||||
|
return Err(err.into());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
log.success("Detected credentials.");
|
||||||
|
|
||||||
|
log.loading(format!(
|
||||||
|
"Fetching secrets from Key Vault: <blue>{}</>",
|
||||||
|
opts.vault_name
|
||||||
|
));
|
||||||
let secrets = fetch_secrets_from_key_vault(&client, opts.filter.as_deref()).await?;
|
let secrets = fetch_secrets_from_key_vault(&client, opts.filter.as_deref()).await?;
|
||||||
println!("Creating output file: {}", opts.output);
|
log.success(format!(
|
||||||
create_env_file(secrets, &opts.output)?;
|
"Fetched secrets from Key Vault: <blue>{}</>",
|
||||||
|
opts.vault_name
|
||||||
|
));
|
||||||
|
|
||||||
println!("Process completed successfully!");
|
log.loading(format!("Creating output file: <blue>{}</>", opts.output));
|
||||||
|
create_env_file(secrets, &opts.output)?;
|
||||||
|
log.success(format!("Created output file: <blue>{}</>", opts.output));
|
||||||
|
|
||||||
|
log.success("Done.");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue