1use common_telemetry::info;
16use servers::tls::{TlsMode, TlsOption};
17use snafu::{OptionExt, ResultExt};
18use sqlx::mysql::{MySqlConnectOptions, MySqlPool, MySqlSslMode};
19
20use crate::error::{self, Result};
21
22async fn setup_mysql_options(
23 store_addrs: &[String],
24 tls_config: Option<&TlsOption>,
25) -> Result<MySqlConnectOptions> {
26 let mysql_url = store_addrs.first().context(error::InvalidArgumentsSnafu {
27 err_msg: "empty store addrs",
28 })?;
29 let opts: MySqlConnectOptions = mysql_url
31 .parse()
32 .context(error::ParseMySqlUrlSnafu { mysql_url })?;
33 let mut opts = opts
34 .no_engine_substitution(false)
35 .pipes_as_concat(false)
36 .timezone(None)
37 .set_names(false);
38
39 let Some(tls_config) = tls_config else {
40 return Ok(opts);
41 };
42
43 match tls_config.mode {
44 TlsMode::Disable => return Ok(opts),
45 TlsMode::Prefer => {
46 opts = opts.ssl_mode(MySqlSslMode::Preferred);
47 }
48 TlsMode::Require => {
49 opts = opts.ssl_mode(MySqlSslMode::Required);
50 }
51 TlsMode::VerifyCa => {
52 opts = opts.ssl_mode(MySqlSslMode::VerifyCa);
53 opts = opts.ssl_ca(&tls_config.ca_cert_path);
54 }
55 TlsMode::VerifyFull => {
56 opts = opts.ssl_mode(MySqlSslMode::VerifyIdentity);
57 opts = opts.ssl_ca(&tls_config.ca_cert_path);
58 }
59 }
60 info!(
61 "Setting up MySQL options with TLS mode: {:?}",
62 tls_config.mode
63 );
64
65 if !tls_config.cert_path.is_empty() && !tls_config.key_path.is_empty() {
66 info!("Loading client certificate for mutual TLS");
67 opts = opts.ssl_client_cert(&tls_config.cert_path);
68 opts = opts.ssl_client_key(&tls_config.key_path);
69 }
70
71 Ok(opts)
72}
73
74pub async fn create_mysql_pool(
76 store_addrs: &[String],
77 tls_config: Option<&TlsOption>,
78) -> Result<MySqlPool> {
79 let opts = setup_mysql_options(store_addrs, tls_config).await?;
80 let pool = MySqlPool::connect_with(opts)
81 .await
82 .context(error::CreateMySqlPoolSnafu)?;
83
84 Ok(pool)
85}