mirror of
https://github.com/bartvdbraak/keyweave.git
synced 2025-04-28 15:21:21 +00:00
feat: consolidate error handling
This commit is contained in:
parent
7dd49a8744
commit
9fbdf1a7d1
1 changed files with 56 additions and 27 deletions
83
src/main.rs
83
src/main.rs
|
@ -1,17 +1,31 @@
|
||||||
use anyhow::Result;
|
use anyhow::Result;
|
||||||
use azure_core::error::HttpError;
|
|
||||||
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 paris::{error, Logger};
|
||||||
|
use std::error::Error;
|
||||||
|
use std::fmt;
|
||||||
use std::fs::File;
|
use std::fs::File;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::sync::mpsc;
|
use tokio::sync::mpsc;
|
||||||
use tokio::sync::Semaphore;
|
use tokio::sync::Semaphore;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
struct CustomError {
|
||||||
|
message: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl fmt::Display for CustomError {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
write!(f, "{}", self.message)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Error for CustomError {}
|
||||||
|
|
||||||
#[derive(Parser, Debug)]
|
#[derive(Parser, Debug)]
|
||||||
#[clap(author, version, about, long_about = None)]
|
#[clap(author, version, about, long_about = None)]
|
||||||
struct Opts {
|
struct Opts {
|
||||||
|
@ -35,12 +49,15 @@ async fn check_vault_dns(vault_name: &str) -> Result<()> {
|
||||||
|
|
||||||
match lookup_result {
|
match lookup_result {
|
||||||
Ok(_) => Ok(()),
|
Ok(_) => Ok(()),
|
||||||
Err(err) => {
|
Err(_err) => {
|
||||||
error!("DNS lookup failed for Key Vault: {}", vault_name);
|
error!("DNS lookup failed for Key Vault: {}", vault_name);
|
||||||
error!(
|
error!(
|
||||||
"Please check that the Key Vault exists or that you have no connectivity issues."
|
"Please check that the Key Vault exists or that you have no connectivity issues."
|
||||||
);
|
);
|
||||||
Err(err.into())
|
Err(CustomError {
|
||||||
|
message: "An error occurred while fetching secrets".to_string(),
|
||||||
|
}
|
||||||
|
.into())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -56,27 +73,33 @@ async fn fetch_secrets_from_key_vault(
|
||||||
let page = match page {
|
let page = match page {
|
||||||
Ok(p) => p,
|
Ok(p) => p,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("\n");
|
Logger::new().newline(1);
|
||||||
error!("Failed to fetch secrets.");
|
match err.as_http_error() {
|
||||||
let specific_error = err.downcast_ref::<HttpError>();
|
Some(err) => {
|
||||||
if let Some(specific_error) = specific_error {
|
if err
|
||||||
if specific_error
|
.error_message()
|
||||||
.error_message()
|
.unwrap()
|
||||||
.unwrap()
|
.contains("does not have secrets list permission on key vault")
|
||||||
.to_string()
|
{
|
||||||
.contains("does not have secrets list permission on key vault")
|
error!("Make sure you have List permissions on the Key Vault.")
|
||||||
{
|
} else if err
|
||||||
error!("Make sure you have List permissions on the Key Vault.");
|
.error_message()
|
||||||
} else if specific_error
|
.unwrap()
|
||||||
.error_message()
|
.contains("is not authorized and caller is not a trusted service")
|
||||||
.unwrap()
|
{
|
||||||
.to_string()
|
error!("Make sure you're on the Key Vaults Firewall allowlist.")
|
||||||
.contains("is not authorized and caller is not a trusted service")
|
} else {
|
||||||
{
|
error!("HTTP Error: {}", err);
|
||||||
error!("Make sure you're on the Key Vaults Firewall allowlist.");
|
}
|
||||||
}
|
}
|
||||||
|
_ => {
|
||||||
|
error!("Error: {}", err);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
return Err(CustomError {
|
||||||
|
message: "An error occurred while fetching secrets".to_string(),
|
||||||
}
|
}
|
||||||
return Err(err.into());
|
.into());
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
secret_values
|
secret_values
|
||||||
|
@ -154,15 +177,21 @@ fn create_env_file(secrets: Vec<(String, String)>, output_file: &str) -> Result<
|
||||||
Ok(f) => f,
|
Ok(f) => f,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
error!("Failed to create output file: {}", err);
|
error!("Failed to create output file: {}", err);
|
||||||
return Err(err.into());
|
return Err(CustomError {
|
||||||
|
message: "n Aerror occurred creating file".to_string(),
|
||||||
|
}
|
||||||
|
.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() {
|
||||||
if let Err(err) = writeln!(file, "{}={}", secret_name, value) {
|
if let Err(_err) = writeln!(file, "{}={}", secret_name, value) {
|
||||||
error!("Failed to write to output file: {}: {}", output_file, err);
|
error!("Failed to write to output file: {}", output_file);
|
||||||
return Err(err.into());
|
return Err(CustomError {
|
||||||
|
message: "An error occurred while writing secrets to file".to_string(),
|
||||||
|
}
|
||||||
|
.into());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,7 +232,7 @@ 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 mut log: Logger<'_> = Logger::new();
|
||||||
|
|
||||||
let vault_url = format!("https://{}.vault.azure.net", opts.vault_name);
|
let vault_url = format!("https://{}.vault.azure.net", opts.vault_name);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue