mirror of
https://github.com/bartvdbraak/keyweave.git
synced 2025-05-05 10:31:20 +00:00
feat: implementation of secret fetching
This commit is contained in:
parent
591df1333f
commit
7b58549f4a
3 changed files with 2070 additions and 4 deletions
1979
Cargo.lock
generated
Normal file
1979
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load diff
|
@ -3,6 +3,9 @@ name = "keyweave"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
azure_identity = "0.17.0"
|
||||||
|
azure_security_keyvault = "0.17.0"
|
||||||
|
clap = { version = "4.4.7", features = ["derive"] }
|
||||||
|
futures = "0.3.29"
|
||||||
|
tokio = {version = "1.33.0", features = ["full"]}
|
||||||
|
|
88
src/main.rs
88
src/main.rs
|
@ -1,3 +1,87 @@
|
||||||
fn main() {
|
use azure_identity::DefaultAzureCredential;
|
||||||
println!("Hello, world!");
|
use azure_security_keyvault::KeyvaultClient;
|
||||||
|
use clap::Parser;
|
||||||
|
use futures::stream::StreamExt;
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::Write;
|
||||||
|
|
||||||
|
#[derive(Parser)]
|
||||||
|
#[clap(version = "0.1.0", author = "Bart van der Braak <bart@vanderbraak.nl>")]
|
||||||
|
struct Opts {
|
||||||
|
#[clap(
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
value_name = "VAULT_NAME",
|
||||||
|
help = "Sets the name of the Azure Key Vault"
|
||||||
|
)]
|
||||||
|
vault_name: String,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
value_name = "FILE",
|
||||||
|
default_value = ".env",
|
||||||
|
help = "Sets the name of the output file"
|
||||||
|
)]
|
||||||
|
output: String,
|
||||||
|
|
||||||
|
#[clap(
|
||||||
|
short,
|
||||||
|
long,
|
||||||
|
value_name = "FILTER",
|
||||||
|
help = "Filters the secrets to be retrieved by name"
|
||||||
|
)]
|
||||||
|
filter: Option<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn fetch_secrets_from_key_vault(
|
||||||
|
vault_url: &str,
|
||||||
|
filter: Option<&str>,
|
||||||
|
) -> Result<Vec<(String, String)>, Box<dyn std::error::Error>> {
|
||||||
|
let credential = DefaultAzureCredential::default();
|
||||||
|
let client = KeyvaultClient::new(&vault_url, std::sync::Arc::new(credential))?;
|
||||||
|
|
||||||
|
let mut secret_values = Vec::new();
|
||||||
|
let mut secret_pages = client.secret_client().list_secrets().into_stream();
|
||||||
|
|
||||||
|
while let Some(page) = secret_pages.next().await {
|
||||||
|
let page = page?;
|
||||||
|
for secret in &page.value {
|
||||||
|
if let Some(filter) = filter {
|
||||||
|
if !secret.id.contains(filter) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
let secret_bundle = client.secret_client().get(&secret.id).await?;
|
||||||
|
secret_values.push((secret.id.clone(), secret_bundle.value.clone()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(secret_values)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_env_file(secrets: Vec<(String, String)>, output_file: &str) -> std::io::Result<()> {
|
||||||
|
let mut file = File::create(output_file)?;
|
||||||
|
for (key, value) in secrets {
|
||||||
|
writeln!(file, "{}={}", key, value)?;
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::main]
|
||||||
|
async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
|
let opts: Opts = Opts::parse();
|
||||||
|
|
||||||
|
let vault_url = format!("https://{}.vault.azure.net/", opts.vault_name);
|
||||||
|
|
||||||
|
println!("Fetching secrets from Key Vault: {}", opts.vault_name);
|
||||||
|
|
||||||
|
let secrets = fetch_secrets_from_key_vault(&vault_url, opts.filter.as_deref()).await?;
|
||||||
|
|
||||||
|
println!("Creating output file: {}", opts.output);
|
||||||
|
create_env_file(secrets, &opts.output)?;
|
||||||
|
|
||||||
|
println!("Process completed successfully!");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue