Skip to content

Commit ad177e9

Browse files
committed
add scheme checks and only set verify when tls/server explicitly set to none
1 parent 557ce58 commit ad177e9

1 file changed

Lines changed: 182 additions & 9 deletions

File tree

crates/stackable-operator/src/crd/git_sync/v1alpha2_impl.rs

Lines changed: 182 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use std::{collections::BTreeMap, path::PathBuf};
33
use k8s_openapi::api::core::v1::{
44
Container, EmptyDirVolumeSource, EnvVar, EnvVarSource, SecretKeySelector, Volume, VolumeMount,
55
};
6-
use snafu::{ResultExt, Snafu};
6+
use snafu::{ResultExt, Snafu, ensure};
77
use strum::{EnumDiscriminants, IntoStaticStr};
88

99
use crate::{
@@ -13,7 +13,10 @@ use crate::{
1313
volume::{VolumeBuilder, VolumeMountBuilder},
1414
},
1515
commons::{
16-
self, product_image_selection::ResolvedProductImage, secret_class::SecretClassVolume,
16+
self,
17+
product_image_selection::ResolvedProductImage,
18+
secret_class::SecretClassVolume,
19+
tls_verification::{CaCert, TlsServerVerification, TlsVerification},
1720
},
1821
crd::git_sync::v1alpha2::{Credentials, GitSync},
1922
product_config_utils::insert_or_update_env_vars,
@@ -54,6 +57,9 @@ pub enum Error {
5457
SecretClassVolume {
5558
source: commons::secret_class::SecretClassVolumeError,
5659
},
60+
61+
#[snafu(display("scheme does not match tls setting"))]
62+
SchemeMismatch { scheme: String },
5763
}
5864

5965
/// Kubernetes resources generated from `GitSync` specifications which should be added to the Pod.
@@ -169,6 +175,40 @@ impl GitSyncResources {
169175
git_sync_container_volume_mounts.push(ssh_volume_mount);
170176
}
171177

178+
// Check tls/scheme compatability early
179+
let scheme = git_sync.repo.scheme();
180+
println!("{}", scheme);
181+
println!("{:#?}", &git_sync.tls.tls);
182+
let ca_cert_path = match &git_sync.tls.tls {
183+
Some(tls) => {
184+
match &tls.verification {
185+
TlsVerification::None {} => {
186+
// "http.sslverify=false" will be set later in the shell script
187+
ensure!(scheme == "http", SchemeMismatchSnafu { scheme });
188+
None
189+
}
190+
TlsVerification::Server(TlsServerVerification {
191+
ca_cert: CaCert::WebPki {},
192+
}) => {
193+
// This will default to github/gitlab using its standard certificates
194+
ensure!(scheme != "http", SchemeMismatchSnafu { scheme });
195+
None
196+
}
197+
TlsVerification::Server(TlsServerVerification {
198+
ca_cert: CaCert::SecretClass(_),
199+
}) => {
200+
ensure!(scheme != "http", SchemeMismatchSnafu { scheme });
201+
Some(format!("{CA_CERT_MOUNT_PATH_PREFIX}-{i}/ca.crt"))
202+
}
203+
}
204+
}
205+
None => {
206+
// Check the scheme but http.sslverify will *not* be set.
207+
ensure!(scheme == "http", SchemeMismatchSnafu { scheme });
208+
None
209+
}
210+
};
211+
172212
if git_sync.tls.tls_ca_cert_secret_class().is_some() {
173213
let ca_cert_secret_mount_path = format!("{CA_CERT_MOUNT_PATH_PREFIX}-{i}");
174214
let ca_cert_secret_volume_name = format!("{CA_CERT_VOLUME_NAME_PREFIX}-{i}");
@@ -179,11 +219,6 @@ impl GitSyncResources {
179219
git_sync_container_volume_mounts.push(ca_cert_volume_mount);
180220
}
181221

182-
let ca_cert_path = git_sync
183-
.tls
184-
.tls_ca_cert_secret_class()
185-
.map(|_| format!("{CA_CERT_MOUNT_PATH_PREFIX}-{i}/ca.crt"));
186-
187222
let container = Self::create_git_sync_container(
188223
&format!("{CONTAINER_NAME_PREFIX}-{i}"),
189224
resolved_product_image,
@@ -329,8 +364,8 @@ impl GitSyncResources {
329364
}
330365

331366
// Tls defaults to webPki but if the user has *explicitly* set this to
332-
// null then we honour this by deactivating the ssl check.
333-
if git_sync.tls.tls.is_none() {
367+
// none then we honour this by deactivating the ssl check.
368+
if let Some(TlsVerification::None {}) = git_sync.tls.tls.as_ref().map(|t| &t.verification) {
334369
internal_git_config.insert(GIT_SSL_VERIFY.to_owned(), "false".to_owned());
335370
}
336371

@@ -441,6 +476,8 @@ wait_for_termination $!"
441476

442477
#[cfg(test)]
443478
mod tests {
479+
use rstest::rstest;
480+
444481
use super::*;
445482
use crate::{
446483
config::fragment::validate, product_config_utils::env_vars_from,
@@ -1371,4 +1408,140 @@ name: ca-cert-0
13711408
serde_yaml::to_string(&git_sync_resources.git_ca_cert_volumes.first()).unwrap()
13721409
);
13731410
}
1411+
1412+
#[rstest]
1413+
// http with tls/null --> deactivate: Ok
1414+
#[case(
1415+
"http://github.com/stackabletech/repo1",
1416+
r#"
1417+
tls: null
1418+
"#,
1419+
true
1420+
)]
1421+
// https with no tls --> defaults to webPki: Ok
1422+
#[case(
1423+
"https://github.com/stackabletech/repo1",
1424+
r#"
1425+
"#,
1426+
true
1427+
)]
1428+
// http with no tls --> defaults to webPki: Error
1429+
#[case(
1430+
"http://github.com/stackabletech/repo1",
1431+
r#"
1432+
"#,
1433+
false
1434+
)]
1435+
// http with tls/None: Ok
1436+
#[case(
1437+
"http://github.com/stackabletech/repo1",
1438+
r#"
1439+
tls:
1440+
verification:
1441+
none: {}
1442+
"#,
1443+
true
1444+
)]
1445+
// https with tls/None: Error
1446+
#[case(
1447+
"http://github.com/stackabletech/repo1",
1448+
r#"
1449+
tls:
1450+
"#,
1451+
true
1452+
)]
1453+
// ssh with tls/secret: Ok
1454+
#[case(
1455+
"ssh://git@github.com/stackabletech/repo.git",
1456+
r#"
1457+
tls:
1458+
verification:
1459+
server:
1460+
caCert:
1461+
secretClass: git-tls-ca
1462+
"#,
1463+
true
1464+
)]
1465+
// https with tls/secret: Ok
1466+
#[case(
1467+
"https://github.com/stackabletech/repo1",
1468+
r#"
1469+
tls:
1470+
verification:
1471+
server:
1472+
caCert:
1473+
secretClass: another-ca
1474+
"#,
1475+
true
1476+
)]
1477+
// https with tls/webPki: Ok
1478+
#[case(
1479+
"https://github.com/stackabletech/repo1",
1480+
r#"
1481+
tls:
1482+
verification:
1483+
server:
1484+
caCert:
1485+
webPki: {}
1486+
"#,
1487+
true
1488+
)]
1489+
// http with tls/webPki: Error
1490+
#[case(
1491+
"http://github.com/stackabletech/repo1",
1492+
r#"
1493+
tls:
1494+
verification:
1495+
server:
1496+
caCert:
1497+
webPki: {}
1498+
"#,
1499+
false
1500+
)]
1501+
// http with tls/secret: Error
1502+
#[case(
1503+
"http://github.com/stackabletech/repo1",
1504+
r#"
1505+
tls:
1506+
verification:
1507+
server:
1508+
caCert:
1509+
secretClass: http-ca
1510+
"#,
1511+
false
1512+
)]
1513+
fn test_git_sync_tls_scheme(#[case] repo: &str, #[case] tls: &str, #[case] expect_ok: bool) {
1514+
let git_sync_spec = format!(
1515+
r#"
1516+
- repo: {repo}
1517+
{tls}
1518+
"#
1519+
);
1520+
1521+
let git_syncs: Vec<GitSync> = yaml_from_str_singleton_map(&git_sync_spec).unwrap();
1522+
1523+
let resolved_product_image = ResolvedProductImage {
1524+
image: "oci.stackable.tech/sdp/product:latest".to_string(),
1525+
app_version_label_value: "1.0.0-latest"
1526+
.parse()
1527+
.expect("static app version label is always valid"),
1528+
product_version: "1.0.0".to_string(),
1529+
image_pull_policy: "Always".to_string(),
1530+
pull_secrets: None,
1531+
};
1532+
1533+
let git_sync_resources = GitSyncResources::new(
1534+
&git_syncs,
1535+
&resolved_product_image,
1536+
&[],
1537+
&[],
1538+
"log-volume",
1539+
&validate(default_container_log_config()).unwrap(),
1540+
);
1541+
if expect_ok {
1542+
assert!(git_sync_resources.is_ok());
1543+
} else {
1544+
assert!(git_sync_resources.is_err());
1545+
}
1546+
}
13741547
}

0 commit comments

Comments
 (0)