Skip to content

Commit 443d7a2

Browse files
author
Per G. da Silva
committed
Update Single/OwnNamespace support e2e
Signed-off-by: Per G. da Silva <[email protected]>
1 parent a6909e9 commit 443d7a2

File tree

8 files changed

+621
-18
lines changed

8 files changed

+621
-18
lines changed

test/experimental-e2e/single_namespace_support_test.go

Lines changed: 203 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -55,14 +55,14 @@ func TestNoop(t *testing.T) {
5555
defer utils.CollectTestArtifacts(t, artifactName, c, cfg)
5656
}
5757

58-
func TestClusterExtensionConfigSupport(t *testing.T) {
58+
func TestClusterExtensionSingleNamespaceSupport(t *testing.T) {
5959
t.Log("Test support for cluster extension config")
6060
defer utils.CollectTestArtifacts(t, artifactName, c, cfg)
6161

6262
t.Log("By creating install namespace, watch namespace and necessary rbac resources")
6363
namespace := corev1.Namespace{
6464
ObjectMeta: metav1.ObjectMeta{
65-
Name: "test-operator",
65+
Name: "single-namespace-operator",
6666
},
6767
}
6868
require.NoError(t, c.Create(t.Context(), &namespace))
@@ -72,7 +72,7 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
7272

7373
watchNamespace := corev1.Namespace{
7474
ObjectMeta: metav1.ObjectMeta{
75-
Name: "test-operator-watch",
75+
Name: "single-namespace-operator-target",
7676
},
7777
}
7878
require.NoError(t, c.Create(t.Context(), &watchNamespace))
@@ -82,7 +82,7 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
8282

8383
serviceAccount := corev1.ServiceAccount{
8484
ObjectMeta: metav1.ObjectMeta{
85-
Name: "test-operator-installer",
85+
Name: "single-namespace-operator-installer",
8686
Namespace: namespace.GetName(),
8787
},
8888
}
@@ -93,7 +93,7 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
9393

9494
clusterRoleBinding := &rbacv1.ClusterRoleBinding{
9595
ObjectMeta: metav1.ObjectMeta{
96-
Name: "test-operator-installer",
96+
Name: "single-namespace-operator-installer",
9797
},
9898
Subjects: []rbacv1.Subject{
9999
{
@@ -114,10 +114,10 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
114114
require.NoError(t, c.Delete(context.Background(), clusterRoleBinding))
115115
})
116116

117-
t.Log("By creating the test-operator ClusterCatalog")
117+
t.Log("By creating the test-catalog ClusterCatalog")
118118
extensionCatalog := &ocv1.ClusterCatalog{
119119
ObjectMeta: metav1.ObjectMeta{
120-
Name: "test-operator-catalog",
120+
Name: "test-catalog",
121121
},
122122
Spec: ocv1.ClusterCatalogSpec{
123123
Source: ocv1.CatalogSource{
@@ -143,16 +143,16 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
143143
require.Equal(ct, ocv1.ReasonAvailable, cond.Reason)
144144
}, pollDuration, pollInterval)
145145

146-
t.Log("By installing the test-operator ClusterExtension configured in SingleNamespace mode")
146+
t.Log("By attempting to install the single-namespace-operator ClusterExtension without any configuration")
147147
clusterExtension := &ocv1.ClusterExtension{
148148
ObjectMeta: metav1.ObjectMeta{
149-
Name: "test-operator-extension",
149+
Name: "single-namespace-operator-extension",
150150
},
151151
Spec: ocv1.ClusterExtensionSpec{
152152
Source: ocv1.SourceConfig{
153153
SourceType: "Catalog",
154154
Catalog: &ocv1.CatalogFilter{
155-
PackageName: "test",
155+
PackageName: "single-namespace-operator",
156156
Selector: &metav1.LabelSelector{
157157
MatchLabels: map[string]string{"olm.operatorframework.io/metadata.name": extensionCatalog.Name},
158158
},
@@ -162,20 +162,205 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
162162
ServiceAccount: ocv1.ServiceAccountReference{
163163
Name: serviceAccount.GetName(),
164164
},
165-
Config: &ocv1.ClusterExtensionConfig{
166-
ConfigType: ocv1.ClusterExtensionConfigTypeInline,
167-
Inline: &apiextensionsv1.JSON{
168-
Raw: []byte(fmt.Sprintf(`{"watchNamespace": "%s"}`, watchNamespace.GetName())),
165+
},
166+
}
167+
require.NoError(t, c.Create(t.Context(), clusterExtension))
168+
t.Cleanup(func() {
169+
require.NoError(t, c.Delete(context.Background(), clusterExtension))
170+
})
171+
172+
t.Log("By waiting for single-namespace-operator extension installation to fail")
173+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
174+
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
175+
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1.TypeProgressing)
176+
require.NotNil(ct, cond)
177+
require.Equal(ct, metav1.ConditionTrue, cond.Status)
178+
require.Equal(ct, ocv1.ReasonRetrying, cond.Reason)
179+
require.Contains(ct, cond.Message, "required field \"watchNamespace\" is missing")
180+
}, pollDuration, pollInterval)
181+
182+
t.Log("By updating the ClusterExtension configuration with a watchNamespace")
183+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
184+
require.NoError(t, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.GetName()}, clusterExtension))
185+
clusterExtension.Spec.Config = &ocv1.ClusterExtensionConfig{
186+
ConfigType: ocv1.ClusterExtensionConfigTypeInline,
187+
Inline: &apiextensionsv1.JSON{
188+
Raw: []byte(fmt.Sprintf(`{"watchNamespace": "%s"}`, watchNamespace.GetName())),
189+
},
190+
}
191+
require.NoError(t, c.Update(t.Context(), clusterExtension))
192+
}, pollDuration, pollInterval)
193+
194+
t.Log("By waiting for single-namespace-operator extension to be installed successfully")
195+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
196+
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
197+
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1.TypeInstalled)
198+
require.NotNil(ct, cond)
199+
require.Equal(ct, metav1.ConditionTrue, cond.Status)
200+
require.Equal(ct, ocv1.ReasonSucceeded, cond.Reason)
201+
require.Contains(ct, cond.Message, "Installed bundle")
202+
require.NotNil(ct, clusterExtension.Status.Install)
203+
require.NotEmpty(ct, clusterExtension.Status.Install.Bundle)
204+
}, pollDuration, pollInterval)
205+
206+
t.Log("By ensuring the single-namespace-operator deployment is correctly configured to watch the watch namespace")
207+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
208+
deployment := &appsv1.Deployment{}
209+
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Namespace: namespace.GetName(), Name: "single-namespace-operator"}, deployment))
210+
require.NotNil(ct, deployment.Spec.Template.GetAnnotations())
211+
require.Equal(ct, watchNamespace.GetName(), deployment.Spec.Template.GetAnnotations()["olm.targetNamespaces"])
212+
}, pollDuration, pollInterval)
213+
}
214+
215+
func TestClusterExtensionOwnNamespaceSupport(t *testing.T) {
216+
t.Log("Test support for cluster extension with OwnNamespace install mode support")
217+
defer utils.CollectTestArtifacts(t, artifactName, c, cfg)
218+
219+
t.Log("By creating install namespace, watch namespace and necessary rbac resources")
220+
namespace := corev1.Namespace{
221+
ObjectMeta: metav1.ObjectMeta{
222+
Name: "own-namespace-operator",
223+
},
224+
}
225+
require.NoError(t, c.Create(t.Context(), &namespace))
226+
t.Cleanup(func() {
227+
require.NoError(t, c.Delete(context.Background(), &namespace))
228+
})
229+
230+
serviceAccount := corev1.ServiceAccount{
231+
ObjectMeta: metav1.ObjectMeta{
232+
Name: "own-namespace-operator-installer",
233+
Namespace: namespace.GetName(),
234+
},
235+
}
236+
require.NoError(t, c.Create(t.Context(), &serviceAccount))
237+
t.Cleanup(func() {
238+
require.NoError(t, c.Delete(context.Background(), &serviceAccount))
239+
})
240+
241+
clusterRoleBinding := &rbacv1.ClusterRoleBinding{
242+
ObjectMeta: metav1.ObjectMeta{
243+
Name: "own-namespace-operator-installer",
244+
},
245+
Subjects: []rbacv1.Subject{
246+
{
247+
Kind: "ServiceAccount",
248+
APIGroup: corev1.GroupName,
249+
Name: serviceAccount.GetName(),
250+
Namespace: serviceAccount.GetNamespace(),
251+
},
252+
},
253+
RoleRef: rbacv1.RoleRef{
254+
APIGroup: rbacv1.GroupName,
255+
Kind: "ClusterRole",
256+
Name: "cluster-admin",
257+
},
258+
}
259+
require.NoError(t, c.Create(t.Context(), clusterRoleBinding))
260+
t.Cleanup(func() {
261+
require.NoError(t, c.Delete(context.Background(), clusterRoleBinding))
262+
})
263+
264+
t.Log("By creating the test-catalog ClusterCatalog")
265+
extensionCatalog := &ocv1.ClusterCatalog{
266+
ObjectMeta: metav1.ObjectMeta{
267+
Name: "test-catalog",
268+
},
269+
Spec: ocv1.ClusterCatalogSpec{
270+
Source: ocv1.CatalogSource{
271+
Type: ocv1.SourceTypeImage,
272+
Image: &ocv1.ImageSource{
273+
Ref: fmt.Sprintf("%s/e2e/test-catalog:v1", os.Getenv("CLUSTER_REGISTRY_HOST")),
274+
PollIntervalMinutes: ptr.To(1),
275+
},
276+
},
277+
},
278+
}
279+
require.NoError(t, c.Create(t.Context(), extensionCatalog))
280+
t.Cleanup(func() {
281+
require.NoError(t, c.Delete(context.Background(), extensionCatalog))
282+
})
283+
284+
t.Log("By waiting for the catalog to serve its metadata")
285+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
286+
require.NoError(ct, c.Get(context.Background(), types.NamespacedName{Name: extensionCatalog.GetName()}, extensionCatalog))
287+
cond := apimeta.FindStatusCondition(extensionCatalog.Status.Conditions, ocv1.TypeServing)
288+
require.NotNil(ct, cond)
289+
require.Equal(ct, metav1.ConditionTrue, cond.Status)
290+
require.Equal(ct, ocv1.ReasonAvailable, cond.Reason)
291+
}, pollDuration, pollInterval)
292+
293+
t.Log("By attempting to install the own-namespace-operator ClusterExtension without any configuration")
294+
clusterExtension := &ocv1.ClusterExtension{
295+
ObjectMeta: metav1.ObjectMeta{
296+
Name: "own-namespace-operator-extension",
297+
},
298+
Spec: ocv1.ClusterExtensionSpec{
299+
Source: ocv1.SourceConfig{
300+
SourceType: "Catalog",
301+
Catalog: &ocv1.CatalogFilter{
302+
PackageName: "own-namespace-operator",
303+
Selector: &metav1.LabelSelector{
304+
MatchLabels: map[string]string{"olm.operatorframework.io/metadata.name": extensionCatalog.Name},
305+
},
169306
},
170307
},
308+
Namespace: namespace.GetName(),
309+
ServiceAccount: ocv1.ServiceAccountReference{
310+
Name: serviceAccount.GetName(),
311+
},
171312
},
172313
}
173314
require.NoError(t, c.Create(t.Context(), clusterExtension))
174315
t.Cleanup(func() {
175316
require.NoError(t, c.Delete(context.Background(), clusterExtension))
176317
})
177318

178-
t.Log("By waiting for test-operator extension to be installed successfully")
319+
t.Log("By waiting for own-namespace-operator extension installation to fail")
320+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
321+
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
322+
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1.TypeProgressing)
323+
require.NotNil(ct, cond)
324+
require.Equal(ct, metav1.ConditionTrue, cond.Status)
325+
require.Equal(ct, ocv1.ReasonRetrying, cond.Reason)
326+
require.Contains(ct, cond.Message, "required field \"watchNamespace\" is missing")
327+
}, pollDuration, pollInterval)
328+
329+
t.Log("By updating the ClusterExtension configuration with a watchNamespace other than the install namespace")
330+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
331+
require.NoError(t, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.GetName()}, clusterExtension))
332+
clusterExtension.Spec.Config = &ocv1.ClusterExtensionConfig{
333+
ConfigType: ocv1.ClusterExtensionConfigTypeInline,
334+
Inline: &apiextensionsv1.JSON{
335+
Raw: []byte(`{"watchNamespace": "some-namespace"}`),
336+
},
337+
}
338+
require.NoError(t, c.Update(t.Context(), clusterExtension))
339+
}, pollDuration, pollInterval)
340+
341+
t.Log("By waiting for own-namespace-operator extension installation to fail")
342+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
343+
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
344+
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1.TypeProgressing)
345+
require.NotNil(ct, cond)
346+
require.Equal(ct, metav1.ConditionTrue, cond.Status)
347+
require.Equal(ct, ocv1.ReasonRetrying, cond.Reason)
348+
require.Contains(ct, cond.Message, fmt.Sprintf("invalid 'watchNamespace' \"some-namespace\": must be install namespace (%s)", clusterExtension.Spec.Namespace))
349+
}, pollDuration, pollInterval)
350+
351+
t.Log("By updating the ClusterExtension configuration with a watchNamespace = install namespace")
352+
require.EventuallyWithT(t, func(ct *assert.CollectT) {
353+
require.NoError(t, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.GetName()}, clusterExtension))
354+
clusterExtension.Spec.Config = &ocv1.ClusterExtensionConfig{
355+
ConfigType: ocv1.ClusterExtensionConfigTypeInline,
356+
Inline: &apiextensionsv1.JSON{
357+
Raw: []byte(fmt.Sprintf(`{"watchNamespace": "%s"}`, clusterExtension.Spec.Namespace)),
358+
},
359+
}
360+
require.NoError(t, c.Update(t.Context(), clusterExtension))
361+
}, pollDuration, pollInterval)
362+
363+
t.Log("By waiting for own-namespace-operator extension to be installed successfully")
179364
require.EventuallyWithT(t, func(ct *assert.CollectT) {
180365
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Name: clusterExtension.Name}, clusterExtension))
181366
cond := apimeta.FindStatusCondition(clusterExtension.Status.Conditions, ocv1.TypeInstalled)
@@ -187,12 +372,12 @@ func TestClusterExtensionConfigSupport(t *testing.T) {
187372
require.NotEmpty(ct, clusterExtension.Status.Install.Bundle)
188373
}, pollDuration, pollInterval)
189374

190-
t.Log("By ensuring the test-operator deployment is correctly configured to watch the watch namespace")
375+
t.Log("By ensuring the own-namespace-operator deployment is correctly configured to watch the watch namespace")
191376
require.EventuallyWithT(t, func(ct *assert.CollectT) {
192377
deployment := &appsv1.Deployment{}
193-
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Namespace: namespace.GetName(), Name: "test-operator"}, deployment))
378+
require.NoError(ct, c.Get(t.Context(), types.NamespacedName{Namespace: namespace.GetName(), Name: "own-namespace-operator"}, deployment))
194379
require.NotNil(ct, deployment.Spec.Template.GetAnnotations())
195-
require.Equal(ct, watchNamespace.GetName(), deployment.Spec.Template.GetAnnotations()["olm.targetNamespaces"])
380+
require.Equal(ct, clusterExtension.Spec.Namespace, deployment.Spec.Template.GetAnnotations()["olm.targetNamespaces"])
196381
}, pollDuration, pollInterval)
197382
}
198383

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
---
2+
apiVersion: apiextensions.k8s.io/v1
3+
kind: CustomResourceDefinition
4+
metadata:
5+
annotations:
6+
controller-gen.kubebuilder.io/version: v0.16.1
7+
name: ownnamespaces.olm.operatorframework.io
8+
spec:
9+
group: olm.operatorframework.io
10+
names:
11+
kind: OwnNamespace
12+
listKind: OwnNamespaceList
13+
plural: ownnamespaces
14+
singular: ownnamespace
15+
scope: Cluster
16+
versions:
17+
- name: v1
18+
served: true
19+
storage: true
20+
schema:
21+
openAPIV3Schema:
22+
type: object
23+
properties:
24+
spec:
25+
type: object
26+
properties:
27+
testField:
28+
type: string

0 commit comments

Comments
 (0)