Skip to content

GCP-859: scope PSC NAT subnet discovery to the management cluster VPC - #8927

Merged
openshift-merge-bot[bot] merged 8 commits into
openshift:mainfrom
cristianoveiga:fix/gcp-psc-vpc-scoped-nat-subnet-discovery
Jul 9, 2026
Merged

GCP-859: scope PSC NAT subnet discovery to the management cluster VPC#8927
openshift-merge-bot[bot] merged 8 commits into
openshift:mainfrom
cristianoveiga:fix/gcp-psc-vpc-scoped-nat-subnet-discovery

Conversation

@cristianoveiga

@cristianoveiga cristianoveiga commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Summary

Fixes PSC NAT subnet discovery to scope subnet lookup to the management cluster's VPC, preventing cross-VPC selection when multiple management clusters share a GCP project.

Root cause: `discoverNATSubnet()` listed all PSC-purpose subnets in a project/region with no VPC filter. GCP rejects a Service Attachment whose NAT subnet and forwarding rule are in different VPCs, causing PSC setup to fail in multi-cluster-per-project deployments.

Changes:

  • Derives the management cluster's VPC from the forwarding rule's `Network` field (authoritative, set by GCP CCM at ILB creation) and passes it as a server-side filter to `Subnetworks.List`
  • Renames `lookupForwardingRuleName` → `lookupForwardingRule` returning `*compute.ForwardingRule` to carry both the name and network URL in a single lookup
  • Handles the partial-write edge case where `ForwardingRuleName` is set but `NATSubnet` is not (controller crashed between the two writes)
  • Extracts a `ComputeClient` interface over the GCP Compute API calls (following the Azure `PrivateLinkServicesAPI` pattern), backed by a `computeServiceAdapter` that bridges the GCP SDK's chained-call surface. Enables unit testing without GCP credentials

Fixes: https://redhat.atlassian.net/browse/GCP-859

Test plan

  • Existing unit tests pass (`go test ./hypershift-operator/controllers/platform/gcp/...`)
  • New unit tests cover all new code paths via `fakeGCPComputeClient`: `lookupForwardingRule` (API error, no results, single/multiple results), `reconcileGCPPrivateServiceConnectSpec` (early return, lookup error, ILB not provisioned, empty Network field, happy path), `discoverNATSubnet` (API error, no subnets, in-use skip, all subnets in use)
  • New e2e test `[Feature:GCPPrivateServiceConnect]` asserts `GCPServiceAttachmentAvailable = True` — GCP enforces VPC consistency server-side when creating a Service Attachment, so a successful attachment is proof the NAT subnet and forwarding rule share the same VPC. No GCP credentials required in the test binary.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added end-to-end coverage for Google Cloud Private Service Connect (PSC) on HostedClusters, including validation of forwarding rule and NAT subnet fields plus service attachment availability.
  • Bug Fixes

    • Improved PSC reconciliation to better discover missing forwarding rule and NAT subnet details, including correct NAT subnet selection when multiple candidates exist.
    • Ensures correct behavior when only one of the networking fields is set, preserving existing values.
  • Tests

    • Expanded unit test coverage for PSC reconciliation logic, forwarding rule lookup behavior, NAT subnet filter formatting, and NAT subnet discovery edge cases.

The previous discoverNATSubnet implementation listed all subnets in the
GCP project/region with purpose=PRIVATE_SERVICE_CONNECT and picked the
first available one, with no filtering by VPC network. This assumed a
single management cluster per GCP project and broke when multiple MCs
shared a project, each in its own VPC — GCP rejects a Service Attachment
whose NAT subnet and forwarding rule are in different VPCs.

Changes:
- Rename lookupForwardingRuleName to lookupForwardingRule and return the
  full *compute.ForwardingRule so callers can access any field without
  future signature changes.
- Gate NAT subnet discovery on the forwarding rule being available; if
  the ILB is not yet provisioned the controller returns nil and requeues
  without writing to the spec.
- Derive the VPC network URL from the forwarding rule's Network field
  (authoritative, set by GCP CCM at ILB creation) and pass it to
  discoverNATSubnet as a server-side filter, eliminating cross-VPC
  subnet selection.
- Guard against a forwarding rule with an empty Network field to surface
  a clear error instead of silently producing a bad filter.
- Handle the partial-write edge case: when ForwardingRuleName is already
  set but NATSubnet is not, re-fetch the forwarding rule to obtain the
  network URL and complete subnet discovery.
- Add TestNATSubnetFilterFormat to cover the VPC-scoped filter string.
- Add e2e test that fetches the forwarding rule and NAT subnet from the
  GCP API and asserts they share the same VPC network URL.

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Pipeline controller notification
This repo is configured to use the pipeline controller. Second-stage tests will be triggered either automatically or after lgtm label is added, depending on the repository configuration. The pipeline controller will automatically detect which contexts are required and will utilize /test Prow commands to trigger the second stage.

For optional jobs, comment /test ? to see a list of all defined jobs. To trigger manually all jobs from second stage use /pipeline required command.

This repository is configured in: LGTM mode

@openshift-ci openshift-ci Bot added the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 3, 2026
@openshift-ci-robot openshift-ci-robot added the jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. label Jul 3, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 3, 2026

Copy link
Copy Markdown

@cristianoveiga: This pull request references GCP-859 which is a valid jira issue.

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

Details

In response to this:

Summary

  • Fixes PSC NAT subnet discovery to filter subnets by the management cluster's VPC network URL (derived from the forwarding rule's Network field), preventing cross-VPC subnet selection when multiple management clusters share a GCP project.
  • Renames lookupForwardingRuleNamelookupForwardingRule returning *compute.ForwardingRule for a cleaner interface.
  • Gates NAT subnet discovery on the forwarding rule being available — controller requeues without writing to spec if the ILB is not yet provisioned.
  • Handles the partial-write edge case where ForwardingRuleName is set but NATSubnet is not.

Fixes: https://redhat.atlassian.net/browse/GCP-859

Test plan

  • Existing unit tests pass (go test ./hypershift-operator/controllers/platform/gcp/...)
  • New TestNATSubnetFilterFormat unit test covers the VPC-scoped filter string format
  • New e2e test [Feature:GCPPrivateServiceConnect] validates that the selected NAT subnet and forwarding rule share the same VPC network URL on a live GCP cluster

🤖 Generated with Claude Code

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.

@openshift-ci

openshift-ci Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci openshift-ci Bot added do-not-merge/needs-area area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/testing Indicates the PR includes changes for e2e testing and removed do-not-merge/needs-area labels Jul 3, 2026
@coderabbitai

coderabbitai Bot commented Jul 3, 2026

Copy link
Copy Markdown
Contributor

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: f1cddbf0-64fa-442c-9157-0cacef7e5997

📥 Commits

Reviewing files that changed from the base of the PR and between cdae895 and e0faece.

📒 Files selected for processing (3)
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • test/e2e/v2/tests/hosted_cluster_psc_test.go
🚧 Files skipped from review as they are similar to previous changes (3)
  • test/e2e/v2/tests/hosted_cluster_psc_test.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go

📝 Walkthrough

Walkthrough

The GCP Private Service Connect controller now uses a compute-client interface, looks up forwarding rules before filling missing spec fields, and scopes NAT subnet discovery to the forwarding rule’s network. Service-attachment operations now go through the same interface. The PR also adds unit tests for lookup and subnet selection behavior, plus an e2e test that checks PSC spec fields and service-attachment status.

🚥 Pre-merge checks | ✅ 11
✅ Passed checks (11 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: scoping PSC NAT subnet discovery to the management cluster VPC.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed Added Ginkgo/Go test titles are static and deterministic; no dynamic names, timestamps, UUIDs, or generated identifiers appear.
Test Structure And Quality ✅ Passed The added Ginkgo e2e test uses BeforeEach gating, one focused It block, clear failure messages, and no cluster writes or unbounded waits; unit tests are isolated and single-purpose.
Topology-Aware Scheduling Compatibility ✅ Passed No node selectors, affinity/anti-affinity, spread constraints, replicas, or PDB changes were introduced; the diff only updates GCP PSC reconciliation and e2e validation.
Ipv6 And Disconnected Network Test Compatibility ✅ Passed hosted_cluster_psc_test.go only lists cluster resources and checks PSC status; no IPv4-only code or public internet/external API calls found.
No-Weak-Crypto ✅ Passed Touched files only add GCP PSC networking logic/tests; no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB, custom crypto, or secret comparisons found.
Container-Privileges ✅ Passed PR only changes Go controller/e2e tests; no added manifests or securityContext/privileged/host* flags were found in the diff.
No-Sensitive-Data-In-Logs ✅ Passed Only non-sensitive logs were added/kept (resource names, counts, state); no passwords, tokens, PII, internal hostnames, or customer data were logged.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/test e2e-v2-gke

@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)
hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go (1)

154-184: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

ForwardingRuleName is overwritten unconditionally, unlike the guarded NATSubnet write.

Line 173 always reassigns gcpPSC.Spec.ForwardingRuleName = hyperv1.GCPResourceName(rule.Name), even when it was already set (the early-return only skips when both fields are non-empty). NATSubnet is correctly guarded with if gcpPSC.Spec.NATSubnet == "". Since lookupForwardingRule can non-deterministically pick "first" among multiple IP-matching forwarding rules (line 207-211), an already-correct ForwardingRuleName could theoretically flip on a later reconcile, causing unnecessary spec churn. Consider guarding the assignment the same way:

🔧 Suggested fix
-	gcpPSC.Spec.ForwardingRuleName = hyperv1.GCPResourceName(rule.Name)
+	if gcpPSC.Spec.ForwardingRuleName == "" {
+		gcpPSC.Spec.ForwardingRuleName = hyperv1.GCPResourceName(rule.Name)
+	}
🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go`
around lines 154 - 184, The spec update in reconcileGCPPrivateServiceConnectSpec
always rewrites GCPPrivateServiceConnect.Spec.ForwardingRuleName, which can
cause unnecessary churn if lookupForwardingRule returns a different matching
rule on a later reconcile. Mirror the NATSubnet guard by only setting
ForwardingRuleName when it is empty, while keeping the existing
lookupForwardingRule and discoverNATSubnet flow intact. Use the
reconcileGCPPrivateServiceConnectSpec and lookupForwardingRule symbols to update
the assignment site without changing the early return behavior.
🧹 Nitpick comments (3)
hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go (1)

294-316: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Test duplicates the filter string instead of exercising the production code path.

TestNATSubnetFilterFormat re-implements the fmt.Sprintf filter construction inline (line 310) rather than calling discoverNATSubnet's actual filter-building logic. If the real filter format in the controller changes, this test won't catch the regression — it will still pass because it only compares itself against itself. This mirrors the pre-existing TestIPAddressFilterFormat pattern, but extracting the filter construction into a small shared helper function (called by both the controller and the test) would give real regression protection.

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go`
around lines 294 - 316, The NAT subnet filter test is duplicating the filter
construction instead of verifying the controller’s real behavior. Move the
filter-building logic used by discoverNATSubnet into a shared helper (similar to
the existing IP address filter pattern), then update TestNATSubnetFilterFormat
to call that helper and compare its output against the expected string. This
keeps the test exercising the production code path and makes the filter format
change-safe.
hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go (1)

243-279: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

N+1 GCP API calls: isSubnetInUse re-lists all Service Attachments for every candidate subnet.

The loop calls r.isSubnetInUse(ctx, subnet.Name) per subnet, and each call performs a fresh ServiceAttachments.List for the whole region (line 217-241, unchanged). With several PSC subnets in a shared VPC, this multiplies redundant GCP API calls unnecessarily. Consider listing Service Attachments once before the loop and building a used-subnet set for O(1) membership checks.

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go`
around lines 243 - 279, The loop in discoverNATSubnet is causing an N+1 pattern
because isSubnetInUse re-lists all Service Attachments for each candidate
subnet. Refactor discoverNATSubnet and/or isSubnetInUse so
ServiceAttachments.List is called once up front, build a set of used subnet
names from the result, and then use that set inside the subnet iteration for
O(1) checks. Keep the existing logging and selection behavior in
GCPPrivateServiceConnectReconciler intact while removing the repeated per-subnet
API calls.
test/e2e/v2/tests/hosted_cluster_psc_test.go (1)

44-93: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Solid adherence to v2 e2e conventions; consider validating all PSC resources, not just the first.

The test correctly uses tc.Context, guards with NotTo(BeEmpty()) before indexing, nil-checks hc.Spec.Platform.GCP, and includes diagnostic assertion messages — all per AGENTS.md. One gap: line 61 only validates pscList.Items[0]. If a hosted cluster can have more than one GCPPrivateServiceConnect (e.g., additional endpoints), the others go unchecked. Consider iterating over all items.

Based on path instructions for test/e2e/v2/**/*.go ("Strictly enforce all standards documented in test/e2e/v2/AGENTS.md"), rule 16 requires asserting non-emptiness before per-item loops and using a found boolean for search loops — worth confirming whether multiple GCPPrivateServiceConnect resources can legitimately exist per hosted cluster to decide if full iteration is warranted here.

🤖 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 `@test/e2e/v2/tests/hosted_cluster_psc_test.go` around lines 44 - 93, The test
only validates the first GCPPrivateServiceConnect item, so additional PSC
resources can be missed. Update the hosted cluster PSC test to iterate over all
entries in pscList.Items (instead of indexing pscList.Items[0]) and apply the
same ForwardingRuleName/NATSubnet checks and network comparison to each
GCPPrivateServiceConnect item; use the existing testCtx, pscList, and
GCPPrivateServiceConnect symbols to keep the logic easy to locate.

Source: Path instructions

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go`:
- Around line 154-184: The spec update in reconcileGCPPrivateServiceConnectSpec
always rewrites GCPPrivateServiceConnect.Spec.ForwardingRuleName, which can
cause unnecessary churn if lookupForwardingRule returns a different matching
rule on a later reconcile. Mirror the NATSubnet guard by only setting
ForwardingRuleName when it is empty, while keeping the existing
lookupForwardingRule and discoverNATSubnet flow intact. Use the
reconcileGCPPrivateServiceConnectSpec and lookupForwardingRule symbols to update
the assignment site without changing the early return behavior.

---

Nitpick comments:
In
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go`:
- Around line 294-316: The NAT subnet filter test is duplicating the filter
construction instead of verifying the controller’s real behavior. Move the
filter-building logic used by discoverNATSubnet into a shared helper (similar to
the existing IP address filter pattern), then update TestNATSubnetFilterFormat
to call that helper and compare its output against the expected string. This
keeps the test exercising the production code path and makes the filter format
change-safe.

In
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go`:
- Around line 243-279: The loop in discoverNATSubnet is causing an N+1 pattern
because isSubnetInUse re-lists all Service Attachments for each candidate
subnet. Refactor discoverNATSubnet and/or isSubnetInUse so
ServiceAttachments.List is called once up front, build a set of used subnet
names from the result, and then use that set inside the subnet iteration for
O(1) checks. Keep the existing logging and selection behavior in
GCPPrivateServiceConnectReconciler intact while removing the repeated per-subnet
API calls.

In `@test/e2e/v2/tests/hosted_cluster_psc_test.go`:
- Around line 44-93: The test only validates the first GCPPrivateServiceConnect
item, so additional PSC resources can be missed. Update the hosted cluster PSC
test to iterate over all entries in pscList.Items (instead of indexing
pscList.Items[0]) and apply the same ForwardingRuleName/NATSubnet checks and
network comparison to each GCPPrivateServiceConnect item; use the existing
testCtx, pscList, and GCPPrivateServiceConnect symbols to keep the logic easy to
locate.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: c3f2f008-5b4d-44f7-a2cd-83c4faef8f0d

📥 Commits

Reviewing files that changed from the base of the PR and between 8e1aa48 and 760e9f4.

📒 Files selected for processing (3)
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • test/e2e/v2/tests/hosted_cluster_psc_test.go

@codecov

codecov Bot commented Jul 3, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 53.84615% with 36 lines in your changes missing coverage. Please review.
✅ Project coverage is 43.52%. Comparing base (8e1aa48) to head (e0faece).
⚠️ Report is 59 commits behind head on main.

Files with missing lines Patch % Lines
...s/platform/gcp/privateserviceconnect_controller.go 53.84% 34 Missing and 2 partials ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #8927      +/-   ##
==========================================
+ Coverage   43.34%   43.52%   +0.18%     
==========================================
  Files         771      771              
  Lines       95534    95749     +215     
==========================================
+ Hits        41408    41678     +270     
+ Misses      51242    51182      -60     
- Partials     2884     2889       +5     
Files with missing lines Coverage Δ
...s/platform/gcp/privateserviceconnect_controller.go 26.91% <53.84%> (+18.16%) ⬆️

... and 6 files with indirect coverage changes

Flag Coverage Δ
cmd-support 37.12% <ø> (+0.24%) ⬆️
cpo-hostedcontrolplane 45.21% <ø> (-0.10%) ⬇️
cpo-other 45.10% <ø> (ø)
hypershift-operator 53.91% <53.84%> (+0.32%) ⬆️
other 32.08% <ø> (+0.39%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/test e2e-v2-gke

- Guard ForwardingRuleName write to avoid unnecessary spec churn when
  the field is already set (mirrors the existing NATSubnet guard).
- Extract filter construction into buildNATSubnetFilter helper so
  TestNATSubnetFilterFormat exercises the production code path.
- Add comment clarifying there is exactly one GCPPrivateServiceConnect
  per hosted cluster.

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@cristianoveiga
cristianoveiga force-pushed the fix/gcp-psc-vpc-scoped-nat-subnet-discovery branch from 478cdd9 to 3189891 Compare July 6, 2026 14:02
@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/test e2e-v2-gke

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

🧹 Nitpick comments (1)
test/e2e/v2/tests/hosted_cluster_psc_test.go (1)

44-48: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Unused GCP platform-spec nil-check.

hc.Spec.Platform.GCP is asserted non-nil but never read afterward in the test body. This looks like a leftover from the previous version of the test that needed GCP project/region fields to build a direct GCP API client (now removed per this PR's shift to condition-based validation). Consider dropping the assertion if the field is truly unused, or keep it only if a future addition will reference it.

♻️ Proposed cleanup
 			testCtx := getTestCtx()
 			hc := testCtx.GetHostedCluster()
-			Expect(hc.Spec.Platform.GCP).NotTo(BeNil(),
-				"GCP platform spec must be set for GCP HostedCluster %s/%s", hc.Namespace, hc.Name)
 
 			// Find the GCPPrivateServiceConnect CR in the control plane namespace.
🤖 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 `@test/e2e/v2/tests/hosted_cluster_psc_test.go` around lines 44 - 48, The test
in hosted_cluster_psc_test.go has an unused nil-check on hc.Spec.Platform.GCP
inside the GCPServiceAttachmentAvailable condition case. Remove the redundant
Expect(hc.Spec.Platform.GCP).NotTo(BeNil()) assertion from the test body unless
a later step in the same It block actually uses the GCP platform fields; keep
the rest of the condition-based validation unchanged.
🤖 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.

Nitpick comments:
In `@test/e2e/v2/tests/hosted_cluster_psc_test.go`:
- Around line 44-48: The test in hosted_cluster_psc_test.go has an unused
nil-check on hc.Spec.Platform.GCP inside the GCPServiceAttachmentAvailable
condition case. Remove the redundant Expect(hc.Spec.Platform.GCP).NotTo(BeNil())
assertion from the test body unless a later step in the same It block actually
uses the GCP platform fields; keep the rest of the condition-based validation
unchanged.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: e32cf1b0-6785-46d9-bd48-c2e859820ee7

📥 Commits

Reviewing files that changed from the base of the PR and between 478cdd9 and 3189891.

📒 Files selected for processing (3)
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • test/e2e/v2/tests/hosted_cluster_psc_test.go
🚧 Files skipped from review as they are similar to previous changes (2)
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go

The hc.Spec.Platform.GCP nil check was left over from the original
test design that called the GCP Compute API using project and region
fields. Now that the test validates VPC correctness via the
GCPServiceAttachmentAvailable condition instead, no GCP platform
fields are accessed and the check is unreachable dead code.

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)

@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)
hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go (1)

315-319: 🩺 Stability & Availability | 🟠 Major | ⚡ Quick win

Return subnet-usage check failures instead of skipping them.

If ListServiceAttachments fails, continuing can mask the real GCP API error and end with a misleading “no available subnet” result. Fail fast with subnet context so reconciliation retries the actual dependency failure.

Proposed fix
 		inUse, err := r.isSubnetInUse(ctx, subnet.Name)
 		if err != nil {
-			log.Error(err, "Failed to check subnet usage", "subnet", subnet.Name)
-			continue
+			return "", fmt.Errorf("failed to check subnet usage for %q: %w", subnet.Name, err)
 		}

As per path instructions, “Never ignore error returns.”

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go`
around lines 315 - 319, The subnet-usage check in the private service connect
reconciliation currently logs and continues on isSubnetInUse failures, which can
hide the real GCP API error. Update the error handling in the
privateserviceconnect controller so that ListServiceAttachments/isSubnetInUse
failures are returned from the reconcile path with subnet context instead of
skipping that subnet, letting the controller retry the actual dependency failure
rather than reaching a misleading “no available subnet” result.

Source: Path instructions

🧹 Nitpick comments (2)
hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go (2)

44-49: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

Capture and assert the Compute API filters in the fake.

The PR’s core contract is VPC-scoped subnet discovery, but the fake drops the filter argument, so discoverNATSubnet could stop passing networkURL to ListSubnetworks without these tests failing.

Proposed test-fake extension
 type fakeComputeClient struct {
 	forwardingRules       []*compute.ForwardingRule
 	forwardingRulesErr    error
+	forwardingRulesFilter string
 	subnetworks           []*compute.Subnetwork
 	subnetworksErr        error
+	subnetworksFilter     string
 	serviceAttachments    []*compute.ServiceAttachment
 	serviceAttachmentsErr error
@@
-func (f *fakeComputeClient) ListForwardingRules(_ context.Context, _, _, _ string) ([]*compute.ForwardingRule, error) {
+func (f *fakeComputeClient) ListForwardingRules(_ context.Context, _, _, filter string) ([]*compute.ForwardingRule, error) {
+	f.forwardingRulesFilter = filter
 	return f.forwardingRules, f.forwardingRulesErr
 }
 
-func (f *fakeComputeClient) ListSubnetworks(_ context.Context, _, _, _ string) ([]*compute.Subnetwork, error) {
+func (f *fakeComputeClient) ListSubnetworks(_ context.Context, _, _, filter string) ([]*compute.Subnetwork, error) {
+	f.subnetworksFilter = filter
 	return f.subnetworks, f.subnetworksErr
 }

Then assert subnetworksFilter == buildNATSubnetFilter(networkURL) in the NAT subnet tests.

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go`
around lines 44 - 49, The fake Compute client methods are ignoring the filter
argument, so the NAT subnet tests are not verifying that discoverNATSubnet
passes the expected network-scoped filter. Update the fakeComputeClient
implementation to capture the filter passed into ListSubnetworks (and keep it
available for assertions), then extend the NAT subnet tests to assert that the
recorded subnetworks filter matches buildNATSubnetFilter(networkURL). Use
discoverNATSubnet, fakeComputeClient, and ListSubnetworks as the key symbols
when wiring the assertion.

383-542: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use “When ... it should ...” descriptions for the new test cases.

These new unit tests use deterministic names, but they don’t follow the repository’s required test-case description format. Consider table-driven subtests with t.Run("When ... it should ...", ...) for the lookup/reconcile/discovery cases.

As per coding guidelines, **/*_test.go: “Always use "When ... it should ..." format for describing test cases when creating unit tests.”

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go`
around lines 383 - 542, The new unit tests in the lookupForwardingRule,
reconcileGCPPrivateServiceConnectSpec, and discoverNATSubnet coverage do not
follow the required “When ... it should ...” test-case description format.
Refactor these deterministic cases into table-driven subtests with t.Run names
like “When ... it should ...” so the scenarios are clearly described and
consistent with the repository’s *_test.go guidelines, while keeping the same
assertions and coverage.

Source: Coding guidelines

🤖 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
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go`:
- Around line 315-319: The subnet-usage check in the private service connect
reconciliation currently logs and continues on isSubnetInUse failures, which can
hide the real GCP API error. Update the error handling in the
privateserviceconnect controller so that ListServiceAttachments/isSubnetInUse
failures are returned from the reconcile path with subnet context instead of
skipping that subnet, letting the controller retry the actual dependency failure
rather than reaching a misleading “no available subnet” result.

---

Nitpick comments:
In
`@hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go`:
- Around line 44-49: The fake Compute client methods are ignoring the filter
argument, so the NAT subnet tests are not verifying that discoverNATSubnet
passes the expected network-scoped filter. Update the fakeComputeClient
implementation to capture the filter passed into ListSubnetworks (and keep it
available for assertions), then extend the NAT subnet tests to assert that the
recorded subnetworks filter matches buildNATSubnetFilter(networkURL). Use
discoverNATSubnet, fakeComputeClient, and ListSubnetworks as the key symbols
when wiring the assertion.
- Around line 383-542: The new unit tests in the lookupForwardingRule,
reconcileGCPPrivateServiceConnectSpec, and discoverNATSubnet coverage do not
follow the required “When ... it should ...” test-case description format.
Refactor these deterministic cases into table-driven subtests with t.Run names
like “When ... it should ...” so the scenarios are clearly described and
consistent with the repository’s *_test.go guidelines, while keeping the same
assertions and coverage.

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: 82047cb6-80e2-41cd-8eb6-747dcb496b6e

📥 Commits

Reviewing files that changed from the base of the PR and between 3189891 and cdae895.

📒 Files selected for processing (3)
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • test/e2e/v2/tests/hosted_cluster_psc_test.go
💤 Files with no reviewable changes (1)
  • test/e2e/v2/tests/hosted_cluster_psc_test.go

@cristianoveiga
cristianoveiga force-pushed the fix/gcp-psc-vpc-scoped-nat-subnet-discovery branch from cdae895 to 1cacd37 Compare July 6, 2026 16:42
…ests

Extracts a ComputeClient interface over the GCP Compute API calls used
by the PSC controller (following the Azure PrivateLinkServicesAPI
pattern). A computeServiceAdapter bridges the GCP SDK's chained-call
surface to the interface. Unit tests inject a fakeGCPComputeClient to
cover the new reconciliation paths without requiring GCP credentials:

- lookupForwardingRule: API error, no results, single result, multiple
  results (uses first)
- reconcileGCPPrivateServiceConnectSpec: both fields set (early return),
  lookup error, ILB not yet provisioned, empty Network field, happy path
- discoverNATSubnet: API error, no subnets, subnet in-use skip, all
  subnets in use

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@cristianoveiga
cristianoveiga force-pushed the fix/gcp-psc-vpc-scoped-nat-subnet-discovery branch from 1cacd37 to 2576bcd Compare July 6, 2026 17:08
@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/test e2e-v2-gke

…ed subnet discovery

Add capturedSubnetFilter to fakeComputeClient so that TestDiscoverNATSubnet_*
tests can assert the VPC-scoped filter reaches the ListSubnetworks call site.
Without this, deleting the filter argument from discoverNATSubnet would not
be caught by any unit test.

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@cristianoveiga
cristianoveiga marked this pull request as ready for review July 6, 2026 20:29
@openshift-ci openshift-ci Bot removed the do-not-merge/work-in-progress Indicates that a PR should not merge because it is a work in progress. label Jul 6, 2026
@openshift-ci
openshift-ci Bot requested review from csrwng and patjlm July 6, 2026 20:29
}
}

// --- reconcileGCPPrivateServiceConnectSpec ---

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: the partial-write edge case (ForwardingRuleName set, NATSubnet empty) that the code comments on L211-213 call out is worth covering here. Something like newGCPPSC("original-rule", "") with a fake returning a different rule name would verify that the existing name is preserved and discoverNATSubnet still gets the correct network URL.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed - added a new test case to cover this.

return subnet.Name, nil
}
// Find the first available PSC subnet in the MC's VPC not already in use by another Service Attachment.
for _, subnet := range subnets {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Pre-existing, not introduced by this PR: isSubnetInUse makes a fresh ListServiceAttachments call per candidate subnet. In environments with several PSC subnets, fetching the list once before the loop and building a set of in-use names would avoid N redundant API calls. Fine as a follow-up.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Cover the case where ForwardingRuleName is already set but NATSubnet is
empty (e.g. transient discoverNATSubnet failure on a prior reconcile).
Asserts the existing name is preserved and the VPC-scoped subnet filter
is still derived from the forwarding rule's Network field.

Also capture the ListSubnetworks filter argument in fakeComputeClient so
all discoverNATSubnet tests can assert the VPC filter reaches the call site.

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@cristianoveiga
cristianoveiga requested a review from cblecker July 7, 2026 15:38
log.V(1).Info("Subnet already in use, trying next", "subnet", subnet.Name)
}

return "", fmt.Errorf("no available PRIVATE_SERVICE_CONNECT subnet found in region %s", r.Region)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggestion: when every isSubnetInUse call errors out (e.g. transient GCP IAM / API failure), this message reports "no available subnet" — which would send operators looking at subnet provisioning rather than API connectivity. Consider tracking error count through the loop and including it here, e.g. "no available PRIVATE_SERVICE_CONNECT subnet found in region %s (failed to check %d of %d candidates due to API errors)".

…fail

When all isSubnetInUse calls fail due to transient GCP API/IAM errors,
the previous error reported "no available subnet" — pointing operators
at subnet provisioning rather than API connectivity. Now includes the
count of failed candidates to distinguish the two failure modes.

Signed-off-by: Cristiano Veiga <cveiga@redhat.com>
Commit-Message-Assisted-by: Claude (via Claude Code)
@cblecker

cblecker commented Jul 7, 2026

Copy link
Copy Markdown
Member

@CodeRabbit resume

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor
✅ Action performed

Reviews resumed.

@openshift-ci openshift-ci Bot added the lgtm Indicates that a PR is ready to be merged. label Jul 7, 2026
@openshift-merge-bot

Copy link
Copy Markdown
Contributor

Scheduling tests matching the pipeline_run_if_changed or not excluded by pipeline_skip_if_only_changed parameters:
/test e2e-aks-4-22
/test e2e-aws-4-22
/test e2e-aks
/test e2e-aws
/test e2e-aws-upgrade-hypershift-operator
/test e2e-azure-v2-self-managed
/test e2e-kubevirt-aws-ovn-reduced
/test e2e-v2-aws
/test e2e-v2-gke

@openshift-ci

openshift-ci Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: cblecker, cristianoveiga

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

The pull request process is described here

Details Needs approval from an approver in each of these files:

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

@openshift-ci openshift-ci Bot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Jul 7, 2026
@cwbotbot

cwbotbot commented Jul 7, 2026

Copy link
Copy Markdown

Test Results

e2e-aws

e2e-aks

Failed Tests

Total failed tests: 17

  • TestAutoscaling
  • TestAutoscaling/ValidateHostedCluster
  • TestAzureScheduler
  • TestAzureScheduler/ValidateHostedCluster
  • TestCreateCluster

... and 12 more failed tests

@hypershift-jira-solve-ci

Copy link
Copy Markdown
Contributor

AI Test Failure Analysis

Job: pull-ci-openshift-hypershift-main-e2e-aks | Build: 2074626809663590400 | Cost: $2.4801042499999997 | Failed step: hypershift-azure-run-e2e

View full analysis report


Generated by hypershift-analyze-e2e-failure post-step using Claude claude-opus-4-6

@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/retest-required

@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/test e2e-azure-v2-self-managed

@cristianoveiga

Copy link
Copy Markdown
Contributor Author

/retest-required

@hypershift-jira-solve-ci

hypershift-jira-solve-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

Test Failure Analysis Complete

Job Information

  • Prow Job: pull-ci-openshift-hypershift-main-e2e-azure-v2-self-managed
  • Build ID: 2075274496696127488
  • Target: e2e-azure-v2-self-managed
  • PR: GCP-859: scope PSC NAT subnet discovery to the management cluster VPC #8927 (GCP-859: scope PSC NAT subnet discovery to the management cluster VPC)
  • Failed Test: [sig-hypershift][Jira:Hypershift][Feature:ControlPlaneInfrastructure] Control Plane Infrastructure Workloads Infrastructure registry validation should not contain any unrecognized pods

Test Failure Analysis

Error

[FAILED] failed to get namespace hypershift
Unexpected error:
    failed to get server groups: Get "https://172.168.191.159:7443/api?timeout=5m0s":
    dial tcp 172.168.191.159:7443: i/o timeout

Summary

The single test failure is a transient management cluster kube-apiserver connectivity timeout, completely unrelated to the PR changes. The test attempted to connect to the self-managed management cluster's API server at 172.168.191.159:7443 and received a TCP-level i/o timeout after exactly 30 seconds. Tests running in the same test group immediately before and after the failure — using the identical MgmtClient and kubeconfig — succeeded, proving the API server was only transiently unreachable. Out of 426 tests that ran in the public test group, 425 passed and only this one failed. The PR (#8927) modifies only GCP Private Service Connect code (3 files, all under platform/gcp/), while the failing job runs on Azure — there is zero overlap between the code changed and the failure.

Root Cause

The root cause is a transient network-level connectivity interruption to the self-managed management cluster's kube-apiserver (172.168.191.159:7443) during the initial seconds of the public test group execution.

Timeline of events:

  1. 18:45:13 — All 6 test groups start concurrently (public, private, oauth-lb, external-oidc, upgrade, autoscaling)
  2. 18:45:15 — The "should not contain any unrecognized pods" test begins in the public group, calling testCtx.MgmtClient.Get() to retrieve the hypershift namespace from the management cluster
  3. 18:45:16external-oidc group passes (11/11 tests) — management cluster was reachable for this group
  4. 18:45:33oauth-lb group passes (13/13 tests) — management cluster was reachable for this group
  5. 18:45:45.48 — The infrastructure validation test fails after a 30-second TCP dial timeout to 172.168.191.159:7443
  6. 18:45:45.82 — The very next tests in the same public group (Container resource requests external-dns, operator) PASS in 0.234s and 0.071s respectively, confirming the management cluster API is reachable again
  7. 18:45:51+ — All subsequent tests in the public group continue passing through completion at 20:18:23

The 30-second timeout window (18:45:15 → 18:45:45) aligns with a brief TCP-level connectivity disruption. This is a known pattern in Azure self-managed clusters where the kube-apiserver (on non-standard port 7443) can experience brief periods of unreachability during initial client connection establishment, particularly when multiple test groups concurrently create their first connections to the API server.

This failure is NOT caused by the PR changes. PR #8927 modifies only 3 files, all GCP-specific:

  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller.go
  • hypershift-operator/controllers/platform/gcp/privateserviceconnect_controller_test.go
  • test/e2e/v2/tests/hosted_cluster_psc_test.go

The failing job is an Azure self-managed test — there is zero code path overlap.

Recommendations
  1. Retry the job — This is a transient infrastructure flake unrelated to the PR changes. A retry should pass.
  2. Consider adding retry logic — The InfrastructureRegistryValidationTest at control_plane_infrastructure_test.go:90 calls testCtx.MgmtClient.Get() without retry/backoff. Adding an Eventually() wrapper (as used by other HyperShift tests) would make this test resilient to transient API server hiccups.
  3. No code changes needed in this PR — The GCP PSC changes are completely unrelated to this Azure connectivity timeout.
Evidence
Evidence Detail
Failing test should not contain any unrecognized pods in control_plane_infrastructure_test.go:90
Error TCP i/o timeout to management cluster kube-apiserver at 172.168.191.159:7443
Timeout duration Exactly 30.001 seconds (18:45:15 → 18:45:45)
Test results 425 Passed, 1 Failed, 1 Pending, 536 Skipped
Recovery proof Next tests in same group PASSED at 18:45:45.82 (0.3s after failure) using same MgmtClient
Other test groups external-oidc (PASS), oauth-lb (PASS), private (PASS), upgrade (PASS), etcd-chaos (PASS), autoscaling (PASS)
k8sgpt diagnostics 0 problems found across all namespaces (hypershift, clusters, clusters-c6dff76500f8ee63be98)
PR file overlap 0% — PR changes only GCP PSC code; failure is on Azure
Management cluster Created successfully at 18:21:20; StorageClass created; monitoring operator was last to stabilize

@cblecker

cblecker commented Jul 9, 2026

Copy link
Copy Markdown
Member

Changes solely in GCP package. Azure confirmed infrastructure flake
/override ci/prow/e2e-azure-v2-self-managed

/verified later by @cristianoveiga

@openshift-ci-robot

Copy link
Copy Markdown

@cblecker: Only users can be targets for the /verified later command.

Details

In response to this:

Changes solely in GCP package. Azure confirmed infrastructure flake
/override ci/prow/e2e-azure-v2-self-managed

/verified later by @cristianoveiga

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.

@openshift-ci

openshift-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@cblecker: Overrode contexts on behalf of cblecker: ci/prow/e2e-azure-v2-self-managed

Details

In response to this:

Changes solely in GCP package. Azure confirmed infrastructure flake
/override ci/prow/e2e-azure-v2-self-managed

/verified later by @cristianoveiga

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

@cblecker

cblecker commented Jul 9, 2026

Copy link
Copy Markdown
Member

/verified later @cristianoveiga

@openshift-ci-robot openshift-ci-robot added verified-later verified Signifies that the PR passed pre-merge verification criteria labels Jul 9, 2026
@openshift-ci-robot

Copy link
Copy Markdown

@cblecker: This PR has been marked to be verified later by @cristianoveiga.

Details

In response to this:

/verified later @cristianoveiga

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.

@openshift-ci

openshift-ci Bot commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

@cristianoveiga: all tests passed!

Full PR test history. Your PR dashboard.

Details

Instructions for interacting with me using PR comments are available here. If you have questions or suggestions related to my behavior, please file an issue against the kubernetes-sigs/prow repository. I understand the commands that are listed here.

@openshift-merge-bot
openshift-merge-bot Bot merged commit ad889e4 into openshift:main Jul 9, 2026
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

approved Indicates a PR has been approved by an approver from all required OWNERS files. area/hypershift-operator Indicates the PR includes changes for the hypershift operator and API - outside an OCP release area/platform/gcp PR/issue for GCP (GCPPlatform) platform area/testing Indicates the PR includes changes for e2e testing jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. lgtm Indicates that a PR is ready to be merged. verified Signifies that the PR passed pre-merge verification criteria verified-later

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants