Skip to content

Commit bc94af6

Browse files
committed
ccm: add possibility to enable tls
1 parent 3335c1f commit bc94af6

File tree

4 files changed

+164
-0
lines changed

4 files changed

+164
-0
lines changed

scylla/tests/ccm_integration/ccm/cluster.rs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::ccm::{IP_ALLOCATOR, ROOT_CCM_DIR};
22

33
use super::ip_allocator::NetPrefix;
44
use super::logged_cmd::{LoggedCmd, RunOptions};
5+
use super::{DB_TLS_CERT_PATH, DB_TLS_KEY_PATH};
56
use anyhow::{Context, Error};
67
use scylla::client::session_builder::SessionBuilder;
78
use std::collections::HashMap;
@@ -313,6 +314,18 @@ impl Node {
313314
Ok(())
314315
}
315316

317+
/// Configures TLS based on the paths provided in the environment variables `DB_TLS_CERT_PATH` and `DB_TLS_KEY_PATH`.
318+
/// If the paths are not provided, the default certificate and key are taken from `./test/tls/db.crt` and `./test/tls/db.key`.
319+
pub(crate) async fn configure_tls(&self) -> Result<(), Error> {
320+
let args = [
321+
("client_encryption_options.enabled", "true"),
322+
("client_encryption_options.certificate", &DB_TLS_CERT_PATH),
323+
("client_encryption_options.keyfile", &DB_TLS_KEY_PATH),
324+
];
325+
326+
self.updateconf(args).await
327+
}
328+
316329
/// This method starts the node. User can provide optional [`NodeStartOptions`] to control the behavior of the node start.
317330
/// If `None` is provided, the default options are used (see the implementation of Default for [`NodeStartOptions`]).
318331
pub(crate) async fn start(&mut self, opts: Option<NodeStartOptions>) -> Result<(), Error> {
@@ -679,6 +692,18 @@ impl Cluster {
679692
Ok(())
680693
}
681694

695+
/// Configures TLS based on the paths provided in the environment variables `DB_TLS_CERT_PATH` and `DB_TLS_KEY_PATH`.
696+
/// If the paths are not provided, the default certificate and key are taken from `./test/tls/db.crt` and `./test/tls/db.key`.
697+
pub(crate) async fn configure_tls(&self) -> Result<(), Error> {
698+
let args = [
699+
("client_encryption_options.enabled", "true"),
700+
("client_encryption_options.certificate", &DB_TLS_CERT_PATH),
701+
("client_encryption_options.keyfile", &DB_TLS_KEY_PATH),
702+
];
703+
704+
self.updateconf(args).await
705+
}
706+
682707
fn get_ccm_env(&self) -> HashMap<String, String> {
683708
let mut env: HashMap<String, String> = HashMap::new();
684709
env.insert(

scylla/tests/ccm_integration/ccm/mod.rs

Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,73 @@ static ROOT_CCM_DIR: LazyLock<String> = LazyLock::new(|| {
5555
ccm_root_dir
5656
});
5757

58+
pub(crate) static DB_TLS_CERT_PATH: LazyLock<String> = LazyLock::new(|| {
59+
let cargo_manifest_dir = env!("CARGO_MANIFEST_DIR");
60+
let db_cert_path_env = std::env::var("DB_TLS_CERT_PATH");
61+
let db_cert_path = match db_cert_path_env {
62+
Ok(x) => x,
63+
Err(e) => {
64+
info!(
65+
"DB_TLS_CERT_PATH env malformed or not present: {}. Using {}/../test/tls/db.crt for db cert.",
66+
e, cargo_manifest_dir
67+
);
68+
cargo_manifest_dir.to_string() + "/../test/tls/db.crt"
69+
}
70+
};
71+
72+
let path = PathBuf::from(&db_cert_path);
73+
if !path.try_exists().unwrap() {
74+
panic!("DB cert file {:?} not found", path);
75+
}
76+
77+
db_cert_path
78+
});
79+
80+
pub(crate) static DB_TLS_KEY_PATH: LazyLock<String> = LazyLock::new(|| {
81+
let cargo_manifest_dir = env!("CARGO_MANIFEST_DIR");
82+
let db_key_path_env = std::env::var("DB_TLS_KEY_PATH");
83+
let db_key_path = match db_key_path_env {
84+
Ok(x) => x,
85+
Err(e) => {
86+
info!(
87+
"DB_TLS_KEY_PATH env malformed or not present: {}. Using {}/../test/tls/db.key for db key.",
88+
e, cargo_manifest_dir
89+
);
90+
cargo_manifest_dir.to_string() + "/../test/tls/db.key"
91+
}
92+
};
93+
94+
let path = PathBuf::from(&db_key_path);
95+
if !path.try_exists().unwrap() {
96+
panic!("DB key file {:?} not found", path);
97+
}
98+
99+
db_key_path
100+
});
101+
102+
#[cfg(feature = "ssl")]
103+
pub(crate) static CA_TLS_CERT_PATH: LazyLock<String> = LazyLock::new(|| {
104+
let cargo_manifest_dir = env!("CARGO_MANIFEST_DIR");
105+
let ca_cert_path_env = std::env::var("CA_TLS_CERT_PATH");
106+
let ca_cert_path = match ca_cert_path_env {
107+
Ok(x) => x,
108+
Err(e) => {
109+
info!(
110+
"CA_TLS_CERT_PATH env malformed or not present: {}. Using {}/../test/tls/ca.crt for ca cert.",
111+
e, cargo_manifest_dir
112+
);
113+
cargo_manifest_dir.to_string() + "/../test/tls/ca.crt"
114+
}
115+
};
116+
117+
let path = PathBuf::from(&ca_cert_path);
118+
if !path.try_exists().unwrap() {
119+
panic!("DB cert file {:?} not found", path);
120+
}
121+
122+
ca_cert_path
123+
});
124+
58125
pub(crate) async fn run_ccm_test<C, T, Fut>(make_cluster_options: C, test_body: T)
59126
where
60127
C: FnOnce() -> ClusterOptions,

scylla/tests/ccm_integration/main.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@ mod common;
33

44
pub(crate) mod ccm;
55
mod test_example;
6+
#[cfg(feature = "ssl")]
7+
mod tls;

scylla/tests/ccm_integration/tls.rs

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
use std::path::PathBuf;
2+
use std::sync::Arc;
3+
4+
use openssl::ssl::{SslContextBuilder, SslMethod, SslVerifyMode};
5+
use tokio::sync::Mutex;
6+
7+
use crate::ccm::cluster::{Cluster, ClusterOptions};
8+
use crate::ccm::{run_ccm_test_with_configuration, CA_TLS_CERT_PATH, CLUSTER_VERSION};
9+
use crate::common::utils::setup_tracing;
10+
11+
fn cluster_1_node() -> ClusterOptions {
12+
ClusterOptions {
13+
name: "cluster_1_node".to_string(),
14+
version: CLUSTER_VERSION.clone(),
15+
nodes: vec![1],
16+
..ClusterOptions::default()
17+
}
18+
}
19+
20+
#[tokio::test]
21+
#[cfg_attr(not(ccm_tests), ignore)]
22+
async fn test_tls_cluster_one_node_connects() {
23+
setup_tracing();
24+
async fn test(cluster: Arc<Mutex<Cluster>>) {
25+
let mut context_builder =
26+
SslContextBuilder::new(SslMethod::tls()).expect("Failed to create ssl context builder");
27+
let ca_dir = tokio::fs::canonicalize(PathBuf::from(&*CA_TLS_CERT_PATH))
28+
.await
29+
.expect("Failed to find ca cert file");
30+
context_builder
31+
.set_ca_file(ca_dir.as_path())
32+
.expect("Failed to set ca file");
33+
context_builder.set_verify(SslVerifyMode::PEER);
34+
35+
let cluster = cluster.lock().await;
36+
let session = cluster
37+
.make_session_builder()
38+
.await
39+
.ssl_context(Some(context_builder.build()))
40+
.build()
41+
.await
42+
.unwrap();
43+
44+
let rows = session
45+
.query_unpaged("select data_center from system.local", &[])
46+
.await
47+
.expect("failed to execute query")
48+
.into_rows_result()
49+
.expect("failed to get rows")
50+
.rows::<(String,)>()
51+
.expect("failed to deserialize rows")
52+
.map(|res| res.map(|row| row.0))
53+
.collect::<Result<Vec<_>, _>>()
54+
.unwrap();
55+
println!("{:?}", rows);
56+
}
57+
58+
run_ccm_test_with_configuration(
59+
cluster_1_node,
60+
|cluster| async move {
61+
cluster
62+
.configure_tls()
63+
.await
64+
.expect("failed to configure tls");
65+
cluster
66+
},
67+
test,
68+
)
69+
.await;
70+
}

0 commit comments

Comments
 (0)