@@ -3,7 +3,7 @@ use std::{collections::BTreeMap, path::PathBuf};
33use 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 } ;
77use strum:: { EnumDiscriminants , IntoStaticStr } ;
88
99use 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) ]
443478mod 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