@@ -248,6 +248,147 @@ func TestWebhookSupport(t *testing.T) {
248248 }, res .Object ["spec" ])
249249}
250250
251+ func TestClusterExtensionConfigSupport (t * testing.T ) {
252+ t .Log ("Test support for cluster extension config" )
253+ defer utils .CollectTestArtifacts (t , artifactName , c , cfg )
254+
255+ t .Log ("By creating install namespace, watch namespace and necessary rbac resources" )
256+ namespace := corev1.Namespace {
257+ ObjectMeta : metav1.ObjectMeta {
258+ Name : "test-operator" ,
259+ },
260+ }
261+ require .NoError (t , c .Create (t .Context (), & namespace ))
262+ t .Cleanup (func () {
263+ require .NoError (t , c .Delete (context .Background (), & namespace ))
264+ })
265+
266+ watchNamespace := corev1.Namespace {
267+ ObjectMeta : metav1.ObjectMeta {
268+ Name : "test-operator-watch" ,
269+ },
270+ }
271+ require .NoError (t , c .Create (t .Context (), & watchNamespace ))
272+ t .Cleanup (func () {
273+ require .NoError (t , c .Delete (context .Background (), & watchNamespace ))
274+ })
275+
276+ serviceAccount := corev1.ServiceAccount {
277+ ObjectMeta : metav1.ObjectMeta {
278+ Name : "test-operator-installer" ,
279+ Namespace : namespace .GetName (),
280+ },
281+ }
282+ require .NoError (t , c .Create (t .Context (), & serviceAccount ))
283+ t .Cleanup (func () {
284+ require .NoError (t , c .Delete (context .Background (), & serviceAccount ))
285+ })
286+
287+ clusterRoleBinding := & rbacv1.ClusterRoleBinding {
288+ ObjectMeta : metav1.ObjectMeta {
289+ Name : "test-operator-installer" ,
290+ },
291+ Subjects : []rbacv1.Subject {
292+ {
293+ Kind : "ServiceAccount" ,
294+ APIGroup : corev1 .GroupName ,
295+ Name : serviceAccount .GetName (),
296+ Namespace : serviceAccount .GetNamespace (),
297+ },
298+ },
299+ RoleRef : rbacv1.RoleRef {
300+ APIGroup : rbacv1 .GroupName ,
301+ Kind : "ClusterRole" ,
302+ Name : "cluster-admin" ,
303+ },
304+ }
305+ require .NoError (t , c .Create (t .Context (), clusterRoleBinding ))
306+ t .Cleanup (func () {
307+ require .NoError (t , c .Delete (context .Background (), clusterRoleBinding ))
308+ })
309+
310+ t .Log ("By creating the test-operator ClusterCatalog" )
311+ extensionCatalog := & ocv1.ClusterCatalog {
312+ ObjectMeta : metav1.ObjectMeta {
313+ Name : "test-operator-catalog" ,
314+ },
315+ Spec : ocv1.ClusterCatalogSpec {
316+ Source : ocv1.CatalogSource {
317+ Type : ocv1 .SourceTypeImage ,
318+ Image : & ocv1.ImageSource {
319+ Ref : fmt .Sprintf ("%s/e2e/test-catalog:v1" , os .Getenv ("CLUSTER_REGISTRY_HOST" )),
320+ PollIntervalMinutes : ptr .To (1 ),
321+ },
322+ },
323+ },
324+ }
325+ require .NoError (t , c .Create (t .Context (), extensionCatalog ))
326+ t .Cleanup (func () {
327+ require .NoError (t , c .Delete (context .Background (), extensionCatalog ))
328+ })
329+
330+ t .Log ("By waiting for the catalog to serve its metadata" )
331+ require .EventuallyWithT (t , func (ct * assert.CollectT ) {
332+ require .NoError (ct , c .Get (context .Background (), types.NamespacedName {Name : extensionCatalog .GetName ()}, extensionCatalog ))
333+ cond := apimeta .FindStatusCondition (extensionCatalog .Status .Conditions , ocv1 .TypeServing )
334+ require .NotNil (ct , cond )
335+ require .Equal (ct , metav1 .ConditionTrue , cond .Status )
336+ require .Equal (ct , ocv1 .ReasonAvailable , cond .Reason )
337+ }, pollDuration , pollInterval )
338+
339+ t .Log ("By installing the test-operator ClusterExtension configured in SingleNamespace mode" )
340+ clusterExtension := & ocv1.ClusterExtension {
341+ ObjectMeta : metav1.ObjectMeta {
342+ Name : "test-operator-extension" ,
343+ },
344+ Spec : ocv1.ClusterExtensionSpec {
345+ Source : ocv1.SourceConfig {
346+ SourceType : "Catalog" ,
347+ Catalog : & ocv1.CatalogFilter {
348+ PackageName : "test" ,
349+ Selector : & metav1.LabelSelector {
350+ MatchLabels : map [string ]string {"olm.operatorframework.io/metadata.name" : extensionCatalog .Name },
351+ },
352+ },
353+ },
354+ Namespace : namespace .GetName (),
355+ ServiceAccount : ocv1.ServiceAccountReference {
356+ Name : serviceAccount .GetName (),
357+ },
358+ Config : & ocv1.ClusterExtensionConfig {
359+ ConfigType : ocv1 .ClusterExtensionConfigTypeInline ,
360+ Inline : & apiextensionsv1.JSON {
361+ Raw : []byte (fmt .Sprintf (`{"watchNamespace": "%s"}` , watchNamespace .GetName ())),
362+ },
363+ },
364+ },
365+ }
366+ require .NoError (t , c .Create (t .Context (), clusterExtension ))
367+ t .Cleanup (func () {
368+ require .NoError (t , c .Delete (context .Background (), clusterExtension ))
369+ })
370+
371+ t .Log ("By waiting for test-operator extension to be installed successfully" )
372+ require .EventuallyWithT (t , func (ct * assert.CollectT ) {
373+ require .NoError (ct , c .Get (t .Context (), types.NamespacedName {Name : clusterExtension .Name }, clusterExtension ))
374+ cond := apimeta .FindStatusCondition (clusterExtension .Status .Conditions , ocv1 .TypeInstalled )
375+ require .NotNil (ct , cond )
376+ require .Equal (ct , metav1 .ConditionTrue , cond .Status )
377+ require .Equal (ct , ocv1 .ReasonSucceeded , cond .Reason )
378+ require .Contains (ct , cond .Message , "Installed bundle" )
379+ require .NotNil (ct , clusterExtension .Status .Install )
380+ require .NotEmpty (ct , clusterExtension .Status .Install .Bundle )
381+ }, pollDuration , pollInterval )
382+
383+ t .Log ("By ensuring the test-operator deployment is correctly configured to watch the watch namespace" )
384+ require .EventuallyWithT (t , func (ct * assert.CollectT ) {
385+ deployment := & appsv1.Deployment {}
386+ require .NoError (ct , c .Get (t .Context (), types.NamespacedName {Namespace : namespace .GetName (), Name : "test-operator" }, deployment ))
387+ require .NotNil (ct , deployment .Spec .Template .GetAnnotations ())
388+ require .Equal (ct , watchNamespace .GetName (), deployment .Spec .Template .GetAnnotations ()["olm.targetNamespaces" ])
389+ }, pollDuration , pollInterval )
390+ }
391+
251392func getWebhookOperatorResource (name string , namespace string , valid bool ) * unstructured.Unstructured {
252393 return & unstructured.Unstructured {
253394 Object : map [string ]interface {}{
0 commit comments