@@ -5,9 +5,9 @@ package pgcluster
55
66import (
77 "context"
8- // #nosec G501
9- "crypto/md5"
8+ "crypto/md5" //nolint:gosec
109 "fmt"
10+ "strconv"
1111 "sync"
1212 "time"
1313
@@ -767,7 +767,6 @@ var _ = Describe("Users", Ordered, func() {
767767
768768 return errors .New ("cluster not deleted" )
769769 }, time .Second * 15 , time .Millisecond * 250 ).Should (BeNil ())
770-
771770 })
772771 })
773772
@@ -1284,3 +1283,260 @@ var _ = Describe("Operator-created sidecar container resources", Ordered, func()
12841283 }
12851284 })
12861285})
1286+
1287+ var _ = Describe ("Validate TLS" , Ordered , func () {
1288+ ctx := context .Background ()
1289+
1290+ const crName = "validate-tls"
1291+ const ns = crName
1292+
1293+ namespace := & corev1.Namespace {
1294+ ObjectMeta : metav1.ObjectMeta {
1295+ Name : crName ,
1296+ Namespace : ns ,
1297+ },
1298+ }
1299+
1300+ BeforeAll (func () {
1301+ By ("Creating the Namespace to perform the tests" )
1302+ err := k8sClient .Create (ctx , namespace )
1303+ Expect (err ).To (Not (HaveOccurred ()))
1304+ })
1305+
1306+ AfterAll (func () {
1307+ By ("Deleting the Namespace to perform the tests" )
1308+ _ = k8sClient .Delete (ctx , namespace )
1309+ })
1310+
1311+ cr , err := readDefaultCR (crName , ns )
1312+ It ("should read default cr.yaml" , func () {
1313+ Expect (err ).NotTo (HaveOccurred ())
1314+ })
1315+
1316+ cr .Default ()
1317+
1318+ It ("should create PerconaPGCluster" , func () {
1319+ Expect (k8sClient .Create (ctx , cr )).Should (Succeed ())
1320+ })
1321+
1322+ checkSecretProjection := func (cr * v2.PerconaPGCluster , projection * corev1.SecretProjection , secretName string , neededKeys []string ) {
1323+ GinkgoHelper ()
1324+ It ("should fail if secret doesn't exist" , func () {
1325+ projection .Name = secretName
1326+
1327+ err := reconciler (cr ).validateTLS (ctx , cr )
1328+ Expect (err ).To (HaveOccurred ())
1329+ })
1330+ It ("should fail if secret doesn't have needed data" , func () {
1331+ secret := & corev1.Secret {
1332+ ObjectMeta : metav1.ObjectMeta {
1333+ Name : secretName ,
1334+ Namespace : cr .Namespace ,
1335+ },
1336+ }
1337+ Expect (k8sClient .Create (ctx , secret )).NotTo (HaveOccurred ())
1338+
1339+ err := reconciler (cr ).validateTLS (ctx , cr )
1340+ Expect (err ).To (HaveOccurred ())
1341+ })
1342+
1343+ It ("should not fail if needed keys specified in the secret" , func () {
1344+ secret := new (corev1.Secret )
1345+ Expect (k8sClient .Get (ctx , types.NamespacedName {
1346+ Name : secretName ,
1347+ Namespace : cr .Namespace ,
1348+ }, secret )).NotTo (HaveOccurred ())
1349+ secret .Data = make (map [string ][]byte )
1350+ for _ , v := range neededKeys {
1351+ secret .Data [v ] = []byte ("some-data" )
1352+ }
1353+ Expect (k8sClient .Update (ctx , secret )).NotTo (HaveOccurred ())
1354+
1355+ err := reconciler (cr ).validateTLS (ctx , cr )
1356+ Expect (err ).NotTo (HaveOccurred ())
1357+ })
1358+
1359+ It ("should not fail if wrong items.path are specified but needed key exist in secrets" , func () {
1360+ projection .Items = []corev1.KeyToPath {}
1361+ for i , v := range neededKeys {
1362+ projection .Items = append (projection .Items , corev1.KeyToPath {
1363+ Key : v ,
1364+ Path : "wrong-path" + "-" + strconv .Itoa (i ),
1365+ })
1366+ }
1367+
1368+ err := reconciler (cr ).validateTLS (ctx , cr )
1369+ Expect (err ).NotTo (HaveOccurred ())
1370+ })
1371+
1372+ It ("should fail if items.key are specified which don't exist in the secret" , func () {
1373+ projection .Items = []corev1.KeyToPath {}
1374+ for i , v := range neededKeys {
1375+ projection .Items = append (projection .Items , corev1.KeyToPath {
1376+ Key : "non-existent-key" + strconv .Itoa (i ),
1377+ Path : v ,
1378+ })
1379+ }
1380+ err := reconciler (cr ).validateTLS (ctx , cr )
1381+ Expect (err ).To (HaveOccurred ())
1382+ })
1383+
1384+ It ("should not fail if wrong items.path are specified but needed key exist in secrets" , func () {
1385+ projection .Items = []corev1.KeyToPath {}
1386+ for _ , v := range neededKeys {
1387+ projection .Items = append (projection .Items , corev1.KeyToPath {
1388+ Key : v ,
1389+ Path : v + "-wrong" ,
1390+ })
1391+ }
1392+
1393+ err := reconciler (cr ).validateTLS (ctx , cr )
1394+ Expect (err ).NotTo (HaveOccurred ())
1395+ })
1396+
1397+ It ("should not fail with custom data keys in the secret" , func () {
1398+ secret := new (corev1.Secret )
1399+ Expect (k8sClient .Get (ctx , types.NamespacedName {
1400+ Name : secretName ,
1401+ Namespace : cr .Namespace ,
1402+ }, secret )).NotTo (HaveOccurred ())
1403+
1404+ secret .Data = map [string ][]byte {}
1405+ for _ , v := range neededKeys {
1406+ secret .Data [v + "-custom" ] = []byte ("some-data" )
1407+ }
1408+ Expect (k8sClient .Update (ctx , secret )).NotTo (HaveOccurred ())
1409+ projection .Items = []corev1.KeyToPath {}
1410+ for _ , v := range neededKeys {
1411+ projection .Items = append (projection .Items , corev1.KeyToPath {
1412+ Key : v + "-custom" ,
1413+ Path : v ,
1414+ })
1415+ }
1416+
1417+ err := reconciler (cr ).validateTLS (ctx , cr )
1418+ Expect (err ).NotTo (HaveOccurred ())
1419+ })
1420+
1421+ It ("should fail if items.key are specified but not paths" , func () {
1422+ projection .Items = []corev1.KeyToPath {}
1423+ for _ , v := range neededKeys {
1424+ projection .Items = append (projection .Items , corev1.KeyToPath {
1425+ Key : v ,
1426+ })
1427+ }
1428+
1429+ err := reconciler (cr ).validateTLS (ctx , cr )
1430+ Expect (err ).To (HaveOccurred ())
1431+ })
1432+ }
1433+
1434+ Context ("checking validation" , func () {
1435+ Describe ("should check validation for cr.Spec.Secrets.CustomRootCATLSSecret" , func () {
1436+ cr := cr .DeepCopy ()
1437+ neededKeys := []string {
1438+ "root.crt" ,
1439+ "root.key" ,
1440+ }
1441+ cr .Spec .Secrets .CustomRootCATLSSecret = new (corev1.SecretProjection )
1442+ checkSecretProjection (cr , cr .Spec .Secrets .CustomRootCATLSSecret , "root-ca" , neededKeys )
1443+ It ("should not fail if the section was not specified" , func () {
1444+ cr .Spec .Secrets .CustomRootCATLSSecret = nil
1445+ err := reconciler (cr ).validateTLS (ctx , cr )
1446+ Expect (err ).NotTo (HaveOccurred ())
1447+ })
1448+ })
1449+ Describe ("should check validation for cr.Spec.Secrets.CustomTLSSecret" , func () {
1450+ cr := cr .DeepCopy ()
1451+ neededKeys := []string {
1452+ "ca.crt" ,
1453+ "tls.crt" ,
1454+ "tls.key" ,
1455+ }
1456+ cr .Spec .Secrets .CustomTLSSecret = new (corev1.SecretProjection )
1457+ checkSecretProjection (cr , cr .Spec .Secrets .CustomTLSSecret , "tls-secret" , neededKeys )
1458+ It ("should not fail if the section was not specified" , func () {
1459+ cr .Spec .Secrets .CustomTLSSecret = nil
1460+ err := reconciler (cr ).validateTLS (ctx , cr )
1461+ Expect (err ).NotTo (HaveOccurred ())
1462+ })
1463+ })
1464+ Describe ("should check validation for cr.Spec.Secrets.CustomReplicationClientTLSSecret" , func () {
1465+ cr := cr .DeepCopy ()
1466+ neededKeys := []string {
1467+ "ca.crt" ,
1468+ "tls.crt" ,
1469+ "tls.key" ,
1470+ }
1471+ cr .Spec .Secrets .CustomReplicationClientTLSSecret = new (corev1.SecretProjection )
1472+ checkSecretProjection (cr , cr .Spec .Secrets .CustomReplicationClientTLSSecret , "repl-tls-secret" , neededKeys )
1473+ It ("should not fail if the section was not specified" , func () {
1474+ cr .Spec .Secrets .CustomReplicationClientTLSSecret = nil
1475+ err := reconciler (cr ).validateTLS (ctx , cr )
1476+ Expect (err ).NotTo (HaveOccurred ())
1477+ })
1478+ })
1479+ })
1480+
1481+ checkSecretProjectionWithCA := func (cr * v2.PerconaPGCluster , projection * corev1.SecretProjection , secretName string ) {
1482+ GinkgoHelper ()
1483+ neededKeys := []string {
1484+ "tls.crt" ,
1485+ "tls.key" ,
1486+ }
1487+ projection .Name = secretName
1488+ It ("should create secret" , func () {
1489+ secret := & corev1.Secret {
1490+ ObjectMeta : metav1.ObjectMeta {
1491+ Name : secretName ,
1492+ Namespace : cr .Namespace ,
1493+ },
1494+ }
1495+ secret .Data = map [string ][]byte {}
1496+ for _ , v := range neededKeys {
1497+ secret .Data [v ] = []byte ("some-data" )
1498+ }
1499+ Expect (k8sClient .Create (ctx , secret )).NotTo (HaveOccurred ())
1500+ })
1501+ It ("should fail when CA is not specified" , func () {
1502+ err := reconciler (cr ).validateTLS (ctx , cr )
1503+ Expect (err ).To (HaveOccurred ())
1504+ })
1505+ It ("should not fail when CA is specified" , func () {
1506+ secretName := secretName + "-ca"
1507+ neededKeys := []string {
1508+ "root.crt" ,
1509+ "root.key" ,
1510+ }
1511+ cr .Spec .Secrets .CustomRootCATLSSecret = new (corev1.SecretProjection )
1512+ projection := cr .Spec .Secrets .CustomRootCATLSSecret
1513+ projection .Name = secretName
1514+ secret := & corev1.Secret {
1515+ ObjectMeta : metav1.ObjectMeta {
1516+ Name : secretName ,
1517+ Namespace : cr .Namespace ,
1518+ },
1519+ }
1520+ secret .Data = make (map [string ][]byte )
1521+ for _ , v := range neededKeys {
1522+ secret .Data [v ] = []byte ("some-data" )
1523+ }
1524+ Expect (k8sClient .Create (ctx , secret )).NotTo (HaveOccurred ())
1525+
1526+ err := reconciler (cr ).validateTLS (ctx , cr )
1527+ Expect (err ).NotTo (HaveOccurred ())
1528+ })
1529+ }
1530+ Context ("check validation for cr.Spec.Secrets.CustomTLSSecret when cr.Spec.Secrets.CustomRootCATLSSecret is specified" , func () {
1531+ cr := cr .DeepCopy ()
1532+ secretName := "custom-tls-secret-with-ca" //nolint:gosec
1533+ cr .Spec .Secrets .CustomTLSSecret = new (corev1.SecretProjection )
1534+ checkSecretProjectionWithCA (cr , cr .Spec .Secrets .CustomTLSSecret , secretName )
1535+ })
1536+ Context ("should check validation for cr.Spec.Secrets.CustomReplicationClientTLSSecret when cr.Spec.Secrets.CustomRootCATLSSecret is specified" , func () {
1537+ cr := cr .DeepCopy ()
1538+ secretName := "custom-replication-tls-secret-with-ca" //nolint:gosec
1539+ cr .Spec .Secrets .CustomReplicationClientTLSSecret = new (corev1.SecretProjection )
1540+ checkSecretProjectionWithCA (cr , cr .Spec .Secrets .CustomReplicationClientTLSSecret , secretName )
1541+ })
1542+ })
0 commit comments