Skip to content

Commit

Permalink
cert_reload integration test: WIP
Browse files Browse the repository at this point in the history
tryint to understand why this fails inside of GH action

Signed-off-by: Flavio Castelli <fcastelli@suse.com>
  • Loading branch information
flavio committed Jul 18, 2024
1 parent 6aa1707 commit 2f43cbc
Showing 1 changed file with 61 additions and 32 deletions.
93 changes: 61 additions & 32 deletions tests/integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -544,23 +544,48 @@ mod certificate_reload_helpers {
}
}

pub fn get_tls_san_names(domain_ip: &str, domain_port: &str) -> Vec<String> {
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
builder.set_verify(SslVerifyMode::NONE);
let connector = builder.build();
let stream = TcpStream::connect(format!("{domain_ip}:{domain_port}")).unwrap();
let stream = connector.connect(domain_ip, stream).unwrap();

let cert = stream.ssl().peer_certificate().unwrap();
cert.subject_alt_names()
.expect("failed to get SAN names")
.iter()
.map(|name| {
name.dnsname()
.expect("failed to get DNS name from SAN entry")
.to_string()
})
.collect::<Vec<String>>()
pub async fn get_tls_san_names(domain_ip: &str, domain_port: &str) -> Vec<String> {
let domain_ip = domain_ip.to_string();
let domain_port = domain_port.to_string();

tokio::task::spawn_blocking(move || {
let mut builder = SslConnector::builder(SslMethod::tls()).unwrap();
builder.set_verify(SslVerifyMode::NONE);
let connector = builder.build();
let stream = TcpStream::connect(format!("{domain_ip}:{domain_port}")).unwrap();
let stream = connector.connect(&domain_ip, stream).unwrap();

let cert = stream.ssl().peer_certificate().unwrap();
cert.subject_alt_names()
.expect("failed to get SAN names")
.iter()
.map(|name| {
name.dnsname()
.expect("failed to get DNS name from SAN entry")
.to_string()
})
.collect::<Vec<String>>()
})
.await
.unwrap()
}

pub async fn check_tls_san_name(domain_ip: &str, domain_port: &str, hostname: &str) -> bool {
let sleep_interval = std::time::Duration::from_secs(1);
let max_retries = 10;
let mut failed_retries = 0;
let hostname = hostname.to_string();
loop {
let san_names = get_tls_san_names(domain_ip, domain_port).await;
if san_names.contains(&hostname) {
return true;
}
failed_retries += 1;
if failed_retries >= max_retries {
return false;
}
tokio::time::sleep(sleep_interval).await;
}
}

pub async fn wait_for_policy_server_to_be_ready(address: &str) {
Expand Down Expand Up @@ -599,11 +624,11 @@ async fn test_detect_certificate_rotation() {
let cert_file = certs_dir.path().join("policy-server.pem");
let key_file = certs_dir.path().join("policy-server-key.pem");

let hostname = "cert1.example.com".to_string();
let tls_data = create_cert(&hostname);
let hostname1 = "cert1.example.com";
let tls_data1 = create_cert(&hostname1);

std::fs::write(&cert_file, tls_data.cert).unwrap();
std::fs::write(&key_file, tls_data.key).unwrap();
std::fs::write(&cert_file, tls_data1.cert).unwrap();
std::fs::write(&key_file, tls_data1.key).unwrap();

let mut config = default_test_config();
config.tls_config = Some(policy_server::config::TlsConfig {
Expand All @@ -616,37 +641,41 @@ async fn test_detect_certificate_rotation() {
let domain_port = config.addr.port().to_string();

tokio::spawn(async move {
policy_server::tracing::setup_tracing(
&config.log_level,
&config.log_fmt,
config.log_no_color,
)
.unwrap();
let api_server = policy_server::PolicyServer::new_from_config(config)
.await
.unwrap();
api_server.run().await.unwrap();
});
wait_for_policy_server_to_be_ready(format!("{domain_ip}:{domain_port}").as_str()).await;

let san_names = get_tls_san_names(&domain_ip, &domain_port);
assert!(san_names.contains(&hostname));
assert!(check_tls_san_name(&domain_ip, &domain_port, hostname1).await);

// Generate a new certificate and key, and switch to them

let old_hostname = hostname.clone();
let hostname = "cert2.example.com".to_string();
let tls_data = create_cert(&hostname);
let hostname2 = "cert2.example.com";
let tls_data2 = create_cert(hostname2);

// write only the cert file
std::fs::write(cert_file, tls_data.cert).unwrap();
std::fs::write(&cert_file, tls_data2.cert).unwrap();

// give inotify some time to ensure it detected the cert change
tokio::time::sleep(std::time::Duration::from_secs(4)).await;

// the old certificate should still be in use, since we didn't change also the key
let san_names = get_tls_san_names(&domain_ip, &domain_port);
assert!(san_names.contains(&old_hostname));
assert!(check_tls_san_name(&domain_ip, &domain_port, hostname1).await);

// write only the cert file
std::fs::write(key_file, tls_data.key).unwrap();
std::fs::write(&key_file, tls_data2.key).unwrap();

// give inotify some time to ensure it detected the cert change
tokio::time::sleep(std::time::Duration::from_secs(4)).await;

// the new certificate should be in use
let san_names = get_tls_san_names(&domain_ip, &domain_port);
assert!(san_names.contains(&hostname));
assert!(check_tls_san_name(&domain_ip, &domain_port, hostname2).await);
}

0 comments on commit 2f43cbc

Please sign in to comment.