Skip to content

ROSAENG-62089: doc: Add client-go vs custom SDK comparison doc - #186

Open
cdoan1 wants to merge 1 commit into
openshift-online:mainfrom
cdoan1:ROSAENG-62661-clientgo
Open

ROSAENG-62089: doc: Add client-go vs custom SDK comparison doc#186
cdoan1 wants to merge 1 commit into
openshift-online:mainfrom
cdoan1:ROSAENG-62661-clientgo

Conversation

@cdoan1

@cdoan1 cdoan1 commented Jul 27, 2026

Copy link
Copy Markdown
Collaborator

Explains why client-go works for rosa-hyperfleet-api consumers, compares approaches (controller-runtime, typed clientset, REST gateway), and recommends starting with the existing API types module.

Description

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/CD or tooling change

Testing

  • Unit tests pass (make test)
  • Integration tests pass (if applicable)
  • Manual verification completed

Checklist

  • My code follows the project's coding conventions
  • I have updated documentation as needed
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass

Summary by CodeRabbit

  • Documentation
    • Added guidance for Go integrations using Kubernetes client-go and controller-runtime patterns.
    • Compared client-go with custom SDK approaches, including authentication, authorization, watch support, maintenance, and ecosystem compatibility.
    • Documented integration options and architectural considerations for REST gateway and Kubernetes API usage.
    • Included recommendations for adopting controller-runtime patterns and selectively adding typed client generation.

Explains why client-go works for rosa-hyperfleet-api consumers,
compares approaches (controller-runtime, typed clientset, REST gateway),
and recommends starting with the existing API types module.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@openshift-ci

openshift-ci Bot commented Jul 27, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cdoan1

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 added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 27, 2026
@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds documentation comparing Kubernetes client-go/controller-runtime usage with a custom SDK, describing current API support, typed-client generation options, REST-gateway constraints, integration paths, and recommended adoption steps.

Changes

Client integration guidance

Layer / File(s) Summary
API capabilities and client prerequisites
docs/api/v2-clientgo-vs-custom-sdk.md
Introduces the comparison scope and documents existing API types, scheme registration, deep-copy support, CRDs, and the absence of generated clientsets, informers, and listers.
Controller-runtime and typed client paths
docs/api/v2-clientgo-vs-custom-sdk.md
Describes generic controller-runtime CRUD/watch usage, optional code-generator support, required generator tags, and client-go versus custom SDK characteristics.
REST gateway boundaries and recommendations
docs/api/v2-clientgo-vs-custom-sdk.md
Explains Kubernetes API server versus REST-gateway architecture, presents three integration paths, and recommends controller-runtime with types-module reuse before generating typed clientsets.

Estimated code review effort: 1 (Trivial) | ~5 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 10 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Ai-Attribution ⚠️ Warning The commit uses a Co-Authored-By trailer for Claude, but the check requires Red Hat Assisted-by or Generated-by attribution. Replace the AI co-author trailer with a Red Hat-compliant Assisted-by or Generated-by trailer, and avoid Co-Authored-By for AI tools.
✅ Passed checks (10 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Weak-Crypto ✅ Passed The new doc contains no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB or custom-crypto/secret-compare code; only SigV4 auth mentions appear.
Container-Privileges ✅ Passed PR only adds a Markdown doc; no container/K8s manifests or privilege settings (privileged, hostPID/Network/IPC, SYS_ADMIN, allowPrivilegeEscalation) were changed.
No-Sensitive-Data-In-Logs ✅ Passed PASS: The new doc has no logging statements or examples exposing secrets/PII; only generic auth terms like token refresh appear.
No-Hardcoded-Secrets ✅ Passed Added doc contains no hardcoded secrets; scans found no credential literals, private keys, or embedded-credential URLs.
No-Injection-Vectors ✅ Passed The PR is documentation-only and the changed file contains no eval/exec, unsafe YAML/pickle, os.system, or HTML injection patterns.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly identifies the documentation change and its comparison between client-go and custom SDK approaches.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🤖 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 `@docs/api/v2-clientgo-vs-custom-sdk.md`:
- Around line 265-268: Update the Path 2 recommendation in the API client
comparison so it refers to continuing to version and document the existing,
already-importable API types module instead of publishing it. Keep the guidance
about using the module for serialization with a thin HTTP client unchanged.
- Around line 280-284: Update the summary table’s client-go support statements
to distinguish controller-runtime/pkg/client, which works today for direct
Kubernetes API access with zero changes, from generated typed client-go clients,
which are not yet implemented and remain optional future work. Adjust the “What
should we do first?” guidance to preserve this distinction.
- Line 120: Update the client initialization in the example to use a
watch-capable client via client.NewWithWatch or client.WithWatch before calling
c.Watch. Keep the existing Watch invocation and ClusterList argument unchanged.
- Around line 35-49: Update the Go examples in this document to be
copy-pastable: add the runtime import and remove the unused controller-runtime
scheme import in the client setup example; define or import ctx and metav1,
replace the invalid NodePoolSpec placeholder with valid Go, and use the
appropriate watch API instead of client.Client.Watch; add the bytes import where
bytes.NewReader is used. If these snippets are intentionally incomplete,
explicitly label them as pseudocode instead.
- Around line 133-148: Update the API type declarations for Cluster, NodePool,
Placement, ManagementCluster, and Manifest to include +genclient markers, while
preserving the existing package-level generation tags and client generation
workflow.
🪄 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: Repository: openshift-online/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Enterprise

Run ID: 77e95f97-5219-45b9-935f-3b18ce287b4f

📥 Commits

Reviewing files that changed from the base of the PR and between d8bf579 and f4c347d.

📒 Files selected for processing (1)
  • docs/api/v2-clientgo-vs-custom-sdk.md

Comment thread docs/api/v2-clientgo-vs-custom-sdk.md
c.Create(ctx, np)

// Watch for changes
c.Watch(ctx, &hyperfleetv1.ClusterList{})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== Relevant doc excerpt =="
sed -n '105,130p' docs/api/v2-clientgo-vs-custom-sdk.md | cat -n

echo
echo "== Controller-runtime version =="
if [ -f go.mod ]; then
  rg -n 'sigs\.k8s\.io/controller-runtime' go.mod || true
fi

echo
echo "== Any mention of Watch-capable client in repo =="
rg -n 'NewWithWatch|WithWatch|Watch\(' docs go.mod .github -g '!**/vendor/**' || true

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 1430


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "== File size =="
wc -l docs/api/v2-clientgo-vs-custom-sdk.md

echo
echo "== Lines around the cited snippet =="
sed -n '115,125p' docs/api/v2-clientgo-vs-custom-sdk.md | cat -n

echo
echo "== Search for any local helper/interface adding Watch to client.Client =="
rg -n 'type .*interface.*Watch|interface .*Watch|func .*Watch\(' -g '*.go' . || true

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 809


Use a watch-capable client here. client.New returns client.Client, which doesn’t expose Watch; switch this example to client.NewWithWatch or wrap it with client.WithWatch so the snippet is valid.

🤖 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 `@docs/api/v2-clientgo-vs-custom-sdk.md` at line 120, Update the client
initialization in the example to use a watch-capable client via
client.NewWithWatch or client.WithWatch before calling c.Watch. Keep the
existing Watch invocation and ClusterList argument unchanged.

Comment on lines +133 to +148
```bash
# 1. Add code-generator to hack/tools
go get k8s.io/code-generator@v0.36.0

# 2. Add generation tags to api/v1alpha1/doc.go
// +k8s:deepcopy-gen=package,register
// +k8s:defaulter-gen=TypeMeta
// +k8s:openapi-gen=true
// +groupName=hyperfleet.io

# 3. Create hack/update-codegen.sh (mirror hypershift's script)
# Generates: client/clientset/, client/informers/, client/listers/

# 4. Add Makefile target
make clients
```

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

# Locate the referenced doc and inspect the relevant section with line numbers.
doc="docs/api/v2-clientgo-vs-custom-sdk.md"
echo "=== $doc (lines 120-170) ==="
sed -n '120,170p' "$doc" | cat -n

echo
echo "=== Search for Kubernetes dependency/version pins ==="
rg -n --hidden --glob '!**/.git/**' 'k8s.io/(client-go|apimachinery|code-generator)|code-generator@|client-go' -S . | sed -n '1,220p'

echo
echo "=== Search for genclient markers and related codegen notes ==="
rg -n --hidden --glob '!**/.git/**' '\+genclient|\+k8s:deepcopy-gen|\+k8s:defaulter-gen|\+k8s:openapi-gen|hack/update-codegen|make clients' -S . | sed -n '1,220p'

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 24495


🏁 Script executed:

#!/bin/bash
set -euo pipefail

doc="docs/api/v2-clientgo-vs-custom-sdk.md"
echo "=== $doc (lines 120-170) ==="
sed -n '120,170p' "$doc" | cat -n

echo
echo "=== Search for Kubernetes dependency/version pins ==="
rg -n --hidden --glob '!**/.git/**' 'k8s.io/(client-go|apimachinery|code-generator)|code-generator@|client-go' -S . | sed -n '1,220p'

echo
echo "=== Search for genclient markers and related codegen notes ==="
rg -n --hidden --glob '!**/.git/**' '\+genclient|\+k8s:deepcopy-gen|\+k8s:defaulter-gen|\+k8s:openapi-gen|hack/update-codegen|make clients' -S . | sed -n '1,220p'

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 24495


🏁 Script executed:

#!/bin/bash
set -euo pipefail

doc="docs/api/v2-clientgo-vs-custom-sdk.md"
echo "=== $doc (lines 120-170) ==="
sed -n '120,170p' "$doc" | cat -n

echo
echo "=== Candidate dependency manifest files ==="
git ls-files | rg '(^|/)(go\.mod|go\.sum|Makefile|go\.work|package\.json|buf\.yaml|helmfile\.yaml|\.mod)$|(^|/)(api|apis|pkg)/.*\.go$' | sed -n '1,240p'

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 4981


🌐 Web query:

Kubernetes code-generator version must match client-go/apimachinery version genclient markers required typed clients

💡 Result:

When working with Kubernetes code generation, maintaining version synchronization between components is critical for stability, though the specific mechanisms and requirements are well-defined: 1. Version Matching: The k8s.io/code-generator repository explicitly states that its HEAD matches the HEAD of k8s.io/apiserver, k8s.io/apimachinery, and k8s.io/client-go [1][2][3]. When consuming these libraries, it is standard practice to align the versions of k8s.io/code-generator, k8s.io/apimachinery, and k8s.io/client-go within your go.mod file [2][4]. Using mismatched versions often leads to compilation errors or subtle runtime issues due to changes in internal API structures or helper library signatures [5]. 2. Genclient Markers: To generate typed clients for your API types, you must use the // +genclient marker [6][7]. - This marker must be placed above the struct definition for the API type (e.g., in your types.go file) [6]. - It must not be placed above the List type (e.g., PodList) [7]. - The generator uses this marker as an opt-in mechanism; without it, the client-gen tool will ignore the type [7][8]. - Additional tags such as // +genclient:nonNamespaced, // +genclient:noStatus, and various verb-control tags (e.g., // +genclient:onlyVerbs=...) can be used to further configure the behavior of the generated client [6][7]. In summary, ensure that your k8s.io dependencies are pinned to compatible versions—ideally matching the Kubernetes release cycle you are targeting [5]—and ensure that every resource you wish to have a typed client for is explicitly annotated with the // +genclient tag [6][7].

Citations:


🌐 Web query:

site:kubernetes.io code-generator genclient marker typed client client-gen README version match client-go/apimachinery

💡 Result:

In the context of the Kubernetes code-generator toolset, the +genclient marker is a directive used to instruct client-gen to generate a typed client for a specific API group or resource [1]. Key points regarding the use of these markers and version matching include: 1. Marker Purpose: The +genclient marker is typically placed in the doc.go file or above the relevant type definition within your API package to signal that the code generator should produce a typed clientset for the associated custom resource [1]. This enables type-safe interactions with your Kubernetes custom resources rather than relying on less efficient or error-prone dynamic clients [1]. 2. Version Matching (client-go and code-generator): It is critical that the version of k8s.io/code-generator matches the version of k8s.io/client-go and the Kubernetes API machinery your project depends on [1]. Mismatches between these dependencies often lead to build failures, incompatible generated code, or runtime errors because the internal structures (such as API schemes and object metadata) may differ between versions [1][2]. 3. Implementation Best Practices: - When setting up your project, ensure that the version (or branch) of code-generator matches the target Kubernetes release [1]. - If using Go modules, the go.mod file should reflect consistent versions across all k8s.io/* repositories. Historically, projects pinned these to specific Kubernetes release tags (e.g., kubernetes-1.9.0) to ensure compatibility [1]. - Beyond genclient, modern Kubernetes development also utilizes various other markers (e.g., +k8s:listType, +k8s:immutable) for declarative validation and server-side apply, which are processed by specialized generators like validation-gen [3][4][5]. Always consult the go.mod file of the specific kubernetes/kubernetes release you are targeting to ensure that your local development dependencies align with the upstream source [6][2].

Citations:


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== api/v1alpha1 files ==="
git ls-files 'hyperfleet-operator/api/v1alpha1/*' | sed -n '1,200p'

echo
echo "=== api/v1alpha1/doc.go ==="
sed -n '1,220p' hyperfleet-operator/api/v1alpha1/doc.go | cat -n

echo
echo "=== api/v1alpha1/cluster_types.go ==="
sed -n '1,220p' hyperfleet-operator/api/v1alpha1/cluster_types.go | cat -n

echo
echo "=== api/v1alpha1/nodepool_types.go ==="
sed -n '1,220p' hyperfleet-operator/api/v1alpha1/nodepool_types.go | cat -n

echo
echo "=== api/v1alpha1/placement_types.go ==="
sed -n '1,220p' hyperfleet-operator/api/v1alpha1/placement_types.go | cat -n

echo
echo "=== api/v1alpha1/managementcluster_types.go ==="
sed -n '1,220p' hyperfleet-operator/api/v1alpha1/managementcluster_types.go | cat -n

echo
echo "=== api/v1alpha1/manifest_types.go ==="
sed -n '1,220p' hyperfleet-operator/api/v1alpha1/manifest_types.go | cat -n

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 689


🏁 Script executed:

#!/bin/bash
set -euo pipefail

echo "=== types files with line numbers ==="
for f in \
  hyperfleet-operator/api/v1alpha1/cluster_types.go \
  hyperfleet-operator/api/v1alpha1/nodepool_types.go \
  hyperfleet-operator/api/v1alpha1/placement_types.go \
  hyperfleet-operator/api/v1alpha1/managementcluster_types.go \
  hyperfleet-operator/api/v1alpha1/manifest_types.go \
  hyperfleet-operator/api/v1alpha1/groupversion_info.go
do
  echo
  echo "--- $f ---"
  sed -n '1,220p' "$f" | cat -n
done

echo
echo "=== search for genclient markers in repo ==="
rg -n --hidden --glob '!**/.git/**' '\+genclient|client-gen|customresourcedefinitions|SchemeBuilder|AddToScheme' hyperfleet-operator/api platform-api hyperfleet-db docs -S | sed -n '1,240p'

Repository: openshift-online/rosa-hyperfleet-api

Length of output: 28947


Add +genclient on the concrete API types.
Package-level tags alone won’t generate a typed clientset; Cluster, NodePool, Placement, ManagementCluster, and Manifest need +genclient markers.

🤖 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 `@docs/api/v2-clientgo-vs-custom-sdk.md` around lines 133 - 148, Update the API
type declarations for Cluster, NodePool, Placement, ManagementCluster, and
Manifest to include +genclient markers, while preserving the existing
package-level generation tags and client generation workflow.

Comment thread docs/api/v2-clientgo-vs-custom-sdk.md
Comment thread docs/api/v2-clientgo-vs-custom-sdk.md
@lucasponce

lucasponce commented Jul 28, 2026

Copy link
Copy Markdown

Let me summarize here all the points:

  • The ROSA v2 model is CRD driven and the source of truth is the API repo.
  • We need a Gateway API server, we can't easily move it to a standard Kubernetes API server (k8s/client-go requires a full Kubernetes API).
  • We want to generate a Go clientset that ROSA clients can import to implement end-to-end features.
  • The maintenance of [1] should be automated and trivial.

[1] https://github.com/openshift-online/rosa-hyperfleet-api/pull/186/changes#diff-7d03eb15fb725d439f1c1aeea03df38e159809ca03441a2ba58913bbf0051b87R154

@cdoan1 cdoan1 changed the title Add client-go vs custom SDK comparison doc ROSAENG-62089: doc: Add client-go vs custom SDK comparison doc Jul 31, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 31, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 31, 2026

Copy link
Copy Markdown
Collaborator

@cdoan1: This pull request references ROSAENG-62089 which is a valid jira issue.

Warning: The referenced jira issue has an invalid target version for the target branch this PR targets: expected the story to target the "5.0.0" version, but no target version was set.

Details

In response to this:

Explains why client-go works for rosa-hyperfleet-api consumers, compares approaches (controller-runtime, typed clientset, REST gateway), and recommends starting with the existing API types module.

Description

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Refactoring (no functional changes)
  • CI/CD or tooling change

Testing

  • Unit tests pass (make test)
  • Integration tests pass (if applicable)
  • Manual verification completed

Checklist

  • My code follows the project's coding conventions
  • I have updated documentation as needed
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass

Summary by CodeRabbit

  • Documentation
  • Added guidance for Go integrations using Kubernetes client-go and controller-runtime patterns.
  • Compared client-go with custom SDK approaches, including authentication, authorization, watch support, maintenance, and ecosystem compatibility.
  • Documented integration options and architectural considerations for REST gateway and Kubernetes API usage.
  • Included recommendations for adopting controller-runtime patterns and selectively adding typed client generation.

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 openshift-eng/jira-lifecycle-plugin repository.

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

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. jira/valid-reference Indicates that this PR references a valid Jira ticket of any type.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants