Skip to content

Use label-selector for namespace discovery instead of iterating#6

Merged
rgrunber merged 3 commits intoredhat-developer:mainfrom
achdmbp:fix/namespace-discovery-performance
Apr 9, 2026
Merged

Use label-selector for namespace discovery instead of iterating#6
rgrunber merged 3 commits intoredhat-developer:mainfrom
achdmbp:fix/namespace-discovery-performance

Conversation

@achdmbp
Copy link
Copy Markdown
Contributor

@achdmbp achdmbp commented Apr 6, 2026

Problem

getProjects() calls oc projects -q which returns every namespace the user has access to. For users with broad RBAC (cluster admins, platform teams), this can be thousands of namespaces. The extension then iterates each one sequentially, making it unusable.

Changes

src/utils/cluster.ts

  • getProjects() — replaced oc projects -q with a label-selector query (app.kubernetes.io/component=workspaces-namespace) that returns only DevSpaces workspace namespaces. Filters by che.eclipse.org/username annotation to match the current user. Falls back gracefully if the query fails.

  • getProjectFromWorkspaceURL() (new) — when connecting via workspace URL, extracts the workspace name from the URL path and resolves the namespace with oc get devworkspace --all-namespaces --field-selector=metadata.name=<name>. Single API call, no iteration.

  • generateHostEntry() — quoted the IdentityFile path to handle paths with spaces (e.g., Application Support on macOS).

src/extension.ts

  • Activation now checks isLoggedIn() before calling getProjects() to prevent activation failures when not authenticated.
  • Connect command uses getProjectFromWorkspaceURL() for direct namespace resolution from the provided URL.

Testing

Tested on a ROSA cluster where the authenticated user has access to 2,302 namespaces. Before this change, the extension never finished loading. After, workspace discovery completes in under 2 seconds.

Both the Remote Explorer view and the "Connect to Dev Spaces" URL flow work correctly.

Thank you for considering this contribution — happy to adjust anything based on your feedback.

…all projects

- Replace oc projects -q with label-selector query on
  app.kubernetes.io/component=workspaces-namespace to find only
  DevSpaces workspace namespaces in a single API call
- Filter by che.eclipse.org/username annotation for current user
- Add getProjectFromWorkspaceURL() to resolve namespace directly
  from workspace URL via field-selector on DevWorkspace CR
- Check isLoggedIn() before getProjects() during activation
- Quote IdentityFile path in SSH config to handle spaces in paths
- Add skipLibCheck to tsconfig for compatibility with global @types
Copy link
Copy Markdown
Member

@rgrunber rgrunber left a comment

Choose a reason for hiding this comment

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

Thanks for proposing something for this. The problem seems to be that by default, users may not have permissions to call these commands, which is probably why oc projects -q was used. I've included some feedback.

If not enough time to respond/update, I'm happy to take over.

Comment thread src/utils/cluster.ts Outdated
Comment thread tsconfig.json Outdated
Comment thread src/utils/cluster.ts Outdated
…covery

- Use 'oc get projects -l' (Project API) instead of 'oc get namespaces -l'
  to avoid cluster-scoped permission errors for regular users
- Case-insensitive exact match on che.eclipse.org/username annotation
  to correctly resolve the user's namespace(s)
- Return all matching namespaces (users may have more than one)
- Simplify getOpenShiftApiURL() to discover the API URL via the
  unauthenticated /oauth/start redirect, replacing .apps. hostname
  parsing — works for both standard and custom DevSpaces domains
- Use Node.js https module instead of curl for cross-platform compatibility
- Quote IdentityFile path in SSH config to handle spaces (macOS)
- Remove skipLibCheck from tsconfig.json
@achdmbp achdmbp force-pushed the fix/namespace-discovery-performance branch from 89a07e9 to 11d7018 Compare April 8, 2026 05:43
@achdmbp
Copy link
Copy Markdown
Contributor Author

achdmbp commented Apr 8, 2026

Thanks for the review @rgrunber. Addressed all feedback:

  • Namespace permissions: Switched from oc get namespaces -l to oc get projects -l which uses the OpenShift Project API (user-scoped, no cluster-scope permissions needed). Tested with a regular user who gets 403 on namespace list but the project query works fine.

  • Annotation matching: Now uses case-insensitive exact match on che.eclipse.org/username and returns all matching namespaces (users can have more than one in edge cases we have).

  • skipLibCheck: Removed.

  • Custom DevSpaces URLs: During testing, discovered that getOpenShiftApiURL fails when DevSpaces is behind a custom domain (e.g., devspaces.example.com instead of *.apps.<cluster>). The .apps. hostname parsing returns undefined for custom domains. Replaced with an approach that hits the unauthenticated /oauth/start endpoint to discover the real cluster hostname via the OAuth redirect, then derives the API URL from that. Works for both standard and custom domains. Uses Node.js https module instead of curl for cross-platform compatibility.

  • Cleanup: Removed getProjectFromWorkspaceURL — the connect command now uses getProjects() directly since it's already fast with the label-selector approach.

Tested end-to-end with both an admin user (2,300+ namespaces) and a regular user with no cluster-scoped permissions. Both work correctly, including with a custom DevSpaces domain.

Happy to adjust further if needed

@achdmbp achdmbp requested a review from rgrunber April 8, 2026 05:49
- Satisfy linter by avoiding dynamic 'require' and just use 'import'
- Avoid destructuring API sensitive types (statusCode can also be
  undefined)
- Fall back to basic approach of extracting API URL if '/oath/start'
  redirect fails

Signed-off-by: Roland Grunberg <rgrunber@redhat.com>
Copy link
Copy Markdown
Member

@rgrunber rgrunber left a comment

Choose a reason for hiding this comment

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

Overall, this looks good to me. The changes in getOpenShiftApiURL seem to work well. I'm not competely sure that 302 will always be the case (maybe should check >= 300 && < 400 ) or whether oauth-openshift.apps will always be the name of the oauth service, but it's a better approach than what was there. I just kept the old approach in case this fails for any reason.

oc get project -l app.kubernetes.io/component=workspaces-namespace is definitely the better approach 👍 . Seems to be confirmed by https://docs.redhat.com/en/documentation/red_hat_openshift_dev_spaces/3.27/html/administration_guide/assembly_configuring-projects_administration_guide#proc_provisioning-projects-in-advance_administration_guide .

Only other things I changed were related to some linting/type compatibility issues. I plan to merge this soon, and kick off a pre-release build.

@rgrunber rgrunber merged commit fb9f909 into redhat-developer:main Apr 9, 2026
@rgrunber rgrunber changed the title fix: use label-selector for namespace discovery instead of iterating … Use label-selector for namespace discovery instead of iterating Apr 9, 2026
@rgrunber
Copy link
Copy Markdown
Member

rgrunber commented Apr 9, 2026

v0.2.2026040904, which is published as a pre-release on the marketplace should contain this. @achdmbp , if you can confirm that this (still) solves the issue, we can probably make a new release.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants