diff --git a/Cargo.lock b/Cargo.lock index a362ece..84f151c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ [root] name = "avvoenv" -version = "0.2.1" +version = "0.3.0" dependencies = [ "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)", "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)", diff --git a/Cargo.toml b/Cargo.toml index 8233610..77d8fba 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "avvoenv" -version = "0.2.1" +version = "0.3.0" authors = ["Avvo Infrastructure Team "] license = "MIT" diff --git a/avvoenv.1.ronn b/avvoenv.1.ronn index 73ea41d..dbc8329 100644 --- a/avvoenv.1.ronn +++ b/avvoenv.1.ronn @@ -12,6 +12,8 @@ avvoenv(1) -- fetch service environment variables [`-F`|`--force`] [`-I`|`--isolate`] [`-i`|`--include` ] + [`-p`|`--app-id` ] + [`-r`|`--app-user` ] [`-s`|`--service` ] [`-t`|`--vault-token` ] [`-u`|`--vault` ] @@ -23,6 +25,8 @@ avvoenv(1) -- fetch service environment variables [`-e`|`--exclude` ] [`-f`|`--format` ] [`-i`|`--include` ] + [`-p`|`--app-id` ] + [`-r`|`--app-user` ] [`-s`|`--service` ] [`-t`|`--vault-token` ] [`-u`|`--vault` ] @@ -92,6 +96,14 @@ current service, or canonicalise the name given with the `--service` option. range eg `[0-9]` or `[a-z]` `[!...]` is the inverse of `[...]` + * `-p`, `--app-id` : + Authenticate with Vault via app-id. If the argument is provided + it will override the `VAULT_APP_ID` environment variable. + + * `-r`, `--app-user` : + Set the user-id for use with Vault app-id authentication. If the + argument is provided it will override the `VAULT_APP_USER` environment variable. + * `-s`, `--service` : Set the service name, overriding the `SERVICE` environment variable. If neither `--service` or `SERVICE` are provided the `./requirements.yml` @@ -161,6 +173,12 @@ outputs to standard output): * `VAULT_ADDR`: The Vault URL, overriding the default of . + * `VAULT_APP_ID`: + The application ID used with Vault app-id authentication. + + * `VAULT_APP_USER`: + The application user ID used with Vault app-id authentication. + * `VAULT_TOKEN`: The token used to authenticate with Vault, overriding the `~/.vault-token` file. diff --git a/src/avvoenv/commands/helpers.rs b/src/avvoenv/commands/helpers.rs index d171a63..dcf888c 100644 --- a/src/avvoenv/commands/helpers.rs +++ b/src/avvoenv/commands/helpers.rs @@ -29,6 +29,8 @@ pub fn add_fetch_opts(mut opts: getopts::Options) -> getopts::Options { opts.optmulti("i", "include", "filter fetched variables", "PATTERN"); opts.optmulti("e", "exclude", "filter fetched variables", "PATTERN"); opts.optopt("t", "vault-token", "set the vault token", "TOKEN"); + opts.optopt("r", "app-user", "authenticate with vault app-user", "VAULT_APP_USER"); + opts.optopt("p", "app-id", "authenticate with vault app-id", "VAULT_APP_ID"); opts } @@ -62,6 +64,14 @@ pub fn env_from_opts(matches: &getopts::Matches) -> Result val, + None => return Err(ErrorWithMessage(String::from("Could not determine app-user"))), + }; + if vault_client.app_id_auth(app_id, app_user).is_err() { + return Err(ErrorWithMessage(String::from("Authentication failed"))); + }; } else { let mut path = std::env::home_dir().unwrap_or(std::path::PathBuf::from("/")); path.push(".vault-token"); diff --git a/src/avvoenv/source/vault.rs b/src/avvoenv/source/vault.rs index 37c7487..34866a0 100644 --- a/src/avvoenv/source/vault.rs +++ b/src/avvoenv/source/vault.rs @@ -21,6 +21,11 @@ pub struct AuthRequest { pub password: String, } +#[derive(Serialize)] +pub struct AuthAppIdRequest { + pub user_id: String, +} + #[derive(Deserialize)] pub struct AuthResponse { pub client_token: String, @@ -75,6 +80,13 @@ impl Client { Ok(()) } + pub fn app_id_auth(&mut self, app_id: String, user_id: String) -> Result<(), errors::Error> { + let request = AuthAppIdRequest { user_id }; + let response: AuthResponseWrapper = self.post_json(&format!("auth/app-id/login/{}", app_id), &request)?; + self.token = Some(response.auth.client_token); + Ok(()) + } + pub fn renew_token(&mut self) -> Result<(), errors::Error> { let _:AuthResponseWrapper = self.post_json("/auth/token/renew-self", &TokenRenewRequest {})?; Ok(())