feat: implement Gateway API routing class for DevWorkspaceRouting - #1680
feat: implement Gateway API routing class for DevWorkspaceRouting#1680btjd wants to merge 3 commits into
Conversation
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: btjd The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
PR needs rebase. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. |
|
@btjd: The following tests failed, say
Full PR test history. Your PR dashboard. DetailsInstructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here. |
📝 WalkthroughWalkthroughAdds Gateway API routing support through configurable Gateway references, generated HTTPRoutes, controller synchronization, deployment RBAC and schemas, scheme registration, and integration tests. ChangesGateway API routing
Estimated code review effort: 4 (Complex) | ~60 minutes Sequence Diagram(s)sequenceDiagram
participant DevWorkspaceRouting
participant GatewayAPISolver
participant HTTPRoute
participant EndpointResolver
DevWorkspaceRouting->>GatewayAPISolver: Generate routing objects
GatewayAPISolver->>HTTPRoute: Create redirect and backend routes
DevWorkspaceRouting->>HTTPRoute: Synchronize routes
DevWorkspaceRouting->>EndpointResolver: Resolve exposed endpoints
EndpointResolver-->>DevWorkspaceRouting: Return URLs and readiness
Suggested reviewers: 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
⚔️ Resolve merge conflicts
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 6
🧹 Nitpick comments (14)
deploy/deployment/openshift/combined.yaml (1)
27952-27957: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueConsider scoping
httproutesverbs instead of wildcard.Granting
'*'onhttproutesis broader than the create/update/delete/watch lifecycle described for HTTPRoutes in this PR. This matches the existing convention for other resources in this ClusterRole (e.g.,ingresses,routes), so it's a minor, optional tightening rather than a new problem.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/deployment/openshift/combined.yaml` around lines 27952 - 27957, In the ClusterRole rule for the gateway.networking.k8s.io httproutes resource, replace the wildcard verb permission with only the required create, update, delete, and watch verbs, matching the lifecycle described and the existing ingresses/routes convention.controllers/controller/devworkspacerouting/solvers/gateway_api_solver.go (2)
17-26: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueGroup third-party imports separately from project-local imports.
metav1andgwapiv1(third-party/Kubernetes) are combined with thegithub.com/devfile/devworkspace-operator/...(project-local) group instead of forming their own group.As per coding guidelines: "Organize imports into three groups separated by blank lines: standard library, third-party/Kubernetes, and project-local imports."
♻️ Proposed import grouping
import ( "fmt" - controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" - "github.com/devfile/devworkspace-operator/pkg/common" - "github.com/devfile/devworkspace-operator/pkg/config" - "github.com/devfile/devworkspace-operator/pkg/constants" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + gwapiv1 "sigs.k8s.io/gateway-api/apis/v1" + + controllerv1alpha1 "github.com/devfile/devworkspace-operator/apis/controller/v1alpha1" + "github.com/devfile/devworkspace-operator/pkg/common" + "github.com/devfile/devworkspace-operator/pkg/config" + "github.com/devfile/devworkspace-operator/pkg/constants" )🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/solvers/gateway_api_solver.go` around lines 17 - 26, Reorganize the import block in gateway API solver so standard-library imports, third-party/Kubernetes imports such as metav1 and gwapiv1, and project-local devworkspace-operator imports are separated by blank lines.Source: Coding guidelines
71-121: 🩺 Stability & Availability | 🔵 TrivialHandle the Gateway's cross-namespace route allowance.
Both generated HTTPRoutes set
ParentRefs[0].Namespaceto the Gateway namespace, while the route namespace comes fromworkspaceMeta.Namespace. That cross-namespace attachment only succeeds if the target Gateway listener’sallowedRoutes.namespaces.fromincludes the workspace namespace. Confirm the pre-provisioned Gateway is documented to require this configuration; otherwise workspaces outside the Gateway namespace will remain unattached.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/solvers/gateway_api_solver.go` around lines 71 - 121, The generated routes in getHTTPRoutesForSpec rely on cross-namespace attachment from workspaceMeta.Namespace to gatewayNamespace. Confirm and document that the pre-provisioned Gateway listeners set allowedRoutes.namespaces.from to permit the workspace namespace; if this configuration is not guaranteed, update the Gateway provisioning/configuration so both createHTTPRedirectRoute and createHTTPSBackendRoute routes can attach successfully.controllers/controller/devworkspacerouting/devworkspacerouting_controller.go (1)
72-72: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winWildcard verbs on the new
httproutesRBAC grant. The kubebuilder marker grantsverbs=*forgateway.networking.k8s.io/httproutes, which controller-gen materializes into the ClusterRole. The controller's actual HTTPRoute lifecycle (list/get/create/update/patch/delete/watch, persync_httproutes.go) doesn't need the full wildcard. This mirrors the pre-existing'*'convention already used foringresses/routesin the same ClusterRole, so it's a consistency-preserving but still-broad grant worth tightening for least privilege.
controllers/controller/devworkspacerouting/devworkspacerouting_controller.go#L72-L72: scope the kubebuilder marker to the verbs actually used, e.g.// +kubebuilder:rbac:groups=gateway.networking.k8s.io,resources=httproutes,verbs=get;list;watch;create;update;patch;delete, then runmake generate_allto regenerate the RBAC manifests.deploy/deployment/kubernetes/combined.yaml#L27952-L27957: this generated entry will update automatically once the marker above is scoped down and manifests are regenerated.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/devworkspacerouting_controller.go` at line 72, Restrict the httproutes RBAC marker in devworkspacerouting_controller.go to get, list, watch, create, update, patch, and delete, then run make generate_all to regenerate deploy/deployment/kubernetes/combined.yaml; update the generated ClusterRole entry at lines 27952-27957 accordingly.deploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yaml (1)
179-184: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueWildcard verb on
httproutes. Duplicate of the same generated rule; see the consolidated note.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yaml` around lines 179 - 184, Remove the duplicate generated RBAC rule granting wildcard verbs on httproutes in the ClusterRole manifest, while retaining the consolidated gateway.networking.k8s.io httproutes rule elsewhere.deploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yaml (1)
179-184: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueWildcard verb on
httproutes. Duplicate of the same generated rule; see the consolidated note.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yaml` around lines 179 - 184, Remove the duplicate generated RBAC rule granting wildcard verbs on the httproutes resource in the gateway.networking.k8s.io API group. Keep the consolidated httproutes rule unchanged and ensure only one equivalent rule remains.deploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yaml (1)
259-264: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueWildcard verb on
httproutes. Same generated rule as the other three RBAC manifests; see the consolidated note anchored on the template.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yaml` around lines 259 - 264, Update the RBAC rule for gateway.networking.k8s.io httproutes in the devworkspace-operator ClusterServiceVersion manifest to replace the wildcard verb with only the required explicit verbs, matching the other generated RBAC manifests and the source template.controllers/controller/devworkspacerouting/util_test.go (2)
168-180: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winMake the helper tolerant of an absent route, and prefer an explicit name over a boolean flag.
Waiting for existence before deleting turns "route was never created" into a 10s teardown hang plus a misleading failure. Cleanup helpers should be idempotent. Also,
deleteHTTPRoute(name, ns, true)at the call sites is opaque; taking the full route name (or exposing aredirectRouteName(endpoint)helper) reads better and removes the duplicated-http-redirectliteral.♻️ Proposed refactor
+func redirectRouteName(endpointName string) string { + return common.RouteName(testWorkspaceID, endpointName) + "-http-redirect" +} + func deleteHTTPRoute(endpointName string, namespace string, isRedirect bool) { createdHTTPRoute := gwapiv1.HTTPRoute{} routeName := common.RouteName(testWorkspaceID, endpointName) if isRedirect { - routeName = routeName + "-http-redirect" + routeName = redirectRouteName(endpointName) } httpRouteNamespacedName := namespacedName(routeName, namespace) - Eventually(func() bool { - err := k8sClient.Get(ctx, httpRouteNamespacedName, &createdHTTPRoute) - return err == nil - }, timeout, interval).Should(BeTrue(), "HTTPRoute should exist in cluster") - deleteObject(&createdHTTPRoute) + if err := k8sClient.Get(ctx, httpRouteNamespacedName, &createdHTTPRoute); err != nil { + Expect(k8sErrors.IsNotFound(err)).Should(BeTrue(), "unexpected error fetching HTTPRoute %s", routeName) + return + } + deleteObject(&createdHTTPRoute) }🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/util_test.go` around lines 168 - 180, Update deleteHTTPRoute to accept the explicit route name rather than the isRedirect boolean, with callers using the existing route-name helpers or a shared redirectRouteName helper instead of duplicating the "-http-redirect" suffix. Make cleanup idempotent by deleting directly and treating a not-found HTTPRoute as successful, removing the Eventually wait that requires prior existence.
168-180: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low valueThe
-http-redirectsuffix is hardcoded in two test locations and (presumably) a third time in the solver. A rename in the solver would leave both tests asserting against a name that no longer exists, and the negative/cleanup paths would fail confusingly rather than pointing at the rename.
controllers/controller/devworkspacerouting/util_test.go#L168-L180: introduce aredirectRouteName(endpointName string) stringhelper (or reuse an exported name-builder from the solver package) and use it here instead of the inline concatenation.controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go#L541-L547: replacecommon.RouteName(testWorkspaceID, exposedEndPointName)+"-http-redirect"with that shared helper.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/util_test.go` around lines 168 - 180, The redirect route suffix is duplicated across test helpers and assertions, so rename changes can leave tests targeting stale names. In controllers/controller/devworkspacerouting/util_test.go:168-180, add or reuse a shared redirectRouteName(endpointName string) helper and use it in deleteHTTPRoute; in controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go:541-547, replace the inline route-name concatenation with that same helper, keeping both tests aligned with the solver’s naming logic.controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go (3)
570-588: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick winNo assertion on
spec.hostnames.The context configures
ClusterHostSuffix: "test-environment-cluster-suffix", but nothing verifies the generated HTTPRoute'shostnames— yet that is exactly what makes the route match traffic for a workspace endpoint. A wrong or empty hostname would pass this whole suite. Consider adding a check thatcreatedHTTPRoute.Spec.Hostnamescontains the expected<endpoint-host>.test-environment-cluster-suffixvalue (and likewise for the redirect route).🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go` around lines 570 - 588, Extend the HTTPRoute assertions in the discoverable endpoint test to verify discoverableHTTPRoute.Spec.Hostnames contains the expected endpoint host combined with ClusterHostSuffix "test-environment-cluster-suffix". Add equivalent hostname validation for the redirect route using its expected endpoint host, while preserving the existing metadata and non-exposed route checks.
366-377: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick winUse the exported constant instead of the
"gateway-api"literal.Line 416 already uses
controllerv1alpha1.DevWorkspaceRoutingGatewayAPI; keeping a raw literal here means a change to the constant's value would silently leave this config pointing at an unknown routing class.♻️ Proposed tweak
- DefaultRoutingClass: "gateway-api", + DefaultRoutingClass: string(controllerv1alpha1.DevWorkspaceRoutingGatewayAPI),🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go` around lines 366 - 377, Replace the hardcoded "gateway-api" value assigned to RoutingConfig.DefaultRoutingClass in the test setup with the exported controllerv1alpha1.DevWorkspaceRoutingGatewayAPI constant, matching the existing usage elsewhere in the test.
455-500: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoffThis "Creates services" body is a near-verbatim third copy.
Lines 455-500 duplicate the Kubernetes (108-161) and OpenShift (244-295) service assertions almost exactly. Service generation is routing-class independent, so extracting a shared
expectConsolidatedServices(createdDWR)helper would keep the three contexts in sync when the service shape changes.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go` around lines 455 - 500, Extract the duplicated service assertions from the “Creates services” tests into a shared expectConsolidatedServices(createdDWR) helper, including consolidated and discoverable Service lookup, labels, owner reference, selectors, ports, and annotations. Replace the near-identical assertion bodies in the Kubernetes, OpenShift, and routing-class contexts with calls to this helper while preserving each test’s setup and context-specific behavior.deploy/templates/components/rbac/role.yaml (2)
177-182: 🔒 Security & Privacy | 🔵 Trivial | 💤 Low valueWildcard verb on
httproutes(root marker lives in the controller). See the consolidated note.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/templates/components/rbac/role.yaml` around lines 177 - 182, Replace the wildcard verb in the httproutes rule with only the explicit verbs required by the controller’s httproute access. Update the rule under apiGroups gateway.networking.k8s.io and resources httproutes, leaving the controller-owned root marker unchanged.
177-182: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick winTighten the Gateway API RBAC verb wildcard to an explicit list.
controllers/controller/devworkspacerouting/devworkspacerouting_controller.go:72generates the fourgateway.networking.k8s.io/httproutesrules, andverbs=*grantsdeletecollectionplus any future Gateway API verbs via both the template and deployed CSV/ClusterRole manifests. Narrow the marker toverbs=get;list;watch;create;update;patch;delete, then regenerate the RBAC manifests; apply the same precedent to the existingingresses/routesverbs=*rules if the same least-privilege goal applies.🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the rest with a brief reason, keep changes minimal, and validate. In `@deploy/templates/components/rbac/role.yaml` around lines 177 - 182, The Gateway API httproutes RBAC rule uses an overly broad verb wildcard. In deploy/templates/components/rbac/role.yaml:177-182, replace verbs=* with get;list;watch;create;update;patch;delete, then regenerate the corresponding manifests in deploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yaml:179-184, deploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yaml:179-184, and deploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yaml:259-264. Apply the same explicit verb list to existing ingresses/routes wildcard rules only if they are part of the same least-privilege change.Source: Coding guidelines
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In
`@controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go`:
- Around line 430-439: Update the AfterEach cleanup around deleteHTTPRoute so
teardown does not require the discoverable endpoint’s redirect HTTPRoute to
exist; use cleanup behavior that tolerates absent routes while still removing
any routes that were created. Keep deletion for the other resources and verified
route variants unchanged, and align this with the non-strict cleanup approach
used by deleteHTTPRoute/util_test.go.
In
`@controllers/controller/devworkspacerouting/devworkspacerouting_controller.go`:
- Around line 246-262: Call syncHTTPRoutes unconditionally in the HTTPRoute
reconciliation block, including when httpRoutes is empty, so its
deletion-diffing cleanup removes stale cluster HTTPRoutes. Preserve the existing
error handling, requeue/status behavior, and assignment of
clusterRoutingObj.HTTPRoutes for successful synchronization.
In `@controllers/controller/devworkspacerouting/suite_test.go`:
- Around line 115-116: Replace the deprecated gwapiv1.AddToScheme call with
gwapiv1.Install in the scheme setup, matching the existing routev1.Install usage
while preserving the existing error assertion.
In
`@deploy/templates/crd/bases/controller.devfile.io_devworkspaceoperatorconfigs.yaml`:
- Around line 66-81: The Gateway reference fields gatewayClassName, name, and
namespace in the CRD schema currently accept unrestricted strings. Add
Kubernetes DNS-1123 resource-name validation, including the appropriate maximum
length, to each field while preserving the existing descriptions and defaults;
ensure name remains required and empty or malformed values are rejected at CRD
validation.
In `@main.go`:
- Line 83: Replace the deprecated gwapiv1.AddToScheme call in the
scheme-registration setup with gwapiv1.Install(scheme), preserving the existing
utilruntime.Must handling and matching the nearby Gateway API registrations.
In `@pkg/provision/sync/diffopts.go`:
- Around line 96-101: Update httpRouteDiffOpts so cmpopts.IgnoreFields for
gwapiv1.ParentReference omits only Group and Kind, keeping Namespace included in
comparisons; leave the other HTTPRoute and reference-field ignore rules
unchanged.
---
Nitpick comments:
In
`@controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go`:
- Around line 570-588: Extend the HTTPRoute assertions in the discoverable
endpoint test to verify discoverableHTTPRoute.Spec.Hostnames contains the
expected endpoint host combined with ClusterHostSuffix
"test-environment-cluster-suffix". Add equivalent hostname validation for the
redirect route using its expected endpoint host, while preserving the existing
metadata and non-exposed route checks.
- Around line 366-377: Replace the hardcoded "gateway-api" value assigned to
RoutingConfig.DefaultRoutingClass in the test setup with the exported
controllerv1alpha1.DevWorkspaceRoutingGatewayAPI constant, matching the existing
usage elsewhere in the test.
- Around line 455-500: Extract the duplicated service assertions from the
“Creates services” tests into a shared expectConsolidatedServices(createdDWR)
helper, including consolidated and discoverable Service lookup, labels, owner
reference, selectors, ports, and annotations. Replace the near-identical
assertion bodies in the Kubernetes, OpenShift, and routing-class contexts with
calls to this helper while preserving each test’s setup and context-specific
behavior.
In
`@controllers/controller/devworkspacerouting/devworkspacerouting_controller.go`:
- Line 72: Restrict the httproutes RBAC marker in
devworkspacerouting_controller.go to get, list, watch, create, update, patch,
and delete, then run make generate_all to regenerate
deploy/deployment/kubernetes/combined.yaml; update the generated ClusterRole
entry at lines 27952-27957 accordingly.
In `@controllers/controller/devworkspacerouting/solvers/gateway_api_solver.go`:
- Around line 17-26: Reorganize the import block in gateway API solver so
standard-library imports, third-party/Kubernetes imports such as metav1 and
gwapiv1, and project-local devworkspace-operator imports are separated by blank
lines.
- Around line 71-121: The generated routes in getHTTPRoutesForSpec rely on
cross-namespace attachment from workspaceMeta.Namespace to gatewayNamespace.
Confirm and document that the pre-provisioned Gateway listeners set
allowedRoutes.namespaces.from to permit the workspace namespace; if this
configuration is not guaranteed, update the Gateway provisioning/configuration
so both createHTTPRedirectRoute and createHTTPSBackendRoute routes can attach
successfully.
In `@controllers/controller/devworkspacerouting/util_test.go`:
- Around line 168-180: Update deleteHTTPRoute to accept the explicit route name
rather than the isRedirect boolean, with callers using the existing route-name
helpers or a shared redirectRouteName helper instead of duplicating the
"-http-redirect" suffix. Make cleanup idempotent by deleting directly and
treating a not-found HTTPRoute as successful, removing the Eventually wait that
requires prior existence.
- Around line 168-180: The redirect route suffix is duplicated across test
helpers and assertions, so rename changes can leave tests targeting stale names.
In controllers/controller/devworkspacerouting/util_test.go:168-180, add or reuse
a shared redirectRouteName(endpointName string) helper and use it in
deleteHTTPRoute; in
controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go:541-547,
replace the inline route-name concatenation with that same helper, keeping both
tests aligned with the solver’s naming logic.
In `@deploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yaml`:
- Around line 259-264: Update the RBAC rule for gateway.networking.k8s.io
httproutes in the devworkspace-operator ClusterServiceVersion manifest to
replace the wildcard verb with only the required explicit verbs, matching the
other generated RBAC manifests and the source template.
In
`@deploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yaml`:
- Around line 179-184: Remove the duplicate generated RBAC rule granting
wildcard verbs on httproutes in the ClusterRole manifest, while retaining the
consolidated gateway.networking.k8s.io httproutes rule elsewhere.
In `@deploy/deployment/openshift/combined.yaml`:
- Around line 27952-27957: In the ClusterRole rule for the
gateway.networking.k8s.io httproutes resource, replace the wildcard verb
permission with only the required create, update, delete, and watch verbs,
matching the lifecycle described and the existing ingresses/routes convention.
In
`@deploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yaml`:
- Around line 179-184: Remove the duplicate generated RBAC rule granting
wildcard verbs on the httproutes resource in the gateway.networking.k8s.io API
group. Keep the consolidated httproutes rule unchanged and ensure only one
equivalent rule remains.
In `@deploy/templates/components/rbac/role.yaml`:
- Around line 177-182: Replace the wildcard verb in the httproutes rule with
only the explicit verbs required by the controller’s httproute access. Update
the rule under apiGroups gateway.networking.k8s.io and resources httproutes,
leaving the controller-owned root marker unchanged.
- Around line 177-182: The Gateway API httproutes RBAC rule uses an overly broad
verb wildcard. In deploy/templates/components/rbac/role.yaml:177-182, replace
verbs=* with get;list;watch;create;update;patch;delete, then regenerate the
corresponding manifests in
deploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yaml:179-184,
deploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yaml:179-184,
and
deploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yaml:259-264.
Apply the same explicit verb list to existing ingresses/routes wildcard rules
only if they are part of the same least-privilege change.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro Plus
Run ID: da5d02c0-ae32-40bb-af72-8715f4d81c15
⛔ Files ignored due to path filters (1)
go.sumis excluded by!**/*.sum
📒 Files selected for processing (26)
apis/controller/v1alpha1/devworkspaceoperatorconfig_types.goapis/controller/v1alpha1/devworkspacerouting_types.goapis/controller/v1alpha1/zz_generated.deepcopy.gocontrollers/controller/devworkspacerouting/devworkspacerouting_controller.gocontrollers/controller/devworkspacerouting/devworkspacerouting_controller_test.gocontrollers/controller/devworkspacerouting/solvers/gateway_api_solver.gocontrollers/controller/devworkspacerouting/solvers/solver.gocontrollers/controller/devworkspacerouting/suite_test.gocontrollers/controller/devworkspacerouting/sync_httproutes.gocontrollers/controller/devworkspacerouting/testdata/gateway.networking.k8s.io_httproutes.yamlcontrollers/controller/devworkspacerouting/util_test.godeploy/bundle/manifests/controller.devfile.io_devworkspaceoperatorconfigs.yamldeploy/bundle/manifests/devworkspace-operator.clusterserviceversion.yamldeploy/deployment/kubernetes/combined.yamldeploy/deployment/kubernetes/objects/devworkspace-controller-role.ClusterRole.yamldeploy/deployment/kubernetes/objects/devworkspaceoperatorconfigs.controller.devfile.io.CustomResourceDefinition.yamldeploy/deployment/openshift/combined.yamldeploy/deployment/openshift/objects/devworkspace-controller-role.ClusterRole.yamldeploy/deployment/openshift/objects/devworkspaceoperatorconfigs.controller.devfile.io.CustomResourceDefinition.yamldeploy/templates/components/rbac/role.yamldeploy/templates/crd/bases/controller.devfile.io_devworkspaceoperatorconfigs.yamlgo.modmain.gopkg/config/sync.gopkg/provision/sync/diff.gopkg/provision/sync/diffopts.go
| AfterEach(func() { | ||
| config.SetGlobalConfigForTesting(testControllerCfg) | ||
| deleteDevWorkspaceRouting(devWorkspaceRoutingName) | ||
| deleteService(common.ServiceName(testWorkspaceID), testNamespace) | ||
| deleteService(common.EndpointName(discoverableEndpointName), testNamespace) | ||
| deleteHTTPRoute(exposedEndPointName, testNamespace, false) | ||
| deleteHTTPRoute(exposedEndPointName, testNamespace, true) | ||
| deleteHTTPRoute(discoverableEndpointName, testNamespace, false) | ||
| deleteHTTPRoute(discoverableEndpointName, testNamespace, true) | ||
| }) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
Cleanup asserts that every one of the four HTTPRoutes exists.
deleteHTTPRoute waits (up to the 10s timeout) for the route to exist and fails the spec if it never appears, so this AfterEach hard-asserts that a -http-redirect route is created for the discoverable endpoint too — something none of the It blocks verify. If the solver only emits a redirect route for non-discoverable exposed endpoints, every spec in this context fails during teardown with a confusing message.
Shares a root cause with the strict-existence wait in util_test.go; see the consolidated note.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@controllers/controller/devworkspacerouting/devworkspacerouting_controller_test.go`
around lines 430 - 439, Update the AfterEach cleanup around deleteHTTPRoute so
teardown does not require the discoverable endpoint’s redirect HTTPRoute to
exist; use cleanup behavior that tolerates absent routes while still removing
any routes that were created. Keep deletion for the other resources and verified
route variants unchanged, and align this with the non-strict cleanup approach
used by deleteHTTPRoute/util_test.go.
| // Sync HTTPRoutes if using gateway-api routing class | ||
| if len(httpRoutes) > 0 { | ||
| httpRoutesInSync, clusterHTTPRoutes, err := r.syncHTTPRoutes(instance, httpRoutes) | ||
| if err != nil { | ||
| failError := &sync.UnrecoverableSyncError{} | ||
| if errors.As(err, &failError) { | ||
| return reconcile.Result{}, r.markRoutingFailed(instance, err.Error()) | ||
| } | ||
| reqLogger.Error(err, "Error syncing HTTPRoutes") | ||
| return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes") | ||
| } else if !httpRoutesInSync { | ||
| reqLogger.Info("HTTPRoutes not in sync") | ||
| return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes") | ||
| } | ||
| clusterRoutingObj.HTTPRoutes = clusterHTTPRoutes | ||
| } | ||
|
|
There was a problem hiding this comment.
🩺 Stability & Availability | 🟠 Major | ⚡ Quick win
HTTPRoute sync/cleanup is skipped when the desired list becomes empty, unlike routes/ingresses.
Wrapping the sync in if len(httpRoutes) > 0 means syncHTTPRoutes (and its getHTTPRoutesToDelete cleanup) never runs once the solver produces zero desired HTTPRoutes for this CR — e.g. if a workspace's exposed endpoints drop to zero while gateway-api routing is still selected. Any previously-created HTTPRoutes stay live in the cluster (still routable) until the whole DevWorkspaceRouting CR is deleted. The routes/ingresses sync calls just above (lines 217-244) run unconditionally for exactly this reason — to let their delete-diffing logic clean up stale objects even when the desired list is empty.
🐛 Proposed fix — always call syncHTTPRoutes
- // Sync HTTPRoutes if using gateway-api routing class
- if len(httpRoutes) > 0 {
- httpRoutesInSync, clusterHTTPRoutes, err := r.syncHTTPRoutes(instance, httpRoutes)
- if err != nil {
- failError := &sync.UnrecoverableSyncError{}
- if errors.As(err, &failError) {
- return reconcile.Result{}, r.markRoutingFailed(instance, err.Error())
- }
- reqLogger.Error(err, "Error syncing HTTPRoutes")
- return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes")
- } else if !httpRoutesInSync {
- reqLogger.Info("HTTPRoutes not in sync")
- return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes")
- }
- clusterRoutingObj.HTTPRoutes = clusterHTTPRoutes
- }
+ // Sync HTTPRoutes (always, so stale HTTPRoutes get cleaned up even when 0 are desired)
+ httpRoutesInSync, clusterHTTPRoutes, err := r.syncHTTPRoutes(instance, httpRoutes)
+ if err != nil {
+ failError := &sync.UnrecoverableSyncError{}
+ if errors.As(err, &failError) {
+ return reconcile.Result{}, r.markRoutingFailed(instance, err.Error())
+ }
+ reqLogger.Error(err, "Error syncing HTTPRoutes")
+ return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes")
+ } else if !httpRoutesInSync {
+ reqLogger.Info("HTTPRoutes not in sync")
+ return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes")
+ }
+ clusterRoutingObj.HTTPRoutes = clusterHTTPRoutes📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| // Sync HTTPRoutes if using gateway-api routing class | |
| if len(httpRoutes) > 0 { | |
| httpRoutesInSync, clusterHTTPRoutes, err := r.syncHTTPRoutes(instance, httpRoutes) | |
| if err != nil { | |
| failError := &sync.UnrecoverableSyncError{} | |
| if errors.As(err, &failError) { | |
| return reconcile.Result{}, r.markRoutingFailed(instance, err.Error()) | |
| } | |
| reqLogger.Error(err, "Error syncing HTTPRoutes") | |
| return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes") | |
| } else if !httpRoutesInSync { | |
| reqLogger.Info("HTTPRoutes not in sync") | |
| return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes") | |
| } | |
| clusterRoutingObj.HTTPRoutes = clusterHTTPRoutes | |
| } | |
| // Sync HTTPRoutes (always, so stale HTTPRoutes get cleaned up even when 0 are desired) | |
| httpRoutesInSync, clusterHTTPRoutes, err := r.syncHTTPRoutes(instance, httpRoutes) | |
| if err != nil { | |
| failError := &sync.UnrecoverableSyncError{} | |
| if errors.As(err, &failError) { | |
| return reconcile.Result{}, r.markRoutingFailed(instance, err.Error()) | |
| } | |
| reqLogger.Error(err, "Error syncing HTTPRoutes") | |
| return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes") | |
| } else if !httpRoutesInSync { | |
| reqLogger.Info("HTTPRoutes not in sync") | |
| return reconcile.Result{Requeue: true}, r.reconcileStatus(instance, nil, nil, false, "Preparing HTTPRoutes") | |
| } | |
| clusterRoutingObj.HTTPRoutes = clusterHTTPRoutes |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@controllers/controller/devworkspacerouting/devworkspacerouting_controller.go`
around lines 246 - 262, Call syncHTTPRoutes unconditionally in the HTTPRoute
reconciliation block, including when httpRoutes is empty, so its
deletion-diffing cleanup removes stale cluster HTTPRoutes. Preserve the existing
error handling, requeue/status behavior, and assignment of
clusterRoutingObj.HTTPRoutes for successful synchronization.
| err = gwapiv1.AddToScheme(scheme.Scheme) | ||
| Expect(err).NotTo(HaveOccurred()) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -t d -p 'gateway-api/apis/v1$' | head
rg -nP '\b(Install|AddToScheme)\b\s*=' --glob '**/gateway-api/apis/v1/*.go'Repository: devfile/devworkspace-operator
Length of output: 167
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Find suite_test and references:"
fd -a 'suite_test.go$' . | sed 's#^\./##' | rg 'controllers/controller/devworkspacerouting|devworkspacerouting' || true
rg -n 'gwapiv1|routev1\.(Install|AddToScheme)|AddToScheme\(scheme\.Scheme\)' controllers/controller/devworkspacerouting go.mod go.sum 2>/dev/null || true
echo
echo "Go module gateway-api deps:"
python3 - <<'PY'
from pathlib import Path
for p in ['go.mod','go.sum']:
if Path(p).exists():
lines=[ln for ln in Path(p).read_text().splitlines() if 'gateway-api' in ln]
print(f'--- {p}')
for ln in lines[:40]:
print(ln)
PYRepository: devfile/devworkspace-operator
Length of output: 10022
🌐 Web query:
sigs.k8s.io/gateway-api v1.2.1 apis v1 Install AddToScheme deprecated
💡 Result:
In the Gateway API Go packages, the AddToScheme function is deprecated in favor of Install [1][2][3]. This deprecation is a common pattern in Kubernetes-related projects to align with updated conventions for registering API types into a runtime.Scheme. Both AddToScheme and Install typically resolve to the same underlying functionality provided by the SchemeBuilder [1][2][3], but Install is the currently supported and recommended idiom [2][4]. If you encounter code using AddToScheme (such as sigs.k8s.io/gateway-api/apis/v1.AddToScheme), you should update it to use the Install function from the same package (e.g., gwv1.Install) [2][4]. This ensures compatibility with current standards and avoids potential warnings or future removal of the deprecated alias [5][1][3]. It is also important to ensure that this registration happens exactly once (typically during the initialization or client setup phase) to avoid concurrency issues like "concurrent map writes" when multiple controllers or analyzers attempt to register types into the same shared runtime.Scheme simultaneously [2].
Citations:
- 1: https://github.com/istio/gateway-api/blob/e60ed053/apis/v1alpha2/zz_generated.register.go
- 2: https://github.com/k8sgpt-ai/k8sgpt/pull/1705/files
- 3: https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/v1.5.0/apix/config/v1alpha1/zz_generated.register.go
- 4: https://apache.googlesource.com/camel-k/+/25c3513fd12c52a386aa0f94148e8ae18eb225ca/pkg/apis/addtoscheme_gateway.go
- 5: https://gateway-api.sigs.k8s.io/guides/crd-management/
Replace the deprecated gwapiv1.AddToScheme call with gwapiv1.Install.
This path is flagged by staticcheck SA1019; Install is the non-deprecated gateway-api v1 scheme-builder replacement and already matches this file’s routev1.Install usage.
🐛 Proposed fix
- err = gwapiv1.AddToScheme(scheme.Scheme)
+ err = gwapiv1.Install(scheme.Scheme)
Expect(err).NotTo(HaveOccurred())📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| err = gwapiv1.AddToScheme(scheme.Scheme) | |
| Expect(err).NotTo(HaveOccurred()) | |
| err = gwapiv1.Install(scheme.Scheme) | |
| Expect(err).NotTo(HaveOccurred()) |
🧰 Tools
🪛 golangci-lint (2.12.2)
[error] 115-115: SA1019: gwapiv1.AddToScheme is deprecated: use Install instead
(staticcheck)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@controllers/controller/devworkspacerouting/suite_test.go` around lines 115 -
116, Replace the deprecated gwapiv1.AddToScheme call with gwapiv1.Install in the
scheme setup, matching the existing routev1.Install usage while preserving the
existing error assertion.
Source: Linters/SAST tools
| gatewayClassName: | ||
| default: nginx | ||
| description: |- | ||
| GatewayClassName is the name of the GatewayClass to use. | ||
| This is used for validation and informational purposes. | ||
| Defaults to "nginx" if not specified. | ||
| type: string | ||
| name: | ||
| description: Name is the name of the Gateway resource | ||
| type: string | ||
| namespace: | ||
| description: |- | ||
| Namespace is the namespace of the Gateway resource. | ||
| If not specified, HTTPRoutes will reference a Gateway in the same namespace | ||
| as the DevWorkspace. | ||
| type: string |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
Validate Gateway reference names as Kubernetes resource names.
name, namespace, and gatewayClassName are unrestricted strings; required only checks that name is present and still permits an empty or malformed value. Add DNS-1123/max-length validation so invalid references are rejected at the CRD boundary instead of failing during routing reconciliation.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In
`@deploy/templates/crd/bases/controller.devfile.io_devworkspaceoperatorconfigs.yaml`
around lines 66 - 81, The Gateway reference fields gatewayClassName, name, and
namespace in the CRD schema currently accept unrestricted strings. Add
Kubernetes DNS-1123 resource-name validation, including the appropriate maximum
length, to each field while preserving the existing descriptions and defaults;
ensure name remains required and empty or malformed values are rejected at CRD
validation.
| utilruntime.Must(controllerv1alpha1.AddToScheme(scheme)) | ||
| utilruntime.Must(dwv1.AddToScheme(scheme)) | ||
| utilruntime.Must(dwv2.AddToScheme(scheme)) | ||
| utilruntime.Must(gwapiv1.AddToScheme(scheme)) |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "Files:"
git ls-files | sed -n '1,120p'
echo
echo "Search gwapiv1 usage:"
rg -n "gwapiv1|Install\\(|AddToScheme\\(" -S . || true
echo
echo "Go module deps references:"
for f in go.mod go.sum; do
if [ -f "$f" ]; then
echo "--- $f ---"
rg -n "gateway|gwapiv1|sigs.k8s.io/gateway-api|AddToScheme|Install" "$f" || true
fi
doneRepository: devfile/devworkspace-operator
Length of output: 20904
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Read main.go around the referenced line without executing repository code.
if [ -f main.go ]; then
echo "--- main.go outline ---"
ast-grep outline main.go --view compact || true
echo "--- main.go lines 60-105 ---"
sed -n '60,105p' main.go | nl -ba -v60
fiRepository: devfile/devworkspace-operator
Length of output: 411
🌐 Web query:
gateway-api v1.2.1 apis/v1 AddToScheme deprecated Install
💡 Result:
In the context of the Kubernetes Gateway API, the function AddToScheme has been deprecated in favor of Install [1]. This transition is part of a broader move within the Kubernetes ecosystem to standardize how API types are registered with a runtime scheme. If you are maintaining code that previously used AddToScheme (e.g., v1alpha2.AddToScheme), you should update it to use the corresponding Install function (e.g., v1alpha2.Install) [1]. This pattern applies across the various API versions of the Gateway API (e.g., v1alpha2, v1beta1, v1) [1][2][3]. Regarding Gateway API v1.2.1 specifically, this was a patch release focused on addressing backward compatibility issues related to the SupportedFeatures field in the GatewayClass API [4][5]. It did not introduce the deprecation of AddToScheme itself, as this pattern is a general evolution of the project's Go client libraries [1]. If you are encountering issues related to installing CRDs or upgrading to v1.2 or later, please ensure that any stored versions of deprecated resources (such as v1alpha2 versions of GRPCRoute or ReferenceGrant) are properly migrated and removed from the storedVersions field in your custom resource definitions [4][6].
Citations:
- 1: remove deprecated v1alpha2.AddToScheme and use v1alpha2.Install instead kubernetes-sigs/gateway-api-inference-extension#649
- 2: https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1alpha2
- 3: https://pkg.go.dev/sigs.k8s.io/gateway-api/apis/v1beta1
- 4: https://github.com/kubernetes-sigs/gateway-api/blob/main/CHANGELOG/1.2-CHANGELOG.md
- 5: https://github.com/kubernetes-sigs/gateway-api/releases/tag/v1.2.1
- 6: https://gateway-api.sigs.k8s.io/guides/getting-started/introduction/
Use gwapiv1.Install(scheme) instead of the deprecated AddToScheme.
AddToScheme is kept only for compatibility in Gateway API Go types; this entry is the only scheme registration still using it here, so switch it to Install to align with the nearby route/template/oauth/security registrations and avoid staticcheck SA1019.
🐛 Proposed fix
- utilruntime.Must(gwapiv1.AddToScheme(scheme))
+ utilruntime.Must(gwapiv1.Install(scheme))📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| utilruntime.Must(gwapiv1.AddToScheme(scheme)) | |
| utilruntime.Must(gwapiv1.Install(scheme)) |
🧰 Tools
🪛 golangci-lint (2.12.2)
[error] 83-83: SA1019: gwapiv1.AddToScheme is deprecated: use Install instead
(staticcheck)
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@main.go` at line 83, Replace the deprecated gwapiv1.AddToScheme call in the
scheme-registration setup with gwapiv1.Install(scheme), preserving the existing
utilruntime.Must handling and matching the nearby Gateway API registrations.
Source: Linters/SAST tools
| var httpRouteDiffOpts = cmp.Options{ | ||
| cmpopts.IgnoreFields(gwapiv1.HTTPRoute{}, "TypeMeta", "ObjectMeta", "Status"), | ||
| cmpopts.IgnoreFields(gwapiv1.BackendRef{}, "Weight"), | ||
| cmpopts.IgnoreFields(gwapiv1.BackendObjectReference{}, "Group", "Kind", "Namespace"), | ||
| cmpopts.IgnoreFields(gwapiv1.ParentReference{}, "Group", "Kind", "Namespace"), | ||
| } |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/bin/bash
fd -t f 'gateway_api_solver.go' --exec cat -n {}Repository: devfile/devworkspace-operator
Length of output: 12597
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Map the diff options file and usages, then inspect the relevant sections.
ast-grep outline pkg/provision/sync/diffopts.go --view expanded || true
printf '\n--- usages ---\n'
rg -n "httpRouteDiffOpts|ParentReference|BackendObjectReference|HTTPRoute" pkg/provision/sync -g '!**/*_test.go'
printf '\n--- diffopts excerpt ---\n'
sed -n '1,180p' pkg/provision/sync/diffopts.goRepository: devfile/devworkspace-operator
Length of output: 5214
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the solver tests around gateway namespace assertions.
rg -n "Namespace|gatewayRef|ParentReference|BackendObjectReference|HTTPRoute" pkg/provision/sync -g '*_test.go'
printf '\n--- solver tests excerpt ---\n'
sed -n '1,240p' pkg/provision/sync/solvers/*gateway*test.go 2>/dev/null || trueRepository: devfile/devworkspace-operator
Length of output: 167
Keep ParentReference.Namespace in the comparison.
Group/Kind can stay ignored, but Namespace comes from GatewayRef.Namespace (or the routing namespace fallback), so ignoring it hides routing.gatewayRef.namespace changes and leaves existing HTTPRoutes attached to the old Gateway namespace.
Proposed fix
var httpRouteDiffOpts = cmp.Options{
cmpopts.IgnoreFields(gwapiv1.HTTPRoute{}, "TypeMeta", "ObjectMeta", "Status"),
cmpopts.IgnoreFields(gwapiv1.BackendRef{}, "Weight"),
cmpopts.IgnoreFields(gwapiv1.BackendObjectReference{}, "Group", "Kind", "Namespace"),
- cmpopts.IgnoreFields(gwapiv1.ParentReference{}, "Group", "Kind", "Namespace"),
+ cmpopts.IgnoreFields(gwapiv1.ParentReference{}, "Group", "Kind"),
}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| var httpRouteDiffOpts = cmp.Options{ | |
| cmpopts.IgnoreFields(gwapiv1.HTTPRoute{}, "TypeMeta", "ObjectMeta", "Status"), | |
| cmpopts.IgnoreFields(gwapiv1.BackendRef{}, "Weight"), | |
| cmpopts.IgnoreFields(gwapiv1.BackendObjectReference{}, "Group", "Kind", "Namespace"), | |
| cmpopts.IgnoreFields(gwapiv1.ParentReference{}, "Group", "Kind", "Namespace"), | |
| } | |
| var httpRouteDiffOpts = cmp.Options{ | |
| cmpopts.IgnoreFields(gwapiv1.HTTPRoute{}, "TypeMeta", "ObjectMeta", "Status"), | |
| cmpopts.IgnoreFields(gwapiv1.BackendRef{}, "Weight"), | |
| cmpopts.IgnoreFields(gwapiv1.BackendObjectReference{}, "Group", "Kind", "Namespace"), | |
| cmpopts.IgnoreFields(gwapiv1.ParentReference{}, "Group", "Kind"), | |
| } |
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
In `@pkg/provision/sync/diffopts.go` around lines 96 - 101, Update
httpRouteDiffOpts so cmpopts.IgnoreFields for gwapiv1.ParentReference omits only
Group and Kind, keeping Namespace included in comparisons; leave the other
HTTPRoute and reference-field ignore rules unchanged.
What does this PR do?
Adds a new
gateway-apirouting class to the DevWorkspace Operator that exposes workspace endpoints via Kubernetes Gateway APIHTTPRoutes instead of Ingress/Route resources.
GatewayAPISolverthat creates HTTPRoutes attached to a pre-provisioned Gateway referenced in the operator config (config.routing.gatewayRef)GatewayReferencetype toDevWorkspaceOperatorConfigAPI to configure the target Gateway name, namespace, and GatewayClassDevWorkspaceRoutingGatewayAPI("gateway-api") routing class constantsigs.k8s.io/gateway-apiadded as a dependency; Gateway API HTTPRoute CRD bundled indeploy/What issues does this PR fix or reference?
https://issues.redhat.com/browse/CRW-23675
Is it tested? How?
Unit tests added for the
GatewayAPISolverand routing controller covering:publicendpoints get HTTPRoutes)Manual verification:
DevWorkspaceOperatorConfigwithrouting.gatewayRefpointing to a pre-provisioned GatewayroutingClass: gateway-apiPR Checklist
/test v8-devworkspace-operator-e2e, v8-che-happy-pathto trigger)v8-devworkspace-operator-e2e: DevWorkspace e2e testv8-che-happy-path: Happy path for verification integration with Che🤖 Generated with Claude Code
Summary by CodeRabbit
New Features
Bug Fixes