Skip to content

Commit

Permalink
feat: support create/revoke signing key (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
wandaitzuchen authored Apr 4, 2022
1 parent 107f8c1 commit 2303a17
Show file tree
Hide file tree
Showing 9 changed files with 123 additions and 36 deletions.
6 changes: 3 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,9 @@ export TEST_CACHE_DEFAULT=<YOUR_TEST_CACHE_DEFAULT>
cargo test --test configure_profile_test
```

- If you already have existing credentials and config files locally, running `cargo test --test configure_profiles_test` with provided `TEST_AUTH_TOKEN_DEFAULT` will overwrite values for token your `default` profile.
- The value for `TEST_CACHE_DEFAULT` needs to match the cache value your `default` profile and the cache needs to exist. However, this cache will be deleted after this test runs successfully.
- If you already have existing credentials and config files locally, running `cargo test --test configure_profiles_test` with provided `TEST_AUTH_TOKEN_DEFAULT` will overwrite the value for token in your `default` profile.
- The value for `TEST_CACHE_DEFAULT` needs to match the cache value in your `default` profile and the cache needs to exist. However, this cache will be deleted after this test runs successfully.

### Deploying

After merge a pr will be created in this repo https://github.com/momentohq/homebrew-tap. Once the pr passes all checks, approve the pr and label is as `pr-pull`. It will then get automatically merged by the homebrew bot, and a release will be created for it.
After merge a pr will be created in this repo https://github.com/momentohq/homebrew-tap. Once the pr passes all checks, approve the pr and label it as `pr-pull`. It will then get automatically merged by the homebrew bot, and a release will be created for it.
16 changes: 14 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,9 @@ features = [ "full",]
version = "1.0"
features = [ "derive",]

[dependencies.serde_json]
version = "1.0.79"

[dependencies.reqwest]
version = "0.11"
features = [ "json", "rustls-tls",]
Expand Down
1 change: 1 addition & 0 deletions src/commands.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod account;
pub mod cache;
pub mod configure;
pub mod signingkey;
14 changes: 7 additions & 7 deletions src/commands/cache/cache_cli.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use log::info;
use log::{debug, info};
use momento::simple_cache_client::SimpleCacheClient;

use crate::error::CliError;
Expand All @@ -11,7 +11,7 @@ async fn get_momento_instance(auth_token: String) -> Result<SimpleCacheClient, C
}

pub async fn create_cache(cache_name: String, auth_token: String) -> Result<(), CliError> {
info!("creating cache...");
debug!("creating cache...");
let mut momento = get_momento_instance(auth_token).await?;
match momento.create_cache(&cache_name).await {
Ok(_) => (),
Expand All @@ -21,7 +21,7 @@ pub async fn create_cache(cache_name: String, auth_token: String) -> Result<(),
}

pub async fn delete_cache(cache_name: String, auth_token: String) -> Result<(), CliError> {
info!("deleting cache...");
debug!("deleting cache...");
let mut momento = get_momento_instance(auth_token).await?;
match momento.delete_cache(&cache_name).await {
Ok(_) => (),
Expand All @@ -31,7 +31,7 @@ pub async fn delete_cache(cache_name: String, auth_token: String) -> Result<(),
}

pub async fn list_caches(auth_token: String) -> Result<(), CliError> {
info!("list cache called");
debug!("list cache called");
let mut momento = get_momento_instance(auth_token).await?;
match momento.list_caches(None).await {
Ok(res) => {
Expand All @@ -51,20 +51,20 @@ pub async fn set(
value: String,
ttl_seconds: u32,
) -> Result<(), CliError> {
info!("setting key: {} into cache: {}", key, cache_name);
debug!("setting key: {} into cache: {}", key, cache_name);
let mut momento = get_momento_instance(auth_token).await?;
match momento
.set(&cache_name, key, value, Some(ttl_seconds))
.await
{
Ok(_) => info!("set success"),
Ok(_) => debug!("set success"),
Err(e) => return Err(CliError { msg: e.to_string() }),
};
Ok(())
}

pub async fn get(cache_name: String, auth_token: String, key: String) -> Result<(), CliError> {
info!("getting key: {} from cache: {}", key, cache_name);
debug!("getting key: {} from cache: {}", key, cache_name);
let mut momento = get_momento_instance(auth_token).await?;
match momento.get(&cache_name, key).await {
Ok(r) => {
Expand Down
1 change: 1 addition & 0 deletions src/commands/signingkey/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
pub mod signingkey_cli;
33 changes: 33 additions & 0 deletions src/commands/signingkey/signingkey_cli.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
use log::debug;
use momento::simple_cache_client::SimpleCacheClient;

use crate::error::CliError;

async fn get_momento_instance(auth_token: String) -> Result<SimpleCacheClient, CliError> {
match SimpleCacheClient::new(auth_token, 100).await {
Ok(m) => Ok(m),
Err(e) => Err(CliError { msg: e.to_string() }),
}
}

pub async fn create_signing_key(ttl_minutes: u32, auth_token: String) -> Result<(), CliError> {
debug!("creating signing key...");
let mut momento = get_momento_instance(auth_token).await?;
match momento.create_signing_key(ttl_minutes).await {
Ok(res) => {
println!("{}", serde_json::to_string_pretty(&res).unwrap());
}
Err(e) => return Err(CliError { msg: e.to_string() }),
};
Ok(())
}

pub async fn revoke_signing_key(key_id: String, auth_token: String) -> Result<(), CliError> {
debug!("revoking signing key...");
let mut momento = get_momento_instance(auth_token).await?;
match momento.revoke_signing_key(&key_id).await {
Ok(_) => (),
Err(e) => return Err(CliError { msg: e.to_string() }),
};
Ok(())
}
83 changes: 60 additions & 23 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use std::{panic, process::exit};
use clap::StructOpt;
use env_logger::Env;
use error::CliError;
use log::{error, info};
use log::{debug, error};
use utils::user::get_creds_and_config;

pub mod commands;
Expand All @@ -24,17 +24,17 @@ struct Momento {

#[derive(Debug, StructOpt)]
enum Subcommand {
#[structopt(about = "Cache Operations")]
#[structopt(about = "Interact with caches")]
Cache {
#[structopt(subcommand)]
operation: CacheCommand,
},
#[structopt(about = "Configure Momento Credentials")]
#[structopt(about = "Configure credentials")]
Configure {
#[structopt(name = "profile", long, short, default_value = "default")]
#[structopt(long, short, default_value = "default")]
profile: String,
},
#[structopt(about = "Manage Accounts")]
#[structopt(about = "Manage accounts")]
Account {
#[structopt(subcommand)]
operation: AccountCommand,
Expand All @@ -45,32 +45,52 @@ enum Subcommand {
enum AccountCommand {
#[structopt(about = "Sign up for Momento")]
Signup {
#[structopt(name = "email", long, short)]
#[structopt(long, short)]
email: String,
#[structopt(
name = "region",
long,
short,
default_value = "us-west-2",
help = "e.g. us-west-2, us-east-1, ap-northeast-1"
)]
region: String,
},

#[structopt(about = "Create a signing key")]
CreateSigningKey {
#[structopt(
long = "ttl",
short = 't',
default_value = "86400",
help = "Duration, in minutes, that the signing key will be valid"
)]
ttl_minutes: u32,
#[structopt(long, short, default_value = "default")]
profile: String,
},

#[structopt(about = "Revoke the signing key")]
RevokeSigningKey {
#[structopt(long = "key-id", short, help = "Signing Key ID")]
key_id: String,
#[structopt(long, short, default_value = "default")]
profile: String,
},
}

#[derive(Debug, StructOpt)]
enum CacheCommand {
#[structopt(about = "Creates a Momento Cache")]
#[structopt(about = "Create a cache")]
Create {
#[structopt(name = "name", long, short)]
#[structopt(long = "name", short = 'n')]
cache_name: String,
#[structopt(name = "profile", long, short, default_value = "default")]
#[structopt(long, short, default_value = "default")]
profile: String,
},

#[structopt(about = "Stores a given item in cache")]
#[structopt(about = "Store a given item in the cache")]
Set {
#[structopt(name = "name", long, short)]
#[structopt(long = "name", short = 'n')]
cache_name: Option<String>,
// TODO: Add support for non-string key-value
#[structopt(long, short)]
Expand All @@ -83,32 +103,32 @@ enum CacheCommand {
help = "Max time, in seconds, that the item will be stored in cache"
)]
ttl_seconds: Option<u32>,
#[structopt(name = "profile", long, short, default_value = "default")]
#[structopt(long, short, default_value = "default")]
profile: String,
},

#[structopt(about = "Gets item from the cache")]
#[structopt(about = "Get an item from the cache")]
Get {
#[structopt(name = "name", long, short)]
#[structopt(long = "name", short = 'n')]
cache_name: Option<String>,
// TODO: Add support for non-string key-value
#[structopt(long, short)]
key: String,
#[structopt(name = "profile", long, short, default_value = "default")]
#[structopt(long, short, default_value = "default")]
profile: String,
},

#[structopt(about = "Deletes the cache")]
#[structopt(about = "Delete the cache")]
Delete {
#[structopt(name = "name", long, short)]
#[structopt(long = "name", short = 'n')]
cache_name: String,
#[structopt(name = "profile", long, short, default_value = "default")]
#[structopt(long, short, default_value = "default")]
profile: String,
},

#[structopt(about = "Lists all momento caches")]
#[structopt(about = "List all caches")]
List {
#[structopt(name = "profile", long, short, default_value = "default")]
#[structopt(long, short, default_value = "default")]
profile: String,
},
}
Expand All @@ -133,7 +153,7 @@ async fn entrypoint() -> Result<(), CliError> {
} => {
let (creds, _config) = get_creds_and_config(&profile).await?;
commands::cache::cache_cli::create_cache(cache_name.clone(), creds.token).await?;
info!("created cache {cache_name}")
debug!("created cache {cache_name}")
}
CacheCommand::Set {
cache_name,
Expand Down Expand Up @@ -171,7 +191,7 @@ async fn entrypoint() -> Result<(), CliError> {
} => {
let (creds, _config) = get_creds_and_config(&profile).await?;
commands::cache::cache_cli::delete_cache(cache_name.clone(), creds.token).await?;
info!("deleted cache {}", cache_name)
debug!("deleted cache {}", cache_name)
}
CacheCommand::List { profile } => {
let (creds, _config) = get_creds_and_config(&profile).await?;
Expand All @@ -185,6 +205,23 @@ async fn entrypoint() -> Result<(), CliError> {
AccountCommand::Signup { email, region } => {
commands::account::signup_user(email, region).await?;
}
AccountCommand::CreateSigningKey {
ttl_minutes,
profile,
} => {
let (creds, _config) = get_creds_and_config(&profile).await?;
commands::signingkey::signingkey_cli::create_signing_key(ttl_minutes, creds.token)
.await?;
}
AccountCommand::RevokeSigningKey { key_id, profile } => {
let (creds, _config) = get_creds_and_config(&profile).await?;
commands::signingkey::signingkey_cli::revoke_signing_key(
key_id.clone(),
creds.token,
)
.await?;
debug!("revoked signing key {}", key_id)
}
},
}
Ok(())
Expand Down

0 comments on commit 2303a17

Please sign in to comment.