Skip to content

SDCICD-1840 Add mcsimulation package with CRD installation logic#3254

Open
YiqinZhang wants to merge 2 commits into
openshift:mainfrom
YiqinZhang:sdcicd-1840-crds
Open

SDCICD-1840 Add mcsimulation package with CRD installation logic#3254
YiqinZhang wants to merge 2 commits into
openshift:mainfrom
YiqinZhang:sdcicd-1840-crds

Conversation

@YiqinZhang

@YiqinZhang YiqinZhang commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

Introduces pkg/common/mcsimulation to support Management Cluster simulation for HCP operator testing. Operators that watch HyperShift resources (e.g. HostedControlPlane) can be tested on ROSA Classic clusters without a real Management Cluster, by installing minimal CRDs that accept arbitrary spec/status fields via x-kubernetes-preserve-unknown-fields: true.

Co-authored-by: Cursor cursor@cursor.com

Summary by CodeRabbit

  • New Features
    • Automated setup/install of Custom Resource Definitions to support Management Cluster simulation and HyperShift operator workflows.
  • Tests
    • Added unit tests covering CRD installation, idempotency, permission errors, establishment polling, and timeout scenarios.
  • Chores
    • Updated module dependency declarations.

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

There are test jobs defined for this repository which are not configured to run automatically. Comment /test ? to see a list of all defined jobs. Review these jobs and use /test <job> to manually trigger jobs most likely to be impacted by the proposed changes.Comment /pipeline required to trigger all required & necessary jobs.

@coderabbitai

coderabbitai Bot commented Jun 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 8f7016c4-4d29-407f-bf62-7d47db2ff382

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

Walkthrough

Promote apiextensions dependency and add mcsimulation package with minimal CRD templates (hcp, vpce), EnsureCRDsInstalled() that creates/awaits Established status and aggregates Forbidden errors, plus unit tests covering idempotency, permission errors, race/retry, and timeouts.

Changes

Management Cluster CRD Installation Feature

Layer / File(s) Summary
Dependency Promotion
go.mod
Promote k8s.io/apiextensions-apiserver v0.35.1 from indirect to direct requirement.
CRD definitions and API
pkg/common/mcsimulation/crds.go (lines 1–94)
Add mcsimulation package, define minimal stub CRDs (hcp, vpce) with preserve-unknown-fields and status subresource; add BuiltinCRDAliases().
CRD installation and polling
pkg/common/mcsimulation/crds.go (lines 96–166)
Add EnsureCRDsInstalled() to validate aliases, create missing CRDs, collect Forbidden errors, and wait for Established; add waitForCRDEstablished() polling helper.
Test coverage
pkg/common/mcsimulation/crds_test.go
Add unit tests and helpers verifying alias handling, idempotency, forbidden error aggregation, race-condition retry behavior, and establishment success/timeout cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 14 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Test Structure And Quality ⚠️ Warning Five tests use context.Background() on cluster operations without timeout, violating requirement #3. TestBuiltinCRDs_Defined asserts multiple unrelated behaviors. Bare assertions lack context. Apply context.WithTimeout to EnsureCRDsInstalled test calls. Split TestBuiltinCRDs_Defined. Include alias names in t.Error messages for clarity.
✅ Passed checks (14 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed Title accurately summarizes the main change: adding the mcsimulation package with CRD installation logic, matching the changeset's primary additions across go.mod, crds.go, and crds_test.go.
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.
Stable And Deterministic Test Names ✅ Passed Test file uses standard Go testing package, not Ginkgo. Custom check for Ginkgo test name stability is not applicable to this PR.
Microshift Test Compatibility ✅ Passed No Ginkgo e2e tests added; PR introduces library code and standard Go unit tests only, not applicable to MicroShift compatibility check.
Single Node Openshift (Sno) Test Compatibility ✅ Passed No Ginkgo e2e tests added. PR contains only standard Go unit tests in crds_test.go using testing.T; SNO check inapplicable.
Topology-Aware Scheduling Compatibility ✅ Passed PR adds CRD installation utilities (mcsimulation package) with no deployment manifests, pod specs, or scheduling constraints. No topology-aware scheduling issues identified.
Ote Binary Stdout Contract ✅ Passed The mcsimulation package is a library with no process entry points. All klog calls are within regular function bodies; no fmt.Print to stdout; no package-level side effects.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed No Ginkgo e2e tests added. The PR adds only standard Go unit tests using testing.T package, which are not subject to IPv6/disconnected network compatibility requirements.
No-Weak-Crypto ✅ Passed No weak cryptography (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB), custom crypto implementations, or non-constant-time secret comparisons detected in the code.
Container-Privileges ✅ Passed PR contains only Go source code and module dependencies; no container/K8s manifests with privilege configurations found.
No-Sensitive-Data-In-Logs ✅ Passed No sensitive data found in logging or error messages. All logs contain only CRD metadata (names, conditions), not credentials, tokens, keys, or PII.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci openshift-ci Bot requested review from minlei98 and ritmun June 8, 2026 20:17
@openshift-ci

openshift-ci Bot commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: YiqinZhang

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 Jun 8, 2026
@YiqinZhang

Copy link
Copy Markdown
Contributor Author

/retest

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/common/mcsimulation/crds_test.go (1)

42-151: ⚡ Quick win

Consider adding test for Create success + Establishment timeout scenario.

Current tests cover waitForCRDEstablished timeout in isolation and EnsureCRDsInstalled with various creation outcomes. Missing coverage for the path where Create succeeds but the CRD never reaches Established state, triggering the error at crds.go:151-153. This is a realistic operator failure mode.

🧪 Suggested test case
func TestEnsureCRDsInstalled_EstablishmentTimeout(t *testing.T) {
	// CRD created but never becomes established
	crdObj := parseCRDForFake(t)
	// No conditions set, so it will never be established
	
	client := dynamicfake.NewSimpleDynamicClient(runtime.NewScheme())
	client.PrependReactor("get", "customresourcedefinitions", func(action k8stesting.Action) (bool, runtime.Object, error) {
		name := action.(k8stesting.GetAction).GetName()
		if name == crdObj.GetName() {
			return true, crdObj, nil
		}
		return notFoundReactor(action)
	})
	client.PrependReactor("create", "customresourcedefinitions", func(action k8stesting.Action) (bool, runtime.Object, error) {
		return true, crdObj, nil
	})
	
	ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
	defer cancel()
	
	err := EnsureCRDsInstalled(ctx, client, []string{"hcp"})
	if err == nil || !strings.Contains(err.Error(), "not Established after install") {
		t.Fatalf("expected 'not Established' error, got: %v", err)
	}
}
🤖 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/common/mcsimulation/crds_test.go` around lines 42 - 151, The tests miss
the case where EnsureCRDsInstalled successfully creates a CRD but
waitForCRDEstablished never observes an Established condition (the code path
that returns "not Established after install" in EnsureCRDsInstalled). Add a unit
test that uses dynamicfake.NewSimpleDynamicClient with reactors: a "create"
reactor that returns the created CRD object (success) and a "get" reactor that
returns that CRD object without any status.conditions (so it never becomes
Established); call EnsureCRDsInstalled (with a context timeout) for the "hcp"
alias and assert the returned error contains the "not Established" message;
reference EnsureCRDsInstalled and waitForCRDEstablished to locate the logic to
exercise.
🤖 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 `@pkg/common/mcsimulation/crds.go`:
- Around line 7-21: Replace the use of the standard log package and any
fmt.Println calls in pkg/common/mcsimulation/crds.go with structured logr/klog
calls: remove the "log" import, import klog (or controller-runtime logger)
instead, and change each log.Printf(...) occurrence (and any fmt.Println) to
klog.InfoS(...) or klog.ErrorS(...) with key/value pairs for context (e.g.,
"msg" text and keys like "crd", "err", "attempt"), and if the original call
logged an error include it under the "err" key; ensure the call sites that
currently use log.Printf around unstructured objects include the object
name/Kind as structured fields so they’re easy to filter.

---

Nitpick comments:
In `@pkg/common/mcsimulation/crds_test.go`:
- Around line 42-151: The tests miss the case where EnsureCRDsInstalled
successfully creates a CRD but waitForCRDEstablished never observes an
Established condition (the code path that returns "not Established after
install" in EnsureCRDsInstalled). Add a unit test that uses
dynamicfake.NewSimpleDynamicClient with reactors: a "create" reactor that
returns the created CRD object (success) and a "get" reactor that returns that
CRD object without any status.conditions (so it never becomes Established); call
EnsureCRDsInstalled (with a context timeout) for the "hcp" alias and assert the
returned error contains the "not Established" message; reference
EnsureCRDsInstalled and waitForCRDEstablished to locate the logic to exercise.
🪄 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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: eab75654-7ee6-478c-889e-8ab7e1f7cda8

📥 Commits

Reviewing files that changed from the base of the PR and between 6d0e7b5 and dc598c9.

📒 Files selected for processing (2)
  • pkg/common/mcsimulation/crds.go
  • pkg/common/mcsimulation/crds_test.go

Comment thread pkg/common/mcsimulation/crds.go
@YiqinZhang YiqinZhang force-pushed the sdcicd-1840-crds branch 2 times, most recently from e02d096 to b83a497 Compare June 9, 2026 13:37
@openshift openshift deleted a comment from openshift-merge-bot Bot Jun 9, 2026
@YiqinZhang

Copy link
Copy Markdown
Contributor Author

/override ci/prow/hypershift-pr-check

@openshift-ci

openshift-ci Bot commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

@YiqinZhang: Overrode contexts on behalf of YiqinZhang: ci/prow/hypershift-pr-check

Details

In response to this:

/override ci/prow/hypershift-pr-check

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.

@openshift openshift deleted a comment from openshift-merge-bot Bot Jun 10, 2026
@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown

Oops, something went wrong! Please try again later. 🐰 💔

@YiqinZhang

Copy link
Copy Markdown
Contributor Author

@coderabbitai full review

@coderabbitai

coderabbitai Bot commented Jun 10, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
pkg/common/mcsimulation/crds.go (1)

136-136: 💤 Low value

Consider extracting CRD establishment timeout as a named constant.

The 30-second timeout is hardcoded. Extract to a package-level constant for clarity and easier tuning.

♻️ Proposed refactor
+const crdEstablishmentTimeout = 30 * time.Second
+
 // EnsureCRDsInstalled resolves a list of CRD aliases and installs any that are
 // not already present on the cluster. Forbidden errors are collected and returned
 // together so callers get a single actionable message with all missing CRDs.

Then at line 136:

-		if err := waitForCRDEstablished(ctx, extClient, name, 30*time.Second); err != nil {
+		if err := waitForCRDEstablished(ctx, extClient, name, crdEstablishmentTimeout); err != nil {
🤖 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/common/mcsimulation/crds.go` at line 136, The hardcoded 30*time.Second
passed to waitForCRDEstablished should be extracted into a package-level
constant (e.g., crdEstablishTimeout) to improve clarity and tunability; add a
top-of-file const like crdEstablishTimeout = 30 * time.Second and replace the
literal 30*time.Second in the call to waitForCRDEstablished(ctx, extClient,
name, crdEstablishTimeout), updating any related comments if present.
🤖 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 `@pkg/common/mcsimulation/crds.go`:
- Line 111: Replace the hardcoded available-aliases string with a dynamic list
from BuiltinCRDAliases(); specifically, change the fmt.Errorf call that
currently uses "(available: hcp, vpce)" to use strings.Join(BuiltinCRDAliases(),
", ") (e.g. fmt.Errorf("unknown CRD alias %q (available: %s)", alias,
strings.Join(BuiltinCRDAliases(), ", "))). Also add the "strings" import if
missing so the code compiles.

---

Nitpick comments:
In `@pkg/common/mcsimulation/crds.go`:
- Line 136: The hardcoded 30*time.Second passed to waitForCRDEstablished should
be extracted into a package-level constant (e.g., crdEstablishTimeout) to
improve clarity and tunability; add a top-of-file const like crdEstablishTimeout
= 30 * time.Second and replace the literal 30*time.Second in the call to
waitForCRDEstablished(ctx, extClient, name, crdEstablishTimeout), updating any
related comments if present.
🪄 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 YAML (base), Central YAML (inherited)

Review profile: CHILL

Plan: Enterprise

Run ID: 23fddf24-b341-4c9b-b285-3ae9c280d94e

📥 Commits

Reviewing files that changed from the base of the PR and between 1d7f2d4 and 0b704f2.

📒 Files selected for processing (3)
  • go.mod
  • pkg/common/mcsimulation/crds.go
  • pkg/common/mcsimulation/crds_test.go

Comment thread pkg/common/mcsimulation/crds.go Outdated
@YiqinZhang

Copy link
Copy Markdown
Contributor Author

/override ci/prow/hypershift-pr-check

@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@YiqinZhang: Overrode contexts on behalf of YiqinZhang: ci/prow/hypershift-pr-check

Details

In response to this:

/override ci/prow/hypershift-pr-check

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.

@openshift-ci

openshift-ci Bot commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

@YiqinZhang: all tests passed!

Full PR test history. Your PR dashboard.

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. I understand the commands that are listed here.

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.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant