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

@rohanKanojia rohanKanojia 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: DevWorkspace
apiVersion: workspace.devfile.io/v1alpha2
metadata:
  name: plain-dw-endpoint-annotations
spec:
  started: true
  routingClass: 'basic'
  template:
    components:
      - name: web-terminal
        container:
          image: quay.io/wto/web-terminal-tooling:next
          memoryRequest: 256Mi
          memoryLimit: 512Mi
          mountSources: true
          command:
           - "tail"
           - "-f"
           - "/dev/null"
          annotation:
            service:
              first-service-annotation: test
              second-service-annotation: test2
          endpoints:
          - name: endpoint-1
            targetPort: 8080
            protocol: http
            annotation:
              first-endpoint-annotation: test1
              second-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

openshift-ci Bot commented May 29, 2025

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 rohanKanojia force-pushed the pr/issue1293 branch 5 times, most recently from abfb699 to 708d590 Compare May 29, 2025 10:21
@rohanKanojia

Copy link
Copy Markdown
Member Author

/ok-to-test

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

Copy link
Copy Markdown
Member Author

/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
Member Author

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
Member Author

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
Member Author

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
Member Author

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
Member Author

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.
func InitializeForTesting(currentInfrastructure Type) {
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
func serviceAnnotations(sourceAnnotations map[string]string, isDiscoverable bool, serviceRoutingConfig controllerv1alpha1.Service) map[string]string {
func mergeServiceAnnotations(sourceAnnotations map[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
Member Author

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.

@akurinnoy akurinnoy 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

openshift-ci Bot commented Aug 5, 2025

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

openshift-ci Bot commented Aug 7, 2025

Copy link
Copy Markdown

New changes are detected. LGTM label has been removed.

@rohanKanojia

Copy link
Copy Markdown
Member Author

/retest

1 similar comment
@rohanKanojia

Copy link
Copy Markdown
Member Author

/retest

@rohanKanojia

Copy link
Copy Markdown
Member Author

/ok-to-test

@rohanKanojia

Copy link
Copy Markdown
Member Author

/retest

@rohanKanojia rohanKanojia force-pushed the pr/issue1293 branch 3 times, most recently from 7260efd to 625d885 Compare August 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

codecov Bot 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 19 commits behind head on main.

Files with missing lines Patch % Lines
apis/controller/v1alpha1/zz_generated.deepcopy.go 0.00% 21 Missing ⚠️
pkg/provision/workspace/routing.go 0.00% 11 Missing ⚠️
...s/controller/devworkspacerouting/solvers/common.go 78.57% 2 Missing and 1 partial ⚠️
...roller/devworkspacerouting/solvers/basic_solver.go 87.50% 2 Missing ⚠️
...ller/devworkspacerouting/solvers/cluster_solver.go 0.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 Sentry.
📢 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

tolusha commented Jun 26, 2026

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

tolusha commented Jun 26, 2026

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


# Criterion Verdict Notes
1 Problem Statement PASS Clear 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.
2 Reproduction Steps PASS Comprehensive testing instructions provided: setup CRC cluster, build custom operator image, install DWO, apply test DevWorkspace YAML with service annotations, and verify the Service resource.
3 Expected Behavior After Fix PASS Clearly 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"}.
4 Scope of Changes PASS 19 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.
5 Test Evidence PASS Strong 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.
6 Deployment & Verification Notes PASS Complete 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 free to 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