Skip to content

Commit 04ff165

Browse files
camilamacedo86ci-robot
authored andcommitted
UPSTREAM: <carry>: Preflight tests use in-cluster catalog and bundles instead of openshift-pipelines-operator-rh
Generated-by: Cursor/Claude
1 parent 9b7f0e5 commit 04ff165

1 file changed

Lines changed: 82 additions & 35 deletions

File tree

openshift/tests-extension/test/olmv1-preflight.go

Lines changed: 82 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,19 @@ import (
1010
. "github.com/onsi/gomega"
1111

1212
"github.com/openshift/api/features"
13+
"github.com/openshift/origin/test/extended/util/image"
1314
corev1 "k8s.io/api/core/v1"
1415
rbacv1 "k8s.io/api/rbac/v1"
16+
apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
1517
"k8s.io/apimachinery/pkg/api/meta"
1618
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1719
"k8s.io/apimachinery/pkg/util/rand"
1820
"sigs.k8s.io/controller-runtime/pkg/client"
1921

2022
olmv1 "github.com/operator-framework/operator-controller/api/v1"
2123

24+
singleownbundle "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/bindata/singleown/bundle"
25+
singleownindex "github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/bindata/singleown/index"
2226
"github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/env"
2327
"github.com/openshift/operator-framework-operator-controller/openshift/tests-extension/pkg/helpers"
2428
)
@@ -35,16 +39,41 @@ const (
3539
scenarioMissingClusterExtensionRevisionsFinalizerPerms preflightAuthTestScenario = 6
3640
)
3741

42+
const preflightBundleVersion = "0.0.5"
43+
3844
var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMPreflightPermissionChecks][Skipped:Disconnected] OLMv1 operator preflight checks", func() {
3945
var (
40-
namespace string
41-
k8sClient client.Client
46+
namespace string
47+
k8sClient client.Client
48+
catalogName string
49+
packageName string
4250
)
43-
BeforeEach(func() {
51+
BeforeEach(func(ctx SpecContext) {
4452
helpers.RequireOLMv1CapabilityOnOpenshift()
53+
helpers.RequireImageRegistry(ctx)
4554
k8sClient = env.Get().K8sClient
4655
namespace = "preflight-test-ns-" + rand.String(4)
4756

57+
// Use an in-cluster catalog and bundle so tests do not depend on external indexes.
58+
crdSuffix := rand.String(4)
59+
packageName = fmt.Sprintf("preflight-operator-%s", crdSuffix)
60+
crdName := fmt.Sprintf("webhooktests-%s.webhook.operators.coreos.io", crdSuffix)
61+
helpers.EnsureCleanupClusterExtension(context.Background(), packageName, crdName)
62+
63+
singleownImage := image.LocationFor("quay.io/olmtest/webhook-operator:v0.0.5")
64+
replacements := map[string]string{
65+
"{{ TEST-BUNDLE }}": "",
66+
"{{ NAMESPACE }}": "",
67+
"{{ TEST-CONTROLLER }}": singleownImage,
68+
"{{ CRD-SUFFIX }}": crdSuffix,
69+
"{{ PACKAGE-NAME }}": packageName,
70+
}
71+
_, _, catalogName, _ = helpers.NewCatalogAndClusterBundles(ctx, replacements,
72+
singleownindex.AssetNames, singleownindex.Asset,
73+
singleownbundle.AssetNames, singleownbundle.Asset,
74+
)
75+
By(fmt.Sprintf("catalog %q and package %q are ready", catalogName, packageName))
76+
4877
By(fmt.Sprintf("creating namespace %s", namespace))
4978
ns := &corev1.Namespace{
5079
ObjectMeta: metav1.ObjectMeta{
@@ -58,39 +87,39 @@ var _ = Describe("[sig-olmv1][OCPFeatureGate:NewOLMPreflightPermissionChecks][Sk
5887
})
5988

6089
It("should report error when {services} are not specified", func(ctx SpecContext) {
61-
runNegativePreflightTest(ctx, scenarioMissingServicePerms, namespace)
90+
runNegativePreflightTest(ctx, scenarioMissingServicePerms, namespace, packageName, catalogName)
6291
})
6392

6493
It("should report error when {create} verb is not specified", func(ctx SpecContext) {
65-
runNegativePreflightTest(ctx, scenarioMissingCreateVerb, namespace)
94+
runNegativePreflightTest(ctx, scenarioMissingCreateVerb, namespace, packageName, catalogName)
6695
})
6796

6897
It("should report error when {ClusterRoleBindings} are not specified", func(ctx SpecContext) {
69-
runNegativePreflightTest(ctx, scenarioMissingClusterRoleBindingsPerms, namespace)
98+
runNegativePreflightTest(ctx, scenarioMissingClusterRoleBindingsPerms, namespace, packageName, catalogName)
7099
})
71100

72101
It("should report error when {ConfigMap:resourceNames} are not all specified", func(ctx SpecContext) {
73-
runNegativePreflightTest(ctx, scenarioMissingNamedConfigMapPerms, namespace)
102+
runNegativePreflightTest(ctx, scenarioMissingNamedConfigMapPerms, namespace, packageName, catalogName)
74103
})
75104

76105
It("should report error when {clusterextension/finalizer} is not specified", func(ctx SpecContext) {
77106
helpers.RequireFeatureGateDisabled(features.FeatureGateNewOLMBoxCutterRuntime)
78-
runNegativePreflightTest(ctx, scenarioMissingClusterExtensionsFinalizerPerms, namespace)
107+
runNegativePreflightTest(ctx, scenarioMissingClusterExtensionsFinalizerPerms, namespace, packageName, catalogName)
79108
})
80109

81110
It("should report error when {clusterextensionrevisions/finalizer} is not specified", func(ctx SpecContext) {
82111
helpers.RequireFeatureGateEnabled(features.FeatureGateNewOLMBoxCutterRuntime)
83-
runNegativePreflightTest(ctx, scenarioMissingClusterExtensionRevisionsFinalizerPerms, namespace)
112+
runNegativePreflightTest(ctx, scenarioMissingClusterExtensionRevisionsFinalizerPerms, namespace, packageName, catalogName)
84113
})
85114

86115
It("should report error when {escalate, bind} is not specified", func(ctx SpecContext) {
87-
runNegativePreflightTest(ctx, scenarioMissingEscalateAndBindPerms, namespace)
116+
runNegativePreflightTest(ctx, scenarioMissingEscalateAndBindPerms, namespace, packageName, catalogName)
88117
})
89118
})
90119

91-
// runNegativePreflightTest creates a deficient ClusterRole and a ClusterExtension that
92-
// relies on it, then waits for the expected preflight failure.
93-
func runNegativePreflightTest(ctx context.Context, scenario preflightAuthTestScenario, namespace string) {
120+
// runNegativePreflightTest creates a ClusterRole that is missing one required permission,
121+
// a ClusterExtension that uses it (via the in-cluster catalog), then waits for the preflight failure.
122+
func runNegativePreflightTest(ctx context.Context, scenario preflightAuthTestScenario, namespace, packageName, catalogName string) {
94123
k8sClient := env.Get().K8sClient
95124
unique := rand.String(8)
96125

@@ -121,28 +150,35 @@ func runNegativePreflightTest(ctx context.Context, scenario preflightAuthTestSce
121150
_ = k8sClient.Delete(ctx, crb)
122151
})
123152

124-
// Step 4: Create ClusterExtension referencing that SA
125-
ce := helpers.NewClusterExtensionObject("openshift-pipelines-operator-rh", "1.15.0", ceName, saName, namespace)
153+
// Step 4: Create ClusterExtension for that SA using the in-cluster catalog.
154+
// Set watchNamespace in config so the controller can run preflight; otherwise it fails on config validation first.
155+
ce := helpers.NewClusterExtensionObject(packageName, preflightBundleVersion, ceName, saName, namespace, helpers.WithCatalogNameSelector(catalogName))
156+
ce.Spec.Config = &olmv1.ClusterExtensionConfig{
157+
ConfigType: "Inline",
158+
Inline: &apiextensionsv1.JSON{
159+
Raw: []byte(fmt.Sprintf(`{"watchNamespace": "%s"}`, namespace)),
160+
},
161+
}
126162
Expect(k8sClient.Create(ctx, ce)).To(Succeed(), "failed to create ClusterExtension")
127163
DeferCleanup(func(ctx SpecContext) {
128164
_ = k8sClient.Delete(ctx, ce)
129165
})
130166

131-
// Step 5: Wait for failure
167+
// Step 5: Wait for the controller to report preflight failure.
168+
// The error is in the Progressing condition. We only check the message, not True/False, so the test stays stable.
132169
By("waiting for ClusterExtension to report preflight failure")
133170
Eventually(func(g Gomega) {
134171
latest := &olmv1.ClusterExtension{}
135172
err := k8sClient.Get(ctx, client.ObjectKey{Name: ce.Name}, latest)
136173
g.Expect(err).NotTo(HaveOccurred())
137174

138-
c := meta.FindStatusCondition(latest.Status.Conditions, "Progressing")
139-
g.Expect(c).NotTo(BeNil())
140-
g.Expect(c.Status).To(Equal(metav1.ConditionTrue))
141-
g.Expect(c.Message).To(ContainSubstring("pre-authorization failed"))
175+
c := meta.FindStatusCondition(latest.Status.Conditions, olmv1.TypeProgressing)
176+
g.Expect(c).NotTo(BeNil(), "Progressing condition should be set")
177+
g.Expect(c.Message).To(ContainSubstring("pre-authorization failed"), "message should report pre-authorization failure")
142178
}).WithTimeout(helpers.DefaultTimeout).WithPolling(helpers.DefaultPolling).Should(Succeed())
143179
}
144180

145-
// createDeficientClusterRole returns a modified ClusterRole according to the test scenario.
181+
// createDeficientClusterRole returns a ClusterRole that is missing one permission needed by the test scenario.
146182
func createDeficientClusterRole(scenario preflightAuthTestScenario, name, ceName string) *rbacv1.ClusterRole {
147183
var baseRules []rbacv1.PolicyRule
148184
if helpers.IsFeatureGateEnabled(features.FeatureGateNewOLMBoxCutterRuntime) {
@@ -189,7 +225,7 @@ func createDeficientClusterRole(scenario preflightAuthTestScenario, name, ceName
189225

190226
switch scenario {
191227
case scenarioMissingServicePerms:
192-
// Remove 'services' and 'services/finalizers'
228+
// Remove services and services/finalizers so preflight fails.
193229
for i, r := range rules {
194230
if r.APIGroups[0] == "" {
195231
filtered := []string{}
@@ -202,7 +238,7 @@ func createDeficientClusterRole(scenario preflightAuthTestScenario, name, ceName
202238
}
203239
}
204240
case scenarioMissingCreateVerb:
205-
// Remove 'create' verb
241+
// Remove the create verb so preflight fails.
206242
for i, r := range rules {
207243
if r.APIGroups[0] == "" {
208244
filtered := []string{}
@@ -215,7 +251,7 @@ func createDeficientClusterRole(scenario preflightAuthTestScenario, name, ceName
215251
}
216252
}
217253
case scenarioMissingClusterRoleBindingsPerms:
218-
// Remove 'clusterrolebindings'
254+
// Remove clusterrolebindings so preflight fails.
219255
for i, r := range rules {
220256
if r.APIGroups[0] == "rbac.authorization.k8s.io" {
221257
filtered := []string{}
@@ -228,26 +264,37 @@ func createDeficientClusterRole(scenario preflightAuthTestScenario, name, ceName
228264
}
229265
}
230266
case scenarioMissingNamedConfigMapPerms:
231-
// Restrict configmaps to named subset (resourceNames)
232-
for i, r := range rules {
233-
if r.APIGroups[0] == "" {
267+
// Allow only one ClusterRole by name so the SA cannot manage the rest; preflight then fails.
268+
// The singleown bundle uses ClusterRoles like webhook-operator-metrics-reader.
269+
for i := range rules {
270+
if rules[i].APIGroups[0] == "rbac.authorization.k8s.io" {
234271
filtered := []string{}
235-
for _, res := range r.Resources {
236-
if res != "configmaps" && res != "configmaps/finalizers" {
272+
for _, res := range rules[i].Resources {
273+
if res != "clusterroles" && res != "clusterroles/finalizers" {
237274
filtered = append(filtered, res)
238275
}
239276
}
240277
rules[i].Resources = filtered
241278
rules = append(rules, rbacv1.PolicyRule{
242-
APIGroups: []string{""},
243-
Resources: []string{"configmaps"},
244-
Verbs: r.Verbs,
245-
ResourceNames: []string{"config-logging", "tekton-config-defaults", "tekton-config-observability"},
279+
APIGroups: []string{"rbac.authorization.k8s.io"},
280+
Resources: []string{"clusterroles", "clusterroles/finalizers"},
281+
Verbs: []string{"delete", "deletecollection", "create", "patch", "get", "list", "update", "watch"},
282+
ResourceNames: []string{"webhook-operator-metrics-reader"},
246283
})
284+
break
247285
}
248286
}
249287
case scenarioMissingClusterExtensionsFinalizerPerms:
250-
// Remove olm.operatorframework.io permission for finalizers
288+
// Remove permission for clusterextensions/finalizers so preflight fails.
289+
filtered := []rbacv1.PolicyRule{}
290+
for _, r := range rules {
291+
if len(r.APIGroups) != 1 || r.APIGroups[0] != "olm.operatorframework.io" {
292+
filtered = append(filtered, r)
293+
}
294+
}
295+
rules = filtered
296+
case scenarioMissingClusterExtensionRevisionsFinalizerPerms:
297+
// Remove permission for clusterextensionrevisions/finalizers so preflight fails.
251298
filtered := []rbacv1.PolicyRule{}
252299
for _, r := range rules {
253300
if len(r.APIGroups) != 1 || r.APIGroups[0] != "olm.operatorframework.io" {
@@ -256,7 +303,7 @@ func createDeficientClusterRole(scenario preflightAuthTestScenario, name, ceName
256303
}
257304
rules = filtered
258305
case scenarioMissingEscalateAndBindPerms:
259-
// Remove 'bind' and 'escalate' verbs
306+
// Remove bind and escalate verbs so preflight fails.
260307
for i, r := range rules {
261308
if r.APIGroups[0] == "rbac.authorization.k8s.io" {
262309
filtered := []string{}

0 commit comments

Comments
 (0)