@@ -2,6 +2,7 @@ use crate::ccm::{IP_ALLOCATOR, ROOT_CCM_DIR};
22
33use super :: ip_allocator:: NetPrefix ;
44use super :: logged_cmd:: { LoggedCmd , RunOptions } ;
5+ use super :: { DB_TLS_CERT_PATH , DB_TLS_KEY_PATH } ;
56use anyhow:: { Context , Error } ;
67use scylla:: client:: session_builder:: SessionBuilder ;
78use std:: collections:: HashMap ;
@@ -264,6 +265,68 @@ impl Node {
264265 env
265266 }
266267
268+ /// Executes `ccm updateconf` and applies it for this node.
269+ /// It accepts the key-value pairs to update the configuration.
270+ ///
271+ /// ### Example
272+ /// ```
273+ /// # use crate::ccm::cluster::Node;
274+ /// # async fn check_only_compiles(node: &Node) -> Result<(), Box<dyn Error>> {
275+ /// let args = [
276+ /// ("client_encryption_options.enabled", "true"),
277+ /// ("client_encryption_options.certificate", "db.cert"),
278+ /// ("client_encryption_options.keyfile", "db.key"),
279+ /// ];
280+ ///
281+ /// node.updateconf(args).await?
282+ /// # Ok(())
283+ /// # }
284+ /// ```
285+ ///
286+ /// The code above is equivalent to the following scylla.yaml:
287+ /// ```yaml
288+ /// client_encryption_options:
289+ /// enabled: true
290+ /// certificate: db.cert
291+ /// keyfile: db.key
292+ /// ```
293+ pub ( crate ) async fn updateconf < K , V > (
294+ & self ,
295+ key_values : impl IntoIterator < Item = ( K , V ) > ,
296+ ) -> Result < ( ) , Error >
297+ where
298+ K : AsRef < str > ,
299+ V : AsRef < str > ,
300+ {
301+ let config_dir = & self . config_dir ;
302+ let mut args: Vec < String > = vec ! [
303+ self . opts. name( ) ,
304+ "updateconf" . to_string( ) ,
305+ "--config-dir" . to_string( ) ,
306+ config_dir. to_string_lossy( ) . into_owned( ) ,
307+ ] ;
308+ for ( k, v) in key_values. into_iter ( ) {
309+ args. push ( format ! ( "{}:{}" , k. as_ref( ) , v. as_ref( ) ) ) ;
310+ }
311+
312+ self . logged_cmd
313+ . run_command ( "ccm" , & args, RunOptions :: new ( ) )
314+ . await ?;
315+ Ok ( ( ) )
316+ }
317+
318+ /// Configures TLS based on the paths provided in the environment variables `DB_TLS_CERT_PATH` and `DB_TLS_KEY_PATH`.
319+ /// If the paths are not provided, the default certificate and key are taken from `./test/tls/db.crt` and `./test/tls/db.key`.
320+ pub ( crate ) async fn configure_tls ( & self ) -> Result < ( ) , Error > {
321+ let args = [
322+ ( "client_encryption_options.enabled" , "true" ) ,
323+ ( "client_encryption_options.certificate" , & DB_TLS_CERT_PATH ) ,
324+ ( "client_encryption_options.keyfile" , & DB_TLS_KEY_PATH ) ,
325+ ] ;
326+
327+ self . updateconf ( args) . await
328+ }
329+
267330 /// This method starts the node. User can provide optional [`NodeStartOptions`] to control the behavior of the node start.
268331 /// If `None` is provided, the default options are used (see the implementation of Default for [`NodeStartOptions`]).
269332 pub ( crate ) async fn start ( & mut self , opts : Option < NodeStartOptions > ) -> Result < ( ) , Error > {
@@ -581,6 +644,67 @@ impl Cluster {
581644 Ok ( ( ) )
582645 }
583646
647+ /// Executes `ccm updateconf` and applies it for all nodes in the cluster.
648+ /// It accepts the key-value pairs to update the configuration.
649+ ///
650+ /// ### Example
651+ /// ```
652+ /// # use crate::ccm::cluster::Cluster;
653+ /// # async fn check_only_compiles(cluster: &Cluster) -> Result<(), Box<dyn Error>> {
654+ /// let args = [
655+ /// ("client_encryption_options.enabled", "true"),
656+ /// ("client_encryption_options.certificate", "db.cert"),
657+ /// ("client_encryption_options.keyfile", "db.key"),
658+ /// ];
659+ ///
660+ /// cluster.updateconf(args).await?
661+ /// # Ok(())
662+ /// # }
663+ /// ```
664+ ///
665+ /// The code above is equivalent to the following scylla.yaml:
666+ /// ```yaml
667+ /// client_encryption_options:
668+ /// enabled: true
669+ /// certificate: db.cert
670+ /// keyfile: db.key
671+ /// ```
672+ pub ( crate ) async fn updateconf < K , V > (
673+ & self ,
674+ key_values : impl IntoIterator < Item = ( K , V ) > ,
675+ ) -> Result < ( ) , Error >
676+ where
677+ K : AsRef < str > ,
678+ V : AsRef < str > ,
679+ {
680+ let config_dir = self . config_dir ( ) ;
681+ let mut args: Vec < String > = vec ! [
682+ "updateconf" . to_string( ) ,
683+ "--config-dir" . to_string( ) ,
684+ config_dir. to_string_lossy( ) . into_owned( ) ,
685+ ] ;
686+ for ( k, v) in key_values. into_iter ( ) {
687+ args. push ( format ! ( "{}:{}" , k. as_ref( ) , v. as_ref( ) ) ) ;
688+ }
689+
690+ self . logged_cmd
691+ . run_command ( "ccm" , & args, RunOptions :: new ( ) )
692+ . await ?;
693+ Ok ( ( ) )
694+ }
695+
696+ /// Configures TLS based on the paths provided in the environment variables `DB_TLS_CERT_PATH` and `DB_TLS_KEY_PATH`.
697+ /// If the paths are not provided, the default certificate and key are taken from `./test/tls/db.crt` and `./test/tls/db.key`.
698+ pub ( crate ) async fn configure_tls ( & self ) -> Result < ( ) , Error > {
699+ let args = [
700+ ( "client_encryption_options.enabled" , "true" ) ,
701+ ( "client_encryption_options.certificate" , & DB_TLS_CERT_PATH ) ,
702+ ( "client_encryption_options.keyfile" , & DB_TLS_KEY_PATH ) ,
703+ ] ;
704+
705+ self . updateconf ( args) . await
706+ }
707+
584708 fn get_ccm_env ( & self ) -> HashMap < String , String > {
585709 let mut env: HashMap < String , String > = HashMap :: new ( ) ;
586710 env. insert (
0 commit comments