@@ -10,6 +10,7 @@ import (
1010 "encoding/json"
1111 "fmt"
1212 "io"
13+ "log"
1314 "net/url"
1415 "path/filepath"
1516
@@ -35,7 +36,8 @@ type LogEntry struct {
3536}
3637
3738type IstioCSRConfig struct {
38- ClusterID string
39+ ClusterID string
40+ IstioDataPlaneNamespaceSelector string
3941}
4042
4143var _ = Describe ("Istio-CSR" , Ordered , Label ("Feature:IstioCSR" ), func () {
@@ -98,6 +100,27 @@ var _ = Describe("Istio-CSR", Ordered, Label("Feature:IstioCSR"), func() {
98100 Expect (err ).NotTo (HaveOccurred ())
99101 ns = namespace
100102
103+ By ("creating cluster issuer" )
104+ loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "cluster_issuer.yaml" ), ns .Name )
105+ DeferCleanup (func () {
106+ loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "cluster_issuer.yaml" ), ns .Name )
107+ })
108+
109+ By ("issuing TLS certificate" )
110+ loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "certificate.yaml" ), ns .Name )
111+ DeferCleanup (func () {
112+ loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "certificate.yaml" ), ns .Name )
113+ })
114+
115+ err = waitForCertificateReadiness (ctx , "my-selfsigned-ca" , ns .Name )
116+ Expect (err ).NotTo (HaveOccurred ())
117+
118+ By ("creating istio-ca issuer" )
119+ loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "istio" , "istio_ca_issuer.yaml" ), ns .Name )
120+ DeferCleanup (func () {
121+ loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "istio" , "istio_ca_issuer.yaml" ), ns .Name )
122+ })
123+
101124 DeferCleanup (func () {
102125 By ("deleting cluster-scoped RBAC resources of the istio-csr agent" )
103126 clientset .RbacV1 ().ClusterRoles ().DeleteCollection (ctx , metav1.DeleteOptions {}, metav1.ListOptions {
@@ -114,21 +137,6 @@ var _ = Describe("Istio-CSR", Ordered, Label("Feature:IstioCSR"), func() {
114137
115138 Context ("grpc call istio.v1.auth.IstioCertificateService/CreateCertificate to istio-csr agent" , func () {
116139 BeforeEach (func () {
117- By ("creating cluster issuer" )
118- loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "cluster_issuer.yaml" ), ns .Name )
119- DeferCleanup (func () {
120- loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "cluster_issuer.yaml" ), ns .Name )
121- })
122-
123- By ("issuing TLS certificate" )
124- loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "certificate.yaml" ), ns .Name )
125- DeferCleanup (func () {
126- loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "self_signed" , "certificate.yaml" ), ns .Name )
127- })
128-
129- err := waitForCertificateReadiness (ctx , "my-selfsigned-ca" , ns .Name )
130- Expect (err ).NotTo (HaveOccurred ())
131-
132140 By ("fetching proto file from api" )
133141 protoContent , err := library .FetchFileFromURL (istioCSRProtoURL )
134142 Expect (err ).Should (BeNil ())
@@ -149,21 +157,19 @@ var _ = Describe("Istio-CSR", Ordered, Label("Feature:IstioCSR"), func() {
149157 DeferCleanup (func () {
150158 clientset .CoreV1 ().ConfigMaps (ns .Name ).Delete (ctx , configMap .Name , metav1.DeleteOptions {})
151159 })
152-
153- By ("creating istio-ca issuer" )
154- loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "istio" , "istio_ca_issuer.yaml" ), ns .Name )
155- DeferCleanup (func () {
156- loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "istio" , "istio_ca_issuer.yaml" ), ns .Name )
157- })
158160 })
159161
160162 It ("should return cert-chain as response" , func () {
161163 serviceAccountName := "cert-manager-istio-csr"
162164 grpcAppName := "grpcurl-istio-csr"
163165
164166 By ("creating istiocsr.operator.openshift.io resource" )
165- loader .CreateFromFile (testassets .ReadFile , filepath .Join ("testdata" , "istio" , "istio_csr.yaml" ), ns .Name )
166- defer loader .DeleteFromFile (testassets .ReadFile , filepath .Join ("testdata" , "istio" , "istio_csr.yaml" ), ns .Name )
167+ loader .CreateFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
168+ IstioCSRConfig {},
169+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template.yaml" ), ns .Name )
170+ defer loader .DeleteFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
171+ IstioCSRConfig {},
172+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template.yaml" ), ns .Name )
167173
168174 istioCSRStatus := waitForIstioCSRReady (ns )
169175
@@ -231,12 +237,12 @@ var _ = Describe("Istio-CSR", Ordered, Label("Feature:IstioCSR"), func() {
231237 IstioCSRConfig {
232238 ClusterID : clusterName ,
233239 },
234- ), filepath .Join ("testdata" , "istio" , "istio_csr_custom_cluster_id .yaml" ), ns .Name )
240+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template .yaml" ), ns .Name )
235241 defer loader .DeleteFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
236242 IstioCSRConfig {
237243 ClusterID : clusterName ,
238244 },
239- ), filepath .Join ("testdata" , "istio" , "istio_csr_custom_cluster_id .yaml" ), ns .Name )
245+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template .yaml" ), ns .Name )
240246
241247 istioCSRStatus := waitForIstioCSRReady (ns )
242248
@@ -299,12 +305,12 @@ var _ = Describe("Istio-CSR", Ordered, Label("Feature:IstioCSR"), func() {
299305 IstioCSRConfig {
300306 ClusterID : clusterName ,
301307 },
302- ), filepath .Join ("testdata" , "istio" , "istio_csr_custom_cluster_id .yaml" ), ns .Name )
308+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template .yaml" ), ns .Name )
303309 defer loader .DeleteFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
304310 IstioCSRConfig {
305311 ClusterID : clusterName ,
306312 },
307- ), filepath .Join ("testdata" , "istio" , "istio_csr_custom_cluster_id .yaml" ), ns .Name )
313+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template .yaml" ), ns .Name )
308314
309315 istioCSRStatus := waitForIstioCSRReady (ns )
310316
@@ -348,4 +354,145 @@ var _ = Describe("Istio-CSR", Ordered, Label("Feature:IstioCSR"), func() {
348354 Expect (succeededPodName ).Should (BeEmpty (), "Job should have failed due to wrong clusterID" )
349355 })
350356 })
357+
358+ Context ("istioDataPlaneNamespaceSelector functionality" , func () {
359+ var testNamespaces []* corev1.Namespace
360+
361+ BeforeEach (func () {
362+ By ("creating test namespaces with different labels" )
363+ namespacesToCreate := []* corev1.Namespace {
364+ {
365+ ObjectMeta : metav1.ObjectMeta {
366+ GenerateName : "ca-injection-enabled-" ,
367+ Labels : map [string ]string {
368+ "cert-manager.io/test-ca-injection" : "enabled" , // matches the IstioCSR resource
369+ },
370+ },
371+ },
372+ {
373+ ObjectMeta : metav1.ObjectMeta {
374+ GenerateName : "ca-injection-disabled-" ,
375+ Labels : map [string ]string {
376+ "cert-manager.io/test-ca-injection" : "disabled" , // doesn't match the IstioCSR resource
377+ },
378+ },
379+ },
380+ {
381+ ObjectMeta : metav1.ObjectMeta {
382+ GenerateName : "ca-injection-unlabeled-" ,
383+ // no labels
384+ },
385+ },
386+ }
387+
388+ for _ , ns := range namespacesToCreate {
389+ createdNs , err := clientset .CoreV1 ().Namespaces ().Create (ctx , ns , metav1.CreateOptions {})
390+ Expect (err ).Should (BeNil ())
391+ testNamespaces = append (testNamespaces , createdNs )
392+ }
393+
394+ DeferCleanup (func () {
395+ for _ , testNs := range testNamespaces {
396+ err := clientset .CoreV1 ().Namespaces ().Delete (ctx , testNs .Name , metav1.DeleteOptions {})
397+ Expect (err ).Should (BeNil ())
398+ }
399+ testNamespaces = []* corev1.Namespace {}
400+ })
401+ })
402+
403+ It ("should only create istio-ca-root-cert ConfigMap in namespaces matching the selector" , func () {
404+ By ("creating istiocsr.operator.openshift.io resource with istioDataPlaneNamespaceSelector" )
405+ loader .CreateFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
406+ IstioCSRConfig {
407+ IstioDataPlaneNamespaceSelector : "cert-manager.io/test-ca-injection=enabled" ,
408+ },
409+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template.yaml" ), ns .Name )
410+ defer loader .DeleteFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
411+ IstioCSRConfig {
412+ IstioDataPlaneNamespaceSelector : "cert-manager.io/test-ca-injection=enabled" ,
413+ },
414+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template.yaml" ), ns .Name )
415+
416+ By ("waiting for IstioCSR to be ready and deployment to be created" )
417+ istioCSRStatus := waitForIstioCSRReady (ns )
418+ log .Printf ("IstioCSR status: %+v" , istioCSRStatus )
419+
420+ By ("verifying ConfigMap creation based on namespace selector" )
421+ var matchingNs * corev1.Namespace
422+ for _ , testNs := range testNamespaces {
423+ labelValue , hasLabel := testNs .Labels ["cert-manager.io/test-ca-injection" ]
424+
425+ if hasLabel && labelValue == "enabled" {
426+ // This namespace should have the ConfigMap
427+ matchingNs = testNs
428+ err := pollTillConfigMapAvailable (ctx , clientset , testNs .Name , "istio-ca-root-cert" )
429+ Expect (err ).Should (BeNil (), fmt .Sprintf ("ConfigMap should exist in namespace %s (enabled)" , testNs .Name ))
430+ } else {
431+ // This namespace should NOT have the ConfigMap
432+ var reason string
433+ if ! hasLabel {
434+ reason = "unlabeled"
435+ } else {
436+ reason = fmt .Sprintf ("with %s label" , labelValue )
437+ }
438+
439+ err := pollTillConfigMapRemains (ctx , clientset , testNs .Name , "istio-ca-root-cert" , lowTimeout )
440+ Expect (err ).Should (BeNil (), fmt .Sprintf ("ConfigMap should NOT exist in namespace %s (%s)" , testNs .Name , reason ))
441+ }
442+ }
443+ Expect (matchingNs ).NotTo (BeNil (), "Should have found at least one namespace with enabled label" )
444+
445+ By ("verifying the ConfigMap contains the correct CA certificate data" )
446+ cm , err := clientset .CoreV1 ().ConfigMaps (matchingNs .Name ).Get (ctx , "istio-ca-root-cert" , metav1.GetOptions {})
447+ Expect (err ).Should (BeNil ())
448+ Expect (cm .Data ).Should (HaveKey ("root-cert.pem" ))
449+ Expect (cm .Data ["root-cert.pem" ]).ShouldNot (BeEmpty ())
450+
451+ By ("verifying ConfigMap exists in exactly 1 namespace (the one with matching label)" )
452+ configMapCount := 0
453+ for _ , testNs := range testNamespaces {
454+ _ , err := clientset .CoreV1 ().ConfigMaps (testNs .Name ).Get (ctx , "istio-ca-root-cert" , metav1.GetOptions {})
455+ if err == nil {
456+ configMapCount ++
457+ }
458+ }
459+ Expect (configMapCount ).Should (Equal (1 ), "ConfigMap should exist in exactly 1 namespace (the one with enabled label)" )
460+ })
461+
462+ It ("should create istio-ca-root-cert ConfigMap in all namespaces when istioDataPlaneNamespaceSelector is not set" , func () {
463+ By ("creating istiocsr.operator.openshift.io resource without istioDataPlaneNamespaceSelector" )
464+ loader .CreateFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
465+ IstioCSRConfig {},
466+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template.yaml" ), ns .Name )
467+ defer loader .DeleteFromFile (AssetFunc (testassets .ReadFile ).WithTemplateValues (
468+ IstioCSRConfig {},
469+ ), filepath .Join ("testdata" , "istio" , "istio_csr_template.yaml" ), ns .Name )
470+
471+ By ("waiting for IstioCSR to be ready and deployment to be created" )
472+ istioCSRStatus := waitForIstioCSRReady (ns )
473+ log .Printf ("IstioCSR status: %+v" , istioCSRStatus )
474+
475+ By ("waiting for istio-ca-root-cert ConfigMap to be created in all test namespaces" )
476+ for _ , testNs := range testNamespaces {
477+ err := pollTillConfigMapAvailable (ctx , clientset , testNs .Name , "istio-ca-root-cert" )
478+ Expect (err ).Should (BeNil (), fmt .Sprintf ("ConfigMap should be created in namespace %s" , testNs .Name ))
479+
480+ By (fmt .Sprintf ("verifying ConfigMap content in namespace %s" , testNs .Name ))
481+ cm , err := clientset .CoreV1 ().ConfigMaps (testNs .Name ).Get (ctx , "istio-ca-root-cert" , metav1.GetOptions {})
482+ Expect (err ).Should (BeNil ())
483+ Expect (cm .Data ).Should (HaveKey ("root-cert.pem" ))
484+ Expect (cm .Data ["root-cert.pem" ]).ShouldNot (BeEmpty ())
485+ }
486+
487+ By ("verifying ConfigMap exists in all 3 test namespaces when no selector is used" )
488+ configMapCount := 0
489+ for _ , testNs := range testNamespaces {
490+ _ , err := clientset .CoreV1 ().ConfigMaps (testNs .Name ).Get (ctx , "istio-ca-root-cert" , metav1.GetOptions {})
491+ if err == nil {
492+ configMapCount ++
493+ }
494+ }
495+ Expect (configMapCount ).Should (Equal (3 ), "ConfigMap should exist in all 3 test namespaces when no selector is configured" )
496+ })
497+ })
351498})
0 commit comments