mirror of
https://github.com/rustfs/rustfs.git
synced 2026-08-25 21:46:50 +00:00
feat(targets): add check_mysql_server_available probe function (#2884)
Signed-off-by: JaySon-Huang <tshent@qq.com> Co-authored-by: houseme <housemecn@gmail.com>
This commit is contained in:
@@ -23,7 +23,7 @@ use std::fmt::Formatter;
|
||||
use std::sync::Arc;
|
||||
use std::sync::atomic::{AtomicU64, Ordering};
|
||||
use std::time::{SystemTime, UNIX_EPOCH};
|
||||
use tracing::warn;
|
||||
use tracing::{debug, warn};
|
||||
|
||||
pub mod amqp;
|
||||
pub mod kafka;
|
||||
@@ -440,6 +440,20 @@ pub(crate) fn delete_stored_payload(
|
||||
}
|
||||
}
|
||||
|
||||
/// Ensures a rustls crypto provider is installed before any TLS operation.
|
||||
///
|
||||
/// Multiple target modules (MySQL, Redis, Postgres, MQTT) need this because
|
||||
/// each may be the first to perform a TLS handshake. Idempotent: if a
|
||||
/// provider is already registered, returns immediately.
|
||||
pub(crate) fn ensure_rustls_provider_installed() {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_some() {
|
||||
return;
|
||||
}
|
||||
if let Err(err) = rustls::crypto::aws_lc_rs::default_provider().install_default() {
|
||||
debug!("rustls provider already installed or unavailable: {err:?}");
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -176,14 +176,6 @@ fn websocket_broker_url(broker: &Url, secure: bool) -> Result<String, TargetErro
|
||||
Ok(url.to_string())
|
||||
}
|
||||
|
||||
fn ensure_rustls_provider_installed() {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_none()
|
||||
&& rustls::crypto::aws_lc_rs::default_provider().install_default().is_err()
|
||||
{
|
||||
debug!("rustls crypto provider was installed concurrently, skipping aws-lc-rs install");
|
||||
}
|
||||
}
|
||||
|
||||
fn validate_path_is_absolute(path: &str, field: &str) -> Result<(), TargetError> {
|
||||
if !Path::new(path).is_absolute() {
|
||||
return Err(TargetError::Configuration(format!("{field} must be an absolute path")));
|
||||
@@ -215,7 +207,7 @@ fn build_root_store(ca_path: &str, trust_leaf_as_ca: bool) -> Result<rustls::Roo
|
||||
}
|
||||
|
||||
fn build_mqtt_tls_transport(broker: &Url, tls: &MQTTTlsConfig) -> Result<Transport, TargetError> {
|
||||
ensure_rustls_provider_installed();
|
||||
super::ensure_rustls_provider_installed();
|
||||
|
||||
let client_config = match tls
|
||||
.policy
|
||||
|
||||
@@ -304,16 +304,6 @@ fn is_valid_identifier_segment(segment: &str) -> bool {
|
||||
true
|
||||
}
|
||||
|
||||
fn ensure_rustls_provider_installed() {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_some() {
|
||||
return;
|
||||
}
|
||||
|
||||
if let Err(err) = rustls::crypto::aws_lc_rs::default_provider().install_default() {
|
||||
debug!("rustls provider already installed or unavailable for mysql target: {err:?}");
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn validate_table_name(table: &str) -> Result<(), TargetError> {
|
||||
let table = table.trim();
|
||||
|
||||
@@ -571,7 +561,7 @@ where
|
||||
.db_name(Some(dsn.database.clone()));
|
||||
|
||||
if dsn.tls {
|
||||
ensure_rustls_provider_installed();
|
||||
super::ensure_rustls_provider_installed();
|
||||
let mut ssl_opts = SslOpts::default();
|
||||
if !self.args.tls_ca.is_empty() {
|
||||
ssl_opts = ssl_opts.with_root_certs(vec![PathBuf::from(self.args.tls_ca.clone()).into()]);
|
||||
@@ -666,7 +656,7 @@ where
|
||||
|
||||
conn.exec_drop(sql, (event_time.as_str(), event_data))
|
||||
.await
|
||||
.map_err(map_mysql_error)?;
|
||||
.map_err(|err| map_mysql_error(err, "Failed to insert event"))?;
|
||||
|
||||
self.delivery_counters.record_success();
|
||||
debug!(target_id = %self.id, "MySQL event inserted");
|
||||
@@ -690,16 +680,16 @@ where
|
||||
/// - `Server(1213|1205|1040)` → `Timeout` (deadlock/lock timeout/too
|
||||
/// many connections, exponential-backoff retry)
|
||||
/// - everything else → `Request` (permanent failure)
|
||||
fn map_mysql_error(err: mysql_async::Error) -> TargetError {
|
||||
pub(crate) fn map_mysql_error(err: mysql_async::Error, operation: &str) -> TargetError {
|
||||
match &err {
|
||||
mysql_async::Error::Io(_) | mysql_async::Error::Driver(_) => TargetError::NotConnected,
|
||||
mysql_async::Error::Server(server_err) => match server_err.code {
|
||||
1213 | 1205 | 1040 => {
|
||||
TargetError::Timeout(format!("MySQL transient server error {}: {}", server_err.code, server_err.message))
|
||||
}
|
||||
_ => TargetError::Request(format!("Failed to insert event: {err}")),
|
||||
_ => TargetError::Request(format!("{operation}: {err}")),
|
||||
},
|
||||
_ => TargetError::Request(format!("Failed to insert event: {err}")),
|
||||
_ => TargetError::Request(format!("{operation}: {err}")),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
use tokio_postgres::Config;
|
||||
use tokio_postgres_rustls::MakeRustlsConnect;
|
||||
use tracing::{debug, error, info, instrument, warn};
|
||||
use tracing::{error, info, instrument, warn};
|
||||
use url::Url;
|
||||
use uuid::Uuid;
|
||||
|
||||
@@ -398,14 +398,6 @@ pub fn table_probe_sql(schema: &str, table: &str) -> String {
|
||||
format!("SELECT 1 FROM {} LIMIT 0", qualified_table(schema, table))
|
||||
}
|
||||
|
||||
fn ensure_rustls_provider_installed() {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_none()
|
||||
&& rustls::crypto::aws_lc_rs::default_provider().install_default().is_err()
|
||||
{
|
||||
debug!("rustls crypto provider was installed concurrently, skipping aws-lc-rs install");
|
||||
}
|
||||
}
|
||||
|
||||
/// Builds a rustls `ClientConfig` for the PostgreSQL connection.
|
||||
///
|
||||
/// When `tls_ca` is empty the OS native trust store is used via
|
||||
@@ -413,7 +405,7 @@ fn ensure_rustls_provider_installed() {
|
||||
/// When `tls_client_cert` and `tls_client_key` are both set the connection
|
||||
/// uses mTLS authentication; otherwise no client cert is sent.
|
||||
pub fn build_tls_config(args: &PostgresArgs) -> Result<rustls::ClientConfig, TargetError> {
|
||||
ensure_rustls_provider_installed();
|
||||
super::ensure_rustls_provider_installed();
|
||||
|
||||
let mut root_store = rustls::RootCertStore::empty();
|
||||
|
||||
|
||||
@@ -290,14 +290,6 @@ fn validate_redis_tls_config(url: &Url, tls: &RedisTlsConfig) -> Result<(), Targ
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn ensure_rustls_provider_installed() {
|
||||
if rustls::crypto::CryptoProvider::get_default().is_none()
|
||||
&& rustls::crypto::aws_lc_rs::default_provider().install_default().is_err()
|
||||
{
|
||||
debug!("rustls crypto provider was installed concurrently, skipping aws-lc-rs install");
|
||||
}
|
||||
}
|
||||
|
||||
pub struct RedisTarget<E>
|
||||
where
|
||||
E: Send + Sync + 'static + Clone + Serialize + DeserializeOwned,
|
||||
@@ -656,7 +648,7 @@ pub(crate) fn build_redis_client(args: &RedisArgs) -> Result<Client, TargetError
|
||||
|
||||
let secure_scheme = matches!(args.url.scheme(), "rediss" | "valkeys");
|
||||
if secure_scheme {
|
||||
ensure_rustls_provider_installed();
|
||||
super::ensure_rustls_provider_installed();
|
||||
let tls_certs = TlsCertificates {
|
||||
client_tls: read_client_tls(&args.tls)?,
|
||||
root_cert: read_root_cert(&args.tls)?,
|
||||
|
||||
Reference in New Issue
Block a user