feat: Migrate HCO automation from v1beta1 to v1 API - #5958
Conversation
|
Warning Review limit reached
Next review available in: 41 minutes You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (10)
📝 WalkthroughWalkthroughThe PR adds ChangesHCO v1 migration
Estimated code review effort: 4 (Complex) | ~60 minutes Possibly related PRs
Suggested labels: Suggested reviewers: 🚥 Pre-merge checks | ✅ 6✅ Passed checks (6 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #5958 +/- ##
==========================================
- Coverage 98.89% 98.89% -0.01%
==========================================
Files 42 42
Lines 2631 2704 +73
==========================================
+ Hits 2602 2674 +72
- Misses 29 30 +1
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Report bugs in Issues Welcome! 🎉This pull request will be automatically processed with the following features: 🔄 Automatic Actions
📋 Available CommandsPR Status Management
Review & Approval
Testing & Validation
Container Operations
Cherry-pick Operations
Branch Management
Label Management
✅ Merge RequirementsThis PR will be automatically approved when the following conditions are met:
📊 Review ProcessApprovers and ReviewersApprovers:
Reviewers:
Available Labels
AI Features
Security Checks
💡 Tips
📌 Additional InformationCustom Commands:
For more information, please refer to the project documentation or contact the maintainers. |
There was a problem hiding this comment.
Actionable comments posted: 11
🤖 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 `@AGENTS.md`:
- Around line 238-240: Update the HCO patch guidance to require v1 builders for
each field group while allowing their generated payloads to be composed into a
single spec patch when an update spans multiple groups. Preserve the prohibition
on manually constructing grouped nested dictionaries, v1beta1 flat paths, and
dict-format feature gates; clarify that merging outputs such as
HCOv1Spec.feature_gates() and HCOv1Spec.virtualization() is valid.
- Around line 244-255: Add blank lines between each bold heading and its
following fenced code block in the documented Before and After sections,
ensuring both opening fences satisfy markdownlint MD031.
In `@tests/install_upgrade_operators/csv/test_hco_api_version.py`:
- Around line 8-12: Update test_hyperconverged_cr_api_version to provide an
assertion failure message containing the observed
hyperconverged_resource_scope_function.instance.apiVersion and the expected
/{Resource.ApiVersion.V1} suffix, while preserving the existing assertion
condition.
In
`@tests/install_upgrade_operators/launcher_updates/test_reset_custom_values.py`:
- Around line 23-52: Replace raw nested HCO patch dictionaries with the existing
HCOv1Spec builders: in
tests/install_upgrade_operators/launcher_updates/test_reset_custom_values.py#L23-L52,
use HCOv1Spec.virtualization(...) for all four reset patches; in
tests/install_upgrade_operators/launcher_updates/constants.py#L48-L48, construct
the customization with HCOv1Spec.virtualization(...); and in
tests/install_upgrade_operators/product_uninstall/test_remove_hco.py#L142-L144,
use HCOv1Spec.deployment(...) for the uninstall strategy patch. Preserve the
existing values and test behavior while using the v1 grouped API consistently.
In `@tests/install_upgrade_operators/product_uninstall/test_remove_kubevirt.py`:
- Around line 20-22: Replace the inline deployment payload in the patches
argument with HCOv1Spec.deployment(uninstallStrategy="RemoveWorkloads"), and add
the HCOv1Spec import if needed. Keep the existing
hyperconverged_resource_scope_function key unchanged and ensure this HCO spec
patch uses the v1 grouped API.
In `@tests/install_upgrade_operators/strict_reconciliation/conftest.py`:
- Around line 127-132: Update the loop adding feature gates in the fixture so
existing_names is updated immediately after appending a new feature-gate object,
ensuring duplicate entries in new_fgs are not emitted.
In `@tests/install_upgrade_operators/strict_reconciliation/constants.py`:
- Line 255: Rename the constant NP_WORKLOADS_KEY_HCO_CR to
NP_WORKLOAD_KEY_HCO_CR in constants.py and update every reference to use the
singular identifier, while preserving its "workload" value.
In
`@tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py`:
- Around line 68-69: Centralize HCO spec patch construction through the grouped
HCOv1Spec builders instead of duplicating schema paths: in
tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py,
update ranges 68-69, 89-98, 118-126, 147-155, and 176-185 to use
HCOv1Spec.security(...), and ranges 202, 225-232, 255-261, 282, and 305-311 to
use HCOv1Spec.virtualization(...); in
tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py
ranges 23-26 and 31-35 also use HCOv1Spec.virtualization(...); in
tests/storage/cdi_config/test_cdi_config.py range 107-113 use
HCOv1Spec.storage(...) for both fragments. Ensure all HCO spec patches and reads
use the v1 grouped API.
In
`@tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py`:
- Line 51: Update the assertion failure message associated with the HCO live
migration configuration lookup in the test to report the actual
HCO.spec.virtualization.liveMigrationConfig path, while preserving the existing
lookup and assertion behavior.
In `@tests/storage/cbt/conftest.py`:
- Around line 50-56: The CBT fixture setup must preserve existing
spec.featureGates entries instead of replacing them with only incrementalBackup.
Update the merged_spec construction around HCOv1Spec.feature_gates and
ResourceEditorValidateHCOReconcile to derive the target feature-gate list from
the current resource, then add or update incrementalBackup while retaining all
existing gates.
In `@utilities/hco.py`:
- Around line 98-106: Update the v1 schema traversal that computes
fg_description to catch missing-key failures, including an absent
spec.featureGates path, and re-raise ValueError with the HCO schema path and
original exception context. Preserve the existing ValueError for unparseable
phases, and add a unit test covering a v1 schema without spec.featureGates.
🪄 Autofix
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: Path: .coderabbit.yaml
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 8b2a21b8-032b-47f8-8c7c-2c93dd44d1b1
⛔ Files ignored due to path filters (1)
uv.lockis excluded by!**/*.lock
📒 Files selected for processing (49)
AGENTS.mdpyproject.tomltests/conftest.pytests/infrastructure/golden_images/update_boot_source/conftest.pytests/infrastructure/vhostmd/test_downwardmetrics_virtio.pytests/infrastructure/vhostmd/test_vhostmd.pytests/install_upgrade_operators/conftest.pytests/install_upgrade_operators/constants.pytests/install_upgrade_operators/crypto_policy/test_crypto_policy_default.pytests/install_upgrade_operators/crypto_policy/test_hco_crypto_policy_propagation.pytests/install_upgrade_operators/crypto_policy/test_hco_custom_profile_negative.pytests/install_upgrade_operators/crypto_policy/utils.pytests/install_upgrade_operators/csv/test_hco_api_version.pytests/install_upgrade_operators/feature_gates/test_update_featuregate_hco.pytests/install_upgrade_operators/hco_enablement_golden_image_updates/test_enable_common_boot_image_import.pytests/install_upgrade_operators/launcher_updates/constants.pytests/install_upgrade_operators/launcher_updates/test_negative_kubevirt_update.pytests/install_upgrade_operators/launcher_updates/test_reset_custom_values.pytests/install_upgrade_operators/must_gather/conftest.pytests/install_upgrade_operators/node_component/conftest.pytests/install_upgrade_operators/node_component/test_deploy_cnv_on_subset_of_nodes_sanity.pytests/install_upgrade_operators/product_uninstall/test_remove_hco.pytests/install_upgrade_operators/product_uninstall/test_remove_kubevirt.pytests/install_upgrade_operators/strict_reconciliation/conftest.pytests/install_upgrade_operators/strict_reconciliation/constants.pytests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.pytests/install_upgrade_operators/strict_reconciliation/test_hco_cr_nondefault_fields.pytests/install_upgrade_operators/strict_reconciliation/test_hco_default_cpu_model.pytests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.pytests/network/kubemacpool/explicit_range/conftest.pytests/storage/cbt/conftest.pytests/storage/cdi_config/test_cdi_config.pytests/storage/cross_cluster_live_migration/utils.pytests/storage/test_cdi_certificate.pytests/storage/test_hotplug.pytests/storage/upgrade/conftest.pytests/utils.pytests/virt/cluster/migration_and_maintenance/test_evictionstrategy.pytests/virt/node/gpu/gpu_pci_passthrough/conftest.pytests/virt/node/gpu/vgpu/conftest.pytests/virt/node/workload_density/test_free_page_reporting.pytests/virt/node/workload_density/test_kernel_samepage_merging.pytests/virt/upgrade/conftest.pytests/virt/upgrade_custom/vgpu/conftest.pytests/virt/utils.pyutilities/constants/hco.pyutilities/hco.pyutilities/infra.pyutilities/unittests/test_hco.py
🔗 Linked repositories identified
CodeRabbit considers these linked repositories for cross-repo context during reviews:
RedHatQE/openshift-virtualization-tests-design-docs(manual)
💤 Files with no reviewable changes (3)
- tests/install_upgrade_operators/constants.py
- tests/install_upgrade_operators/conftest.py
- utilities/infra.py
| 1. **HCO spec patches MUST use v1 grouped structure** — use `HCOv1Spec` builders, NEVER construct raw nested dicts manually | ||
| 2. **Feature gates MUST use v1 list format** — use `HCOv1Spec.feature_gates(name=True/False)`, NEVER dict format `{"featureGates": {"name": true}}` | ||
| 3. **NEVER use v1beta1 flat spec paths** — `spec.liveMigrationConfig` is wrong, `spec.virtualization.liveMigrationConfig` is correct. See `HCOv1Spec` group builders in `utilities/constants/hco.py` for the complete mapping |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
MEDIUM: Allow composition of builder-generated patches.
The absolute prohibition conflicts with multi-group patches. For example, tests/storage/cbt/conftest.py combines HCOv1Spec.feature_gates() and HCOv1Spec.virtualization() results before passing one spec patch.
Require builders for each field group. Permit merging builder-generated payloads when one update changes multiple groups. Do not require developers to hand-write grouped paths.
🤖 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 `@AGENTS.md` around lines 238 - 240, Update the HCO patch guidance to require
v1 builders for each field group while allowing their generated payloads to be
composed into a single spec patch when an update spans multiple groups. Preserve
the prohibition on manually constructing grouped nested dictionaries, v1beta1
flat paths, and dict-format feature gates; clarify that merging outputs such as
HCOv1Spec.feature_gates() and HCOv1Spec.virtualization() is valid.
| **Before (v1beta1 -- WRONG):** | ||
| ```python | ||
| # Flat spec path -- WRONG | ||
| patch = {"spec": {"liveMigrationConfig": {"parallelOutboundMigrationsPerNode": 5}}} | ||
| hco_resource.update(resource_dict=patch) | ||
|
|
||
| # Dict feature gate -- WRONG | ||
| fg_patch = {"spec": {"featureGates": {"withHostPassthroughCPU": True}}} | ||
| ``` | ||
|
|
||
| **After (v1 -- CORRECT):** | ||
| ```python |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win
MEDIUM: Add blank lines around both fenced code blocks.
markdownlint reports MD031 at Lines 245 and 255. Add a blank line after each bold heading before the opening fence.
🧰 Tools
🪛 markdownlint-cli2 (0.23.2)
[warning] 245-245: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
[warning] 255-255: Fenced code blocks should be surrounded by blank lines
(MD031, blanks-around-fences)
🤖 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 `@AGENTS.md` around lines 244 - 255, Add blank lines between each bold heading
and its following fenced code block in the documented Before and After sections,
ensuring both opening fences satisfy markdownlint MD031.
Source: Linters/SAST tools
| def test_hyperconverged_cr_api_version(hyperconverged_resource_scope_function): | ||
| """ | ||
| This test will check the Hyperconverged CR's api_version for v1beta1 | ||
| This test will check the Hyperconverged CR's api_version for v1 | ||
| """ | ||
| assert Resource.ApiVersion.V1BETA1 in hyperconverged_resource_scope_function.instance.apiVersion | ||
| assert hyperconverged_resource_scope_function.instance.apiVersion.endswith(f"/{Resource.ApiVersion.V1}") |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win
LOW: Add an assertion failure message.
If the API version is not v1, this assertion does not show the observed value. Add a message with the actual apiVersion and expected suffix.
🤖 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 `@tests/install_upgrade_operators/csv/test_hco_api_version.py` around lines 8 -
12, Update test_hyperconverged_cr_api_version to provide an assertion failure
message containing the observed
hyperconverged_resource_scope_function.instance.apiVersion and the expected
/{Resource.ApiVersion.V1} suffix, while preserving the existing assertion
condition.
Source: Learnings
| "patch": {"spec": {"virtualization": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: None}}}, | ||
| }, | ||
| DEFAULT_WORKLOAD_UPDATE_STRATEGY, | ||
| marks=(pytest.mark.polarion("CNV-6928"),), | ||
| ), | ||
| pytest.param( | ||
| { | ||
| "patch": {"spec": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: {"batchEvictionInterval": None}}}, | ||
| "patch": { | ||
| "spec": {"virtualization": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: {"batchEvictionInterval": None}}} | ||
| }, | ||
| }, | ||
| MOD_CUST_DEFAULT_BATCH_EVICTION_INTERVAL, | ||
| marks=pytest.mark.polarion("CNV-6929"), | ||
| id="test_hyperconverged_reset_workload_update_strategy_batch_eviction_size", | ||
| ), | ||
| pytest.param( | ||
| { | ||
| "patch": {"spec": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: {"batchEvictionSize": None}}}, | ||
| "patch": { | ||
| "spec": {"virtualization": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: {"batchEvictionSize": None}}} | ||
| }, | ||
| }, | ||
| MOD_CUST_DEFAULT_BATCH_EVICTION_SIZE, | ||
| marks=pytest.mark.polarion("CNV-6930"), | ||
| id="test_hyperconverged_reset_workload_update_strategy_workload_update_methods", | ||
| ), | ||
| pytest.param( | ||
| { | ||
| "patch": {"spec": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: {WORKLOADUPDATEMETHODS: None}}}, | ||
| "patch": { | ||
| "spec": {"virtualization": {WORKLOAD_UPDATE_STRATEGY_KEY_NAME: {WORKLOADUPDATEMETHODS: None}}} | ||
| }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
HIGH: Centralize HCO patch construction with HCOv1Spec.
These changed sites construct HCO patch payloads with raw nested dictionaries. The repository requires HCO spec patches to use HCOv1Spec builders.
tests/install_upgrade_operators/launcher_updates/test_reset_custom_values.py#L23-L52: useHCOv1Spec.virtualization(...)for all four reset patches.tests/install_upgrade_operators/launcher_updates/constants.py#L48-L48: useHCOv1Spec.virtualization(**CUSTOM_STRATEGY).tests/install_upgrade_operators/product_uninstall/test_remove_hco.py#L142-L144: useHCOv1Spec.deployment(uninstallStrategy=REMOVE_STRATEGY).
As per coding guidelines: all HCO spec patches and reads must use the v1 grouped API and HCOv1Spec builders.
Based on learnings: reuse existing implementations instead of duplicating schema construction.
📍 Affects 3 files
tests/install_upgrade_operators/launcher_updates/test_reset_custom_values.py#L23-L52(this comment)tests/install_upgrade_operators/launcher_updates/constants.py#L48-L48tests/install_upgrade_operators/product_uninstall/test_remove_hco.py#L142-L144
🤖 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 `@tests/install_upgrade_operators/launcher_updates/test_reset_custom_values.py`
around lines 23 - 52, Replace raw nested HCO patch dictionaries with the
existing HCOv1Spec builders: in
tests/install_upgrade_operators/launcher_updates/test_reset_custom_values.py#L23-L52,
use HCOv1Spec.virtualization(...) for all four reset patches; in
tests/install_upgrade_operators/launcher_updates/constants.py#L48-L48, construct
the customization with HCOv1Spec.virtualization(...); and in
tests/install_upgrade_operators/product_uninstall/test_remove_hco.py#L142-L144,
use HCOv1Spec.deployment(...) for the uninstall strategy patch. Preserve the
existing values and test behavior while using the v1 grouped API consistently.
Sources: Coding guidelines, Learnings
| patches={ | ||
| hyperconverged_resource_scope_function: {"spec": {"deployment": {"uninstallStrategy": "RemoveWorkloads"}}} | ||
| }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
HIGH: Use HCOv1Spec.deployment(...) for the uninstall-strategy patch.
The nested payload is correct for HCO v1, but this code bypasses the shared builder. Replace it with HCOv1Spec.deployment(uninstallStrategy="RemoveWorkloads"). Add the HCOv1Spec import if this file does not already have it.
Proposed fix
- hyperconverged_resource_scope_function: {"spec": {"deployment": {"uninstallStrategy": "RemoveWorkloads"}}}
+ hyperconverged_resource_scope_function: HCOv1Spec.deployment(
+ uninstallStrategy="RemoveWorkloads"
+ )As per path instructions, “All HCO spec patches and reads must use the v1 grouped API and HCOv1Spec builders.”
📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| patches={ | |
| hyperconverged_resource_scope_function: {"spec": {"deployment": {"uninstallStrategy": "RemoveWorkloads"}}} | |
| }, | |
| patches={ | |
| hyperconverged_resource_scope_function: HCOv1Spec.deployment( | |
| uninstallStrategy="RemoveWorkloads" | |
| ) | |
| }, |
🤖 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 `@tests/install_upgrade_operators/product_uninstall/test_remove_kubevirt.py`
around lines 20 - 22, Replace the inline deployment payload in the patches
argument with HCOv1Spec.deployment(uninstallStrategy="RemoveWorkloads"), and add
the HCOv1Spec import if needed. Keep the existing
hyperconverged_resource_scope_function key unchanged and ensure this HCO spec
patch uses the v1 grouped API.
Source: Path instructions
| "nodePlacement": NP_INFRA_VALUE_CDI_CR, | ||
| } | ||
| NP_WORKLOADS_KEY_HCO_CR = "workloads" | ||
| NP_WORKLOADS_KEY_HCO_CR = "workload" |
There was a problem hiding this comment.
📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win
MEDIUM: Rename the constant to match the singular HCO v1 field.
The value is now "workload", but the identifier remains NP_WORKLOADS_KEY_HCO_CR. Rename it to NP_WORKLOAD_KEY_HCO_CR and update its references. The current name misstates the v1 schema and can cause future code to use the obsolete plural field.
🤖 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 `@tests/install_upgrade_operators/strict_reconciliation/constants.py` at line
255, Rename the constant NP_WORKLOADS_KEY_HCO_CR to NP_WORKLOAD_KEY_HCO_CR in
constants.py and update every reference to use the singular identifier, while
preserving its "workload" value.
| "patch": {"spec": {"security": {HCO_CR_CERT_CONFIG_KEY: EXPCT_CERTC_DEFAULTS}}}, | ||
| }, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
HIGH: Centralize HCO patch construction in HCOv1Spec.
These changed inputs duplicate the v1 schema. Use the shared builder that owns each grouped path.
tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L68-L69: useHCOv1Spec.security(...).tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L89-L98: useHCOv1Spec.security(...)for the CA duration patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L118-L126: useHCOv1Spec.security(...)for the CA renewal patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L147-L155: useHCOv1Spec.security(...)for the server duration patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L176-L185: useHCOv1Spec.security(...)for the server renewal patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L202-L202: useHCOv1Spec.virtualization(...)for the live-migration defaults patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L225-L232: useHCOv1Spec.virtualization(...)for the completion-timeout patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L255-L261: useHCOv1Spec.virtualization(...)for the parallel-migrations patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L282-L282: useHCOv1Spec.virtualization(...)for the outbound-migrations patch.tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L305-L311: useHCOv1Spec.virtualization(...)for the progress-timeout patch.tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py#L23-L26: useHCOv1Spec.virtualization(...)for the auto-converge patch.tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py#L31-L35: useHCOv1Spec.virtualization(...)for the post-copy patch.tests/storage/cdi_config/test_cdi_config.py#L107-L113: useHCOv1Spec.storage(...)for both storage fragments.
As per coding guidelines, all HCO spec patches and reads must use the v1 grouped API and HCOv1Spec builders.
📍 Affects 3 files
tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L68-L69(this comment)tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L89-L98tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L118-L126tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L147-L155tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L176-L185tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L202-L202tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L225-L232tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L255-L261tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L282-L282tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py#L305-L311tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py#L23-L26tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py#L31-L35tests/storage/cdi_config/test_cdi_config.py#L107-L113
🤖 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
`@tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py`
around lines 68 - 69, Centralize HCO spec patch construction through the grouped
HCOv1Spec builders instead of duplicating schema paths: in
tests/install_upgrade_operators/strict_reconciliation/test_hco_cr_modify_defaults.py,
update ranges 68-69, 89-98, 118-126, 147-155, and 176-185 to use
HCOv1Spec.security(...), and ranges 202, 225-232, 255-261, 282, and 305-311 to
use HCOv1Spec.virtualization(...); in
tests/install_upgrade_operators/strict_reconciliation/test_livemigration_config_update.py
ranges 23-26 and 31-35 also use HCOv1Spec.virtualization(...); in
tests/storage/cdi_config/test_cdi_config.py range 107-113 use
HCOv1Spec.storage(...) for both fragments. Ensure all HCO spec patches and reads
use the v1 grouped API.
Source: Coding guidelines
| fg_patch = HCOv1Spec.feature_gates(incrementalBackup=True) | ||
| cbt_patch = HCOv1Spec.virtualization( | ||
| changedBlockTrackingLabelSelectors={"virtualMachineLabelSelector": {"matchLabels": CBT_ENABLED_LABEL}}, | ||
| ) | ||
| merged_spec = {**fg_patch["spec"], **cbt_patch["spec"]} | ||
| with ResourceEditorValidateHCOReconcile( | ||
| patches={ | ||
| hyperconverged_resource_scope_module: { | ||
| "spec": { | ||
| "featureGates": {"incrementalBackup": True}, | ||
| "changedBlockTrackingLabelSelectors": { | ||
| "virtualMachineLabelSelector": {"matchLabels": CBT_ENABLED_LABEL}, | ||
| }, | ||
| }, | ||
| }, | ||
| }, | ||
| patches={hyperconverged_resource_scope_module: {"spec": merged_spec}}, |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win
🧩 Analysis chain
🏁 Script executed:
#!/usr/bin/env bash
set -euo pipefail
rg -n -C 12 'class ResourceEditor|def update\(|PatchType|merge-patch|server-side' utilities libs tests || true
rg -n -C 8 'HCOv1Spec\.feature_gates|incrementalBackup|featureGates' utilities tests || trueRepository: RedHatQE/openshift-virtualization-tests
Length of output: 50395
🏁 Script executed (no clone):
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import urllib.request
import json
import re
import tempfile
import zipfile
# Fetch KubeVirt HCO CRD from the upstream GitHub API.
url = "https://api.github.com/repos/kubevirt/hyperconverged-cluster-operator/contents/config/crd/bases/hco.kubevirt.io_hyperconvergeds.yaml"
with urllib.request.urlopen(url, timeout=30) as r:
crd_yaml = r.read().decode("utf-8")
PY
Length of output: 2411
🏁 Script executed:
#!/bin/bash
set -euo pipefail
# Inspect the base ResourceEditor implementation and installed dependency versions that define patch semantics.
rg -n -C 20 'class ResourceEditor|def update\(|patches|PatchType|patch_type|patched|server.apply|server.side|json\.patch|merge_patch' utilities pyproject.toml uv.lock poetry.lock setup.cfg setup.py 2>/dev/null || true
# Print exact source around ResourceEditor and ResourceEditorValidateHCOReconcile.
sed -n '1,130p' utilities/hco.py
# Print relevant project dependency declarations and lock versions.
for f in pyproject.toml uv.lock poetry.lock poetry.lock.cpan; do
if [ -f "$f" ]; then
echo "---- $f ----"
rg -n 'openshift-client|kubectl|kubernetes-client|openshift|resource|operator-sdk|kubernetes' "$f" || true
fi
doneRepository: RedHatQE/openshift-virtualization-tests
Length of output: 50395
🏁 Script executed:
#!/bin/bash
set -euo pipefail
echo "---- dependency files ----"
for f in pyproject.toml requirements.txt pipenv.lock constraints.txt setup.cfg setup.py pdm.lock; do
if [ -f "$f" ]; then
echo "==== $f ===="
rg -n 'openshift-client|kubernetes|kubernetes-client|pyopenssl|sslp|openshift' "$f" || true
fi
done
echo "---- ResourceEditor definition locations ----"
rg -n 'class ResourceEditor|def update\(' . --glob '*.py' || true
echo "---- installed package metadata if available ----"
python3 - <<'PY'
import importlib.util, site, os
mods = ['ovirt-engine-sdk-python', 'ovirt-engine-sdk-python3', 'ovirt_engine_sdk', 'vapi-runtime', 'vapi-bindings']
for mod in mods:
spec = importlib.util.find_spec(mod)
print(f"{mod}: {spec.origin if spec else 'not found'}")
import pkg_resources
try:
for name in ['ovirt-engine-sdk-python', 'ovirt-engine-sdk-python3']:
try:
dist = pkg_resources.get_distribution(name)
print(f"dist={dist.project_name} {dist.version} location={dist.location}")
except pkg_resources.DistributionNotFound:
pass
except Exception as e:
print("pkg_resources failed:", e)
PY
echo "---- source around ResourceEditor from installed/vendored or path ----"
python3 - <<'PY'
import importlib.util, sys
for mod in ['ovirt_engine_sdk','ovirt-engine-sdk-python']:
spec = importlib.util.find_spec(mod)
print("spec", mod, spec)
PYRepository: RedHatQE/openshift-virtualization-tests
Length of output: 970
🏁 Script executed on all repositories:
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import urllib3, json
http = urllib3.PoolManager()
url = "https://api.github.com/repos/kubevirt/hyperconverged-cluster-operator/contents/config/crd/bases/hco.kubevirt.io_hyperconvergeds.yaml"
res = http.request("GET", url)
print("status", res.status)
if res.status == 200:
data = json.loads(res.data)
print("sha", data.get("sha"))
print("content len", len(data.get("content","")))
print("\nfeatureGates keys (first 20 lines of decoded content)")
import base64
txt = "\n".join(base64.b64decode(data["content"] + "===\n" * (3-len(data["content"]>%3))).decode().split("\n")[:40])
print(txt)
PY
Length of output: 1030
🏁 Script executed (no clone):
#!/bin/bash
set -euo pipefail
python3 - <<'PY'
import urllib3, json, base64
http = urllib3.PoolManager()
url = "https://api.github.com/repos/kubevirt/hyperconverged-cluster-operator/contents/config/crd/bases/hco.kubevirt.io_hyperconvergeds.yaml"
res = http.request("GET", url)
print("status", res.status)
print("content type", res.headers.get("content-type"))
if res.status == 200:
data = json.loads(res.data)
lines_resolved = base64.b64decode(data["content"] + "==").decode().splitlines()
feature_lines = [
i for i, l in enumerate(lines_resolved, start=1)
if "featureGates" in l
]
begin = max(0, feature_lines[0]-10) if feature_lines else 0
end = min(len(lines_resolved), feature_lines[-1]+25) if feature_lines else min(60, len(lines_resolved))
for i in range(begin, end):
print(f"{i+1:4}: {lines_resolved[i]}")
PY
echo "---- pypi openshift-python-utilities ResourceEditor docs/source ----"
python3 - <<'PY'
import urllib.request
url = "https://pypi.org/pypi/openshift-python-utilities/json"
print("getting pypi openshift-python-utilities", url)
try:
with urllib.request.urlopen(url, timeout=30, context=urllib.request.create_default_context(cafile="/etc/ssl/certs/ca-certificates.crt")) as r:
data = r.read().decode()
print(data[:4000])
except Exception as e:
print("pypi failed:", repr(e))
PY
Length of output: 245
🌐 Web query:
openshift-python-utilities ResourceEditor class update patches kubernetes client patch_type
💡 Result:
The ResourceEditor class in the openshift-python-wrapper (often associated with RedHatQE utilities) is used to perform bulk or complex updates on Kubernetes/OpenShift resources by applying patches [1]. When updating resources, the library leverages the underlying Kubernetes client (typically the DynamicClient) to execute these patches. In contexts like the mcp_server's update_resource function, the patch_type parameter supports three primary Kubernetes patch strategies [2][3][4]: 1. merge: The default patch type, which performs a JSON Merge Patch (RFC 7396) [2][3]. 2. strategic: Supports Strategic Merge Patch, which is particularly useful for resources with specific merge keys defined in the Kubernetes API [2][3]. 3. json: Supports JSON Patch (RFC 6902) [2][3]. While ResourceEditor simplifies the process of aggregating patches across multiple resources or fields before applying them [1], the underlying patch execution adheres to these standard Kubernetes client conventions [2][3]. When using the Resource class directly for updates, the update method often takes a resource dictionary representing the desired state or partial changes to be merged [5][6][7].
Citations:
- 1: https://context7.com/redhatqe/openshift-virtualization-tests/llms.txt?tokens=10000
- 2: https://github.com/RedHatQE/openshift-python-wrapper/blob/main/mcp_server/README.md
- 3: https://redhatqe-openshift-python-wrapper-47.mintlify.app/advanced/mcp-server
- 4: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/advanced/mcp-server
- 5: https://redhatqe-openshift-python-wrapper-47.mintlify.app/core-concepts/resources
- 6: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/guides/resource-crud-operations
- 7: https://redhatqe-openshift-python-wrapper-47.mintlify.app/api-reference/resource
🌐 Web query:
site:github.com/RedHatQE/openshift-python-wrapper class ResourceEditor update patches patch_type
💡 Result:
There is no standard class named ResourceEditor that uses the specific signature update patches patch_type in public documentation. However, in the context of the RedHatQE openshift-python-wrapper library, there is a function called update_resource that manages resource updates using patch operations and a patch_type parameter [1]. The update_resource function supports the following patch_type options for updating Kubernetes or OpenShift resources [1]: merge (default) strategic json When calling this function, the patch_type parameter determines how the provided patch data is applied to the target resource [1]. Example usage: update_resource( resource_type="deployment", name="my-app", namespace="default", patch={"spec": {"replicas": 3}}, patch_type="merge") [1]
Citations:
🌐 Web query:
"openpatch" "ResourceEditor" "openshift-python-wrapper"
💡 Result:
There is no known tool, class, or method named openpatch or ResourceEditor within the openshift-python-wrapper library [1][2][3]. In the openshift-python-wrapper, resource updates are handled via the Resource class using the update method, which performs a partial update (patch) [4][5]. To perform a partial update, you pass a dictionary containing the fields to be updated to the update method [4][5]. For example: deployment.update(resource_dict={"spec": {"replicas": 10}}) [4] For situations where a full replacement is required, such as removing existing fields, the library provides the update_replace method [5]. If you were referring to a different tool, openpatch and ResourceEditor do not appear in the official documentation or the codebase of the RedHatQE/openshift-python-wrapper project [1][3][5].
Citations:
- 1: https://github.com/RedHatQE/openshift-python-wrapper
- 2: https://github.com/redhatqe/openshift-python-wrapper
- 3: https://redhatqe-openshift-python-wrapper-47.mintlify.app/introduction
- 4: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/guides/resource-crud-operations
- 5: https://redhatqe-openshift-python-wrapper-47.mintlify.app/api-reference/resource
🌐 Web query:
"openshift-python-wrapper" "ResourceEditor" "resource.py"
💡 Result:
The openshift-python-wrapper library does not appear to contain a class or component named ResourceEditor. The foundational base class for all Kubernetes and OpenShift resources in the library is named Resource, which is located in the ocp_resources/resource.py module [1][2][3]. The Resource class provides the standard interface for CRUD (Create, Read, Update, and Delete) operations, resource management, and schema validation across the library [1][2][3]. All specific resource implementations, such as Pod or Deployment, inherit from either Resource or its subclass, NamespacedResource [2][3]. The library documentation and codebase focus on the Resource class for managing cluster objects and utilize a class generator tool to automatically create resource classes from Kubernetes API schemas, rather than a ResourceEditor [4][5][6].
Citations:
- 1: https://redhatqe-openshift-python-wrapper-47.mintlify.app/api-reference/resource
- 2: https://redhatqe-openshift-python-wrapper-47.mintlify.app/core-concepts/resources
- 3: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/core-concepts/resources
- 4: https://github.com/RedHatQE/openshift-python-wrapper
- 5: https://redhatqe-openshift-python-wrapper-47.mintlify.app/introduction
- 6: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/contributing/adding-resources
🌐 Web query:
site:github.com/RedHatQE/openshift-python-wrapper "class ResourceEditor"
💡 Result:
There is no widely recognized or standardized class named ResourceEditor in mainstream software development or the queried RedHatQE/openshift-python-wrapper library [1][2][3][4]. The openshift-python-wrapper library provides various classes for interacting with Kubernetes and OpenShift resources (such as Pod, Namespace, and VirtualMachine), but it does not include a class specifically identified as ResourceEditor [1][2][4]. The term may refer to a custom, project-specific, or obscure class name not present in the searched authoritative technical documentation [1][3][4].
Citations:
- 1: https://github.com/RedHatQE/openshift-python-wrapper/blob/main/mcp_server/README.md
- 2: https://github.com/RedHatQE/openshift-python-wrapper/blob/main/ocp_resources/pod.py
- 3: https://github.com/RedHatQE/openshift-python-wrapper/blob/main/fake_kubernetes_client/README.md
- 4: https://github.com/RedHatQE/openshift-python-wrapper/blob/73d51a432625e092e65a18848b053336214a036a/README.md
🌐 Web query:
site:github.com/RedHatQE/openshift-python-utilities "class ResourceEditor" "ResourceEditor"
💡 Result:
The term ResourceEditor refers to several different classes and tools depending on the programming environment and context: 1. Spring Framework (Java): The org.springframework.core.io.ResourceEditor is a PropertyEditor implementation used to convert String-based resource locations (such as file paths, URLs, or classpath locations) into Spring Resource objects [1][2]. It is widely used within the Spring Framework to handle resource injection and configuration [3][4]. 2. Apache Sling: The Apache Sling Resource Editor is a web-based tool designed to visualize and edit content stored in the Apache Sling repository [5]. 3. Visual Studio (.NET/C#): Historically, Visual Studio included a ResourceEditor component within its project system to manage application resources (like bitmaps, strings, or files) [6][7]. Microsoft has been moving away from some of these legacy editors in favor of more modern project system implementations [6]. 4. Other Contexts: - LWUIT (Java ME): The ResourceEditor was a GUI tool used to design user interfaces and manage localization resources for Java ME applications [8][9]. - ResForge: The ResourceEditor protocol or class is used in tools like ResForge to handle specific Macintosh resource types [10]. Because ResourceEditor is a generic name, its specific function depends entirely on the framework or library being used [1][5][10][7].
Citations:
- 1: https://github.com/spring-projects/spring-framework/blob/master/spring-beans/src/main/java/org/springframework/beans/support/ResourceEditorRegistrar.java
- 2: https://github.com/spring-projects/spring-framework/blob/main/spring-beans/src/main/java/org/springframework/beans/propertyeditors/URLEditor.java
- 3: https://stackoverflow.com/questions/20269704/spring-propertysource-and-environment-type-conversions
- 4: https://stackoverflow.com/questions/36997267/java-lang-nosuchmethoderror-org-springframework-core-io-resourceeditor
- 5: https://github.com/sandroboehme/resourceeditor
- 6: dotnet/project-system@fe83fba
- 7: https://stackoverflow.com/questions/26123494/use-c-exe-to-modify-resources-of-a-different-c-exe
- 8: https://stackoverflow.com/questions/6829425/buttongroup-and-resourceeditor
- 9: https://stackoverflow.com/questions/6915087/how-to-solve-localization-problem-with-lwuit
- 10: https://github.com/andrews05/ResForge/blob/master/Plugins/Sources/MenuEditor/MenuEditor.swift
🌐 Web query:
"ResourceEditor" "OcpResources" "kubernetes"
💡 Result:
The terms "ResourceEditor" and "ocpResources" do not refer to standard, built-in features of the Kubernetes or OpenShift core APIs, but rather to components found in specific ecosystem tools and development frameworks. 1. ResourceEditor: This name generally refers to custom user interface components used for modifying Kubernetes resources. For example, it is used in: - The Headlamp Kubernetes UI (a plugin-based web interface) as a component for editing resource manifests [1]. - The OpenShift Console, which includes a YAMLEditorPage component used to view and edit resource YAML [2]. - Various external platforms or plugins that provide a browser-based YAML editor for Kubernetes objects [3]. 2. OcpResources: This term typically appears in two contexts related to the Red Hat OpenShift ecosystem: - OpenShift Python Wrapper: In this testing framework, OcpResources refers to a collection of Python classes that provide a structured way to interact with Kubernetes and OpenShift resources [4][5][6]. The library defines a base Resource class and subclasses (such as NamespacedResource) that handle CRUD operations, schema validation, and lifecycle management for various API objects [4][5][7]. - OpenShift/Hypershift Internal Logic: In the context of the Hypershift project (an OpenShift component), ocpResources is an internal list or registry used to track or test GroupVersionKinds (GVKs) present on a management cluster [8]. In summary, there is no single Kubernetes "ResourceEditor" or "OcpResources" core feature. If you are developing with OpenShift or testing against it, OcpResources likely refers to the Python wrapper library [4][5]. If you are working on a dashboard or UI, ResourceEditor likely refers to a specific component within your interface framework [2][1].
Citations:
- 1: https://github.com/headlamp-k8s/plugins/blob/3dd8bdbe/strimzi/src/components/ResourceEditor.tsx
- 2: OCPBUGS-31355: add readOnly option to ResourceYAMLEditor openshift/console#13694
- 3: https://docs.ops0.com/docs/kubernetes/resources
- 4: https://redhatqe-openshift-python-wrapper-47.mintlify.app/api-reference/resource
- 5: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/core-concepts/resources
- 6: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/contributing/adding-resources
- 7: https://redhatqe-openshift-python-wrapper-47.mintlify.app/core-concepts/namespaced-resources
- 8: OCPBUGS-43698: dump: make ControlPlaneComponent's GKV optional openshift/hypershift#4965
🌐 Web query:
"ResourceEditor" "ocp_resources" "update" "patches"
💡 Result:
The term ResourceEditor in the context of ocp_resources generally refers to a utility component within OpenShift testing frameworks, specifically seen in repositories like RedHatQE's openshift-virtualization-tests [1][2]. In these contexts, ResourceEditor is a Python class or utility used to programmatically manage, modify, and update OpenShift Custom Resources (CRs) during test execution [1][2]. There is no standard, standalone OpenShift administrative command named ocp_resources update patches. If you are working with automated testing frameworks, the ResourceEditor utility typically provides methods to patch or update resource definitions (e.g., using the patch or update methods) to modify configurations [1][2]. If you are instead referring to patching or updating OpenShift resources in a general operational context: 1. Standard Patching: To update OpenShift resources via the CLI, you typically use oc patch <resource_type>/<resource_name> --patch '<patch_data>' --type=merge (or strategic). 2. Resource Editors: Various integrated development environments (IDEs) and tools (like the Kubernetes by Red Hat extension for IntelliJ) include their own GUI-based resource editors that allow you to modify YAML configurations directly within the cluster [3][4][5]. If your goal is to perform a specific update or patch via a framework, you should consult the documentation of the specific repository or toolset where you encountered the ResourceEditor class to understand its specific API and methods for applying updates [1][2].
Citations:
- 1: https://github.com/RedHatQE/openshift-virtualization-tests/blob/main/utilities/infra.py
- 2: https://ithub.global.ssl.fastly.net/RedHatQE/openshift-virtualization-tests/blob/main/tests/conftest.py
- 3: https://plugins.jetbrains.com/plugin/15921-kubernetes-by-red-hat/versions/stable/219166
- 4: https://github.com/redhat-developer/intellij-kubernetes/releases
- 5: https://www.ibm.com/docs/en/fusion-software/2.13.0?topic=cataloging-integrating-data-file-filtering
🌐 Web query:
"from ocp_resources import ResourceEditor"
💡 Result:
The ResourceEditor class is a component of the ocp_resources Python library (commonly referred to as the OpenShift Python Wrapper) [1]. This library is an open-source tool developed to provide a standardized, intuitive interface for interacting with Kubernetes and OpenShift cluster resources [2][3]. While specific documentation for ResourceEditor is less prominent than the core Resource base class [4][5], it is frequently used within the testing frameworks maintained by Red Hat QE (Quality Engineering) to facilitate the modification or management of cluster resources during test execution [1]. In the broader context of the ocp_resources library: - Purpose: The library simplifies CRUD (Create, Read, Update, Delete) operations, resource management, and cluster interaction [4][3]. - Core Concept: All resource types (e.g., Pod, Deployment, Namespace) inherit from a common Resource base class [6][5]. - Usage: Users typically interact with the library by first acquiring a client via get_client() [4][7]. - Ecosystem: It is designed to be highly compatible with testing workflows, offering support for context managers for automatic resource cleanup and resource-specific functionality like log streaming and command execution [2][3]. If you are working with a codebase containing from ocp_resources import ResourceEditor, it is likely part of an automated testing or cluster management suite designed to handle resource lifecycles or complex state modifications [1]. You can explore the library's official documentation for comprehensive details on standard resource operations [3][8].
Citations:
- 1: https://ithub.global.ssl.fastly.net/RedHatQE/openshift-virtualization-tests/blob/main/tests/conftest.py
- 2: https://opensource.com/article/23/4/cluster-open-source-python-api-wrapper
- 3: https://redhatqe-openshift-python-wrapper-47.mintlify.app/introduction
- 4: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/api-reference/resource
- 5: https://redhatqe-openshift-python-wrapper-47.mintlify.app/api-reference/resource
- 6: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/core-concepts/resources
- 7: https://redhatqe-openshift-python-wrapper-47.mintlify.app/guides/resource-crud-operations
- 8: https://redhatqe-openshift-python-wrapper-47.mintlify.app/quickstart
🌐 Web query:
"ocp_resources" "ResourceEditor" "patch_type" "merge"
💡 Result:
The term merge in the context of patch_type refers to the JSON Merge Patch strategy (defined in RFC 7396) used for updating Kubernetes or OpenShift resources [1][2][3]. In Kubernetes and OpenShift ecosystems—including kubectl/oc CLI tools, Python wrappers, and various operators—the patch_type parameter determines how a patch payload is applied to an existing object [4][5][2][6]. The merge patch strategy is one of three primary types [3]: 1. Merge Patch (patch_type: merge): Uses JSON Merge Patch [1][3]. It is a simple, intuitive way to merge JSON objects [2]. It is particularly useful for updates where you simply want to overwrite or add fields in a JSON structure [1][2]. However, it cannot be used to remove fields (setting a field to null effectively removes it) and it lacks the list-merging capabilities found in strategic merge patches [2][7]. 2. Strategic Merge Patch (patch_type: strategic): The default behavior for most native Kubernetes resources [2][6]. It is "Kubernetes-aware," meaning it uses metadata (such as patchMergeKey) defined in the API schema to intelligently merge lists rather than replacing them entirely [7][8]. Note that this type is generally not supported for Custom Resource Definitions (CRDs) [4][6]. 3. JSON Patch (patch_type: json): Uses RFC 6902 JSON Patch [1][2]. This provides precise, granular control over operations like add, remove, replace, move, and copy [1][2]. When using tools like oc patch, kubectl patch, or various library wrappers, you specify --type merge (or patch_type="merge") to explicitly invoke the JSON Merge Patch strategy [4][5][6]. This is often the required approach when working with CRDs or when specific field handling behavior that differs from the default strategic merge is needed [9].
Citations:
- 1: https://glama.ai/mcp/servers/skyhook-io/radar/tools/patch_resource
- 2: https://github.com/hypen-code/hypen-argocd-mcp/blob/main/docs/patch_resource.md
- 3: https://github.com/kubernetes/apimachinery/blob/5a348c53/pkg/types/patch.go
- 4: https://manpages.opensuse.org/Tumbleweed/oc/oc-patch.1.en.html
- 5: https://github.com/RedHatQE/openshift-python-wrapper/blob/main/mcp_server/README.md
- 6: https://kubernetes.website.cncfstack.com/docs/reference/kubectl/generated/kubectl_patch/
- 7: https://github.com/kubernetes-sigs/controller-runtime/blob/main/pkg/client/patch.go
- 8: pkg/helm/release/manager.go: refactor to use ThreeWayMergePatch operator-framework/operator-sdk#2808
- 9: Allow merge type specification in resource.patch openshift/openshift-restclient-python#174
🌐 Web query:
"ocp_resources" "ResourceEditor" "oc patch"
💡 Result:
The terms in your query refer to two distinct contexts within the OpenShift ecosystem: command-line operations using the OpenShift CLI (oc) and internal components of the OpenShift Python automation framework. oc patch The command oc patch is a standard OpenShift CLI utility used to apply partial updates (patches) to existing resources on a cluster [1][2]. It allows you to modify specific fields without needing to replace the entire resource definition [3][4]. Common usage patterns include: - Strategic Merge Patch (default): Ideal for updating fields in existing objects [1][2]. oc patch <resource_type> <resource_name> -p '{"spec":{"key":"value"}}' - JSON Patch: Useful for precise operations like replacing or adding items in an array [1][2]. oc patch <resource_type> <resource_name> --type='json' -p='[{"op": "replace", "path": "/path/to/field", "value":"new_value"}]' ResourceEditor The term ResourceEditor (or ResourceYAMLEditor) typically refers to internal components used within the OpenShift Console web interface (often related to React components for editing resource YAML) [5] or class structures within the OpenShift Python Wrapper (a test/automation library) [6][7][8]. In the context of the OpenShift Python Wrapper (frequently used by Red Hat QE), resources are managed via Python classes (e.g., Pod, Deployment) that inherit from a base Resource class [6][8]. In this library, patching or updating a resource is handled through methods like.update, which accepts a dictionary representing the desired changes [7][8][9]. It does not involve the oc patch command directly, but rather performs API calls to achieve the same result programmatically [7][9]. If you are encountering these terms together in an error message or log, you may be using an automation tool that wraps oc commands or interacts with the OpenShift API; checking the documentation for the specific framework or library you are using is recommended [6][8].
Citations:
- 1: https://manpages.opensuse.org/Tumbleweed/oc/oc-patch.1.en.html
- 2: https://docs.okd.io/4.20/cli_reference/openshift_cli/developer-cli-commands.html
- 3: https://docs.redhat.com/en/documentation/openshift_container_platform/4.19/html/configuring_network_settings/configuring-cluster-network-range
- 4: https://access.redhat.com/articles/3319751
- 5: OCPBUGS-31355: add readOnly option to ResourceYAMLEditor openshift/console#13694
- 6: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/contributing/adding-resources
- 7: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/api-reference/resource
- 8: https://mintlify.wiki/RedHatQE/openshift-python-wrapper/core-concepts/resources
- 9: https://redhatqe-openshift-python-wrapper-47.mintlify.app/guides/resource-crud-operations
🌐 Web query:
"ocp_resources" "ResourceEditor" "Resource" "backup_resources"
💡 Result:
The query terms provided do not correspond to a single integrated feature or official OpenShift/Kubernetes command. Instead, they appear to be a mix of separate concepts and third-party projects related to OpenShift resource management and backups [1][2][3]. 1. OADP (OpenShift API for Data Protection): This is the official Red Hat solution for backing up and restoring OpenShift applications [1][2]. It uses custom resources (CRs) such as Backup, Restore, and Schedule to manage data protection [1][2]. It does not utilize a specific tool called "ResourceEditor" for this purpose [1][2]. 2. ResourceEditor: This term is associated with KubeStash and the Appscode ecosystem (kmodules), which provides tools for managing Kubernetes resources and backup configurations [4]. It is not a standard component of OpenShift's native backup solution (OADP) [1][2]. 3. ocp_resources: This appears to be a reference to a Python utility library used in OpenShift QE and testing environments (e.g., ocp-resources or openshift-python-wrapper) for interacting with the Kubernetes API programmatically [3]. If you are attempting to perform backups in OpenShift, the authoritative method is using OADP [1][2]. You create a Backup custom resource to define which resources to include or exclude [1][5]. You can preview resources by running dry-run operations or using Velero commands before committing to a full backup [6][7]. For more granular resource discovery to assist in backup planning, tools like the oc get-resources plugin exist in the broader Kubernetes/OpenShift community to audit namespace and cluster-scoped resources [8].
Citations:
- 1: https://docs.redhat.com/en/documentation/openshift_container_platform/4.14/html-single/backup_and_restore/index
- 2: https://docs.redhat.com/en/documentation/openshift_container_platform/4.15/html/backup_and_restore/oadp-application-backup-and-restore
- 3: https://redhatqe-openshift-python-wrapper-47.mintlify.app/api-reference/utilities/client
- 4: kmodules/resource-metadata@9e2d67a
- 5: https://docs.okd.io/4.10/backup_and_restore/application_backup_and_restore/backing_up_and_restoring/backing-up-applications.html
- 6: https://docs.okd.io/4.18/backup_and_restore/application_backup_and_restore/backing_up_and_restoring/restoring-applications.html
- 7: https://docs.okd.io/4.22/backup_and_restore/application_backup_and_restore/backing_up_and_restoring/backing-up-applications.html
- 8: https://community.ibm.com/community/user/blogs/sandeep-prajapati/2026/01/11/making-kubernetes-or-openshift-backup-and-restore
Preserve existing spec.featureGates entries.
ResourceEditor applies these patches as resource updates, and HCOv1Spec.feature_gates(incrementalBackup=True) produces only {"featureGates": [{"name": "incrementalBackup"}]}. A merge update on spec.featureGates will replace the existing list, which can remove other configured gates. Build the target list from the existing feature gates and add/modify incrementalBackup, or include both the existing entries and the new selector in one preserved patch payload.
🤖 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 `@tests/storage/cbt/conftest.py` around lines 50 - 56, The CBT fixture setup
must preserve existing spec.featureGates entries instead of replacing them with
only incrementalBackup. Update the merged_spec construction around
HCOv1Spec.feature_gates and ResourceEditorValidateHCOReconcile to derive the
target feature-gate list from the current resource, then add or update
incrementalBackup while retaining all existing gates.
| fg_description = v1_version["schema"]["openAPIV3Schema"]["properties"]["spec"]["properties"]["featureGates"].get( | ||
| "description", "" | ||
| ) | ||
| phases = dict(_FG_PHASE_RE.findall(fg_description)) | ||
| if not phases: | ||
| raise ValueError( | ||
| f"Failed to parse FG phases from HCO CRD — format may have changed. " | ||
| f"Description starts with: {fg_description[:200]!r}" | ||
| ) |
There was a problem hiding this comment.
🎯 Functional Correctness | 🟠 Major | ⚡ Quick win
HIGH: Normalize missing schema keys to the documented ValueError.
If the CRD moves or removes spec.featureGates.description, Line 98 raises KeyError. The session fixture then fails with no schema context. This contradicts the function contract that changed or unavailable v1 schema produces ValueError.
Catch the missing-key case and re-raise ValueError with the HCO schema path and exception context. Add a unit test for a v1 version that lacks spec.featureGates.
Proposed fix
- fg_description = v1_version["schema"]["openAPIV3Schema"]["properties"]["spec"]["properties"]["featureGates"].get(
- "description", ""
- )
+ try:
+ fg_description = v1_version["schema"]["openAPIV3Schema"]["properties"]["spec"]["properties"][
+ "featureGates"
+ ].get("description", "")
+ except KeyError as exception:
+ raise ValueError("HCO v1 schema does not contain spec.featureGates.description") from exception
+
+ if not isinstance(fg_description, str):
+ raise ValueError("HCO v1 schema has a non-string spec.featureGates.description")📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| fg_description = v1_version["schema"]["openAPIV3Schema"]["properties"]["spec"]["properties"]["featureGates"].get( | |
| "description", "" | |
| ) | |
| phases = dict(_FG_PHASE_RE.findall(fg_description)) | |
| if not phases: | |
| raise ValueError( | |
| f"Failed to parse FG phases from HCO CRD — format may have changed. " | |
| f"Description starts with: {fg_description[:200]!r}" | |
| ) | |
| try: | |
| fg_description = v1_version["schema"]["openAPIV3Schema"]["properties"]["spec"]["properties"][ | |
| "featureGates" | |
| ].get("description", "") | |
| except KeyError as exception: | |
| raise ValueError("HCO v1 schema does not contain spec.featureGates.description") from exception | |
| if not isinstance(fg_description, str): | |
| raise ValueError("HCO v1 schema has a non-string spec.featureGates.description") | |
| phases = dict(_FG_PHASE_RE.findall(fg_description)) | |
| if not phases: | |
| raise ValueError( | |
| f"Failed to parse FG phases from HCO CRD — format may have changed. " | |
| f"Description starts with: {fg_description[:200]!r}" | |
| ) |
🧰 Tools
🪛 ast-grep (0.45.0)
[warning] 100-100: XPath query is request-/variable-derived; use parameterized XPath to prevent injection.
Context: _FG_PHASE_RE.findall(fg_description)
Note: [CWE-643] Improper Neutralization of Data within XPath Expressions ('XPath Injection').
(xpath-injection-python)
🪛 Ruff (0.16.1)
[warning] 103-106: Avoid specifying long messages outside the exception class
(TRY003)
🤖 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 `@utilities/hco.py` around lines 98 - 106, Update the v1 schema traversal that
computes fg_description to catch missing-key failures, including an absent
spec.featureGates path, and re-raise ValueError with the HCO schema path and
original exception context. Preserve the existing ValueError for unparseable
phases, and add a unit test covering a v1 schema without spec.featureGates.
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5952. Overlapping filesuv.lock |
Introduce HCOv1Spec callable spec group builders and FG helpers in utilities/constants/hco.py. Add parse_hco_fg_phases() to read FG phase defaults from the CRD at runtime. Remove the v1beta1 API version override in get_hyperconverged_resource(). Bump openshift-python-wrapper to 11.0.139 which includes the v1-regenerated HyperConverged class. Update all central HCO utility functions to use v1 grouped spec paths. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert all HCO spec patches and reads in install_upgrade_operators to use v1 grouped structure via HCOv1Spec builders. Migrate feature gate patches from dict to list format. Remove dead FG constants and the unused multiarch block in expected_value fixture. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert HCO spec patches in storage tests to use HCOv1Spec builders for storage, virtualization, and security groups. Migrate feature gate patches from dict to list format. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert HCO spec patches in virt tests to use HCOv1Spec builders for virtualization group (permittedHostDevices, virtualMachineOptions, ksmConfiguration, evictionStrategy). Migrate feature gate patches from dict to list format. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert kubeMacPoolConfiguration patches and reads to use HCOv1Spec.networking() and v1 grouped spec paths. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert featureGates patches in vhostmd tests and dataImportCronTemplates patches in golden_images tests to use HCOv1Spec builders. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Convert vmStateStorageClass patch to use HCOv1Spec.storage(). Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add 15 new tests covering HCOv1Spec spec group builders, feature_gates() (enable/disable/multiple), is_fg_enabled() (explicit, default beta/alpha, unknown FG), and CRD-based FG phase parsing. Update existing test mocks from v1beta1 flat format to v1 grouped structure. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add HCO v1 API Usage (MANDATORY) section requiring HCOv1Spec builders for all HCO spec patches, v1 list format for feature gates, and is_fg_enabled() for FG state reads. Signed-off-by: Harel Meir <hmeir@redhat.com> Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
b130a55 to
d9ad4da
Compare
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5922. Overlapping filestests/conftest.py |
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5877. Overlapping filespyproject.toml |
vsibirsk
left a comment
There was a problem hiding this comment.
pr link in the description points to wrong repo (tests instead on python wrapper :) )
| with ResourceEditorValidateHCOReconcile( | ||
| admin_client=admin_client, | ||
| patches={hyperconverged_resource_scope_function: {"spec": {EVICTIONSTRATEGY: "None"}}}, | ||
| patches={hyperconverged_resource_scope_function: HCOv1Spec.virtualization(**{EVICTIONSTRATEGY: "None"})}, |
There was a problem hiding this comment.
why not evictionStrategy=None?
| Z_STREAM = "z-stream" | ||
|
|
||
|
|
||
| class _SpecGroup: |
There was a problem hiding this comment.
| return current | ||
|
|
||
|
|
||
| class HCOv1Spec: |
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5672. Overlapping filestests/conftest.py |
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5975. Overlapping filestests/install_upgrade_operators/conftest.py |
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5708. Overlapping filestests/storage/test_hotplug.py |
|
/retest all Auto-triggered: Files in this PR were modified by merged PR #5674. Overlapping filestests/conftest.py |
What this PR does / why we need it:
Migrates all HCO automation from v1beta1 to v1 API. The upstream
openshift-python-wrapper PR #2777 regenerated the HyperConverged class
from the v1 CRD schema. This PR updates all test code to match.
Key changes:
HCOv1Specclass with callable spec group builders and FG helpersparse_hco_fg_phases()to read FG phase defaults from the CRD at runtimeget_hyperconverged_resource()50 files changed across 9 commits, organized by domain (utilities, IUO,
storage, virt, network, infrastructure).
Which issue(s) this PR fixes:
CNV-87694
Special notes for reviewer:
spec.workloadsis renamed toworkload(singular) in v1spec.featureGates(NOT under a group), only format changesenableMultiArchBootImageImport,disableMDevConfiguration,persistentReservation) should be read from their dedicated spec fieldschangedBlockTrackingLabelSelectorsmoved underspec.virtualizationjira-ticket:
https://redhat.atlassian.net/browse/CNV-87694
🤖 Generated with Claude Code
Summary by CodeRabbit