WIP: Automatically create node layout, keys and buckets #883
3 changed files with 60 additions and 5 deletions
|
@ -1,8 +1,5 @@
|
||||||
use crate::admin::AdminRpc;
|
use crate::admin::AdminRpc;
|
||||||
use crate::cli::{
|
use crate::cli::{cmd_apply_layout, cmd_assign_role, fetch_layout, fetch_status, ApplyLayoutOpt, AssignRoleOpt, BucketOperation, BucketOpt, KeyImportOpt, KeyInfoOpt, KeyOperation, PermBucketOpt, WebsiteOpt};
|
||||||
cmd_apply_layout, cmd_assign_role, fetch_layout, fetch_status, ApplyLayoutOpt, AssignRoleOpt,
|
|
||||||
BucketOperation, BucketOpt, KeyImportOpt, KeyInfoOpt, KeyOperation, PermBucketOpt,
|
|
||||||
};
|
|
||||||
use bytesize::ByteSize;
|
use bytesize::ByteSize;
|
||||||
use garage_model::helper::error::Error as HelperError;
|
use garage_model::helper::error::Error as HelperError;
|
||||||
use garage_net::endpoint::Endpoint;
|
use garage_net::endpoint::Endpoint;
|
||||||
|
@ -10,7 +7,7 @@ use garage_net::message::PRIO_NORMAL;
|
||||||
use garage_net::NodeID;
|
use garage_net::NodeID;
|
||||||
use garage_rpc::layout::NodeRoleV;
|
use garage_rpc::layout::NodeRoleV;
|
||||||
use garage_rpc::system::SystemRpc;
|
use garage_rpc::system::SystemRpc;
|
||||||
use garage_util::config::{AutoBucket, AutoKey, AutoNode, AutoPermission};
|
use garage_util::config::{AutoBucket, AutoBucketWebsite, AutoKey, AutoNode, AutoPermission, WebsiteAllowance};
|
||||||
use garage_util::data::Uuid;
|
use garage_util::data::Uuid;
|
||||||
use garage_util::error::Error;
|
use garage_util::error::Error;
|
||||||
|
|
||||||
|
@ -100,6 +97,32 @@ pub async fn bucket_create(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub async fn bucket_configure_website(
|
||||||
|
rpc_cli: &Endpoint<AdminRpc, ()>,
|
||||||
|
rpc_host: NodeID,
|
||||||
|
bucket_name: String,
|
||||||
|
website: &AutoBucketWebsite,
|
||||||
|
) -> Result<(), Error> {
|
||||||
|
match rpc_cli
|
||||||
|
.call(
|
||||||
|
&rpc_host,
|
||||||
|
AdminRpc::BucketOperation(BucketOperation::Website(WebsiteOpt{
|
||||||
|
allow: matches!(website.mode, WebsiteAllowance::Allow),
|
||||||
|
deny: matches!(website.mode, WebsiteAllowance::Deny),
|
||||||
|
bucket: bucket_name.clone(),
|
||||||
|
index_document: website.index_document.clone(),
|
||||||
|
error_document: website.error_document.clone(),
|
||||||
|
})),
|
||||||
|
PRIO_NORMAL,
|
||||||
|
)
|
||||||
|
.await?
|
||||||
|
{
|
||||||
|
Ok(_) => Ok(()),
|
||||||
|
Err(HelperError::BadRequest(msg)) => Err(Error::Message(msg)),
|
||||||
|
resp => Err(Error::unexpected_rpc_message(resp)),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub async fn grant_permission(
|
pub async fn grant_permission(
|
||||||
rpc_cli: &Endpoint<AdminRpc, ()>,
|
rpc_cli: &Endpoint<AdminRpc, ()>,
|
||||||
rpc_host: NodeID,
|
rpc_host: NodeID,
|
||||||
|
|
|
@ -309,6 +309,11 @@ pub async fn cmd_auto(
|
||||||
for perm in bucket.allow.iter() {
|
for perm in bucket.allow.iter() {
|
||||||
grant_permission(rpc_admin, rpc_host, bucket.name.clone(), perm).await?;
|
grant_permission(rpc_admin, rpc_host, bucket.name.clone(), perm).await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Configure website access.
|
||||||
|
if let Some(website) = bucket.website.as_ref() {
|
||||||
|
bucket_configure_website(rpc_admin, rpc_host, bucket.name.clone(), website).await?
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
|
|
|
@ -232,6 +232,33 @@ pub struct AutoBucket {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
/// Permissions to grant on bucket to given keys
|
/// Permissions to grant on bucket to given keys
|
||||||
pub allow: Vec<AutoPermission>,
|
pub allow: Vec<AutoPermission>,
|
||||||
|
/// Website configuration
|
||||||
|
pub website: Option<AutoBucketWebsite>
|
||||||
|
}
|
||||||
|
|
||||||
|
fn default_index_document() -> String {
|
||||||
|
"index.html".to_string()
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Bucket website configuration to create automatically
|
||||||
|
#[derive(Deserialize, Debug, Clone, Default)]
|
||||||
|
pub struct AutoBucketWebsite {
|
||||||
|
/// Allow or deny (default) website access
|
||||||
|
#[serde(default)]
|
||||||
|
pub mode: WebsiteAllowance,
|
||||||
|
/// Error document: the optional document returned when an error occurs
|
||||||
|
pub error_document: Option<String>,
|
||||||
|
/// Index document: the suffix appended to request paths ending by /
|
||||||
|
#[serde(default = "default_index_document")]
|
||||||
|
pub index_document: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Deserialize, Debug, Clone, Default)]
|
||||||
|
#[serde(rename_all = "lowercase")]
|
||||||
|
pub enum WebsiteAllowance {
|
||||||
|
Allow,
|
||||||
|
#[default]
|
||||||
|
Deny,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Permission to create automatically
|
/// Permission to create automatically
|
||||||
|
|
Loading…
Reference in a new issue