Skip to content

Commit

Permalink
mocking vault
Browse files Browse the repository at this point in the history
  • Loading branch information
timglabisch committed Jan 10, 2024
1 parent 06d28b7 commit d871665
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 23 deletions.
10 changes: 10 additions & 0 deletions readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -184,3 +184,13 @@ example:
without pgp: ./.vault/private_keys/[username].pem
with pgp: ./.vault/private_keys/[username].pem.pgp

# Mocking vault calls / Integrationtests

if you want to test vault in ci environments, it is good to make sure that a certain secret would be there, even if you don't want to expose the secret.
it can also be useful to overwrite all the secrets in vault (just for ci). this is possible with this the argument `--i_know_what_i_do__enable_fetch_raw_secrets_from_env=[USER]`.
if you use the commandline argument vault ensures that the `[USER]` could decrypt the secret. You must provide the secret to vault as an environment variable `VAULT_DEBUG_SECRET_[SECRET]`.
this allows you to write integration tests for scripts that need to call vault.

```
export VAULT_DEBUG_SECRET_foo=some_test_value; vault --i_know_what_i_do__enable_fetch_raw_secrets_from_env=test get_multi '{"secrets": [{"secret": "foo"}]}'
```
33 changes: 33 additions & 0 deletions src/key/key_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ use toml;
pub struct KeyMap {
pems: Vec<Pem>,
entries: Vec<KeyMapEntry>,
debug_enable_fetch_raw_secrets_from_env: Option<String>,
}

#[derive(Debug)]
Expand All @@ -43,6 +44,7 @@ pub struct Subscription {

pub struct KeyMapConfig {
pub path_private_key: String,
pub debug_enable_fetch_raw_secrets_from_env: Option<String>,
}

impl Subscription {
Expand Down Expand Up @@ -316,6 +318,7 @@ impl KeyMap {
Ok(KeyMap {
pems: Self::build_private_pems(&config)?,
entries: buffer,
debug_enable_fetch_raw_secrets_from_env: config.debug_enable_fetch_raw_secrets_from_env.clone(),
})
}

Expand All @@ -340,7 +343,37 @@ impl KeyMap {

Ok(String::from_utf8(decrypted.get_content().to_vec()).context(anyhow!("Invalid Utf8"))?)
}

pub fn decrypt_debug_enable_fetch_raw_secrets_from_env(&self, subscription_key: &str) -> Result<UncryptedVaultFile, Error> {
let decrypt_user = self.debug_enable_fetch_raw_secrets_from_env.as_ref().expect("decrypt user must be given");
let secret_path = format!("./.vault/secrets/{}/{}.crypt", subscription_key, decrypt_user);

let crypt_file = match fs::metadata(&secret_path) {
Ok(k) => k,
Err(e) => return Err(anyhow!("could not find key - crypt file {} does not exist", &secret_path))

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust aarch64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust aarch64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust aarch64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust aarch64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-unknown-linux-musl/ubuntu-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust aarch64-apple-darwin/macos-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust aarch64-apple-darwin/macos-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-apple-darwin/macos-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-apple-darwin/macos-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-apple-darwin/macos-latest

unused variable: `e`

Check warning on line 353 in src/key/key_map.rs

View workflow job for this annotation

GitHub Actions / Build rust x86_64-apple-darwin/macos-latest

unused variable: `e`
};

if !crypt_file.is_file() {
return Err(anyhow!("could not find key - crypt file {} is not a file", &secret_path))
}

let env_var = format!("VAULT_DEBUG_SECRET_{}", subscription_key);
let secret = match ::std::env::var(&env_var) {
Ok(k) => k,
Err(e) => {
return Err(anyhow!("could not find key - could not read env var {}, error: {}", &env_var, e))
}
};

Ok(UncryptedVaultFile::new(secret.into_bytes()))
}

pub fn decrypt(&self, subscription_key: &str) -> Result<UncryptedVaultFile, Error> {

if self.debug_enable_fetch_raw_secrets_from_env.is_some() {
return self.decrypt_debug_enable_fetch_raw_secrets_from_env(subscription_key);
}

let possible_files: Vec<String> = {
let mut buffer = vec![];

Expand Down
66 changes: 43 additions & 23 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ fn main() -> ::anyhow::Result<()> {
.required(false)
.help("are you using a feature that only exists in a new vault version and your coworkers are still using an old version? install --min-version to warn your coworkers =)"),
)
.arg(
Arg::new("i_know_what_i_do__enable_fetch_raw_secrets_from_env")
.long("i_know_what_i_do__enable_fetch_raw_secrets_from_env")
.required(false)
)
.version(cargo_crate_version!())
.subcommand(
::clap::Command::new("get").arg(
Expand Down Expand Up @@ -89,6 +94,8 @@ fn main() -> ::anyhow::Result<()> {
)
.get_matches();

let debug_enable_fetch_raw_secrets_from_env = matches.get_one::<String>("i_know_what_i_do__enable_fetch_raw_secrets_from_env").map(|x|x.clone());

if let Some(min_version) = matches.get_one::<String>("expect_version") {
let version_requirement = VersionReq::parse(min_version).context("could not parse version requirement, expected something like >=1.2.3, <1.8.0")?;
let version_current = Version::parse(cargo_crate_version!()).context("could not parse current version, should not happen")?;
Expand Down Expand Up @@ -123,6 +130,7 @@ fn main() -> ::anyhow::Result<()> {
for _ in 1..3 {
let keymap = KeyMap::from_path(&KeyMapConfig {
path_private_key: path_private_key.clone(),
debug_enable_fetch_raw_secrets_from_env: debug_enable_fetch_raw_secrets_from_env.clone()
})?;

println!("keys are fine");
Expand All @@ -138,21 +146,9 @@ fn main() -> ::anyhow::Result<()> {

let mut keymap = KeyMap::from_path(&KeyMapConfig {
path_private_key: path_private_key.clone(),
debug_enable_fetch_raw_secrets_from_env: debug_enable_fetch_raw_secrets_from_env.clone()
})?;

if let Some(matches) = matches.subcommand_matches("update") {
let status = self_update::backends::github::Update::configure()
.repo_owner("easybill")
.repo_name("vault")
.bin_name("vault")
.show_download_progress(true)
.current_version(matches.get_one::<String>("current_version").expect("current version has a default"))
.build()?
.update()?;
println!("Update status: `{}`!", status.version());
return Ok(())
}

// You can check the value provided by positional arguments, or option arguments
if let Some(matches) = matches.subcommand_matches("get") {
let key = matches.get_one::<String>("key").expect("key must exists");
Expand All @@ -177,14 +173,6 @@ fn main() -> ::anyhow::Result<()> {
);
}

if let Some(matches) = matches.subcommand_matches("create-openssl-key") {
let username = matches.get_one::<String>("username").expect("username must exists");

create_keys(username)?;

return Ok(());
}

if let Some(matches) = matches.subcommand_matches("template") {
let filename = matches.get_one::<String>("filename").expect("filename must exists");

Expand All @@ -202,8 +190,37 @@ fn main() -> ::anyhow::Result<()> {
return Ok(());
}

if debug_enable_fetch_raw_secrets_from_env.is_some() {
unimplemented!("command is not implemented for debug_enable_fetch_raw_secrets_from_env");
}

if let Some(matches) = matches.subcommand_matches("update") {
let status = self_update::backends::github::Update::configure()
.repo_owner("easybill")
.repo_name("vault")
.bin_name("vault")
.show_download_progress(true)
.current_version(matches.get_one::<String>("current_version").expect("current version has a default"))
.build()?
.update()?;
println!("Update status: `{}`!", status.version());
return Ok(())
}

if let Some(matches) = matches.subcommand_matches("create-openssl-key") {
let username = matches.get_one::<String>("username").expect("username must exists");

create_keys(username)?;

return Ok(());
}

if let Some(_matches) = matches.subcommand_matches("rotate") {
rotate_keys(&KeyMapConfig { path_private_key }).context("rotate keys")?;

rotate_keys(&KeyMapConfig {
path_private_key,
debug_enable_fetch_raw_secrets_from_env: debug_enable_fetch_raw_secrets_from_env.clone()
}).context("rotate keys")?;
return Ok(());
}

Expand All @@ -213,7 +230,10 @@ fn main() -> ::anyhow::Result<()> {

if scan_for_new_secrets(&keymap)? > 0 {
// refresh the keymap
keymap = KeyMap::from_path(&KeyMapConfig { path_private_key })?;
keymap = KeyMap::from_path(&KeyMapConfig {
path_private_key,
debug_enable_fetch_raw_secrets_from_env: debug_enable_fetch_raw_secrets_from_env.clone()
})?;
}

// check loaded keys:
Expand Down

0 comments on commit d871665

Please sign in to comment.