From d4a54a085b1197f5e01e696404be331605a46e3d Mon Sep 17 00:00:00 2001 From: Ning Sun Date: Fri, 1 Mar 2024 11:49:54 +0800 Subject: [PATCH] feat: add configuration for tls watch option (#3395) * feat: add configuration for tls watch option * test: sleep longer to ensure async task run * test: update config api integration test * refactor: rename function --- config/frontend.example.toml | 2 + config/standalone.example.toml | 6 ++- src/frontend/src/server.rs | 7 ++-- src/servers/src/tls.rs | 42 ++++++++++++++++++-- src/servers/tests/mysql/mysql_server_test.rs | 3 ++ src/servers/tests/postgres/mod.rs | 3 ++ tests-integration/tests/http.rs | 2 + 7 files changed, 57 insertions(+), 8 deletions(-) diff --git a/config/frontend.example.toml b/config/frontend.example.toml index 29219fe4b8..dc9c6917bd 100644 --- a/config/frontend.example.toml +++ b/config/frontend.example.toml @@ -31,6 +31,7 @@ runtime_size = 2 mode = "disable" cert_path = "" key_path = "" +watch = false # PostgresSQL server options, see `standalone.example.toml`. [postgres] @@ -43,6 +44,7 @@ runtime_size = 2 mode = "disable" cert_path = "" key_path = "" +watch = false # OpenTSDB protocol options, see `standalone.example.toml`. [opentsdb] diff --git a/config/standalone.example.toml b/config/standalone.example.toml index b30b0d58b7..0a9c0873cc 100644 --- a/config/standalone.example.toml +++ b/config/standalone.example.toml @@ -44,6 +44,8 @@ mode = "disable" cert_path = "" # Private key file path. key_path = "" +# Watch for Certificate and key file change and auto reload +watch = false # PostgresSQL server options. [postgres] @@ -62,6 +64,8 @@ mode = "disable" cert_path = "" # private key file path. key_path = "" +# Watch for Certificate and key file change and auto reload +watch = false # OpenTSDB protocol options. [opentsdb] @@ -118,7 +122,7 @@ sync_period = "1000ms" # Number of topics to be created upon start. # num_topics = 64 # Topic selector type. -# Available selector types: +# Available selector types: # - "round_robin" (default) # selector_type = "round_robin" # The prefix of topic name. diff --git a/src/frontend/src/server.rs b/src/frontend/src/server.rs index 4866dd7fab..2346591c77 100644 --- a/src/frontend/src/server.rs +++ b/src/frontend/src/server.rs @@ -29,7 +29,7 @@ use servers::postgres::PostgresServer; use servers::query_handler::grpc::ServerGrpcQueryHandlerAdapter; use servers::query_handler::sql::ServerSqlQueryHandlerAdapter; use servers::server::{Server, ServerHandlers}; -use servers::tls::{watch_tls_config, ReloadableTlsServerConfig}; +use servers::tls::{maybe_watch_tls_config, ReloadableTlsServerConfig}; use snafu::ResultExt; use crate::error::{self, Result, StartServerSnafu}; @@ -199,7 +199,8 @@ where ReloadableTlsServerConfig::try_new(opts.tls.clone()).context(StartServerSnafu)?, ); - watch_tls_config(tls_server_config.clone()).context(StartServerSnafu)?; + // will not watch if watch is disabled in tls option + maybe_watch_tls_config(tls_server_config.clone()).context(StartServerSnafu)?; let mysql_io_runtime = Arc::new( RuntimeBuilder::default() @@ -232,7 +233,7 @@ where ReloadableTlsServerConfig::try_new(opts.tls.clone()).context(StartServerSnafu)?, ); - watch_tls_config(tls_server_config.clone()).context(StartServerSnafu)?; + maybe_watch_tls_config(tls_server_config.clone()).context(StartServerSnafu)?; let pg_io_runtime = Arc::new( RuntimeBuilder::default() diff --git a/src/servers/src/tls.rs b/src/servers/src/tls.rs index 1c0be507e7..f36970a42b 100644 --- a/src/servers/src/tls.rs +++ b/src/servers/src/tls.rs @@ -61,6 +61,8 @@ pub struct TlsOption { pub cert_path: String, #[serde(default)] pub key_path: String, + #[serde(default)] + pub watch: bool, } impl TlsOption { @@ -138,6 +140,10 @@ impl TlsOption { pub fn key_path(&self) -> &Path { Path::new(&self.key_path) } + + pub fn watch_enabled(&self) -> bool { + self.mode != TlsMode::Disable && self.watch + } } /// A mutable container for TLS server config @@ -186,8 +192,8 @@ impl ReloadableTlsServerConfig { } } -pub fn watch_tls_config(tls_server_config: Arc) -> Result<()> { - if tls_server_config.get_tls_option().mode == TlsMode::Disable { +pub fn maybe_watch_tls_config(tls_server_config: Arc) -> Result<()> { + if !tls_server_config.get_tls_option().watch_enabled() { return Ok(()); } @@ -250,6 +256,7 @@ mod tests { mode: Disable, cert_path: "/path/to/cert_path".to_string(), key_path: "/path/to/key_path".to_string(), + watch: false }, TlsOption::new( Some(Disable), @@ -274,6 +281,7 @@ mod tests { assert!(matches!(t.mode, TlsMode::Disable)); assert!(t.key_path.is_empty()); assert!(t.cert_path.is_empty()); + assert!(!t.watch_enabled()); let setup = t.setup(); let setup = setup.unwrap(); @@ -297,6 +305,7 @@ mod tests { assert!(matches!(t.mode, TlsMode::Prefer)); assert!(!t.key_path.is_empty()); assert!(!t.cert_path.is_empty()); + assert!(!t.watch_enabled()); } #[test] @@ -316,6 +325,7 @@ mod tests { assert!(matches!(t.mode, TlsMode::Require)); assert!(!t.key_path.is_empty()); assert!(!t.cert_path.is_empty()); + assert!(!t.watch_enabled()); } #[test] @@ -335,6 +345,7 @@ mod tests { assert!(matches!(t.mode, TlsMode::VerifyCa)); assert!(!t.key_path.is_empty()); assert!(!t.cert_path.is_empty()); + assert!(!t.watch_enabled()); } #[test] @@ -354,6 +365,28 @@ mod tests { assert!(matches!(t.mode, TlsMode::VerifyFull)); assert!(!t.key_path.is_empty()); assert!(!t.cert_path.is_empty()); + assert!(!t.watch_enabled()); + } + + #[test] + fn test_tls_option_watch_enabled() { + let s = r#" + { + "mode": "verify_full", + "cert_path": "/some_dir/some.crt", + "key_path": "/some_dir/some.key", + "watch": true + } + "#; + + let t: TlsOption = serde_json::from_str(s).unwrap(); + + assert!(t.should_force_tls()); + + assert!(matches!(t.mode, TlsMode::VerifyFull)); + assert!(!t.key_path.is_empty()); + assert!(!t.cert_path.is_empty()); + assert!(t.watch_enabled()); } #[test] @@ -377,12 +410,13 @@ mod tests { .into_os_string() .into_string() .expect("failed to convert path to string"), + watch: true, }; let server_config = Arc::new( ReloadableTlsServerConfig::try_new(server_tls).expect("failed to create server config"), ); - watch_tls_config(server_config.clone()).expect("failed to watch server config"); + maybe_watch_tls_config(server_config.clone()).expect("failed to watch server config"); assert_eq!(0, server_config.get_version()); assert!(server_config.get_server_config().is_some()); @@ -391,7 +425,7 @@ mod tests { .expect("failed to copy key to tmpdir"); // waiting for async load - std::thread::sleep(std::time::Duration::from_millis(100)); + std::thread::sleep(std::time::Duration::from_millis(300)); assert!(server_config.get_version() > 1); assert!(server_config.get_server_config().is_some()); } diff --git a/src/servers/tests/mysql/mysql_server_test.rs b/src/servers/tests/mysql/mysql_server_test.rs index 3cbac4ee93..6f5b20dc7e 100644 --- a/src/servers/tests/mysql/mysql_server_test.rs +++ b/src/servers/tests/mysql/mysql_server_test.rs @@ -255,6 +255,7 @@ async fn test_server_required_secure_client_plain() -> Result<()> { mode: servers::tls::TlsMode::Require, cert_path: "tests/ssl/server.crt".to_owned(), key_path: "tests/ssl/server-rsa.key".to_owned(), + watch: false, }; let client_tls = false; @@ -292,6 +293,7 @@ async fn test_server_required_secure_client_plain_with_pkcs8_priv_key() -> Resul mode: servers::tls::TlsMode::Require, cert_path: "tests/ssl/server.crt".to_owned(), key_path: "tests/ssl/server-pkcs8.key".to_owned(), + watch: false, }; let client_tls = false; @@ -592,6 +594,7 @@ async fn do_test_query_all_datatypes_with_secure_server( "tests/ssl/server-rsa.key".to_owned() } }, + watch: false, }; do_test_query_all_datatypes(server_tls, client_tls).await diff --git a/src/servers/tests/postgres/mod.rs b/src/servers/tests/postgres/mod.rs index 7668723df3..3dec74d0e1 100644 --- a/src/servers/tests/postgres/mod.rs +++ b/src/servers/tests/postgres/mod.rs @@ -273,6 +273,7 @@ async fn test_server_secure_require_client_plain() -> Result<()> { mode: servers::tls::TlsMode::Require, cert_path: "tests/ssl/server.crt".to_owned(), key_path: "tests/ssl/server-rsa.key".to_owned(), + watch: false, }; let server_port = start_test_server(server_tls).await?; let r = create_plain_connection(server_port, false).await; @@ -288,6 +289,7 @@ async fn test_server_secure_require_client_plain_with_pkcs8_priv_key() -> Result mode: servers::tls::TlsMode::Require, cert_path: "tests/ssl/server.crt".to_owned(), key_path: "tests/ssl/server-pkcs8.key".to_owned(), + watch: false, }; let server_port = start_test_server(server_tls).await?; let r = create_plain_connection(server_port, false).await; @@ -520,6 +522,7 @@ async fn do_simple_query_with_secure_server( "tests/ssl/server-rsa.key".to_owned() } }, + watch: false, }; do_simple_query(server_tls, client_tls).await diff --git a/tests-integration/tests/http.rs b/tests-integration/tests/http.rs index cb48533823..f424ad8942 100644 --- a/tests-integration/tests/http.rs +++ b/tests-integration/tests/http.rs @@ -685,6 +685,7 @@ runtime_size = 2 mode = "disable" cert_path = "" key_path = "" +watch = false [frontend.postgres] enable = true @@ -695,6 +696,7 @@ runtime_size = 2 mode = "disable" cert_path = "" key_path = "" +watch = false [frontend.opentsdb] enable = true