chore: add tls log and removing unused crates (#359)

* chore: add tls log

* improve code for http

* improve code dependencies for `cargo.toml` and removing unused crates

* modify name

* improve code

* fix

* Update crates/config/src/constants/env.rs

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>

* improve code

* fix

* add `is_enabled` and `is_disabled`

---------

Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
houseme
2025-08-07 19:02:09 +08:00
committed by GitHub
parent 130f85a575
commit e0c99bced4
16 changed files with 322 additions and 144 deletions
-10
View File
@@ -17,31 +17,21 @@ rustfs-ecstore = { workspace = true }
rustfs-common = { workspace = true }
rustfs-filemeta = { workspace = true }
rustfs-madmin = { workspace = true }
rustfs-utils = { workspace = true }
tokio = { workspace = true, features = ["full"] }
tokio-util = { workspace = true }
tracing = { workspace = true }
serde = { workspace = true, features = ["derive"] }
serde_json = { workspace = true }
thiserror = { workspace = true }
bytes = { workspace = true }
time = { workspace = true, features = ["serde"] }
uuid = { workspace = true, features = ["v4", "serde"] }
anyhow = { workspace = true }
async-trait = { workspace = true }
futures = { workspace = true }
url = { workspace = true }
rustfs-lock = { workspace = true }
lazy_static = { workspace = true }
chrono = { workspace = true }
[dev-dependencies]
rmp-serde = { workspace = true }
tokio-test = { workspace = true }
serde_json = { workspace = true }
serial_test = "3.2.0"
once_cell = { workspace = true }
tracing-subscriber = { workspace = true }
walkdir = "2.5.0"
tempfile = { workspace = true }
-7
View File
@@ -28,18 +28,11 @@ documentation = "https://docs.rs/rustfs-signer/latest/rustfs_checksum/"
[dependencies]
bytes = { workspace = true }
crc-fast = { workspace = true }
hex = { workspace = true }
http = { workspace = true }
http-body = { workspace = true }
base64-simd = { workspace = true }
md-5 = { workspace = true }
pin-project-lite = { workspace = true }
sha1 = { workspace = true }
sha2 = { workspace = true }
tracing = { workspace = true }
[dev-dependencies]
bytes-utils = { workspace = true }
pretty_assertions = { workspace = true }
tracing-test = { workspace = true }
tokio = { workspace = true, features = ["macros", "rt"] }
+262
View File
@@ -19,3 +19,265 @@ pub const ENV_WORD_DELIMITER: &str = "_";
/// Medium-drawn lines separator
/// This is used to separate words in environment variable names.
pub const ENV_WORD_DELIMITER_DASH: &str = "-";
#[derive(Debug, PartialEq, Eq, Clone, Copy, Default)]
pub enum EnableState {
True,
False,
#[default]
Empty,
Yes,
No,
On,
Off,
Enabled,
Disabled,
Ok,
NotOk,
Success,
Failure,
Active,
Inactive,
One,
Zero,
}
impl std::fmt::Display for EnableState {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.write_str(self.as_str())
}
}
impl std::str::FromStr for EnableState {
type Err = ();
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim() {
s if s.eq_ignore_ascii_case("true") => Ok(EnableState::True),
s if s.eq_ignore_ascii_case("false") => Ok(EnableState::False),
"" => Ok(EnableState::Empty),
s if s.eq_ignore_ascii_case("yes") => Ok(EnableState::Yes),
s if s.eq_ignore_ascii_case("no") => Ok(EnableState::No),
s if s.eq_ignore_ascii_case("on") => Ok(EnableState::On),
s if s.eq_ignore_ascii_case("off") => Ok(EnableState::Off),
s if s.eq_ignore_ascii_case("enabled") => Ok(EnableState::Enabled),
s if s.eq_ignore_ascii_case("disabled") => Ok(EnableState::Disabled),
s if s.eq_ignore_ascii_case("ok") => Ok(EnableState::Ok),
s if s.eq_ignore_ascii_case("not_ok") => Ok(EnableState::NotOk),
s if s.eq_ignore_ascii_case("success") => Ok(EnableState::Success),
s if s.eq_ignore_ascii_case("failure") => Ok(EnableState::Failure),
s if s.eq_ignore_ascii_case("active") => Ok(EnableState::Active),
s if s.eq_ignore_ascii_case("inactive") => Ok(EnableState::Inactive),
"1" => Ok(EnableState::One),
"0" => Ok(EnableState::Zero),
_ => Err(()),
}
}
}
impl EnableState {
/// Returns the default value for the enum.
pub fn get_default() -> Self {
Self::default()
}
/// Returns the string representation of the enum.
pub fn as_str(&self) -> &str {
match self {
EnableState::True => "true",
EnableState::False => "false",
EnableState::Empty => "",
EnableState::Yes => "yes",
EnableState::No => "no",
EnableState::On => "on",
EnableState::Off => "off",
EnableState::Enabled => "enabled",
EnableState::Disabled => "disabled",
EnableState::Ok => "ok",
EnableState::NotOk => "not_ok",
EnableState::Success => "success",
EnableState::Failure => "failure",
EnableState::Active => "active",
EnableState::Inactive => "inactive",
EnableState::One => "1",
EnableState::Zero => "0",
}
}
/// is_enabled checks if the state represents an enabled condition.
pub fn is_enabled(self) -> bool {
matches!(
self,
EnableState::True
| EnableState::Yes
| EnableState::On
| EnableState::Enabled
| EnableState::Ok
| EnableState::Success
| EnableState::Active
| EnableState::One
)
}
/// is_disabled checks if the state represents a disabled condition.
pub fn is_disabled(self) -> bool {
matches!(
self,
EnableState::False
| EnableState::No
| EnableState::Off
| EnableState::Disabled
| EnableState::NotOk
| EnableState::Failure
| EnableState::Inactive
| EnableState::Zero
| EnableState::Empty
)
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn test_enable_state_display_and_fromstr() {
let cases = [
(EnableState::True, "true"),
(EnableState::False, "false"),
(EnableState::Empty, ""),
(EnableState::Yes, "yes"),
(EnableState::No, "no"),
(EnableState::On, "on"),
(EnableState::Off, "off"),
(EnableState::Enabled, "enabled"),
(EnableState::Disabled, "disabled"),
(EnableState::Ok, "ok"),
(EnableState::NotOk, "not_ok"),
(EnableState::Success, "success"),
(EnableState::Failure, "failure"),
(EnableState::Active, "active"),
(EnableState::Inactive, "inactive"),
(EnableState::One, "1"),
(EnableState::Zero, "0"),
];
for (variant, string) in cases.iter() {
assert_eq!(&variant.to_string(), string);
assert_eq!(EnableState::from_str(string).unwrap(), *variant);
}
// Test invalid string
assert!(EnableState::from_str("invalid").is_err());
}
#[test]
fn test_enable_state_enum() {
let cases = [
(EnableState::True, "true"),
(EnableState::False, "false"),
(EnableState::Empty, ""),
(EnableState::Yes, "yes"),
(EnableState::No, "no"),
(EnableState::On, "on"),
(EnableState::Off, "off"),
(EnableState::Enabled, "enabled"),
(EnableState::Disabled, "disabled"),
(EnableState::Ok, "ok"),
(EnableState::NotOk, "not_ok"),
(EnableState::Success, "success"),
(EnableState::Failure, "failure"),
(EnableState::Active, "active"),
(EnableState::Inactive, "inactive"),
(EnableState::One, "1"),
(EnableState::Zero, "0"),
];
for (variant, string) in cases.iter() {
assert_eq!(variant.to_string(), *string);
}
}
#[test]
fn test_enable_state_enum_from_str() {
let cases = [
("true", EnableState::True),
("false", EnableState::False),
("", EnableState::Empty),
("yes", EnableState::Yes),
("no", EnableState::No),
("on", EnableState::On),
("off", EnableState::Off),
("enabled", EnableState::Enabled),
("disabled", EnableState::Disabled),
("ok", EnableState::Ok),
("not_ok", EnableState::NotOk),
("success", EnableState::Success),
("failure", EnableState::Failure),
("active", EnableState::Active),
("inactive", EnableState::Inactive),
("1", EnableState::One),
("0", EnableState::Zero),
];
for (string, variant) in cases.iter() {
assert_eq!(EnableState::from_str(string).unwrap(), *variant);
}
}
#[test]
fn test_enable_state_default() {
let default_state = EnableState::get_default();
assert_eq!(default_state, EnableState::Empty);
assert_eq!(default_state.as_str(), "");
}
#[test]
fn test_enable_state_as_str() {
let cases = [
(EnableState::True, "true"),
(EnableState::False, "false"),
(EnableState::Empty, ""),
(EnableState::Yes, "yes"),
(EnableState::No, "no"),
(EnableState::On, "on"),
(EnableState::Off, "off"),
(EnableState::Enabled, "enabled"),
(EnableState::Disabled, "disabled"),
(EnableState::Ok, "ok"),
(EnableState::NotOk, "not_ok"),
(EnableState::Success, "success"),
(EnableState::Failure, "failure"),
(EnableState::Active, "active"),
(EnableState::Inactive, "inactive"),
(EnableState::One, "1"),
(EnableState::Zero, "0"),
];
for (variant, string) in cases.iter() {
assert_eq!(variant.as_str(), *string);
}
}
#[test]
fn test_enable_state_is_enabled() {
let enabled_states = [
EnableState::True,
EnableState::Yes,
EnableState::On,
EnableState::Enabled,
EnableState::Ok,
EnableState::Success,
EnableState::Active,
EnableState::One,
];
for state in enabled_states.iter() {
assert!(state.is_enabled());
}
let disabled_states = [
EnableState::False,
EnableState::No,
EnableState::Off,
EnableState::Disabled,
EnableState::NotOk,
EnableState::Failure,
EnableState::Inactive,
EnableState::Zero,
EnableState::Empty,
];
for state in disabled_states.iter() {
assert!(state.is_disabled());
}
}
}
+1
View File
@@ -14,3 +14,4 @@
pub(crate) mod app;
pub(crate) mod env;
pub(crate) mod tls;
+15
View File
@@ -0,0 +1,15 @@
// Copyright 2024 RustFS Team
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
pub const ENV_TLS_KEYLOG: &str = "RUSTFS_TLS_KEYLOG";
+2
View File
@@ -18,6 +18,8 @@ pub mod constants;
pub use constants::app::*;
#[cfg(feature = "constants")]
pub use constants::env::*;
#[cfg(feature = "constants")]
pub use constants::tls::*;
#[cfg(feature = "notify")]
pub mod notify;
#[cfg(feature = "observability")]
+1 -2
View File
@@ -69,7 +69,6 @@ hmac = { workspace = true }
sha1 = { workspace = true }
sha2 = { workspace = true }
hex-simd = { workspace = true }
path-clean = { workspace = true }
tempfile.workspace = true
hyper.workspace = true
hyper-util.workspace = true
@@ -123,4 +122,4 @@ harness = false
[[bench]]
name = "comparison_benchmark"
harness = false
harness = false
-3
View File
@@ -32,9 +32,7 @@ workspace = true
async-trait.workspace = true
bytes.workspace = true
futures.workspace = true
lazy_static.workspace = true
rustfs-protos.workspace = true
rand.workspace = true
serde.workspace = true
serde_json.workspace = true
tokio.workspace = true
@@ -44,4 +42,3 @@ url.workspace = true
uuid.workspace = true
thiserror.workspace = true
once_cell.workspace = true
lru.workspace = true
+9 -9
View File
@@ -19,7 +19,7 @@ use crate::{
target::Target,
};
use futures::stream::{FuturesUnordered, StreamExt};
use rustfs_config::notify::{ENABLE_KEY, ENABLE_ON, NOTIFY_ROUTE_PREFIX};
use rustfs_config::notify::{ENABLE_KEY, NOTIFY_ROUTE_PREFIX};
use rustfs_config::{DEFAULT_DELIMITER, ENV_PREFIX};
use rustfs_ecstore::config::{Config, KVS};
use std::collections::{HashMap, HashSet};
@@ -111,10 +111,10 @@ impl TargetRegistry {
// 3.1. Instance discovery: Based on the '..._ENABLE_INSTANCEID' format
let enable_prefix = format!("{ENV_PREFIX}{NOTIFY_ROUTE_PREFIX}{target_type}_{ENABLE_KEY}_").to_uppercase();
for (key, value) in &all_env {
if value.eq_ignore_ascii_case(ENABLE_ON)
|| value.eq_ignore_ascii_case("true")
|| value.eq_ignore_ascii_case("1")
|| value.eq_ignore_ascii_case("yes")
if value.eq_ignore_ascii_case(rustfs_config::EnableState::One.as_str())
|| value.eq_ignore_ascii_case(rustfs_config::EnableState::On.as_str())
|| value.eq_ignore_ascii_case(rustfs_config::EnableState::True.as_str())
|| value.eq_ignore_ascii_case(rustfs_config::EnableState::Yes.as_str())
{
if let Some(id) = key.strip_prefix(&enable_prefix) {
if !id.is_empty() {
@@ -202,10 +202,10 @@ impl TargetRegistry {
let enabled = merged_config
.lookup(ENABLE_KEY)
.map(|v| {
v.eq_ignore_ascii_case(ENABLE_ON)
|| v.eq_ignore_ascii_case("true")
|| v.eq_ignore_ascii_case("1")
|| v.eq_ignore_ascii_case("yes")
v.eq_ignore_ascii_case(rustfs_config::EnableState::One.as_str())
|| v.eq_ignore_ascii_case(rustfs_config::EnableState::On.as_str())
|| v.eq_ignore_ascii_case(rustfs_config::EnableState::True.as_str())
|| v.eq_ignore_ascii_case(rustfs_config::EnableState::Yes.as_str())
})
.unwrap_or(false);
-1
View File
@@ -45,4 +45,3 @@ serde_json.workspace = true
md-5 = { workspace = true }
[dev-dependencies]
tokio-test = { workspace = true }
-3
View File
@@ -31,14 +31,11 @@ bytes = { workspace = true }
http.workspace = true
time.workspace = true
hyper.workspace = true
serde.workspace = true
serde_urlencoded.workspace = true
rustfs-utils = { workspace = true, features = ["full"] }
s3s.workspace = true
[dev-dependencies]
tempfile = { workspace = true }
rand = { workspace = true }
[lints]
workspace = true
+13 -1
View File
@@ -21,7 +21,7 @@ use std::collections::HashMap;
use std::io::Error;
use std::path::Path;
use std::sync::Arc;
use std::{fs, io};
use std::{env, fs, io};
use tracing::{debug, warn};
/// Load public certificate from file.
@@ -194,6 +194,18 @@ pub fn create_multi_cert_resolver(
})
}
/// Checks if TLS key logging is enabled.
pub fn tls_key_log() -> bool {
env::var(rustfs_config::ENV_TLS_KEYLOG)
.map(|v| {
v.eq_ignore_ascii_case(rustfs_config::EnableState::One.as_str())
|| v.eq_ignore_ascii_case(rustfs_config::EnableState::On.as_str())
|| v.eq_ignore_ascii_case(rustfs_config::EnableState::True.as_str())
|| v.eq_ignore_ascii_case(rustfs_config::EnableState::Yes.as_str())
})
.unwrap_or(false)
}
#[cfg(test)]
mod tests {
use super::*;