Skip to content

fix: revert multus_network_name to use class_plan_config for VM lookups - #592

Merged
myakove merged 4 commits into
RedHatQE:mainfrom
krcmarik:fix/multus-network-name-rhv-regression
Jul 13, 2026
Merged

myakove merged 4 commits into
RedHatQE:mainfrom
krcmarik:fix/multus-network-name-rhv-regression

Conversation

@krcmarik

@krcmarik krcmarik commented Jul 8, 2026 •

Copy link
Copy Markdown
Collaborator

PR #583 changed the multus_network_name fixture to use prepared_plan
(cloned VM names) instead of class_plan_config (original template names)
for network lookups. This broke all RHV tests because RHV clones VMs
FROM templates — cloned VMs are VMs, not templates. The provider's
get_vm_or_template_networks() calls get_template_by_name(), which
searches the oVirt templates service and raises NotFoundError for
cloned VM names.

Reverting to class_plan_config is safe because cloned VMs always
inherit the source VM/template networks — no code path in the
codebase adds or modifies network assignments after cloning.

For copy-offload tests, the config uses a placeholder VM name
("xcopy-template-test") that gets overridden from .providers.json
at runtime. This override is now also applied in multus_network_name
via a shared helper to ensure the network lookup uses the real
VM name.

Also extracts the copy-offload VM name override logic into
apply_copyoffload_vm_name_override() to eliminate duplication
between multus_network_name and prepared_plan fixtures

Summary by CodeRabbit

Summary by CodeRabbit

  • Bug Fixes
    • Improved network detection for VM-based test setups by deriving network lookup targets from the original class plan configuration rather than cloned VM names.
    • VM and template discovery now consistently respects copy-offload default naming, improving reliability for subsequent network lookups.

PR RedHatQE#583 changed the multus_network_name fixture to use prepared_plan
(cloned VM names) instead of class_plan_config (original template names)
for network lookups. This broke all RHV tests because RHV clones VMs
FROM templates — cloned VMs are VMs, not templates. The provider's
get_vm_or_template_networks() calls get_template_by_name(), which
searches the oVirt templates service and raises NotFoundError for
cloned VM names.

Reverting to class_plan_config is safe because cloned VMs always
inherit the source VM/template networks — no code path in the
codebase adds or modifies network assignments after cloning. The
original template names are what all providers need for network
lookups.
@coderabbitai

coderabbitai Bot commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Caution

Review failed

An error occurred during the review process. Please try again later.

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

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.

❤️ Share

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

@redhat-qe-bot

Copy link
Copy Markdown

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: Disabled for this repository
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: All label categories are enabled (default configuration)

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message
  • /security-override - Set security check runs to pass (maintainers only)
  • /security-override cancel - Re-run security checks

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest build-container - Rebuild and test container image
  • /retest conventional-title - Validate commit message format
  • /retest all - Run all available tests

Container Operations

  • /build-and-push-container - Build and push container image (tagged with PR number)
    • Supports additional build arguments: /build-and-push-container --build-arg KEY=value

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3
  • /cherry-pick-retry <branch> - Retry a failed cherry-pick (merged PRs only)

Branch Management

  • /rebase - Rebase this PR branch onto its base branch

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. Status Checks: All required status checks must pass
  3. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  4. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • krcmarik
  • myakove
  • solenoci

Reviewers:

  • krcmarik
  • myakove
  • solenoci
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (claude/claude-opus-4-6-1m)
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6-1m)
  • Test Oracle: Triggers: approved (cursor/gpt-5.4-xhigh-fast); /test-oracle can be used anytime
Security Checks
  • Suspicious Path Detection: Monitors paths: .claude/, .vscode/, .cursor/, .devcontainer/, .pi/, .github/workflows/, .github/actions/
  • Committer Identity Check: Verifies last committer matches PR author
  • Mandatory: Security checks block merge (use /security-override to bypass — maintainers only)

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Container Builds: Container images are automatically tagged with the PR number
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix RHV regression by using class_plan_config for Multus network lookups

🐞 Bug fix 🧪 Tests 🕐 10-20 Minutes

Grey Divider

AI Description

• Revert multus_network_name to query networks using original template/VM names from
 class_plan_config.
• Prevent RHV/oVirt NotFoundError when provider network lookup hits templates service with cloned VM
 names.
• Restore cross-provider-consistent behavior for NAD creation during test setup.
Diagram

graph TD
  A(["pytest: multus_network_name"]) --> B["class_plan_config (names)"] --> C[["BaseProvider.get_vm_or_template_networks"]] --> D["oVirt/RHV templates API"]
  E["prepared_plan (cloned names)"] -. no longer used .-> A
  subgraph Legend
    direction LR
    _fx(["Fixture"]) ~~~ _cfg["Config/Plan data"] ~~~ _api[["Provider abstraction"]]
  end
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Make provider lookup accept VM names and resolve VM-vs-template internally
  • ➕ Centralizes RHV/oVirt name-resolution logic in provider layer instead of fixtures
  • ➕ Could allow using prepared_plan consistently across providers
  • ➖ Higher blast radius across providers and test suite; risk of subtle behavior changes
  • ➖ Requires clear contract for mixed VM/template names and handling clones
2. Cache networks from source template prior to cloning and pass network IDs forward
  • ➕ Avoids name-based lookups entirely; more robust to renames
  • ➕ Could speed up repeated lookups across many tests
  • ➖ More plumbing between planning, cloning, and NAD creation
  • ➖ May be premature complexity if current name-based lookup is stable

Recommendation: Keep this PR’s approach: using class_plan_config (original template/source names) is the least risky and matches RHV’s template-based network lookup behavior. Consider the provider-layer resolution alternative only if future work requires prepared_plan to be the single source of truth across providers.

Files changed (1) +2 / -6

Bug fix (1) +2 / -6
conftest.pyRestore network lookups to use class_plan_config VM/template names +2/-6

Restore network lookups to use class_plan_config VM/template names

• Removes prepared_plan from the multus_network_name fixture inputs and switches the VM/template name list back to class_plan_config. This avoids passing cloned VM names into RHV’s template-based network lookup path that raises NotFoundError.

conftest.py

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 8, 2026
@qodo-code-review

qodo-code-review Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (1) 📘 Rule violations (2) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 97 rules

Grey Divider


Action required

1. OpenShift VM names mismatch ✗ Dismissed 🐞 Bug ≡ Correctness ⭐ New
Description
multus_network_name now queries networks using class_plan_config VM names, but OpenShift-source VMs
are created in prepared_plan with a computed vm_name_suffix, so the inventory contains only suffixed
VM names. This can make OCPProvider.get_vm_or_template_networks() fail with a ValueError (VM not
found), preventing NAD creation and blocking the test run.
Code

conftest.py[R865-872]

+    virtual_machines = [dict(vm) for vm in class_plan_config["virtual_machines"]]
+    # Copy-offload configs use a placeholder VM name; the real name comes from .providers.json
+    apply_copyoffload_vm_name_override(virtual_machines=virtual_machines, source_provider=source_provider)
+    vms = [vm["name"] for vm in virtual_machines]
+    LOGGER.info(f"Found VMs for network lookup: {vms}")

    # Query networks using provider abstraction (handles templates vs VMs internally)
    networks = source_provider.get_vm_or_template_networks(names=vms, inventory=source_provider_inventory)
Relevance

⭐⭐⭐ High

Team recently accepted fixes for inventory “VM not found”/name-mismatch issues affecting lookups
(PRs #583, #462).

PR-#583
PR-#462

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
OpenShift-source VM creation appends a suffix, but multus_network_name now uses the unsuffixed
class_plan_config names for inventory-based lookups, which can’t be found in Forklift inventory and
therefore raises ValueError.

conftest.py[814-873]
conftest.py[1088-1115]
utilities/mtv_migration.py[319-330]
utilities/utils.py[439-460]
libs/providers/openshift.py[340-355]
libs/forklift_inventory.py[128-134]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`multus_network_name` now builds the network-lookup VM name list from `class_plan_config["virtual_machines"]`. For OpenShift as a *source* provider, `prepared_plan` creates the actual source CNV VMs with `name + vm_name_suffix`, so the Forklift inventory will not contain the base names. Network lookup via `OCPProvider.get_vm_or_template_networks()` (inventory-based) can therefore raise `ValueError: VM <name> not found`.

## Issue Context
- `prepared_plan` computes `vm_name_suffix` and uses it when creating CNV source VMs.
- `OCPProvider.get_vm_or_template_networks()` delegates to `inventory.vms_networks_mappings()`, which fails if the provided VM names are not present in inventory.

## Fix Focus Areas
- conftest.py[814-907]
- conftest.py[1088-1115]

### Suggested change
Re-introduce `prepared_plan` as a dependency of `multus_network_name` (or otherwise access the prepared/suffixed names) and use provider-conditional naming:
- If `source_provider.type == Provider.ProviderType.OPENSHIFT`, build `vms` from `prepared_plan["virtual_machines"]` (the actual created VM names).
- Otherwise keep the current `class_plan_config`-based lookup (and keep the copy-offload override).

This preserves the RHV fix (template-name lookup) while keeping OpenShift-source lookups aligned with the names that exist in inventory.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Copyoffload VM name mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
multus_network_name now always uses class_plan_config["virtual_machines"][*]["name"] for network
lookup, but prepared_plan rewrites clone sources to copyoffload_config['default_vm_name']; when
these differ, network discovery can fail (VM not found) or create the wrong NAD count for the VM
actually being migrated.
Code

conftest.py[R864-868]

+    vms = [vm["name"] for vm in class_plan_config["virtual_machines"]]
+    LOGGER.info(f"Found VMs from class plan config: {vms}")

    # Query networks using provider abstraction (handles templates vs VMs internally)
    networks = source_provider.get_vm_or_template_networks(names=vms, inventory=source_provider_inventory)
Relevance

⭐⭐ Medium

No similar historical finding; team fixed name-lookup bugs before (PR462), but revert rationale may
override edge-case concern.

PR-#225
PR-#462
PR-#583

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR change makes multus_network_name use raw plan VM names, but prepared_plan can override those
names for copy-offload before cloning; since inventory lookups are name-based and raise when a VM
name is missing, this creates a concrete failure mode when the placeholder name doesn't exist (or
when the overridden VM has different network interfaces).

conftest.py[813-904]
conftest.py[1038-1045]
tests/tests_config/config.py[88-110]
libs/forklift_inventory.py[116-122]
libs/providers/vmware.py[1866-1897]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`multus_network_name` derives VM names from `class_plan_config`, but for vSphere copy-offload flows `prepared_plan` rewrites the VM name (source) to `source_provider.copyoffload_config["default_vm_name"]`. This makes `multus_network_name` query networks for a stale/placeholder name (e.g., `xcopy-template-test`) instead of the real selected VM, which can raise "VM ... not found" from inventory and/or create a different number of NADs than `get_network_migration_map()` will require.

### Issue Context
- Copy-offload plans in `tests/tests_config/config.py` use a placeholder VM name (`xcopy-template-test`) with `clone=True`.
- In `prepared_plan`, that placeholder is overwritten from provider config (`default_vm_name`) before cloning.
- After this PR, `multus_network_name` no longer applies that same override when determining which VM(s) to query for networks.

### Fix Focus Areas
- conftest.py[813-903]
- conftest.py[1038-1045]
- tests/tests_config/config.py[88-110]

### Suggested fix (one of)
1) Re-apply the same copy-offload override logic inside `multus_network_name` before building `vms` (mirror the `prepared_plan` behavior for `default_vm_name` when `clone=True`).

2) Alternatively, reintroduce `prepared_plan` as an *optional* dependency and pick names conditionally:
  - RHV: use `class_plan_config` template names.
  - Others (esp. vSphere copyoffload): use the effective names after overrides (from `prepared_plan` or from applying the same override logic).

Either approach ensures network lookup/NAD count is computed for the same effective VM(s) used later by `get_network_migration_map()`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

3. apply_copyoffload_vm_name_override branches on VMware 📘 Rule violation ⌂ Architecture ⭐ New
Description
utilities/copyoffload_migration.py introduces provider-specific branching via `isinstance(...,
VMWareProvider)` and imports the VMware provider directly, placing provider-specific behavior in
shared test utilities rather than in libs/providers/*. This increases coupling and violates the
requirement to keep provider-specific logic inside provider modules.
Code

utilities/copyoffload_migration.py[R71-79]

+    if not isinstance(source_provider, VMWareProvider) or not source_provider.copyoffload_config:
+        return
+    default_vm_override = source_provider.copyoffload_config.get("default_vm_name")
+    if not default_vm_override:
+        return
+    for vm in virtual_machines:
+        if vm.get("clone", False):
+            LOGGER.info(f"Overriding VM name '{vm['name']}' with '{default_vm_override}' from provider config")
+            vm["name"] = default_vm_override
Relevance

⭐ Low

Repo commonly uses provider-specific isinstance branching in shared fixtures/utilities and accepted
it previously (e.g., PR #415).

PR-#415

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1263111 requires that provider-specific branching live in provider modules, not in
shared scaffolding. The added helper imports VMWareProvider and branches on it in
utilities/copyoffload_migration.py, and this helper is invoked from conftest.py, making shared
test scaffolding depend on VMware-specific logic.

Rule 1263111: Keep provider-specific logic within provider modules, not shared test scaffolding
utilities/copyoffload_migration.py[58-79]
conftest.py[865-868]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
Provider-specific logic (VMware-only branching) is implemented in a shared utility (`utilities/copyoffload_migration.py`) instead of being encapsulated in the VMware provider module.

## Issue Context
The new helper `apply_copyoffload_vm_name_override()` is called from `conftest.py` to adjust copy-offload placeholder VM names, but it determines provider type using `VMWareProvider` directly.

## Fix Focus Areas
- utilities/copyoffload_migration.py[58-79]
- conftest.py[865-868]
- libs/providers/vmware.py[77-120]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


4. Missing Returns: in apply_copyoffload_vm_name_override 📘 Rule violation ✧ Quality
Description
The new function apply_copyoffload_vm_name_override has a docstring with an Args: section but no
Returns: section, even though it returns None. This violates the required docstring structure
and reduces API clarity/consistency.
Code

utilities/copyoffload_migration.py[R62-70]

+    """Override placeholder VM names with the real VM name from copy-offload config.
+
+    Copy-offload test configs use placeholder names (e.g., "xcopy-template-test") that
+    must be resolved to the real template name from the provider's copyoffload_config.
+
+    Args:
+        virtual_machines (list[dict[str, Any]]): List of VM config dicts to update in place.
+        source_provider (BaseProvider): Source provider that may have copyoffload_config.
+    """
Relevance

⭐ Low

Recent reviews rejected adding Returns: None to void-function docstrings (PRs #566, #572).

PR-#566
PR-#572

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 70457 requires new functions to include Args:, Returns: (explicitly documenting
None when applicable), and Raises: when applicable. The new function’s docstring includes
Args: but omits Returns: entirely.

Rule 70457: Require docstrings with Args/Returns/Raises for new functions
utilities/copyoffload_migration.py[58-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`apply_copyoffload_vm_name_override()` is newly added but its docstring is missing a required `Returns:` section (it should explicitly document returning `None`).

## Issue Context
Repo compliance requires new functions to use the standard docstring format including `Args:`, `Returns:`, and `Raises:` when applicable.

## Fix Focus Areas
- utilities/copyoffload_migration.py[58-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


5. Heavy conftest import 🐞 Bug ⚙ Maintainability
Description
conftest.py now imports apply_copyoffload_vm_name_override from
utilities.copyoffload_migration at module import time, which forces pytest collection to import
the entire copy-offload migration module (and its heavy runtime dependencies) even for runs that
don’t exercise copy-offload paths. This increases coupling and can slow down or broaden the import
surface of the test harness unnecessarily.
Code

conftest.py[45]

+from utilities.copyoffload_migration import apply_copyoffload_vm_name_override
Relevance

⭐ Low

Similar “avoid import-time work during collection” suggestion was rejected in PR #294; likely not
enforced.

PR-#294

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new module-scope import in conftest.py triggers import of utilities.copyoffload_migration,
which itself imports many runtime dependencies (k8s/ocp_resources/rrmngmnt/etc.) and now also
imports VMWareProvider at runtime, increasing the import graph during test collection.

conftest.py[38-53]
utilities/copyoffload_migration.py[18-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`conftest.py` imports `apply_copyoffload_vm_name_override` from `utilities.copyoffload_migration` at module scope. Because `conftest.py` is imported during pytest collection, this forces importing the full copy-offload migration module (and its transitive dependencies) for every test run.

### Issue Context
The helper is small and is used in `multus_network_name` and `prepared_plan`, but it currently lives inside a large module intended for copy-offload migration flows.

### Fix Focus Areas
- conftest.py[45-45]
- utilities/copyoffload_migration.py[39-41]
- utilities/copyoffload_migration.py[58-81]

### Suggested fix
Either:
1) Move `apply_copyoffload_vm_name_override` into a lightweight utility module (e.g., `utilities/copyoffload_utils.py`) with minimal imports, and import it from there in `conftest.py`, **or**
2) Remove the module-scope import from `conftest.py` and perform a local import inside the fixtures right before use, to defer importing `utilities.copyoffload_migration` until it’s actually needed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


View more (1)
6. Unjustified Any in virtual_machines ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The new signature uses Any in virtual_machines: list[dict[str, Any]] without an inline
justification comment. This violates the requirement to document why Any is unavoidable and may
weaken type safety.
Code

utilities/copyoffload_migration.py[R58-61]

+def apply_copyoffload_vm_name_override(
+    virtual_machines: list[dict[str, Any]],
+    source_provider: BaseProvider,
+) -> None:
Relevance

⭐ Low

Team previously rejected adding inline justification comments for new Any usages (PR #572).

PR-#572

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1256238 requires that newly added/modified Any annotations include an inline
justification comment (same or previous line) describing why a more precise type is not feasible.
The new parameter annotation introduces Any without such a comment.

Rule 1256238: Restrict use of Any to documented, unavoidable cases
utilities/copyoffload_migration.py[58-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new function signature uses `Any` (`list[dict[str, Any]]`) without an inline justification comment explaining why a more precise type (e.g., TypedDict/Protocol/object/Mapping) cannot be used.

## Issue Context
Compliance requires every newly introduced/modified `Any` usage to be justified with an inline comment (same line or immediately preceding).

## Fix Focus Areas
- utilities/copyoffload_migration.py[58-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Previous review results

Review updated until commit 405104e

Results up to commit c4a3aa9


🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Action required
1. Copyoffload VM name mismatch ✓ Resolved 🐞 Bug ≡ Correctness
Description
multus_network_name now always uses class_plan_config["virtual_machines"][*]["name"] for network
lookup, but prepared_plan rewrites clone sources to copyoffload_config['default_vm_name']; when
these differ, network discovery can fail (VM not found) or create the wrong NAD count for the VM
actually being migrated.
Code

conftest.py[R864-868]

+    vms = [vm["name"] for vm in class_plan_config["virtual_machines"]]
+    LOGGER.info(f"Found VMs from class plan config: {vms}")

    # Query networks using provider abstraction (handles templates vs VMs internally)
    networks = source_provider.get_vm_or_template_networks(names=vms, inventory=source_provider_inventory)
Relevance

⭐⭐ Medium

No similar historical finding; team fixed name-lookup bugs before (PR462), but revert rationale may
override edge-case concern.

PR-#225
PR-#462
PR-#583

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR change makes multus_network_name use raw plan VM names, but prepared_plan can override those
names for copy-offload before cloning; since inventory lookups are name-based and raise when a VM
name is missing, this creates a concrete failure mode when the placeholder name doesn't exist (or
when the overridden VM has different network interfaces).

conftest.py[813-904]
conftest.py[1038-1045]
tests/tests_config/config.py[88-110]
libs/forklift_inventory.py[116-122]
libs/providers/vmware.py[1866-1897]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`multus_network_name` derives VM names from `class_plan_config`, but for vSphere copy-offload flows `prepared_plan` rewrites the VM name (source) to `source_provider.copyoffload_config["default_vm_name"]`. This makes `multus_network_name` query networks for a stale/placeholder name (e.g., `xcopy-template-test`) instead of the real selected VM, which can raise "VM ... not found" from inventory and/or create a different number of NADs than `get_network_migration_map()` will require.

### Issue Context
- Copy-offload plans in `tests/tests_config/config.py` use a placeholder VM name (`xcopy-template-test`) with `clone=True`.
- In `prepared_plan`, that placeholder is overwritten from provider config (`default_vm_name`) before cloning.
- After this PR, `multus_network_name` no longer applies that same override when determining which VM(s) to query for networks.

### Fix Focus Areas
- conftest.py[813-903]
- conftest.py[1038-1045]
- tests/tests_config/config.py[88-110]

### Suggested fix (one of)
1) Re-apply the same copy-offload override logic inside `multus_network_name` before building `vms` (mirror the `prepared_plan` behavior for `default_vm_name` when `clone=True`).

2) Alternatively, reintroduce `prepared_plan` as an *optional* dependency and pick names conditionally:
  - RHV: use `class_plan_config` template names.
  - Others (esp. vSphere copyoffload): use the effective names after overrides (from `prepared_plan` or from applying the same override logic).

Either approach ensures network lookup/NAD count is computed for the same effective VM(s) used later by `get_network_migration_map()`.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Results up to commit 38b4f59


🐞 Bugs (1) 📘 Rule violations (1) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)


Informational
1. Missing Returns: in apply_copyoffload_vm_name_override 📘 Rule violation ✧ Quality
Description
The new function apply_copyoffload_vm_name_override has a docstring with an Args: section but no
Returns: section, even though it returns None. This violates the required docstring structure
and reduces API clarity/consistency.
Code

utilities/copyoffload_migration.py[R62-70]

+    """Override placeholder VM names with the real VM name from copy-offload config.
+
+    Copy-offload test configs use placeholder names (e.g., "xcopy-template-test") that
+    must be resolved to the real template name from the provider's copyoffload_config.
+
+    Args:
+        virtual_machines (list[dict[str, Any]]): List of VM config dicts to update in place.
+        source_provider (BaseProvider): Source provider that may have copyoffload_config.
+    """
Relevance

⭐ Low

Recent reviews rejected adding Returns: None to void-function docstrings (PRs #566, #572).

PR-#566
PR-#572

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 70457 requires new functions to include Args:, Returns: (explicitly documenting
None when applicable), and Raises: when applicable. The new function’s docstring includes
Args: but omits Returns: entirely.

Rule 70457: Require docstrings with Args/Returns/Raises for new functions
utilities/copyoffload_migration.py[58-70]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`apply_copyoffload_vm_name_override()` is newly added but its docstring is missing a required `Returns:` section (it should explicitly document returning `None`).

## Issue Context
Repo compliance requires new functions to use the standard docstring format including `Args:`, `Returns:`, and `Raises:` when applicable.

## Fix Focus Areas
- utilities/copyoffload_migration.py[58-70]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


2. Heavy conftest import 🐞 Bug ⚙ Maintainability
Description
conftest.py now imports apply_copyoffload_vm_name_override from
utilities.copyoffload_migration at module import time, which forces pytest collection to import
the entire copy-offload migration module (and its heavy runtime dependencies) even for runs that
don’t exercise copy-offload paths. This increases coupling and can slow down or broaden the import
surface of the test harness unnecessarily.
Code

conftest.py[45]

+from utilities.copyoffload_migration import apply_copyoffload_vm_name_override
Relevance

⭐ Low

Similar “avoid import-time work during collection” suggestion was rejected in PR #294; likely not
enforced.

PR-#294

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new module-scope import in conftest.py triggers import of utilities.copyoffload_migration,
which itself imports many runtime dependencies (k8s/ocp_resources/rrmngmnt/etc.) and now also
imports VMWareProvider at runtime, increasing the import graph during test collection.

conftest.py[38-53]
utilities/copyoffload_migration.py[18-41]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`conftest.py` imports `apply_copyoffload_vm_name_override` from `utilities.copyoffload_migration` at module scope. Because `conftest.py` is imported during pytest collection, this forces importing the full copy-offload migration module (and its transitive dependencies) for every test run.

### Issue Context
The helper is small and is used in `multus_network_name` and `prepared_plan`, but it currently lives inside a large module intended for copy-offload migration flows.

### Fix Focus Areas
- conftest.py[45-45]
- utilities/copyoffload_migration.py[39-41]
- utilities/copyoffload_migration.py[58-81]

### Suggested fix
Either:
1) Move `apply_copyoffload_vm_name_override` into a lightweight utility module (e.g., `utilities/copyoffload_utils.py`) with minimal imports, and import it from there in `conftest.py`, **or**
2) Remove the module-scope import from `conftest.py` and perform a local import inside the fixtures right before use, to defer importing `utilities.copyoffload_migration` until it’s actually needed.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


3. Unjustified Any in virtual_machines ✓ Resolved 📘 Rule violation ⚙ Maintainability
Description
The new signature uses Any in virtual_machines: list[dict[str, Any]] without an inline
justification comment. This violates the requirement to document why Any is unavoidable and may
weaken type safety.
Code

utilities/copyoffload_migration.py[R58-61]

+def apply_copyoffload_vm_name_override(
+    virtual_machines: list[dict[str, Any]],
+    source_provider: BaseProvider,
+) -> None:
Relevance

⭐ Low

Team previously rejected adding inline justification comments for new Any usages (PR #572).

PR-#572

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
PR Compliance ID 1256238 requires that newly added/modified Any annotations include an inline
justification comment (same or previous line) describing why a more precise type is not feasible.
The new parameter annotation introduces Any without such a comment.

Rule 1256238: Restrict use of Any to documented, unavoidable cases
utilities/copyoffload_migration.py[58-61]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The new function signature uses `Any` (`list[dict[str, Any]]`) without an inline justification comment explaining why a more precise type (e.g., TypedDict/Protocol/object/Mapping) cannot be used.

## Issue Context
Compliance requires every newly introduced/modified `Any` usage to be justified with an inline comment (same line or immediately preceding).

## Fix Focus Areas
- utilities/copyoffload_migration.py[58-61]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Qodo Logo

Comment thread conftest.py Resolved
Copy-offload configs use a placeholder VM name ("xcopy-template-test")
that gets overridden from .providers.json at runtime. Apply the same
override in multus_network_name before network lookup.

Extracts the override logic into apply_copyoffload_vm_name_override()
to eliminate duplication between multus_network_name and prepared_plan.
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 38b4f59

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 9, 2026

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

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
utilities/copyoffload_migration.py (1)

58-81: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Type annotation list[dict[str, str | bool]] is too narrow for heterogeneous VM config dicts.

The VM config dicts are heterogeneous structures loaded from plan config — they contain values beyond str and bool (e.g., nested dicts, lists, integers). The downstream caller in conftest.py:1020 types this as list[dict[str, Any]], creating a mismatch at the call site. Using Any here is justified because the dict is a heterogeneous config object, not a uniform mapping. Per coding guidelines, Any should be avoided "unless justified" — this is a justified case.

🔧 Proposed fix for type annotation
 def apply_copyoffload_vm_name_override(
-    virtual_machines: list[dict[str, str | bool]],
+    virtual_machines: list[dict[str, Any]],
     source_provider: BaseProvider,
 ) -> None:
     """Override placeholder VM names with the real VM name from copy-offload config.

     Copy-offload test configs use placeholder names (e.g., "xcopy-template-test") that
     must be resolved to the real template name from the provider's copyoffload_config.

     Args:
-        virtual_machines (list[dict[str, str | bool]]): List of VM config dicts to update in place.
+        virtual_machines (list[dict[str, Any]]): List of VM config dicts to update in place.
         source_provider (BaseProvider): Source provider that may have copyoffload_config.
     """
🤖 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/copyoffload_migration.py` around lines 58 - 81, The type annotation
on apply_copyoffload_vm_name_override is too restrictive for the heterogeneous
VM config objects passed in from the caller. Update the virtual_machines
parameter from a narrow dict value union to a more flexible Any-based mapping so
it matches the list[dict[str, Any]] shape used upstream in conftest.py and
accurately reflects the mixed config data stored in each VM entry. Keep the rest
of the function behavior the same while preserving the in-place name override
logic.
🤖 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.

Outside diff comments:
In `@utilities/copyoffload_migration.py`:
- Around line 58-81: The type annotation on apply_copyoffload_vm_name_override
is too restrictive for the heterogeneous VM config objects passed in from the
caller. Update the virtual_machines parameter from a narrow dict value union to
a more flexible Any-based mapping so it matches the list[dict[str, Any]] shape
used upstream in conftest.py and accurately reflects the mixed config data
stored in each VM entry. Keep the rest of the function behavior the same while
preserving the in-place name override logic.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 85166765-4383-4480-a8e6-b8bf9aec4339

📥 Commits

Reviewing files that changed from the base of the PR and between 38b4f59 and e361e0f.

📒 Files selected for processing (1)
  • utilities/copyoffload_migration.py

Comment thread conftest.py Resolved
@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 405104e

@krcmarik

Copy link
Copy Markdown
Collaborator Author

/verified

@krcmarik

Copy link
Copy Markdown
Collaborator Author

/approve
/lgtm
(Just restoring the flag and approval after rebase only, no code change)

@myakove
myakove merged commit ff91989 into RedHatQE:main Jul 13, 2026
9 checks passed
@redhat-qe-bot2

Copy link
Copy Markdown

New container for ghcr.io/redhatqe/mtv-api-tests:latest published

@krcmarik

Copy link
Copy Markdown
Collaborator Author

/cherry-pick v2.11

@rh-bot-1

Copy link
Copy Markdown

Cherry-picked PR fix: revert multus_network_name to use class_plan_config for VM lookups into v2.11: #600

redhat-qe-bot1 pushed a commit that referenced this pull request Jul 14, 2026
…ps (#592) (#600)

* fix: revert multus_network_name to use class_plan_config for VM lookups

PR #583 changed the multus_network_name fixture to use prepared_plan
(cloned VM names) instead of class_plan_config (original template names)
for network lookups. This broke all RHV tests because RHV clones VMs
FROM templates — cloned VMs are VMs, not templates. The provider's
get_vm_or_template_networks() calls get_template_by_name(), which
searches the oVirt templates service and raises NotFoundError for
cloned VM names.

Reverting to class_plan_config is safe because cloned VMs always
inherit the source VM/template networks — no code path in the
codebase adds or modifies network assignments after cloning. The
original template names are what all providers need for network
lookups.

* fix: add copy-offload VM name override to multus_network_name

Copy-offload configs use a placeholder VM name ("xcopy-template-test")
that gets overridden from .providers.json at runtime. Apply the same
override in multus_network_name before network lookup.

Extracts the override logic into apply_copyoffload_vm_name_override()
to eliminate duplication between multus_network_name and prepared_plan.

* fix: use specific type for VM config dict in apply_copyoffload_vm_name_override

Co-authored-by: Marián Krčmárik <mkrcmari@redhat.com>
@krcmarik
krcmarik deleted the fix/multus-network-name-rhv-regression branch September 15, 2026 14:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants