Skip to content

feat : Add support to add Service annotations from DevWorkspaceRouting configuration (#1293) - #1439

Open
rohanKanojia wants to merge 4 commits into
devfile:mainfrom
rohankanojia-forks:pr/issue1293
Open

feat : Add support to add Service annotations from DevWorkspaceRouting configuration (#1293)#1439
rohanKanojia wants to merge 4 commits into
devfile:mainfrom
rohankanojia-forks:pr/issue1293

Conversation

@rohanKanojia

@rohanKanojiarohanKanojia commented May 29, 2025

Copy link
Copy Markdown
Member

What does this PR do?

Add support for adding Service annotations from DevWorkspace component configuration to actual Service created by DevWorkspace operator

  • Add new field service that contains annotation field for storing annotations in DevWorkspaceRouting CustomResourceDefinition
  • Update code to read DevWorkspace component service annotation to DevWorkspaceRouting service configuration and apply these annotations while creating routing objects in DevWorkspaceRouting controller
  • Removes references to service annotations from the unsupported Devfile API documentation
  • Remove the webhook warning when applying service annotations

Signed-off-by: Rohan Kumar rohaan@redhat.com

What issues does this PR fix or reference?

Fix#1293

Is it tested? How?

  • Make sure CRC cluster is running
  • Install DWO on cluster based on changes added in this PR. You'd need to create new container image and install operator
export DWO_IMG=quay.io/rokumar/devworkspace-controller:dev
make docker
make install
  • Apply the following DevWorkspace object, that adds one endpoint exposes by a Service. There is also configuration for adding annotations in Service:
kind: DevWorkspaceapiVersion: workspace.devfile.io/v1alpha2metadata:
name: plain-dw-endpoint-annotationsspec:
started: trueroutingClass: 'basic'template:
components:
- name: web-terminalcontainer:
image: quay.io/wto/web-terminal-tooling:nextmemoryRequest: 256MimemoryLimit: 512MimountSources: truecommand:
- "tail"
- "-f"
- "/dev/null"annotation:
service:
first-service-annotation: testsecond-service-annotation: test2endpoints:
- name: endpoint-1targetPort: 8080protocol: httpannotation:
first-endpoint-annotation: test1second-endpoint-annotation: test2 
  • Once the workspace has started, check the created Service, annotations specified in should be applied there
oc get svc workspaceaf104799e6fb4633-service -ojsonpath='{.metadata.annotations}'
{"first-service-annotation":"test","second-service-annotation":"test2"}

PR Checklist

  • E2E tests pass (when PR is ready, comment /test v8-devworkspace-operator-e2e, v8-che-happy-path to trigger)
    • v8-devworkspace-operator-e2e: DevWorkspace e2e test
    • v8-che-happy-path: Happy path for verification integration with Che

@openshift-ci

Copy link
Copy Markdown

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@rohanKanojia
rohanKanojiaforce-pushed the pr/issue1293 branch 5 times, most recently from abfb699 to 708d590CompareMay 29, 2025 10:21
@rohanKanojia

Copy link
Copy Markdown
MemberAuthor

/ok-to-test

@rohanKanojia
rohanKanojiaforce-pushed the pr/issue1293 branch 3 times, most recently from 2c63671 to 96c6a02CompareMay 29, 2025 14:18
@rohanKanojia

Copy link
Copy Markdown
MemberAuthor

/ok-to-test

// GetDiscoverableServicesForEndpoints converts the endpoint list into a set of services, each corresponding to a single discoverable
// endpoint from the list. Endpoints with the NoneEndpointExposure are ignored.
func GetDiscoverableServicesForEndpoints(endpoints map[string]controllerv1alpha1.EndpointList, meta DevWorkspaceMetadata) []corev1.Service {
func GetDiscoverableServicesForEndpoints(routingSpec controllerv1alpha1.DevWorkspaceRoutingSpec, meta DevWorkspaceMetadata) []corev1.Service {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If possible, it would be best if this function signature (and also GetServiceForEndpoints) are not changed so that function consumers are not affected. For example for che-operator, we use solver.GetServiceForEndpoints in che_routing.go

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or, if we want to change the function signature, maybe we can refactor it to use "Functional Options Pattern" so that new fields can be easily added without breaking consumer code: https://golang.cafe/blog/golang-functional-options-pattern.html ?

For example something similar to:

solver.GetDiscoverableServicesForEndpoints(
solver.WithEndpoints(endpoints),
solver.WithMetadata(metadata),
solver.WithAnnotations(annotations),
)

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm, good point. I wasn't aware about this. Let me think if it's possible to do it without changing method signature.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking closely at the changes, Currently Service generation is closely tied to Endpoints, We're going over component to endpoint map and creating Service accordingly. At this point we know for which component we're creating Service, so we can add appropriate annotations for appropriate component.

However, if we want to move this logic outside and set annotations after creating the Service; it would be uncertain which Service belongs to which component. If we decide to mutate Service with a marker label containing component, it should become possible:

I mean replacing this

Namespace: meta.Namespace,
Labels: map[string]string{
constants.DevWorkspaceIDLabel: meta.DevWorkspaceId,
},

 Labels: map[string]string{
constants.DevWorkspaceIDLabel: meta.DevWorkspaceId,
+ "workspace.dev/component": componentName,
},

We can then iterate over generated Services and apply annotations by reading component label (that can be deleted after processing). If you think this approach is okay then I can make changes to keep original method signature.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IMHO it should be the DWO that provides the API that conforms with the Devfile spec, therefore, it makes more sense to apply annotations within the functions provided by DWO

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Umm, Not 100% sure I understand but do you mean it's okay to keep these changes?

}

var isOpenShift = func() bool {
return infrastructure.IsOpenShift()

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since infrastructure.IsOpenShift() is commonly used in the codebase, I don't think this fcuntion is necessary

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I had exposed this for testing. I wanted to mock the behavior of infrastructure.IsOpenShift() method.

Let me think on how I can do it without adding this function.

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, I see there is already a method created for mocking behavior of this method for tests

// InitializeForTesting is used to mock running on a specific type of cluster (Kubernetes, OpenShift) in testing code.
funcInitializeForTesting(currentInfrastructureType) {
current=currentInfrastructure
initialized=true

I'll use already provided method instead of what I added.

return annotations
}

func serviceAnnotations(sourceAnnotations map[string]string, isDiscoverable bool, serviceRoutingConfig controllerv1alpha1.Service) map[string]string {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
funcserviceAnnotations(sourceAnnotationsmap[string]string, isDiscoverablebool, serviceRoutingConfig controllerv1alpha1.Service) map[string]string {
funcmergeServiceAnnotations(sourceAnnotationsmap[string]string, serviceRoutingConfig controllerv1alpha1.Service) map[string]string {

I suggest "merge" for more clarity.

Also, for readability and simplicity I think it would be best to avoid boolean flags and instead call the function like:

serviceAnnotations := map[string]string{
constants.DevWorkspaceDiscoverableServiceAnnotation: "true",
}
mergeServiceAnnotations(serviceAnnotations, routingSpec.Service[componentName]),

WDYT?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, I'll update it as per your comments.

@akurinnoyakurinnoy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I followed the "Is it tested? How?" steps and got the expected result.

@openshift-ci

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: akurinnoy, dkwon17, rohanKanojia

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci

Copy link
Copy Markdown

New changes are detected. LGTM label has been removed.

@rohanKanojia

Copy link
Copy Markdown
MemberAuthor

/retest

1 similar comment
@rohanKanojia

Copy link
Copy Markdown
MemberAuthor

/retest

@rohanKanojia

Copy link
Copy Markdown
MemberAuthor

/ok-to-test

@rohanKanojia

Copy link
Copy Markdown
MemberAuthor

/retest

@rohanKanojia
rohanKanojiaforce-pushed the pr/issue1293 branch 3 times, most recently from 7260efd to 625d885CompareAugust 25, 2025 10:21
Signed-off-by: Rohan Kumar <rohaan@redhat.com>
Signed-off-by: Rohan Kumar <rohaan@redhat.com>
Signed-off-by: Rohan Kumar <rohaan@redhat.com>
Signed-off-by: Rohan Kumar <rohaan@redhat.com>
@codecov

codecovBot commented Sep 2, 2025

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 44.11765% with 38 lines in your changes missing coverage. Please review.
✅ Project coverage is 35.20%. Comparing base (8f2d764) to head (f74cc50).
⚠️ Report is 131 commits behind head on main.

Files with missing linesPatch %Lines
apis/controller/v1alpha1/zz_generated.deepcopy.go0.00%21 Missing ⚠️
pkg/provision/workspace/routing.go0.00%11 Missing ⚠️
...s/controller/devworkspacerouting/solvers/common.go78.57%2 Missing and 1 partial ⚠️
...roller/devworkspacerouting/solvers/basic_solver.go87.50%2 Missing ⚠️
...ller/devworkspacerouting/solvers/cluster_solver.go0.00%1 Missing ⚠️
Additional details and impacted files
@@ Coverage Diff @@## main #1439 +/- ##
==========================================
+ Coverage 34.05% 35.20% +1.14% 
==========================================
Files 160 160 Lines 13336 13388 +52 ==========================================
+ Hits 4542 4713 +171 + Misses 8484 8355 -129 - Partials 310 320 +10 

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@openshift-merge-robot

Copy link
Copy Markdown

PR needs rebase.

Details

Instructions 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.

@tolusha

Copy link
Copy Markdown
Contributor

Hi! I'm che-ai-assistant — I help with your pull requests.

Available commands:

  • /che-ai-assistant generate-che-doc — Generate a documentation PR based on this PR's changes
  • /che-ai-assistant ok-pr-review — Run a comprehensive PR review (summary, code review, deep review, impact analysis)
  • /che-ai-assistant ok-pr-test-ready — Ensure PR has validation steps
  • /che-ai-assistant help — Show this help message

@tolusha

tolusha commented Jun 26, 2026

Copy link
Copy Markdown
Contributor

/che-ai-assistant ok-pr-readiness

Review is complete. Please check the review comments below.

@tolusha

Copy link
Copy Markdown
Contributor

PR Readiness Assessment: PR #1439 — feat : Add support to add Service annotations from DevWorkspaceRouting configuration (#1293)

Repository: devfile/devworkspace-operator
Linked Issue: #1293 — Add Service Annotations to the DevWorkspaceRouting CRD


#CriterionVerdictNotes
1Problem StatementPASSClear description of the feature: adding support for Service annotations from DevWorkspace component configuration. Linked issue #1293 provides additional context about resolving container-level service annotations.
2Reproduction StepsPASSComprehensive testing instructions provided: setup CRC cluster, build custom operator image, install DWO, apply test DevWorkspace YAML with service annotations, and verify the Service resource.
3Expected Behavior After FixPASSClearly stated: service annotations specified in the DevWorkspace component config should appear on the created Kubernetes Service. Expected output shown: {"first-service-annotation":"test","second-service-annotation":"test2"}.
4Scope of ChangesPASS19 files changed with clear rationale. Core changes: new Service field in DevWorkspaceRouting CRD, updates to routing controllers to merge and apply annotations, removal of webhook warnings (now supported), comprehensive tests. Most file count is CRD manifests and generated code. Breaking changes documented in CHANGELOG.
5Test EvidencePASSStrong test coverage: 247 lines of new unit tests in basic_solver_test.go covering annotation merging, Kubernetes ingress generation, and OpenShift route generation. Existing controller tests updated to verify service annotations. Manual testing guidance with specific commands and expected output.
6Deployment & Verification NotesPASSComplete verification guidance: specific commands to build operator image (make docker), install (make install), apply test DevWorkspace, and verify with oc get svc using JSONPath to inspect annotations.

Overall: READY


Missing Information

While the PR is comprehensive, these minor items could be added:

  • E2E test results: The PR checklist shows E2E tests haven't been triggered yet. Comment /test v8-devworkspace-operator-e2e, v8-che-happy-path to run them as indicated in the checklist.
  • Target version/milestone: Consider mentioning which operator version this targets (appears to be v0.37.0 based on CHANGELOG structure).

What's Good

  • Excellent testing instructions: Step-by-step manual verification with exact commands, sample YAML, and expected output makes this trivial to reproduce and verify.
  • Comprehensive test coverage: New unit tests cover both Kubernetes (Ingress) and OpenShift (Route) platforms, plus annotation merging logic.
  • API changes well-documented: Breaking changes in method signatures clearly documented in CHANGELOG with specific methods and parameter changes listed.
  • Feature completion: Removed service annotations from unsupported features documentation and webhook warnings, showing the feature is fully integrated.
  • Clear example configuration: Sample DevWorkspace YAML demonstrates both endpoint-level and service-level annotations, making the feature easy to understand.
  • Generated code properly updated: All necessary generated files (deepcopy, CRD manifests for multiple platforms) have been regenerated.

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add Service Annotations to the DevWorkspaceRouting CRD

5 participants

@rohanKanojia@openshift-merge-robot@tolusha@akurinnoy@dkwon17