mirror of
https://github.com/rustfs/rustfs.git
synced 2026-05-06 22:28:16 +08:00
feat(config): allow specifying keys via files (key files) (#1814)
Co-authored-by: houseme <housemecn@gmail.com> Co-authored-by: heihutu <30542132+heihutu@users.noreply.github.com>
This commit is contained in:
@@ -523,4 +523,82 @@ mod tests {
|
||||
assert_eq!(opt.server_domains[1], "127.0.0.1:9000");
|
||||
assert_eq!(opt.server_domains[2], "localhost");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_access_key_arguments_mutually_exclusive_cli() {
|
||||
// Test that CLI args configuration fails on conflict
|
||||
let args = vec![
|
||||
"rustfs",
|
||||
"/test/volume",
|
||||
"--access-key",
|
||||
"foobar",
|
||||
"--access-key-file",
|
||||
"/foo/bar",
|
||||
];
|
||||
let opt_res = Opt::try_parse_from(args);
|
||||
|
||||
// can't specify both access-key and access-key-file at once
|
||||
assert!(opt_res.is_err());
|
||||
let err = opt_res.err().unwrap();
|
||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
#[allow(unsafe_code)]
|
||||
fn test_access_key_arguments_mutually_exclusive_env_var() {
|
||||
// Test that env var args configuration fails on conflict
|
||||
with_env_var("RUSTFS_VOLUMES", "/data/my disk/vol1", || {
|
||||
with_env_var("RUSTFS_ACCESS_KEY", "foo", || {
|
||||
with_env_var("RUSTFS_ACCESS_KEY_FILE", "/foo/bar", || {
|
||||
let args = vec!["rustfs"];
|
||||
let opt_res = Opt::try_parse_from(args);
|
||||
|
||||
// can't specify both RUSTFS_ACCESS_KEY and RUSTFS_ACCESS_KEY_FILE at once
|
||||
assert!(opt_res.is_err());
|
||||
let err = opt_res.err().unwrap();
|
||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_secret_key_arguments_mutually_exclusive_cli() {
|
||||
// Test that CLI args configuration fails on conflict
|
||||
let args = vec![
|
||||
"rustfs",
|
||||
"/test/volume",
|
||||
"--secret-key",
|
||||
"foobar",
|
||||
"--secret-key-file",
|
||||
"/foo/bar",
|
||||
];
|
||||
let opt_res = Opt::try_parse_from(args);
|
||||
|
||||
// can't specify both secret-key and secret-key-file at once
|
||||
assert!(opt_res.is_err());
|
||||
let err = opt_res.err().unwrap();
|
||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[serial]
|
||||
#[allow(unsafe_code)]
|
||||
fn test_secret_key_arguments_mutually_exclusive_env_var() {
|
||||
// Test that env var args configuration fails on conflict
|
||||
with_env_var("RUSTFS_VOLUMES", "/data/my disk/vol1", || {
|
||||
with_env_var("RUSTFS_SECRET_KEY", "foo", || {
|
||||
with_env_var("RUSTFS_SECRET_KEY_FILE", "/foo/bar", || {
|
||||
let args = vec!["rustfs"];
|
||||
let opt_res = Opt::try_parse_from(args);
|
||||
|
||||
// can't specify both RUSTFS_SECRET_KEY and RUSTFS_SECRET_KEY_FILE at once
|
||||
assert!(opt_res.is_err());
|
||||
let err = opt_res.err().unwrap();
|
||||
assert_eq!(err.kind(), clap::error::ErrorKind::ArgumentConflict);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
use clap::Parser;
|
||||
use clap::builder::NonEmptyStringValueParser;
|
||||
use const_str::concat;
|
||||
use std::path::PathBuf;
|
||||
use std::string::ToString;
|
||||
shadow_rs::shadow!(build);
|
||||
|
||||
@@ -77,20 +78,20 @@ pub struct Opt {
|
||||
pub server_domains: Vec<String>,
|
||||
|
||||
/// Access key used for authentication.
|
||||
#[arg(
|
||||
long,
|
||||
default_value_t = rustfs_credentials::DEFAULT_ACCESS_KEY.to_string(),
|
||||
env = "RUSTFS_ACCESS_KEY"
|
||||
)]
|
||||
pub access_key: String,
|
||||
#[arg(long, env = "RUSTFS_ACCESS_KEY", group = "access-key")]
|
||||
pub access_key: Option<String>,
|
||||
|
||||
/// Access key stored in a file used for authentication.
|
||||
#[arg(long, env = "RUSTFS_ACCESS_KEY_FILE", group = "access-key")]
|
||||
pub access_key_file: Option<PathBuf>,
|
||||
|
||||
/// Secret key used for authentication.
|
||||
#[arg(
|
||||
long,
|
||||
default_value_t = rustfs_credentials::DEFAULT_SECRET_KEY.to_string(),
|
||||
env = "RUSTFS_SECRET_KEY"
|
||||
)]
|
||||
pub secret_key: String,
|
||||
#[arg(long, env = "RUSTFS_SECRET_KEY", group = "secret-key")]
|
||||
pub secret_key: Option<String>,
|
||||
|
||||
/// Secret key stored in a file used for authentication.
|
||||
#[arg(long, env = "RUSTFS_SECRET_KEY_FILE", group = "secret-key")]
|
||||
pub secret_key_file: Option<PathBuf>,
|
||||
|
||||
/// Enable console server
|
||||
#[arg(
|
||||
@@ -161,9 +162,151 @@ pub struct Opt {
|
||||
pub buffer_profile: String,
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Opt {
|
||||
#[derive(Clone)]
|
||||
pub struct Config {
|
||||
/// DIR points to a directory on a filesystem.
|
||||
pub volumes: Vec<String>,
|
||||
|
||||
/// bind to a specific ADDRESS:PORT, ADDRESS can be an IP or hostname
|
||||
pub address: String,
|
||||
|
||||
/// Domain name used for virtual-hosted-style requests.
|
||||
pub server_domains: Vec<String>,
|
||||
|
||||
/// Access key used for authentication.
|
||||
pub access_key: String,
|
||||
|
||||
/// Secret key used for authentication.
|
||||
pub secret_key: String,
|
||||
|
||||
/// Enable console server
|
||||
pub console_enable: bool,
|
||||
|
||||
/// Console server bind address
|
||||
pub console_address: String,
|
||||
|
||||
/// Observability endpoint for trace, metrics and logs,only support grpc mode.
|
||||
pub obs_endpoint: String,
|
||||
|
||||
/// tls path for rustfs API and console.
|
||||
pub tls_path: Option<String>,
|
||||
|
||||
pub license: Option<String>,
|
||||
|
||||
pub region: Option<String>,
|
||||
|
||||
/// Enable KMS encryption for server-side encryption
|
||||
pub kms_enable: bool,
|
||||
|
||||
/// KMS backend type (local or vault)
|
||||
pub kms_backend: String,
|
||||
|
||||
/// KMS key directory for local backend
|
||||
pub kms_key_dir: Option<String>,
|
||||
|
||||
/// Vault address for vault backend
|
||||
pub kms_vault_address: Option<String>,
|
||||
|
||||
/// Vault token for vault backend
|
||||
pub kms_vault_token: Option<String>,
|
||||
|
||||
/// Default KMS key ID for encryption
|
||||
pub kms_default_key_id: Option<String>,
|
||||
|
||||
/// Disable adaptive buffer sizing with workload profiles
|
||||
/// Set this flag to use legacy fixed-size buffer behavior from PR #869
|
||||
pub buffer_profile_disable: bool,
|
||||
|
||||
/// Workload profile for adaptive buffer sizing
|
||||
/// Options: GeneralPurpose, AiTraining, DataAnalytics, WebWorkload, IndustrialIoT, SecureStorage
|
||||
pub buffer_profile: String,
|
||||
}
|
||||
|
||||
impl Config {
|
||||
/// parse the command line arguments and environment arguments from [`Opt`] and convert them
|
||||
/// into a ready to use [`Config`]
|
||||
///
|
||||
/// This includes some intermediate checks for mutually exclusive options
|
||||
pub fn parse() -> std::io::Result<Self> {
|
||||
let Opt {
|
||||
volumes,
|
||||
address,
|
||||
server_domains,
|
||||
access_key,
|
||||
access_key_file,
|
||||
secret_key,
|
||||
secret_key_file,
|
||||
console_enable,
|
||||
console_address,
|
||||
obs_endpoint,
|
||||
tls_path,
|
||||
license,
|
||||
region,
|
||||
kms_enable,
|
||||
kms_backend,
|
||||
kms_key_dir,
|
||||
kms_vault_address,
|
||||
kms_vault_token,
|
||||
kms_default_key_id,
|
||||
buffer_profile_disable,
|
||||
buffer_profile,
|
||||
} = Opt::parse();
|
||||
|
||||
let access_key = access_key
|
||||
.map(Ok)
|
||||
.or_else(|| {
|
||||
let path = access_key_file.as_ref()?;
|
||||
Some(std::fs::read_to_string(path))
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| {
|
||||
// neither argument was specified ... using default
|
||||
rustfs_credentials::DEFAULT_ACCESS_KEY.to_string()
|
||||
})
|
||||
.trim()
|
||||
.to_string();
|
||||
|
||||
let secret_key = secret_key
|
||||
.map(Ok)
|
||||
.or_else(|| {
|
||||
let path = secret_key_file.as_ref()?;
|
||||
Some(std::fs::read_to_string(path))
|
||||
})
|
||||
.transpose()?
|
||||
.unwrap_or_else(|| {
|
||||
// neither argument was specified ... using default
|
||||
rustfs_credentials::DEFAULT_SECRET_KEY.to_string()
|
||||
})
|
||||
.trim()
|
||||
.to_string();
|
||||
|
||||
Ok(Config {
|
||||
volumes,
|
||||
address,
|
||||
server_domains,
|
||||
access_key,
|
||||
secret_key,
|
||||
console_enable,
|
||||
console_address,
|
||||
obs_endpoint,
|
||||
tls_path,
|
||||
license,
|
||||
region,
|
||||
kms_enable,
|
||||
kms_backend,
|
||||
kms_key_dir,
|
||||
kms_vault_address,
|
||||
kms_vault_token,
|
||||
kms_default_key_id,
|
||||
buffer_profile_disable,
|
||||
buffer_profile,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Debug for Config {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
f.debug_struct("Opt")
|
||||
f.debug_struct("Config")
|
||||
.field("volumes", &self.volumes)
|
||||
.field("address", &self.address)
|
||||
.field("server_domains", &self.server_domains)
|
||||
|
||||
@@ -163,22 +163,22 @@ pub(crate) async fn add_bucket_notification_configuration(buckets: Vec<String>)
|
||||
/// If not enabled, it attempts to load any persisted KMS configuration from
|
||||
/// cluster storage and starts the service if found.
|
||||
/// # Arguments
|
||||
/// * `opt` - The application configuration options
|
||||
/// * `config` - The application configuration options
|
||||
///
|
||||
/// Returns `std::io::Result<()>` indicating success or failure
|
||||
#[instrument(skip(opt))]
|
||||
pub(crate) async fn init_kms_system(opt: &config::Opt) -> std::io::Result<()> {
|
||||
#[instrument(skip(config))]
|
||||
pub(crate) async fn init_kms_system(config: &config::Config) -> std::io::Result<()> {
|
||||
// Initialize global KMS service manager (starts in NotConfigured state)
|
||||
let service_manager = rustfs_kms::init_global_kms_service_manager();
|
||||
|
||||
// If KMS is enabled in configuration, configure and start the service
|
||||
if opt.kms_enable {
|
||||
if config.kms_enable {
|
||||
info!("KMS is enabled via command line, configuring and starting service...");
|
||||
|
||||
// Create KMS configuration from command line options
|
||||
let kms_config = match opt.kms_backend.as_str() {
|
||||
let kms_config = match config.kms_backend.as_str() {
|
||||
"local" => {
|
||||
let key_dir = opt
|
||||
let key_dir = config
|
||||
.kms_key_dir
|
||||
.as_ref()
|
||||
.ok_or_else(|| Error::other("KMS key directory is required for local backend"))?;
|
||||
@@ -190,7 +190,7 @@ pub(crate) async fn init_kms_system(opt: &config::Opt) -> std::io::Result<()> {
|
||||
master_key: None,
|
||||
file_permissions: Some(0o600),
|
||||
}),
|
||||
default_key_id: opt.kms_default_key_id.clone(),
|
||||
default_key_id: config.kms_default_key_id.clone(),
|
||||
timeout: std::time::Duration::from_secs(30),
|
||||
retry_attempts: 3,
|
||||
enable_cache: true,
|
||||
@@ -198,11 +198,11 @@ pub(crate) async fn init_kms_system(opt: &config::Opt) -> std::io::Result<()> {
|
||||
}
|
||||
}
|
||||
"vault" => {
|
||||
let vault_address = opt
|
||||
let vault_address = config
|
||||
.kms_vault_address
|
||||
.as_ref()
|
||||
.ok_or_else(|| Error::other("Vault address is required for vault backend"))?;
|
||||
let vault_token = opt
|
||||
let vault_token = config
|
||||
.kms_vault_token
|
||||
.as_ref()
|
||||
.ok_or_else(|| Error::other("Vault token is required for vault backend"))?;
|
||||
@@ -220,14 +220,14 @@ pub(crate) async fn init_kms_system(opt: &config::Opt) -> std::io::Result<()> {
|
||||
key_path_prefix: "rustfs/kms/keys".to_string(),
|
||||
tls: None,
|
||||
})),
|
||||
default_key_id: opt.kms_default_key_id.clone(),
|
||||
default_key_id: config.kms_default_key_id.clone(),
|
||||
timeout: std::time::Duration::from_secs(30),
|
||||
retry_attempts: 3,
|
||||
enable_cache: true,
|
||||
cache_config: rustfs_kms::config::CacheConfig::default(),
|
||||
}
|
||||
}
|
||||
_ => return Err(Error::other(format!("Unsupported KMS backend: {}", opt.kms_backend))),
|
||||
_ => return Err(Error::other(format!("Unsupported KMS backend: {}", config.kms_backend))),
|
||||
};
|
||||
|
||||
// Configure the KMS service
|
||||
@@ -287,22 +287,22 @@ pub(crate) async fn init_kms_system(opt: &config::Opt) -> std::io::Result<()> {
|
||||
/// - Custom profile: Set via `--buffer-profile` or `RUSTFS_BUFFER_PROFILE` environment variable
|
||||
///
|
||||
/// # Arguments
|
||||
/// * `opt` - The application configuration options
|
||||
pub(crate) fn init_buffer_profile_system(opt: &config::Opt) {
|
||||
/// * `config` - The application configuration options
|
||||
pub(crate) fn init_buffer_profile_system(config: &config::Config) {
|
||||
use crate::config::workload_profiles::{
|
||||
RustFSBufferConfig, WorkloadProfile, init_global_buffer_config, set_buffer_profile_enabled,
|
||||
};
|
||||
|
||||
if opt.buffer_profile_disable {
|
||||
if config.buffer_profile_disable {
|
||||
// User explicitly disabled buffer profiling - use GeneralPurpose profile in disabled mode
|
||||
info!("Buffer profiling disabled via --buffer-profile-disable, using GeneralPurpose profile");
|
||||
set_buffer_profile_enabled(false);
|
||||
} else {
|
||||
// Enabled by default: use configured workload profile
|
||||
info!("Buffer profiling enabled with profile: {}", opt.buffer_profile);
|
||||
info!("Buffer profiling enabled with profile: {}", config.buffer_profile);
|
||||
|
||||
// Parse the workload profile from configuration string
|
||||
let profile = WorkloadProfile::from_name(&opt.buffer_profile);
|
||||
let profile = WorkloadProfile::from_name(&config.buffer_profile);
|
||||
|
||||
// Log the selected profile for operational visibility
|
||||
info!("Active buffer profile: {:?}", profile);
|
||||
|
||||
@@ -38,7 +38,6 @@ use crate::server::{
|
||||
SHUTDOWN_TIMEOUT, ServiceState, ServiceStateManager, ShutdownSignal, init_cert, init_event_notifier, shutdown_event_notifier,
|
||||
start_audit_system, start_http_server, stop_audit_system, wait_for_shutdown,
|
||||
};
|
||||
use clap::Parser;
|
||||
use license::init_license;
|
||||
use rustfs_common::{GlobalReadiness, SystemStage, set_global_addr};
|
||||
use rustfs_credentials::init_global_action_credentials;
|
||||
@@ -100,13 +99,13 @@ fn main() {
|
||||
}
|
||||
async fn async_main() -> Result<()> {
|
||||
// Parse the obtained parameters
|
||||
let opt = config::Opt::parse();
|
||||
let config = config::Config::parse()?;
|
||||
|
||||
// Initialize the configuration
|
||||
init_license(opt.license.clone());
|
||||
init_license(config.license.clone());
|
||||
|
||||
// Initialize Observability
|
||||
let guard = match init_obs(Some(opt.clone().obs_endpoint)).await {
|
||||
let guard = match init_obs(Some(config.clone().obs_endpoint)).await {
|
||||
Ok(g) => g,
|
||||
Err(e) => {
|
||||
println!("Failed to initialize observability: {e}");
|
||||
@@ -135,7 +134,7 @@ async fn async_main() -> Result<()> {
|
||||
rustfs_trusted_proxies::init();
|
||||
|
||||
// Initialize TLS if a certificate path is provided
|
||||
if let Some(tls_path) = &opt.tls_path {
|
||||
if let Some(tls_path) = &config.tls_path {
|
||||
match init_cert(tls_path).await {
|
||||
Ok(_) => {
|
||||
info!(target: "rustfs::main", "TLS initialized successfully with certs from {}", tls_path);
|
||||
@@ -148,7 +147,7 @@ async fn async_main() -> Result<()> {
|
||||
}
|
||||
|
||||
// Run parameters
|
||||
match run(opt).await {
|
||||
match run(config).await {
|
||||
Ok(_) => Ok(()),
|
||||
Err(e) => {
|
||||
error!("Server encountered an error and is shutting down: {}", e);
|
||||
@@ -157,17 +156,17 @@ async fn async_main() -> Result<()> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(skip(opt))]
|
||||
async fn run(opt: config::Opt) -> Result<()> {
|
||||
debug!("opt: {:?}", &opt);
|
||||
#[instrument(skip(config))]
|
||||
async fn run(config: config::Config) -> Result<()> {
|
||||
debug!("config: {:?}", &config);
|
||||
// 1. Initialize global readiness tracker
|
||||
let readiness = Arc::new(GlobalReadiness::new());
|
||||
|
||||
if let Some(region) = &opt.region {
|
||||
if let Some(region) = &config.region {
|
||||
rustfs_ecstore::global::set_global_region(region.clone());
|
||||
}
|
||||
|
||||
let server_addr = parse_and_resolve_address(opt.address.as_str()).map_err(Error::other)?;
|
||||
let server_addr = parse_and_resolve_address(config.address.as_str()).map_err(Error::other)?;
|
||||
let server_port = server_addr.port();
|
||||
let server_address = server_addr.to_string();
|
||||
|
||||
@@ -182,7 +181,7 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
);
|
||||
|
||||
// Set up AK and SK
|
||||
match init_global_action_credentials(Some(opt.access_key.clone()), Some(opt.secret_key.clone())) {
|
||||
match init_global_action_credentials(Some(config.access_key.clone()), Some(config.secret_key.clone())) {
|
||||
Ok(_) => {
|
||||
info!(target: "rustfs::main::run", "Global action credentials initialized successfully.");
|
||||
}
|
||||
@@ -195,10 +194,10 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
|
||||
set_global_rustfs_port(server_port);
|
||||
|
||||
set_global_addr(&opt.address).await;
|
||||
set_global_addr(&config.address).await;
|
||||
|
||||
// For RPC
|
||||
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), opt.volumes.clone())
|
||||
let (endpoint_pools, setup_type) = EndpointServerPools::from_volumes(server_address.clone().as_str(), config.volumes.clone())
|
||||
.await
|
||||
.map_err(Error::other)?;
|
||||
|
||||
@@ -248,16 +247,16 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
state_manager.update(ServiceState::Starting);
|
||||
|
||||
let s3_shutdown_tx = {
|
||||
let mut s3_opt = opt.clone();
|
||||
s3_opt.console_enable = false;
|
||||
let s3_shutdown_tx = start_http_server(&s3_opt, state_manager.clone(), readiness.clone()).await?;
|
||||
let mut s3_config = config.clone();
|
||||
s3_config.console_enable = false;
|
||||
let s3_shutdown_tx = start_http_server(&s3_config, state_manager.clone(), readiness.clone()).await?;
|
||||
Some(s3_shutdown_tx)
|
||||
};
|
||||
|
||||
let console_shutdown_tx = if opt.console_enable && !opt.console_address.is_empty() {
|
||||
let mut console_opt = opt.clone();
|
||||
console_opt.address = console_opt.console_address.clone();
|
||||
let console_shutdown_tx = start_http_server(&console_opt, state_manager.clone(), readiness.clone()).await?;
|
||||
let console_shutdown_tx = if config.console_enable && !config.console_address.is_empty() {
|
||||
let mut console_config = config.clone();
|
||||
console_config.address = console_config.console_address.clone();
|
||||
let console_shutdown_tx = start_http_server(&console_config, state_manager.clone(), readiness.clone()).await?;
|
||||
Some(console_shutdown_tx)
|
||||
} else {
|
||||
None
|
||||
@@ -290,7 +289,7 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
// init replication_pool
|
||||
init_background_replication(store.clone()).await;
|
||||
// Initialize KMS system if enabled
|
||||
init_kms_system(&opt).await?;
|
||||
init_kms_system(&config).await?;
|
||||
|
||||
// Initialize FTP system if enabled
|
||||
#[cfg(feature = "ftps")]
|
||||
@@ -333,7 +332,7 @@ async fn run(opt: config::Opt) -> Result<()> {
|
||||
let ftps_shutdown_tx: Option<tokio::sync::broadcast::Sender<()>> = None;
|
||||
|
||||
// Initialize buffer profiling system
|
||||
init_buffer_profile_system(&opt);
|
||||
init_buffer_profile_system(&config);
|
||||
|
||||
// Initialize event notifier
|
||||
init_event_notifier().await;
|
||||
|
||||
@@ -60,11 +60,11 @@ use tracing::{Span, debug, error, info, instrument, warn};
|
||||
use tracing_opentelemetry::OpenTelemetrySpanExt;
|
||||
|
||||
pub async fn start_http_server(
|
||||
opt: &config::Opt,
|
||||
config: &config::Config,
|
||||
worker_state_manager: ServiceStateManager,
|
||||
readiness: Arc<GlobalReadiness>,
|
||||
) -> Result<tokio::sync::broadcast::Sender<()>> {
|
||||
let server_addr = parse_and_resolve_address(opt.address.as_str()).map_err(Error::other)?;
|
||||
let server_addr = parse_and_resolve_address(config.address.as_str()).map_err(Error::other)?;
|
||||
let server_port = server_addr.port();
|
||||
|
||||
// The listening address and port are obtained from the parameters
|
||||
@@ -150,7 +150,7 @@ pub async fn start_http_server(
|
||||
TcpListener::from_std(socket.into())?
|
||||
};
|
||||
|
||||
let tls_acceptor = setup_tls_acceptor(opt.tls_path.as_deref().unwrap_or_default()).await?;
|
||||
let tls_acceptor = setup_tls_acceptor(config.tls_path.as_deref().unwrap_or_default()).await?;
|
||||
let tls_enabled = tls_acceptor.is_some();
|
||||
let protocol = if tls_enabled { "https" } else { "http" };
|
||||
// Obtain the listener address
|
||||
@@ -173,7 +173,7 @@ pub async fn start_http_server(
|
||||
let api_endpoints = format!("{protocol}://{local_ip_str}:{server_port}");
|
||||
let localhost_endpoint = format!("{protocol}://127.0.0.1:{server_port}");
|
||||
let now_time = jiff::Zoned::now().strftime("%Y-%m-%d %H:%M:%S").to_string();
|
||||
if opt.console_enable {
|
||||
if config.console_enable {
|
||||
admin::console::init_console_cfg(local_ip, server_port);
|
||||
|
||||
info!(
|
||||
@@ -193,8 +193,8 @@ pub async fn start_http_server(
|
||||
info!(target: "rustfs::main::startup","RustFS API: {api_endpoints} {localhost_endpoint}");
|
||||
println!("RustFS Http API: {api_endpoints} {localhost_endpoint}");
|
||||
println!("RustFS Start Time: {now_time}");
|
||||
if rustfs_credentials::DEFAULT_ACCESS_KEY.eq(&opt.access_key)
|
||||
&& rustfs_credentials::DEFAULT_SECRET_KEY.eq(&opt.secret_key)
|
||||
if rustfs_credentials::DEFAULT_ACCESS_KEY.eq(&config.access_key)
|
||||
&& rustfs_credentials::DEFAULT_SECRET_KEY.eq(&config.secret_key)
|
||||
{
|
||||
warn!(
|
||||
"Detected default credentials '{}:{}', we recommend that you change these values with 'RUSTFS_ACCESS_KEY' and 'RUSTFS_SECRET_KEY' environment variables",
|
||||
@@ -212,20 +212,20 @@ pub async fn start_http_server(
|
||||
let store = storage::ecfs::FS::new();
|
||||
let mut b = S3ServiceBuilder::new(store.clone());
|
||||
|
||||
let access_key = opt.access_key.clone();
|
||||
let secret_key = opt.secret_key.clone();
|
||||
let access_key = config.access_key.clone();
|
||||
let secret_key = config.secret_key.clone();
|
||||
|
||||
b.set_auth(IAMAuth::new(access_key, secret_key));
|
||||
b.set_access(store.clone());
|
||||
b.set_route(admin::make_admin_route(opt.console_enable)?);
|
||||
b.set_route(admin::make_admin_route(config.console_enable)?);
|
||||
|
||||
// Virtual-hosted-style requests are only set up for S3 API when server domains are configured and console is disabled
|
||||
if !opt.server_domains.is_empty() && !opt.console_enable {
|
||||
MultiDomain::new(&opt.server_domains).map_err(Error::other)?; // validate domains
|
||||
if !config.server_domains.is_empty() && !config.console_enable {
|
||||
MultiDomain::new(&config.server_domains).map_err(Error::other)?; // validate domains
|
||||
|
||||
// add the default port number to the given server domains
|
||||
let mut domain_sets = std::collections::HashSet::new();
|
||||
for domain in &opt.server_domains {
|
||||
for domain in &config.server_domains {
|
||||
domain_sets.insert(domain.to_string());
|
||||
if let Some((host, _)) = domain.split_once(':') {
|
||||
domain_sets.insert(format!("{host}:{server_port}"));
|
||||
@@ -256,7 +256,7 @@ pub async fn start_http_server(
|
||||
debug!("HTTP response compression is disabled");
|
||||
}
|
||||
|
||||
let is_console = opt.console_enable;
|
||||
let is_console = config.console_enable;
|
||||
tokio::spawn(async move {
|
||||
// Note: CORS layer is removed from global middleware stack
|
||||
// - S3 API CORS is handled by bucket-level CORS configuration in apply_cors_headers()
|
||||
|
||||
Reference in New Issue
Block a user