Skip to content

OSAC-768: Add network attachment support for VMaaS tests - #45

Merged
ori-amizur merged 2 commits into
osac-project:mainfrom
ori-amizur:OSAC-768
Jun 3, 2026
Merged

ori-amizur merged 2 commits into
osac-project:mainfrom
ori-amizur:OSAC-768

Conversation

@ori-amizur

@ori-amizur ori-amizur commented May 24, 2026 •

Copy link
Copy Markdown
Contributor
Update all compute instance tests to use explicit network attachments,
ensuring VMs are provisioned on OSAC-managed subnets instead of the
default pod network.

Changes:
1. Add network_attachments parameter to OsacCLI.create_compute_instance()
   - Supports subnet and security-groups configuration
   - Builds --network-attachment CLI flags
   - Validates attachment structure

2. Add networking fixtures in tests/vmaas/conftest.py:
   - test_run_id: Unique ID per test run to avoid resource conflicts
   - default_networking: Creates VirtualNetwork + Subnet with cleanup
   - default_subnet: Returns subnet ID for CLI/gRPC usage
   - default_subnet_ref: Returns subnet CR name for K8s API usage

3. Update all compute instance tests to use network attachments:
   - test_compute_instance_api_fields: Use default_subnet_ref
   - test_compute_instance_cli_fields: Use default_subnet
   - test_compute_instance_creation: Use default_subnet
   - test_compute_instance_delete_during_provision: Use default_subnet
   - test_compute_instance_restart: Use default_subnet
   - test_compute_instance_restart_negative: Use default_subnet

This ensures VMs are created with proper tenant network isolation,
IP management, and security group support rather than using the
default Kubernetes pod network (masquerade).

Summary by CodeRabbit

  • Tests

    • Added VM networking fixtures provisioning VirtualNetwork/Subnet resources with automatic cleanup
    • Enhanced compute instance tests to use and validate explicit network attachments/subnet assignments in all flows
    • CLI test helper now accepts optional network attachments when creating instances
  • Chores

    • Bumped OSAC build version from 0.0.61 to 0.0.62
  • Tests

    • Added a session-scoped autouse fixture to optionally configure OVN-Kubernetes egress for CI environments

Review Change Stack

@openshift-ci-robot

openshift-ci-robot commented May 24, 2026 •

Copy link
Copy Markdown

@ori-amizur: This pull request references OSAC-768 which is a valid jira issue.

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

Details

In response to this:

Primary Change:

  • Updated all compute instance tests to use explicit network attachments
  • VMs now created in OSAC-managed subnets instead of default pod network
  • Tests use --network-attachment flag with default_subnet fixture

This change ensures VMs are provisioned on proper tenant networks with correct isolation, security groups, and IP management rather than using the default Kubernetes pod network (masquerade).

Technical Fixes Required:

  1. JWT Token Expiration Fix
  • Changed JWT fixtures from session to function scope
  • Fixtures now get fresh tokens for each test (tokens expire after 5 min)
  • Fixes grpcurl timeout errors after 300 seconds
  1. Kubernetes Field Name Fix
  • Added default_subnet_ref fixture for K8s API usage
  • Updated test_compute_instance_api_fields to use subnetRef (not subnet)
  • Fixes "unknown field 'spec.networkAttachments[0].subnet'" error
  1. Session Fixture Improvements
  • Added unique test_run_id to prevent resource naming conflicts
  • Fixed VirtualNetwork cleanup parameter bug (vn_id vs virtual_network_id)
  • Enhanced default_networking to return both UUIDs and CR names
  1. Error Reporting Improvements
  • Enhanced runner.py run() to show stderr/stdout on failures
  • Enhanced k8s_client.py apply() to show manifest on failures
  • Added remove_finalizers() method to k8s_client
  1. Stuck Job Detection
  • Added wait_for_deletion() enhancement to detect stuck AAP jobs
  • Automatically removes finalizers after 10 minutes to prevent hangs
  1. Test Infrastructure Updates
  • Added relogin() method to OsacCLI for token refresh
  • Updated compute instance tests to use default_subnet fixture

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the openshift-eng/jira-lifecycle-plugin repository.

@coderabbitai

coderabbitai Bot commented May 24, 2026 •

Copy link
Copy Markdown

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Adds CLI support for per-instance network_attachments and fixtures to create a VirtualNetwork and Subnet for tests; updates vmaas tests to attach instances to that subnet, adds a session autouse OVN egress fixture, and bumps Containerfile OSAC_VERSION. Risk: Low — test/infrastructure changes only.

Changes

Network Attachment Feature

Layer / File(s) Summary
CLI Network Attachment Support
tests/core/osac_cli.py
Adds Any import and an optional `network_attachments: list[dict[str, Any]]
Networking Test Fixtures
tests/vmaas/conftest.py
Adds test_run_id and default_networking session fixtures that create VirtualNetwork and Subnet CRs via gRPC, wait for CR names and Ready state, yield IDs/CR names, and teardown resources with deletion waits; also adds default_subnet and default_subnet_ref.
VMAAS Test Updates with Network Attachments
tests/vmaas/test_compute_instance_api_fields.py, tests/vmaas/test_compute_instance_cli_fields.py, tests/vmaas/test_compute_instance_creation.py, tests/vmaas/test_compute_instance_delete_during_provision.py, tests/vmaas/test_compute_instance_restart.py, tests/vmaas/test_compute_instance_restart_negative.py
Updates six tests to accept default_subnet or default_subnet_ref fixtures and pass explicit networkAttachments (API tests) or network_attachments (CLI tests) referencing the created subnet when constructing compute instances.
OVN-Kubernetes Egress Autouse Fixture
tests/conftest.py
Adds a session-scoped, autouse fixture that conditionally patches OpenShift network operator to enable OVN-Kubernetes egress (ipForwarding/routing), waits for daemonset rollout, verifies via oc queries, and logs warnings on errors.
Containerfile OSAC_VERSION bump
Containerfile
Bumps build arg OSAC_VERSION from 0.0.61 to 0.0.62.

Sequence Diagram(s)

sequenceDiagram
  participant TestRunner
  participant GRPCClient
  participant K8sClient
  TestRunner->>GRPCClient: Create VirtualNetwork CR
  GRPCClient->>K8sClient: Wait for VirtualNetwork CR name and Ready
  TestRunner->>GRPCClient: Create Subnet CR linked to VN
  GRPCClient->>K8sClient: Wait for Subnet CR name and Ready
  TestRunner->>TestRunner: yield subnet_id and subnet_ref
  TestRunner->>K8sClient: delete Subnet CR, wait for deletion
  TestRunner->>K8sClient: delete VirtualNetwork CR, wait for deletion
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Suggested labels

lgtm

Suggested reviewers

  • tzumainn
  • eranco74

"A subnet born for test and play,
CLI flags march out in array.
Fixtures spin the network thread,
Instances wake where packets tread.
Version bumped — the build's OK!"

🚥 Pre-merge checks | ✅ 9 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Ai-Attribution ⚠️ Warning Claude AI tools were used (.claude/ config, CLAUDE.md present). PR summary states "AI-generated". Commit lacks required Red Hat Assisted-by/Generated-by attribution trailers. Add Red Hat attribution trailer (Assisted-by: Red Hat / Generated-by: Claude) to commit message before merging to comply with AI attribution requirements.
✅ Passed checks (9 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'OSAC-768: Add network attachment support for VMaaS tests' directly and clearly describes the primary change—enabling network attachments for VMaaS tests—which aligns with the substantial changes to networking infrastructure across multiple test files.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
No-Hardcoded-Secrets ✅ Passed No hardcoded secrets, API keys, tokens, or suspicious base64 strings detected. All sensitive values use env() with safe test defaults.
No-Weak-Crypto ✅ Passed No weak crypto (MD5, SHA1, DES, RC4, 3DES, Blowfish, ECB mode) or custom implementations found. Containerfile correctly uses SHA256 for checksum verification.
No-Injection-Vectors ✅ Passed No injection vectors detected. All subprocess calls use positional args without shell=True. Network attachment inputs validated as strings. No eval/exec/pickle/SQL concatenation found.
Container-Privileges ✅ Passed No container privilege escalation detected. Containerfile lacks privileged:true, hostPID/Network/IPC, SYS_ADMIN, allowPrivilegeEscalation. All test code uses standard security.
No-Sensitive-Data-In-Logs ✅ Passed PR logging prints only status messages and resource IDs. No passwords, tokens, API keys, or PII are exposed in logs or exception messages.

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

✨ 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 and usage tips.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 5

🧹 Nitpick comments (2)
tests/core/helpers.py (1)

90-92: ⚡ Quick win

Don’t suppress all exceptions in the job-state probe.

Catching Exception and silently passing hides real regressions (auth, API, parsing) and removes debugging signal. Catch only expected failures and surface context.

🤖 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/core/helpers.py` around lines 90 - 92, The catch-all "except
Exception:" in the job-state probe (the except Exception: block in
tests/core/helpers.py) should not silently pass; replace it with explicit
expected exceptions (e.g., network/parsing/auth exceptions your probe can raise
such as requests.RequestException, ValueError, KeyError or whatever your probe
uses) and handle them (log context or call pytest.fail) while letting unexpected
exceptions bubble up (or re-raise them). In short: change "except Exception:
pass" to "except (ExpectedExceptionA, ExpectedExceptionB) as e: <handle/log/fail
with context>" and keep a final "except Exception: raise" only if you need to
re-raise unrecognized errors so regressions aren’t suppressed.
tests/vmaas/test_compute_instance_cli_fields.py (1)

26-29: ⚡ Quick win

Assert the network attachment made it into the ComputeInstance spec.

This test now passes a subnet attachment, but it never verifies spec.networkAttachments. Adding that check will make this test actually guard the new CLI behavior.

Proposed assertion block
     spec: dict[str, Any] = ci_spec["spec"]
+    attachments: list[dict[str, Any]] = spec.get("networkAttachments", [])
+    assert len(attachments) > 0, "networkAttachments should not be empty"
+    assert any(
+        a.get("subnet") == default_subnet or a.get("subnetRef") == default_subnet
+        for a in attachments
+    ), f"Expected subnet attachment for {default_subnet}, got {attachments}"
+
     assert spec["cores"] == TEST_CORES, f"cores mismatch: {spec['cores']} != {TEST_CORES}"
🤖 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/vmaas/test_compute_instance_cli_fields.py` around lines 26 - 29, After
creating the instance with cli.create_compute_instance (the call assigned to
uuid), fetch the created ComputeInstance resource and assert that its
spec.networkAttachments contains the passed attachment (e.g., contains an entry
with subnet == default_subnet); specifically, locate the test's use of
cli.create_compute_instance and add an assertion that the retrieved
ComputeInstance.spec.networkAttachments includes the expected subnet attachment
to ensure the CLI actually populated spec.networkAttachments.
🤖 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 `@tests/core/helpers.py`:
- Around line 64-65: The current fixed max_iterations = 60 (5s sleeps) caps
total wait to 300s, which makes the default max_stuck_time (600s) unreachable;
update the loop bounds to derive max_iterations from max_stuck_time and the
sleep interval (e.g., max_iterations = int(math.ceil(max_stuck_time /
sleep_seconds))) so the "stuck for max_stuck_time" branch can be reached; apply
the same change to the other loops that use the hardcoded 60 (the blocks
referenced around the other checks) and ensure the code uses the shared sleep
interval variable and max_stuck_time parameter rather than a hardcoded iteration
cap.
- Around line 84-86: The force-cleanup branch in tests/core/helpers.py calls
k8s.remove_finalizers(resource="computeinstance", name=name), sleeps 5s and
returns without verifying deletion, which can race with downstream checks;
replace the blind sleep+return with a polling loop that checks for the CR's
absence (e.g., repeatedly call k8s.get or a provided
k8s.exists/wait_for_deletion helper with a timeout and short sleep interval)
until the resource is gone or timeout; apply the same change to the other
identical block (lines referenced as 97-100) so both force-cleanup paths confirm
the CR is deleted before returning.

In `@tests/core/k8s_client.py`:
- Around line 44-45: The subprocess.run call that executes kubectl
(subprocess.run(args, input=manifest, capture_output=True, text=True,
check=True)) is missing a timeout and can hang CI; add a reasonable timeout
argument (e.g., timeout=30) to that subprocess.run invocation, and update error
handling to catch subprocess.TimeoutExpired in addition to
subprocess.CalledProcessError so the test fails fast and emits a clear error
(refer to subprocess.run, subprocess.CalledProcessError,
subprocess.TimeoutExpired, args, and manifest to locate the code).

In `@tests/core/osac_cli.py`:
- Around line 57-69: The loop handling network_attachments in
tests/core/osac_cli.py currently allows invalid entries like subnet=None; update
the validation in the for attachment in network_attachments block to (1) require
that attachment.get("subnet") returns a non-empty string (raise a ValueError
with a clear message referencing the attachment when not), (2) ensure
attachment.get("security_groups") if present is a list and every element is a
non-empty string (raise TypeError/ValueError if not), and (3) only build parts
and call args.extend(["--network-attachment", ",".join(parts)]) when validation
passes; include the variable names subnet and security_groups in the error
messages to aid debugging.

In `@tests/vmaas/conftest.py`:
- Around line 60-125: The fixture default_networking currently creates vn_id and
subnet_id before yield but only performs cleanup after yield; wrap the setup and
yield in a try/finally so any partial failures still trigger teardown: move the
yield inside a try block and place the existing cleanup logic in the finally
block, track whether vn_id/vn_cr_name and subnet_id/subnet_cr_name were set
(e.g., check for None) and only call grpc.delete_subnet,
grpc.delete_virtual_network, wait_for_*_deletion and
k8s_hub_client.remove_finalizers for resources that were actually created; keep
using the same helper names (create_virtual_network, create_subnet,
wait_for_virtual_network_cr, wait_for_subnet_cr, wait_for_virtual_network_ready,
wait_for_subnet_ready, wait_for_subnet_deletion,
wait_for_virtual_network_deletion) to locate where to insert the try/finally and
conditional cleanup checks.

---

Nitpick comments:
In `@tests/core/helpers.py`:
- Around line 90-92: The catch-all "except Exception:" in the job-state probe
(the except Exception: block in tests/core/helpers.py) should not silently pass;
replace it with explicit expected exceptions (e.g., network/parsing/auth
exceptions your probe can raise such as requests.RequestException, ValueError,
KeyError or whatever your probe uses) and handle them (log context or call
pytest.fail) while letting unexpected exceptions bubble up (or re-raise them).
In short: change "except Exception: pass" to "except (ExpectedExceptionA,
ExpectedExceptionB) as e: <handle/log/fail with context>" and keep a final
"except Exception: raise" only if you need to re-raise unrecognized errors so
regressions aren’t suppressed.

In `@tests/vmaas/test_compute_instance_cli_fields.py`:
- Around line 26-29: After creating the instance with
cli.create_compute_instance (the call assigned to uuid), fetch the created
ComputeInstance resource and assert that its spec.networkAttachments contains
the passed attachment (e.g., contains an entry with subnet == default_subnet);
specifically, locate the test's use of cli.create_compute_instance and add an
assertion that the retrieved ComputeInstance.spec.networkAttachments includes
the expected subnet attachment to ensure the CLI actually populated
spec.networkAttachments.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: 876a90d4-e9ec-498c-9599-56f8c78c3478

📥 Commits

Reviewing files that changed from the base of the PR and between 79d49a5 and 80d1a8e.

📒 Files selected for processing (12)
  • tests/conftest.py
  • tests/core/helpers.py
  • tests/core/k8s_client.py
  • tests/core/osac_cli.py
  • tests/core/runner.py
  • tests/vmaas/conftest.py
  • tests/vmaas/test_compute_instance_api_fields.py
  • tests/vmaas/test_compute_instance_cli_fields.py
  • tests/vmaas/test_compute_instance_creation.py
  • tests/vmaas/test_compute_instance_delete_during_provision.py
  • tests/vmaas/test_compute_instance_restart.py
  • tests/vmaas/test_compute_instance_restart_negative.py

Comment thread tests/core/helpers.py Outdated
Comment thread tests/core/helpers.py Outdated
Comment thread tests/core/k8s_client.py Outdated
Comment thread tests/core/osac_cli.py
Comment thread tests/vmaas/conftest.py Outdated

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

The networking part looks good.
I don't think we need the rest though

Comment thread tests/core/helpers.py Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🤖 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 `@tests/core/runner.py`:
- Around line 13-23: The run() function currently only catches
subprocess.CalledProcessError; update it to also catch subprocess.TimeoutExpired
and re-raise a RuntimeError with the same enriched context (include the command
args, the timeout value, and any available stdout/stderr) so timeouts are
formatted consistently with CalledProcessError handling; reference the run()
function and handle subprocess.TimeoutExpired similarly to how
CalledProcessError (e) is processed, combining a clear message with
e.stdout/e.stderr and the timeout attribute before raising.

In `@tests/vmaas/conftest.py`:
- Around line 99-147: The finally block only runs robust teardown when both
vn_id/vn_cr_name and subnet_id/subnet_cr_name are present, causing leaked
resources on partial failures; modify the cleanup logic in the exception/finally
path to handle VN and Subnet independently: if vn_id and vn_cr_name exist run
the virtual network deletion sequence (grpc.delete_virtual_network,
wait_for_virtual_network_deletion, and fallback
k8s_hub_client.remove_finalizers), and if subnet_id and subnet_cr_name exist run
the subnet deletion sequence (grpc.delete_subnet, wait_for_subnet_deletion, and
fallback remove_finalizers); ensure these independent cleanup attempts occur
both in the except block for partial setup failures and in finally so either
resource gets the robust wait+finalizer removal logic even when the other
resource was not created.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Enterprise

Run ID: c167cdfc-c1c8-4701-9f87-a9f8fac4d25d

📥 Commits

Reviewing files that changed from the base of the PR and between 80d1a8e and faffaf0.

📒 Files selected for processing (12)
  • tests/conftest.py
  • tests/core/helpers.py
  • tests/core/k8s_client.py
  • tests/core/osac_cli.py
  • tests/core/runner.py
  • tests/vmaas/conftest.py
  • tests/vmaas/test_compute_instance_api_fields.py
  • tests/vmaas/test_compute_instance_cli_fields.py
  • tests/vmaas/test_compute_instance_creation.py
  • tests/vmaas/test_compute_instance_delete_during_provision.py
  • tests/vmaas/test_compute_instance_restart.py
  • tests/vmaas/test_compute_instance_restart_negative.py
✅ Files skipped from review due to trivial changes (1)
  • tests/core/helpers.py

Comment thread tests/core/runner.py Outdated
Comment on lines +13 to +23
try:
result = subprocess.run(args, capture_output=True, text=True, timeout=timeout, check=True)
return result.stdout.strip()
except subprocess.CalledProcessError as e:
# Re-raise with stderr included in the error message for better debugging
error_msg = f"Command {args} failed with exit code {e.returncode}"
if e.stderr:
error_msg += f"\n\nSTDERR:\n{e.stderr.strip()}"
if e.stdout:
error_msg += f"\n\nSTDOUT:\n{e.stdout.strip()}"
raise RuntimeError(error_msg) from e

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Wrap subprocess.TimeoutExpired in tests/core/runner.py::run()

run() wraps subprocess.CalledProcessError into RuntimeError, but subprocess.run(..., timeout=timeout) can also raise subprocess.TimeoutExpired, which currently escapes unwrapped and loses the existing error formatting/context.

Proposed fix
 def run(*args: str, timeout: int = 300) -&gt; str:
     try:
         result = subprocess.run(args, capture_output=True, text=True, timeout=timeout, check=True)
         return result.stdout.strip()
+    except subprocess.TimeoutExpired as e:
+        error_msg = f"Command {args} timed out after {timeout}s"
+        if e.stderr:
+            error_msg += f"\n\nSTDERR:\n{str(e.stderr).strip()}"
+        if e.stdout:
+            error_msg += f"\n\nSTDOUT:\n{str(e.stdout).strip()}"
+        raise RuntimeError(error_msg) from e
     except subprocess.CalledProcessError as e:
         # Re-raise with stderr included in the error message for better debugging
         error_msg = f"Command {args} failed with exit code {e.returncode}"
         if e.stderr:
             error_msg += f"\n\nSTDERR:\n{e.stderr.strip()}"
         if e.stdout:
             error_msg += f"\n\nSTDOUT:\n{e.stdout.strip()}"
🧰 Tools
🪛 Ruff (0.15.13)

[error] 14-14: subprocess call: check for execution of untrusted input

(S603)

🤖 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/core/runner.py` around lines 13 - 23, The run() function currently only
catches subprocess.CalledProcessError; update it to also catch
subprocess.TimeoutExpired and re-raise a RuntimeError with the same enriched
context (include the command args, the timeout value, and any available
stdout/stderr) so timeouts are formatted consistently with CalledProcessError
handling; reference the run() function and handle subprocess.TimeoutExpired
similarly to how CalledProcessError (e) is processed, combining a clear message
with e.stdout/e.stderr and the timeout attribute before raising.

Comment thread tests/vmaas/conftest.py Outdated
@ori-amizur ori-amizur changed the title OSAC-768: Add network attachment support: VMs now created in subnets instead of pod network OSAC-768: Add network attachment support for VMaaS tests May 24, 2026
@ori-amizur
ori-amizur requested a review from eranco74 May 24, 2026 20:28
@eranco74

Copy link
Copy Markdown
Contributor

/approve
/lgtm

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

♻️ Duplicate comments (1)
tests/vmaas/conftest.py (1)

99-136: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Partial setup failures still risk leaked networking resources (Severity: Major).

Line 116 gates robust teardown on all VN+Subnet identifiers being present, so a mid-setup failure can skip deletion-wait/finalizer fallback for whichever resource was created. Impact: leftover CRs can poison later test sessions and cause cascading flakes.

Suggested fix
-    finally:
-        # Normal cleanup runs regardless of setup success/failure
-        # Only attempt cleanup if resources were successfully created
-        if vn_id and vn_cr_name and subnet_id and subnet_cr_name:
+    finally:
+        # Cleanup subnet independently if created
+        if subnet_id and subnet_cr_name:
             print(f"\nCleaning up test networking resources: {test_run_id}")
-
-            # Delete subnet first
             try:
                 print(f"Deleting Subnet {subnet_id}...")
                 grpc.delete_subnet(subnet_id=subnet_id)
                 wait_for_subnet_deletion(k8s=k8s_hub_client, name=subnet_cr_name)
                 print(f"Subnet {subnet_id} deleted")
             except Exception as e:
                 print(f"WARNING: Failed to delete subnet {subnet_id}: {e}")
+                try:
+                    k8s_hub_client.remove_finalizers(resource="subnet", name=subnet_cr_name)
+                    time.sleep(5)
+                except Exception as cleanup_error:
+                    print(f"WARNING: Failed to force-cleanup subnet: {cleanup_error}")
 
-            # Delete virtual network
+        # Cleanup virtual network independently if created
+        if vn_id and vn_cr_name:
             try:
                 print(f"Deleting VirtualNetwork {vn_id}...")
                 grpc.delete_virtual_network(vn_id=vn_id)
                 wait_for_virtual_network_deletion(k8s=k8s_hub_client, name=vn_cr_name)
                 print(f"VirtualNetwork {vn_id} deleted")
             except Exception as e:
                 print(f"WARNING: Failed to delete virtual network {vn_id}: {e}")
+                try:
+                    k8s_hub_client.remove_finalizers(resource="virtualnetwork", name=vn_cr_name)
+                    time.sleep(5)
+                except Exception as cleanup_error:
+                    print(f"WARNING: Failed to force-cleanup virtualnetwork: {cleanup_error}")
🤖 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/vmaas/conftest.py` around lines 99 - 136, The finally block only runs
deletion when all four identifiers (vn_id, vn_cr_name, subnet_id,
subnet_cr_name) are truthy, which leaks resources created before a mid-setup
failure; change the cleanup to attempt deletion of each resource independently:
check subnet_id and subnet_cr_name and run grpc.delete_subnet +
wait_for_subnet_deletion (handle exceptions and log warnings), and separately
check vn_id and vn_cr_name and run grpc.delete_virtual_network +
wait_for_virtual_network_deletion (handle exceptions and log warnings); if both
exist prefer deleting subnet first as currently done, but do not gate one on the
other so partial creations are always cleaned up (refer to the variables vn_id,
vn_cr_name, subnet_id, subnet_cr_name and functions grpc.delete_subnet,
grpc.delete_virtual_network, wait_for_subnet_deletion,
wait_for_virtual_network_deletion).
🤖 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.

Duplicate comments:
In `@tests/vmaas/conftest.py`:
- Around line 99-136: The finally block only runs deletion when all four
identifiers (vn_id, vn_cr_name, subnet_id, subnet_cr_name) are truthy, which
leaks resources created before a mid-setup failure; change the cleanup to
attempt deletion of each resource independently: check subnet_id and
subnet_cr_name and run grpc.delete_subnet + wait_for_subnet_deletion (handle
exceptions and log warnings), and separately check vn_id and vn_cr_name and run
grpc.delete_virtual_network + wait_for_virtual_network_deletion (handle
exceptions and log warnings); if both exist prefer deleting subnet first as
currently done, but do not gate one on the other so partial creations are always
cleaned up (refer to the variables vn_id, vn_cr_name, subnet_id, subnet_cr_name
and functions grpc.delete_subnet, grpc.delete_virtual_network,
wait_for_subnet_deletion, wait_for_virtual_network_deletion).

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: osac-project/coderabbit/.coderabbit.yaml

Review profile: ASSERTIVE

Plan: Enterprise

Run ID: d75e7470-3a06-4bc6-93af-b0d6c4a15618

📥 Commits

Reviewing files that changed from the base of the PR and between 843d64c and 4517a20.

📒 Files selected for processing (9)
  • Containerfile
  • tests/core/osac_cli.py
  • tests/vmaas/conftest.py
  • tests/vmaas/test_compute_instance_api_fields.py
  • tests/vmaas/test_compute_instance_cli_fields.py
  • tests/vmaas/test_compute_instance_creation.py
  • tests/vmaas/test_compute_instance_delete_during_provision.py
  • tests/vmaas/test_compute_instance_restart.py
  • tests/vmaas/test_compute_instance_restart_negative.py

@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@openshift-ci openshift-ci Bot removed the lgtm label May 26, 2026
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

1 similar comment
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

1 similar comment
@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

Update all compute instance tests to use explicit network attachments,
ensuring VMs are provisioned on OSAC-managed subnets instead of the
default pod network.

Changes:
1. Add network_attachments parameter to OsacCLI.create_compute_instance()
   - Supports subnet and security-groups configuration
   - Builds --network-attachment CLI flags
   - Validates attachment structure

2. Add networking fixtures in tests/vmaas/conftest.py:
   - test_run_id: Unique ID per test run to avoid resource conflicts
   - default_networking: Creates VirtualNetwork + Subnet with cleanup
   - default_subnet: Returns subnet ID for CLI/gRPC usage
   - default_subnet_ref: Returns subnet CR name for K8s API usage

3. Update all compute instance tests to use network attachments:
   - test_compute_instance_api_fields: Use default_subnet_ref
   - test_compute_instance_cli_fields: Use default_subnet
   - test_compute_instance_creation: Use default_subnet
   - test_compute_instance_delete_during_provision: Use default_subnet
   - test_compute_instance_restart: Use default_subnet
   - test_compute_instance_restart_negative: Use default_subnet

This ensures VMs are created with proper tenant network isolation,
IP management, and security group support rather than using the
default Kubernetes pod network (masquerade).

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@openshift-ci openshift-ci Bot added the lgtm label Jun 1, 2026
@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

2 similar comments
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@ori-amizur
ori-amizur enabled auto-merge (squash) June 2, 2026 10:52
@openshift-ci openshift-ci Bot removed the lgtm label Jun 2, 2026
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@openshift-ci openshift-ci Bot added the lgtm label Jun 2, 2026
@ori-amizur

Copy link
Copy Markdown
Contributor Author

/retest

@ori-amizur

Copy link
Copy Markdown
Contributor Author

/test e2e-vmaas

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

1 similar comment
@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/lgtm
/approve

@openshift-ci

openshift-ci Bot commented Jun 3, 2026

Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: eranco74, omer-vishlitzky, ori-amizur

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Details Needs approval from an approver in each of these files:
  • OWNERS [eranco74,omer-vishlitzky]

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/retest ci/prow/images

@omer-vishlitzky

Copy link
Copy Markdown
Contributor

/test images

@ori-amizur
ori-amizur merged commit 1319485 into osac-project:main Jun 3, 2026
4 of 5 checks passed
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.

4 participants