@@ -17,13 +17,18 @@ package controllers
17
17
18
18
import (
19
19
"context"
20
+ "crypto/x509"
21
+ "encoding/pem"
22
+ "fmt"
20
23
"io/ioutil"
24
+ "os"
21
25
"strings"
22
26
"time"
23
27
24
28
"github.com/go-logr/logr"
25
29
"github.com/onsi/gomega/format"
26
30
netv1 "k8s.io/api/networking/v1"
31
+ rbacv1 "k8s.io/api/rbac/v1"
27
32
"k8s.io/apimachinery/pkg/api/resource"
28
33
29
34
. "github.com/onsi/ginkgo"
@@ -161,6 +166,78 @@ var _ = Describe("The Openshift Notebook controller", func() {
161
166
162
167
})
163
168
169
+ // New test case for RoleBinding reconciliation
170
+ When ("Reconcile RoleBindings is called for a Notebook" , func () {
171
+ const (
172
+ name = "test-notebook-rolebinding"
173
+ namespace = "default"
174
+ )
175
+ notebook := createNotebook (name , namespace )
176
+
177
+ // Define the role and role-binding names and types used in the reconciliation
178
+ roleRefName := "ds-pipeline-user-access-dspa"
179
+ roleBindingName := "elyra-pipelines-" + name
180
+
181
+ BeforeEach (func () {
182
+ // Skip the tests if SET_PIPELINE_RBAC is not set to "true"
183
+ fmt .Printf ("SET_PIPELINE_RBAC is: %s\n " , os .Getenv ("SET_PIPELINE_RBAC" ))
184
+ if os .Getenv ("SET_PIPELINE_RBAC" ) != "true" {
185
+ Skip ("Skipping RoleBinding reconciliation tests as SET_PIPELINE_RBAC is not set to 'true'" )
186
+ }
187
+ })
188
+
189
+ It ("Should create a RoleBinding when the referenced Role exists" , func () {
190
+ ctx := context .Background ()
191
+
192
+ By ("Creating a Notebook and ensuring the Role exists" )
193
+ Expect (cli .Create (ctx , notebook )).Should (Succeed ())
194
+ time .Sleep (interval )
195
+
196
+ // Simulate the Role required by RoleBinding
197
+ role := & rbacv1.Role {
198
+ ObjectMeta : metav1.ObjectMeta {
199
+ Name : roleRefName ,
200
+ Namespace : namespace ,
201
+ },
202
+ }
203
+ Expect (cli .Create (ctx , role )).Should (Succeed ())
204
+ defer func () {
205
+ if err := cli .Delete (ctx , role ); err != nil {
206
+ GinkgoT ().Logf ("Failed to delete Role: %v" , err )
207
+ }
208
+ }()
209
+
210
+ By ("Checking that the RoleBinding is created" )
211
+ roleBinding := & rbacv1.RoleBinding {}
212
+ Eventually (func () error {
213
+ return cli .Get (ctx , types.NamespacedName {Name : roleBindingName , Namespace : namespace }, roleBinding )
214
+ }, duration , interval ).Should (Succeed ())
215
+
216
+ Expect (roleBinding .RoleRef .Name ).To (Equal (roleRefName ))
217
+ Expect (roleBinding .Subjects [0 ].Name ).To (Equal (name ))
218
+ Expect (roleBinding .Subjects [0 ].Kind ).To (Equal ("ServiceAccount" ))
219
+ })
220
+
221
+ It ("Should delete the RoleBinding when the Notebook is deleted" , func () {
222
+ ctx := context .Background ()
223
+
224
+ By ("Ensuring the RoleBinding exists" )
225
+ roleBinding := & rbacv1.RoleBinding {}
226
+ Eventually (func () error {
227
+ return cli .Get (ctx , types.NamespacedName {Name : roleBindingName , Namespace : namespace }, roleBinding )
228
+ }, duration , interval ).Should (Succeed ())
229
+
230
+ By ("Deleting the Notebook" )
231
+ Expect (cli .Delete (ctx , notebook )).Should (Succeed ())
232
+
233
+ By ("Ensuring the RoleBinding is deleted" )
234
+ Eventually (func () error {
235
+ return cli .Get (ctx , types.NamespacedName {Name : roleBindingName , Namespace : namespace }, roleBinding )
236
+ }, duration , interval ).Should (Succeed ())
237
+ })
238
+
239
+ })
240
+
164
241
// New test case for notebook creation
165
242
When ("Creating a Notebook, test certificate is mounted" , func () {
166
243
const (
@@ -230,6 +307,12 @@ var _ = Describe("The Openshift Notebook controller", func() {
230
307
}
231
308
// Check if the volume is present and matches the expected one
232
309
Expect (notebook .Spec .Template .Spec .Volumes ).To (ContainElement (expectedVolume ))
310
+
311
+ // Check the content in workbench-trusted-ca-bundle matches what we expect:
312
+ // - have 2 certificates there in ca-bundle.crt
313
+ // - both certificates are valid
314
+ configMapName := "workbench-trusted-ca-bundle"
315
+ checkCertConfigMap (ctx , notebook .Namespace , configMapName , "ca-bundle.crt" , 2 )
233
316
})
234
317
235
318
})
@@ -329,6 +412,12 @@ var _ = Describe("The Openshift Notebook controller", func() {
329
412
},
330
413
}
331
414
Expect (notebook .Spec .Template .Spec .Volumes ).To (ContainElement (expectedVolume ))
415
+
416
+ // Check the content in workbench-trusted-ca-bundle matches what we expect:
417
+ // - have 2 certificates there in ca-bundle.crt
418
+ // - both certificates are valid
419
+ configMapName := "workbench-trusted-ca-bundle"
420
+ checkCertConfigMap (ctx , notebook .Namespace , configMapName , "ca-bundle.crt" , 2 )
332
421
})
333
422
})
334
423
@@ -594,21 +683,23 @@ var _ = Describe("The Openshift Notebook controller", func() {
594
683
}, duration , interval ).Should (BeTrue ())
595
684
})
596
685
597
- It ("Should reconcile the Notebook when modified" , func () {
598
- By ("By simulating a manual Notebook modification" )
599
- notebook .Spec .Template .Spec .ServiceAccountName = "foo"
600
- notebook .Spec .Template .Spec .Containers [1 ].Image = "bar"
601
- notebook .Spec .Template .Spec .Volumes [1 ].VolumeSource = corev1.VolumeSource {}
602
- Expect (cli .Update (ctx , notebook )).Should (Succeed ())
603
- time .Sleep (interval )
604
-
605
- By ("By checking that the webhook has restored the Notebook spec" )
606
- Eventually (func () error {
607
- key := types.NamespacedName {Name : Name , Namespace : Namespace }
608
- return cli .Get (ctx , key , notebook )
609
- }, duration , interval ).Should (Succeed ())
610
- Expect (CompareNotebooks (* notebook , expectedNotebook )).Should (BeTrue ())
611
- })
686
+ // RHOAIENG-14552: We *do not* reconcile OAuth in the notebook when it's modified
687
+
688
+ //It("Should reconcile the Notebook when modified", func() {
689
+ // By("By simulating a manual Notebook modification")
690
+ // notebook.Spec.Template.Spec.ServiceAccountName = "foo"
691
+ // notebook.Spec.Template.Spec.Containers[1].Image = "bar"
692
+ // notebook.Spec.Template.Spec.Volumes[1].VolumeSource = corev1.VolumeSource{}
693
+ // Expect(cli.Update(ctx, notebook)).Should(Succeed())
694
+ // time.Sleep(interval)
695
+ //
696
+ // By("By checking that the webhook has restored the Notebook spec")
697
+ // Eventually(func() error {
698
+ // key := types.NamespacedName{Name: Name, Namespace: Namespace}
699
+ // return cli.Get(ctx, key, notebook)
700
+ // }, duration, interval).Should(Succeed())
701
+ // Expect(CompareNotebooks(*notebook, expectedNotebook)).Should(BeTrue())
702
+ //})
612
703
613
704
serviceAccount := & corev1.ServiceAccount {}
614
705
expectedServiceAccount := createOAuthServiceAccount (Name , Namespace )
@@ -1039,3 +1130,32 @@ func createOAuthConfigmap(name, namespace string, label map[string]string, confi
1039
1130
Data : configMapData ,
1040
1131
}
1041
1132
}
1133
+
1134
+ // checkCertConfigMap checks the content of a config map defined by the name and namespace
1135
+ // It triest to parse the given certFileName and checks that all certificates can be parsed there and that the number of the certificates matches what we expect.
1136
+ func checkCertConfigMap (ctx context.Context , namespace string , configMapName string , certFileName string , expNumberCerts int ) {
1137
+ configMap := & corev1.ConfigMap {}
1138
+ key := types.NamespacedName {Namespace : namespace , Name : configMapName }
1139
+ Expect (cli .Get (ctx , key , configMap )).Should (Succeed ())
1140
+
1141
+ // Attempt to decode PEM encoded certificates so we are sure all are readable as expected
1142
+ certData := configMap .Data [certFileName ]
1143
+ certDataByte := []byte (certData )
1144
+ certificatesFound := 0
1145
+ for len (certDataByte ) > 0 {
1146
+ block , remainder := pem .Decode (certDataByte )
1147
+ certDataByte = remainder
1148
+
1149
+ if block == nil {
1150
+ break
1151
+ }
1152
+
1153
+ if block .Type == "CERTIFICATE" {
1154
+ // Attempt to parse the certificate
1155
+ _ , err := x509 .ParseCertificate (block .Bytes )
1156
+ Expect (err ).ShouldNot (HaveOccurred ())
1157
+ certificatesFound ++
1158
+ }
1159
+ }
1160
+ Expect (certificatesFound ).Should (Equal (expNumberCerts ), "Number of parsed certificates don't match expected one:\n " + certData )
1161
+ }
0 commit comments