From a3cdf9607c562a261c555da2a319f3de136e098b Mon Sep 17 00:00:00 2001 From: Todd Short Date: Thu, 27 Aug 2026 14:50:51 -0400 Subject: [PATCH] Restore C3 hard block: APIService not yet fully supported in OLMv1 The operator-controller PR #2885 added the rendering infrastructure (BundleCSVAPIServiceGenerator, validator, cert provider support) for APIService objects, but the code is not yet registered in ResourceGenerators or BundleValidator pending end-to-end Boxcutter path validation. C3 is therefore reinstated as a hard block in the migration tool. Operators with owned APIService definitions remain ineligible until OLMv1 supports them end-to-end. SDD documents updated: requirements.md: C3 is a hard block (not temporary), updated rationale plan.md: Phase 7 reflects infrastructure status; C3 removal deferred Co-Authored-By: Claude Sonnet 4.6 (1M context) Signed-off-by: Todd Short --- migration/pkg/migration/compatibility.go | 24 ++++++++++-- specs/20260821-migration-v0-to-v1/plan.md | 37 +++++++++---------- .../requirements.md | 2 +- 3 files changed, 39 insertions(+), 24 deletions(-) diff --git a/migration/pkg/migration/compatibility.go b/migration/pkg/migration/compatibility.go index 8549301..8526621 100644 --- a/migration/pkg/migration/compatibility.go +++ b/migration/pkg/migration/compatibility.go @@ -27,9 +27,8 @@ func (m *Migrator) CheckCompatibility(ctx context.Context, opts Options, csv *op // Dependency checks (C2 — hard block) report.Checks = append(report.Checks, checkNoDependencies(bundleProperties)...) - // C3 (APIService definitions) was removed: OLMv1 now manages APIService objects - // natively via the registry+v1 renderer (OPRUN-4723). Operators with owned - // APIService definitions are now Eligible with no override required. + // APIService definitions check (C3 — hard block) + report.Checks = append(report.Checks, checkNoAPIServices(csv)) // OperatorCondition checks (C4) condCheck, err := m.checkNoOperatorConditions(ctx, opts, csv) @@ -194,6 +193,25 @@ func parseProperties(propertiesJSON string) ([]olmProperty, error) { return wrapped.Properties, nil } +// checkNoAPIServices enforces C3 — no owned APIService definitions (hard block). +// OLMv1's registry+v1 renderer does not support APIService-based operators +// end-to-end. The underlying implementation exists in operator-controller as infrastructure +// but is not supported by the Boxcutter rendering path. +func checkNoAPIServices(csv *operatorsv1alpha1.ClusterServiceVersion) CheckResult { + if len(csv.Spec.APIServiceDefinitions.Owned) > 0 { + return CheckResult{ + Name: "No APIService definitions", + Passed: false, + Message: "CSV has spec.apiservicedefinitions.owned set; OLMv1 does not support APIService-based operators", + } + } + return CheckResult{ + Name: "No APIService definitions", + Passed: true, + Message: "CSV does not define owned APIServices", + } +} + // checkNoDependencies enforces C2 — no olm.package.required or olm.gvk.required (hard block). func checkNoDependencies(propertiesJSON string) []CheckResult { if propertiesJSON == "" { diff --git a/specs/20260821-migration-v0-to-v1/plan.md b/specs/20260821-migration-v0-to-v1/plan.md index 936a5c4..f2946e7 100644 --- a/specs/20260821-migration-v0-to-v1/plan.md +++ b/specs/20260821-migration-v0-to-v1/plan.md @@ -85,9 +85,10 @@ Verified during Phase 8 E2E. - On use, record `olm.operatorframework.io/acknowledged-: "true"` on the CE. - Collector places all objects (incl. CRDs) into the COS with `IfNoController`. -**Note:** Once [OPRUN-4723](https://redhat.atlassian.net/browse/OPRUN-4723) (Phase 7) merges, -**remove C3 entirely** — OLMv1 will manage APIService objects natively so operators with -APIService definitions become Eligible with no flag required. +**Note:** C3 remains a hard block until OLMv1 supports APIService-based operators end-to-end. +The rendering infrastructure was added in operator-controller ([OPRUN-4723](https://redhat.atlassian.net/browse/OPRUN-4723)) +but is not yet wired into the Boxcutter path. C3 will be removed in a future phase once +end-to-end support is confirmed. **Depends on:** Phases 1, 2. **Exit:** each soft check flips Ineligible→Eligible when its flag is set; CE carries the matching annotation. @@ -136,26 +137,22 @@ then reports catalog-available. labels copied; old namespace deleted only when acknowledged. ## Phase 7 — OLMv1 APIService renderer support *(cross-repo, operator-controller)* — [OPRUN-4723](https://redhat.atlassian.net/browse/OPRUN-4723) -**Goal:** Remove C3 (APIService definitions) as a permanent hard block by adding -`apiregistration.k8s.io` support to the OLMv1 registry+v1 bundle renderer. +**Goal:** Add `apiregistration.k8s.io` support to the OLMv1 registry+v1 bundle renderer as +infrastructure for future end-to-end APIService support. -The current `ResourceGenerators` list in `internal/operator-controller/rukpak/render/registryv1/registryv1.go` -has **no** generator for `APIService` objects — it generates ServiceAccounts, RBAC, CRDs, -Deployments, Webhooks, and CertProvider, but not `k8s.io/kube-aggregator` APIService -registrations. Until this is fixed, operators that own APIService definitions cannot be -migrated at all (C3 hard block). +The rendering code (`BundleCSVAPIServiceGenerator`, `CheckAPIServiceDeploymentReferentialIntegrity`, +cert provider updates) was added to operator-controller as infrastructure but is **not yet +registered** in `ResourceGenerators` or `BundleValidator` because end-to-end Boxcutter support +is not yet confirmed. C3 remains a hard block until this is fully wired and validated. **Scope (in `operator-controller`):** -- Add a `BundleCSVAPIServiceGenerator` to `ResourceGenerators` that reads - `csv.spec.apiservicedefinitions.owned` and emits the corresponding `APIService` objects. -- Update the `BundleValidator` if APIService-specific validation rules are needed. -- Once merged, **remove C3 entirely** from the migration tool (Phase 3 / OPRUN-4719) — OLMv1 - manages APIService objects natively; operators with APIService definitions become Eligible - with no override flag needed. - -**Depends on:** nothing (can start immediately, runs in parallel). **Exit:** registry+v1 -renderer generates `APIService` objects; C3 removed from migration tool (Phase 3 / OPRUN-4719 -updated). +- Added `BundleCSVAPIServiceGenerator`, `CheckAPIServiceDeploymentReferentialIntegrity`, and + cert provider support for `APIService` objects (implemented but not yet registered in + `ResourceGenerators` / `BundleValidator` pending Boxcutter end-to-end validation). +- C3 remains a hard block in the migration tool until the Boxcutter path is fully wired. + +**Depends on:** nothing (ran in parallel). **Status:** rendering infrastructure merged; C3 +removal deferred until end-to-end Boxcutter support is confirmed. ## Phase 8 — Testing — *(testing stories auto-created per epic)* **Goal:** Confidence across unit and E2E (R-wide). diff --git a/specs/20260821-migration-v0-to-v1/requirements.md b/specs/20260821-migration-v0-to-v1/requirements.md index a3d011d..b69670f 100644 --- a/specs/20260821-migration-v0-to-v1/requirements.md +++ b/specs/20260821-migration-v0-to-v1/requirements.md @@ -130,7 +130,7 @@ annotation, R2.5) or **hard** (must be remediated first — no override). |---|---|---|---| | C1 | AllNamespaces watch scope | OperatorGroup targets specific namespaces (Own/Single/Multi) | `--acknowledge-watch-scope-change` | | C2 | No dependency resolution *(hard)* | CSV declares `olm.package.required` or `olm.gvk.required` | none — OLMv1 fundamentally does not resolve dependencies; migrating without them would leave the operator broken | -| C3 | No APIService definitions *(hard, temporary)* | CSV `spec.apiservicedefinitions.owned` is non-empty | none — OLMv1's registry+v1 renderer currently has **no** `apiregistration.k8s.io` generator; when [OPRUN-4723](https://redhat.atlassian.net/browse/OPRUN-4723) merges, OLMv1 will manage APIService objects natively and **C3 is removed entirely** (no override flag; operators with APIService definitions become Eligible) | +| C3 | No APIService definitions *(hard)* | CSV `spec.apiservicedefinitions.owned` is non-empty | none — OLMv1 does not yet fully support APIService-based operators end-to-end. The rendering infrastructure exists in operator-controller ([OPRUN-4723](https://redhat.atlassian.net/browse/OPRUN-4723)) but is not yet wired into the Boxcutter path. C3 will be removed when end-to-end support is confirmed. | | C4 | No active OperatorCondition | `OperatorCondition.status.conditions` has entries (see R9) | `--acknowledge-operator-condition` | | C5 | OLMv0-API RBAC without OLMv1 RBAC | The installed RBAC (from live cluster, sourced from bundle manifests or CSV) grants access to `operators.coreos.com` resources (`subscriptions`/`installplans`/`clusterserviceversions`/`catalogsources`, **excluding** `operatorconditions`) **and** does not also grant equivalent OLMv1 API access — operators updated for OLMv1 compatibility will carry both and pass | `--acknowledge-olmv0-api-access` | | C6 | No scoped ServiceAccount | OperatorGroup `spec.serviceAccountName` is set | `--acknowledge-scoped-serviceaccount` |