Merge pull request #523 from rustfs/config/enable-console-by-default

Config/enable console by default
This commit is contained in:
weisd
2025-06-30 21:53:15 +08:00
committed by GitHub
8 changed files with 93 additions and 102 deletions
@@ -52,6 +52,7 @@ fn _build_chunk_signature(
get_signature(signing_key, &chunk_string_to_sign) get_signature(signing_key, &chunk_string_to_sign)
} }
#[allow(clippy::too_many_arguments)]
pub fn streaming_sign_v4( pub fn streaming_sign_v4(
mut req: request::Builder, mut req: request::Builder,
_access_key_id: &str, _access_key_id: &str,
@@ -12,8 +12,6 @@ const _SIGN_V4_ALGORITHM: &str = "AWS4-HMAC-SHA256";
const SIGN_V2_ALGORITHM: &str = "AWS"; const SIGN_V2_ALGORITHM: &str = "AWS";
fn encode_url2path(req: &request::Builder, _virtual_host: bool) -> String { fn encode_url2path(req: &request::Builder, _virtual_host: bool) -> String {
//path = serde_urlencoded::to_string(req.uri_ref().unwrap().path().unwrap()).unwrap(); //path = serde_urlencoded::to_string(req.uri_ref().unwrap().path().unwrap()).unwrap();
let path = req.uri_ref().unwrap().path().to_string(); let path = req.uri_ref().unwrap().path().to_string();
path path
@@ -60,13 +58,11 @@ pub fn pre_sign_v2(
.parse() .parse()
.unwrap(), .unwrap(),
); );
req.uri(Uri::from_parts(parts).unwrap()) req.uri(Uri::from_parts(parts).unwrap())
} }
fn _post_pre_sign_signature_v2(policy_base64: &str, secret_access_key: &str) -> String { fn _post_pre_sign_signature_v2(policy_base64: &str, secret_access_key: &str) -> String {
hex(hmac_sha1(secret_access_key, policy_base64)) hex(hmac_sha1(secret_access_key, policy_base64))
} }
+17 -17
View File
@@ -34,7 +34,7 @@ pub fn get_signing_key(secret: &str, loc: &str, t: OffsetDateTime, service_type:
let date = hmac_sha256(s.into_bytes(), t.format(&format).unwrap().into_bytes()); let date = hmac_sha256(s.into_bytes(), t.format(&format).unwrap().into_bytes());
let location = hmac_sha256(date, loc); let location = hmac_sha256(date, loc);
let service = hmac_sha256(location, service_type); let service = hmac_sha256(location, service_type);
hmac_sha256(service, "aws4_request") hmac_sha256(service, "aws4_request")
} }
@@ -166,22 +166,20 @@ fn get_canonical_request(req: &request::Builder, ignored_headers: &HashMap<Strin
query_params.sort_by(|a, b| a.0.cmp(&b.0)); query_params.sort_by(|a, b| a.0.cmp(&b.0));
// Build canonical query string // Build canonical query string
let sorted_params: Vec<String> = query_params let sorted_params: Vec<String> = query_params.iter().map(|(k, v)| format!("{}={}", k, v)).collect();
.iter()
.map(|(k, v)| format!("{}={}", k, v) )
.collect();
canonical_query_string = sorted_params.join("&"); canonical_query_string = sorted_params.join("&");
canonical_query_string = canonical_query_string.replace("+", "%20"); canonical_query_string = canonical_query_string.replace("+", "%20");
} }
let mut canonical_request = <Vec<String>>::new(); let canonical_request = [
canonical_request.push(req.method_ref().unwrap().to_string()); req.method_ref().unwrap().to_string(),
canonical_request.push(req.uri_ref().unwrap().path().to_string()); req.uri_ref().unwrap().path().to_string(),
canonical_request.push(canonical_query_string); canonical_query_string,
canonical_request.push(get_canonical_headers(req, ignored_headers)); get_canonical_headers(req, ignored_headers),
canonical_request.push(get_signed_headers(req, ignored_headers)); get_signed_headers(req, ignored_headers),
canonical_request.push(hashed_payload.to_string()); hashed_payload.to_string(),
];
canonical_request.join("\n") canonical_request.join("\n")
} }
@@ -256,14 +254,13 @@ pub fn pre_sign_v4(
.parse() .parse()
.unwrap(), .unwrap(),
); );
req.uri(Uri::from_parts(parts).unwrap()) req.uri(Uri::from_parts(parts).unwrap())
} }
fn _post_pre_sign_signature_v4(policy_base64: &str, t: OffsetDateTime, secret_access_key: &str, location: &str) -> String { fn _post_pre_sign_signature_v4(policy_base64: &str, t: OffsetDateTime, secret_access_key: &str, location: &str) -> String {
let signing_key = get_signing_key(secret_access_key, location, t, SERVICE_TYPE_S3); let signing_key = get_signing_key(secret_access_key, location, t, SERVICE_TYPE_S3);
get_signature(signing_key, policy_base64) get_signature(signing_key, policy_base64)
} }
@@ -271,6 +268,7 @@ fn _sign_v4_sts(req: request::Builder, access_key_id: &str, secret_access_key: &
sign_v4_inner(req, 0, access_key_id, secret_access_key, "", location, SERVICE_TYPE_STS, HeaderMap::new()) sign_v4_inner(req, 0, access_key_id, secret_access_key, "", location, SERVICE_TYPE_STS, HeaderMap::new())
} }
#[allow(clippy::too_many_arguments)]
fn sign_v4_inner( fn sign_v4_inner(
mut req: request::Builder, mut req: request::Builder,
content_len: i64, content_len: i64,
@@ -403,6 +401,7 @@ pub fn sign_v4_trailer(
} }
#[cfg(test)] #[cfg(test)]
#[allow(unused_variables, unused_mut)]
mod tests { mod tests {
use http::request; use http::request;
use time::macros::datetime; use time::macros::datetime;
@@ -433,9 +432,10 @@ mod tests {
); );
headers.insert("x-amz-date", timestamp.parse().unwrap()); headers.insert("x-amz-date", timestamp.parse().unwrap());
let mut query = <Vec<(String, String)>>::new(); let query = vec![
query.push(("max-keys".to_string(), "2".to_string())); ("max-keys".to_string(), "2".to_string()),
query.push(("prefix".to_string(), "J".to_string())); ("prefix".to_string(), "J".to_string()),
];
let uri = req.uri_ref().unwrap().clone(); let uri = req.uri_ref().unwrap().clone();
let mut parts = req.uri_ref().unwrap().clone().into_parts(); let mut parts = req.uri_ref().unwrap().clone().into_parts();
parts.path_and_query = Some( parts.path_and_query = Some(
@@ -692,7 +692,6 @@ pub struct ExpirationOptions {
pub expire: bool, pub expire: bool,
} }
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct TransitionOptions { pub struct TransitionOptions {
pub status: String, pub status: String,
+1 -1
View File
@@ -220,7 +220,7 @@ impl TierConfigMgr {
if cfg.is_none() { if cfg.is_none() {
return "internal".to_string(); return "internal".to_string();
} }
cfg.expect("err").tier_type.to_string() cfg.expect("err").tier_type.as_lowercase()
} }
pub fn list_tiers(&self) -> Vec<TierConfig> { pub fn list_tiers(&self) -> Vec<TierConfig> {
+11 -5
View File
@@ -51,7 +51,7 @@ impl TierType {
} }
} }
pub fn to_string(&self) -> String { pub fn as_lowercase(&self) -> String {
match self { match self {
TierType::S3 => "s3".to_string(), TierType::S3 => "s3".to_string(),
TierType::RustFS => "rustfs".to_string(), TierType::RustFS => "rustfs".to_string(),
@@ -199,11 +199,17 @@ pub struct TierS3 {
impl TierS3 { impl TierS3 {
#[allow(dead_code)] #[allow(dead_code)]
fn new<F>(name: &str, access_key: &str, secret_key: &str, bucket: &str, options: Vec<F>) -> Result<TierConfig, std::io::Error> fn create<F>(
name: &str,
access_key: &str,
secret_key: &str,
bucket: &str,
options: Vec<F>,
) -> Result<TierConfig, std::io::Error>
where where
F: Fn(TierS3) -> Box<Result<(), std::io::Error>> + Send + Sync + 'static, F: Fn(TierS3) -> Box<Result<(), std::io::Error>> + Send + Sync + 'static,
{ {
if name == "" { if name.is_empty() {
return Err(std::io::Error::other(ERR_TIER_NAME_EMPTY)); return Err(std::io::Error::other(ERR_TIER_NAME_EMPTY));
} }
let sc = TierS3 { let sc = TierS3 {
@@ -264,7 +270,7 @@ pub struct TierMinIO {
impl TierMinIO { impl TierMinIO {
#[allow(dead_code)] #[allow(dead_code)]
fn new<F>( fn create<F>(
name: &str, name: &str,
endpoint: &str, endpoint: &str,
access_key: &str, access_key: &str,
@@ -275,7 +281,7 @@ impl TierMinIO {
where where
F: Fn(TierMinIO) -> Box<Result<(), std::io::Error>> + Send + Sync + 'static, F: Fn(TierMinIO) -> Box<Result<(), std::io::Error>> + Send + Sync + 'static,
{ {
if name == "" { if name.is_empty() {
return Err(std::io::Error::other(ERR_TIER_NAME_EMPTY)); return Err(std::io::Error::other(ERR_TIER_NAME_EMPTY));
} }
let m = TierMinIO { let m = TierMinIO {
+62 -73
View File
@@ -118,39 +118,36 @@ impl Operation for AddTier {
let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await; let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await;
//tier_config_mgr.reload(api); //tier_config_mgr.reload(api);
match tier_config_mgr.add(args, force).await { if let Err(err) = tier_config_mgr.add(args, force).await {
Err(err) => { if err.code == ERR_TIER_ALREADY_EXISTS.code {
if err.code == ERR_TIER_ALREADY_EXISTS.code { return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierNameAlreadyExist".into()),
S3ErrorCode::Custom("TierNameAlreadyExist".into()), "tier name already exists!",
"tier name already exists!", ));
)); } else if err.code == ERR_TIER_NAME_NOT_UPPERCASE.code {
} else if err.code == ERR_TIER_NAME_NOT_UPPERCASE.code { return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierNameNotUppercase".into()),
S3ErrorCode::Custom("TierNameNotUppercase".into()), "tier name not uppercase!",
"tier name not uppercase!", ));
)); } else if err.code == ERR_TIER_BACKEND_IN_USE.code {
} else if err.code == ERR_TIER_BACKEND_IN_USE.code { return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierNameBackendInUse!".into()),
S3ErrorCode::Custom("TierNameBackendInUse!".into()), "tier name backend in use!",
"tier name backend in use!", ));
)); } else if err.code == ERR_TIER_CONNECT_ERR.code {
} else if err.code == ERR_TIER_CONNECT_ERR.code { return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierConnectError".into()),
S3ErrorCode::Custom("TierConnectError".into()), "tier connect error!",
"tier connect error!", ));
)); } else if err.code == ERR_TIER_INVALID_CREDENTIALS.code {
} else if err.code == ERR_TIER_INVALID_CREDENTIALS.code { return Err(S3Error::with_message(S3ErrorCode::Custom(err.code.clone().into()), err.message.clone()));
return Err(S3Error::with_message(S3ErrorCode::Custom(err.code.clone().into()), err.message.clone())); } else {
} else { warn!("tier_config_mgr add failed, e: {:?}", err);
warn!("tier_config_mgr add failed, e: {:?}", err); return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierAddFailed".into()),
S3ErrorCode::Custom("TierAddFailed".into()), format!("tier add failed. {}", err),
format!("tier add failed. {}", err.to_string()), ));
));
}
} }
Ok(_) => (),
} }
if let Err(e) = tier_config_mgr.save().await { if let Err(e) = tier_config_mgr.save().await {
warn!("tier_config_mgr save failed, e: {:?}", e); warn!("tier_config_mgr save failed, e: {:?}", e);
@@ -203,24 +200,21 @@ impl Operation for EditTier {
let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await; let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await;
//tier_config_mgr.reload(api); //tier_config_mgr.reload(api);
match tier_config_mgr.edit(&tier_name, creds).await { if let Err(err) = tier_config_mgr.edit(&tier_name, creds).await {
Err(err) => { if err.code == ERR_TIER_NOT_FOUND.code {
if err.code == ERR_TIER_NOT_FOUND.code { return Err(S3Error::with_message(S3ErrorCode::Custom("TierNotFound".into()), "tier not found!"));
return Err(S3Error::with_message(S3ErrorCode::Custom("TierNotFound".into()), "tier not found!")); } else if err.code == ERR_TIER_MISSING_CREDENTIALS.code {
} else if err.code == ERR_TIER_MISSING_CREDENTIALS.code { return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierMissingCredentials".into()),
S3ErrorCode::Custom("TierMissingCredentials".into()), "tier missing credentials!",
"tier missing credentials!", ));
)); } else {
} else { warn!("tier_config_mgr edit failed, e: {:?}", err);
warn!("tier_config_mgr edit failed, e: {:?}", err); return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierEditFailed".into()),
S3ErrorCode::Custom("TierEditFailed".into()), format!("tier edit failed. {}", err),
format!("tier edit failed. {}", err.to_string()), ));
));
}
} }
Ok(_) => (),
} }
if let Err(e) = tier_config_mgr.save().await { if let Err(e) = tier_config_mgr.save().await {
warn!("tier_config_mgr save failed, e: {:?}", e); warn!("tier_config_mgr save failed, e: {:?}", e);
@@ -304,22 +298,20 @@ impl Operation for RemoveTier {
let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await; let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await;
//tier_config_mgr.reload(api); //tier_config_mgr.reload(api);
match tier_config_mgr.remove(&tier_name, force).await { if let Err(err) = tier_config_mgr.remove(&tier_name, force).await {
Err(err) => { if err.code == ERR_TIER_NOT_FOUND.code {
if err.code == ERR_TIER_NOT_FOUND.code { return Err(S3Error::with_message(S3ErrorCode::Custom("TierNotFound".into()), "tier not found."));
return Err(S3Error::with_message(S3ErrorCode::Custom("TierNotFound".into()), "tier not found.")); } else if err.code == ERR_TIER_BACKEND_NOT_EMPTY.code {
} else if err.code == ERR_TIER_BACKEND_NOT_EMPTY.code { return Err(S3Error::with_message(S3ErrorCode::Custom("TierNameBackendInUse".into()), "tier is used."));
return Err(S3Error::with_message(S3ErrorCode::Custom("TierNameBackendInUse".into()), "tier is used.")); } else {
} else { warn!("tier_config_mgr remove failed, e: {:?}", err);
warn!("tier_config_mgr remove failed, e: {:?}", err); return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierRemoveFailed".into()),
S3ErrorCode::Custom("TierRemoveFailed".into()), format!("tier remove failed. {}", err),
format!("tier remove failed. {}", err.to_string()), ));
));
}
} }
Ok(_) => (),
} }
if let Err(e) = tier_config_mgr.save().await { if let Err(e) = tier_config_mgr.save().await {
warn!("tier_config_mgr save failed, e: {:?}", e); warn!("tier_config_mgr save failed, e: {:?}", e);
return Err(S3Error::with_message(S3ErrorCode::Custom("TierRemoveFailed".into()), "tier save failed")); return Err(S3Error::with_message(S3ErrorCode::Custom("TierRemoveFailed".into()), "tier save failed"));
@@ -422,7 +414,7 @@ impl Operation for ClearTier {
let mut force: bool = false; let mut force: bool = false;
let force_str = query.force; let force_str = query.force;
if force_str != "" { if !force_str.is_empty() {
force = force_str.parse().unwrap(); force = force_str.parse().unwrap();
} }
@@ -438,15 +430,12 @@ impl Operation for ClearTier {
let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await; let mut tier_config_mgr = GLOBAL_TierConfigMgr.write().await;
//tier_config_mgr.reload(api); //tier_config_mgr.reload(api);
match tier_config_mgr.clear_tier(force).await { if let Err(err) = tier_config_mgr.clear_tier(force).await {
Err(err) => { warn!("tier_config_mgr clear failed, e: {:?}", err);
warn!("tier_config_mgr clear failed, e: {:?}", err); return Err(S3Error::with_message(
return Err(S3Error::with_message( S3ErrorCode::Custom("TierClearFailed".into()),
S3ErrorCode::Custom("TierClearFailed".into()), format!("tier clear failed. {}", err),
format!("tier clear failed. {}", err.to_string()), ));
));
}
Ok(_) => (),
} }
if let Err(e) = tier_config_mgr.save().await { if let Err(e) = tier_config_mgr.save().await {
warn!("tier_config_mgr save failed, e: {:?}", e); warn!("tier_config_mgr save failed, e: {:?}", e);
+1 -1
View File
@@ -51,7 +51,7 @@ pub struct Opt {
pub secret_key: String, pub secret_key: String,
/// Enable console server /// Enable console server
#[arg(long, default_value_t = false, env = "RUSTFS_CONSOLE_ENABLE")] #[arg(long, default_value_t = true, env = "RUSTFS_CONSOLE_ENABLE")]
pub console_enable: bool, pub console_enable: bool,
/// Console server bind address /// Console server bind address