From 53f71b3a57b3c1828292e26b7865d31e9bec44d6 Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Wed, 15 Dec 2021 18:36:15 +0100 Subject: Implement bucket alias and bucket unalias --- src/garage/cli/cmd.rs | 5 ++++- src/garage/cli/structs.rs | 31 +++++++++++++++++++++++++++++++ src/garage/cli/util.rs | 11 +++++++++-- 3 files changed, 44 insertions(+), 3 deletions(-) (limited to 'src/garage/cli') diff --git a/src/garage/cli/cmd.rs b/src/garage/cli/cmd.rs index 3cdf4d26..015eeec9 100644 --- a/src/garage/cli/cmd.rs +++ b/src/garage/cli/cmd.rs @@ -161,12 +161,15 @@ pub async fn cmd_admin( } AdminRpc::BucketList(bl) => { println!("List of buckets:"); + let mut table = vec![]; for alias in bl { if let Some(p) = alias.state.get().as_option() { let wflag = if p.website_access { "W" } else { " " }; - println!("- {} {} {:?}", wflag, alias.name, p.bucket_id); + table.push(format!("{}\t{}\t{:?}", wflag, alias.name, p.bucket_id)); } } + format_table(table); + println!("Buckets that don't have a global alias (i.e. that only exist in the namespace of an access key) are not shown."); } AdminRpc::BucketInfo(bucket) => { print_bucket_info(&bucket); diff --git a/src/garage/cli/structs.rs b/src/garage/cli/structs.rs index b2b5375d..590be1c0 100644 --- a/src/garage/cli/structs.rs +++ b/src/garage/cli/structs.rs @@ -150,6 +150,14 @@ pub enum BucketOperation { #[structopt(name = "delete")] Delete(DeleteBucketOpt), + /// Alias bucket under new name + #[structopt(name = "alias")] + Alias(AliasBucketOpt), + + /// Remove bucket alias + #[structopt(name = "unalias")] + Unalias(UnaliasBucketOpt), + /// Allow key to read or write to bucket #[structopt(name = "allow")] Allow(PermBucketOpt), @@ -193,6 +201,29 @@ pub struct DeleteBucketOpt { pub yes: bool, } +#[derive(Serialize, Deserialize, StructOpt, Debug)] +pub struct AliasBucketOpt { + /// Existing bucket name (its alias in global namespace or its full hex uuid) + pub existing_bucket: String, + + /// New bucket name + pub new_name: String, + + /// Make this alias local to the specified access key + #[structopt(long = "local")] + pub local: Option, +} + +#[derive(Serialize, Deserialize, StructOpt, Debug)] +pub struct UnaliasBucketOpt { + /// Bucket name + pub name: String, + + /// Unalias in bucket namespace local to this access key + #[structopt(long = "local")] + pub local: Option, +} + #[derive(Serialize, Deserialize, StructOpt, Debug)] pub struct PermBucketOpt { /// Access key name or ID diff --git a/src/garage/cli/util.rs b/src/garage/cli/util.rs index be34183e..ba88502d 100644 --- a/src/garage/cli/util.rs +++ b/src/garage/cli/util.rs @@ -12,17 +12,22 @@ pub fn print_key_info(key: &Key) { match &key.state { Deletable::Present(p) => { println!("\nKey-specific bucket aliases:"); + let mut table = vec![]; for (alias_name, _, alias) in p.local_aliases.items().iter() { if let Some(bucket_id) = alias.as_option() { - println!("- {} {:?}", alias_name, bucket_id); + table.push(format!("\t{}\t{}", alias_name, hex::encode(bucket_id))); } } + format_table(table); + println!("\nAuthorized buckets:"); + let mut table = vec![]; for (b, perm) in p.authorized_buckets.items().iter() { let rflag = if perm.allow_read { "R" } else { " " }; let wflag = if perm.allow_write { "W" } else { " " }; - println!("- {}{} {:?}", rflag, wflag, b); + table.push(format!("\t{}{}\t{:?}", rflag, wflag, b)); } + format_table(table); } Deletable::Deleted => { println!("\nKey is deleted."); @@ -41,12 +46,14 @@ pub fn print_bucket_info(bucket: &Bucket) { println!("- {}", alias); } } + println!("\nKey-specific aliases:"); for ((key_id, alias), _, active) in p.local_aliases.items().iter() { if *active { println!("- {} {}", key_id, alias); } } + println!("\nAuthorized keys:"); for (k, perm) in p.authorized_keys.items().iter() { let rflag = if perm.allow_read { "R" } else { " " }; -- cgit v1.2.3