Skip to content

OPNET-621: Add e2e-metal-ipi-bgp-vip lane for BGP-based VIP management - #82698

Open
mkowalski wants to merge 1 commit into
openshift:mainfrom
mkowalski:bgp-vip-lane
Open

OPNET-621: Add e2e-metal-ipi-bgp-vip lane for BGP-based VIP management#82698
mkowalski wants to merge 1 commit into
openshift:mainfrom
mkowalski:bgp-vip-lane

Conversation

@mkowalski

@mkowalski mkowalski commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Adds a CI lane for BGP-based VIP management on baremetal IPI (enhancement 1982, DevPreviewNoUpgrade):

  • baremetalds-e2e-bgp-vip workflow — standard baremetalds/ofcir install with BGP_VIP_MANAGEMENT=true + ENABLE_BGP_TOR=true (dev-scripts knob: OPNET-787: Add BGP_VIP_MANAGEMENT one-click knob openshift-metal3/dev-scripts#1939; ToR speaker: dev-scripts#1929), IPv4, 2 workers, FEATURE_SET=DevPreviewNoUpgrade
  • baremetalds-e2e-bgp-vip-verify step — replaces the conformance suite with the feature's acceptance criteria: vipManagement: BGP on the Infrastructure CR, frr-k8s static pods and zero keepalived pods on the control plane, the API VIP advertised to the hypervisor ToR from every master and the ingress VIP from the workers (BGP path counts via vtysh), console HTTP 200 over the BGP-routed VIP. The script body has been validated verbatim against a live BGP-VIP cluster (passes, and the failure branches trigger on synthetic bad input)
  • Optional on-demand presubmit e2e-metal-ipi-bgp-vip on openshift/installer (always_run: false, optional: true)

Expected red for now: the flow needs openshift/installer#10718 + openshift/machine-config-operator#6326 + openshift/cluster-network-operator#3047 and the dev-scripts knob to merge. On installer#10718 itself the ephemeral payload carries the PR's installer, so /test e2e-metal-ipi-bgp-vip there exercises the real flow — the lane doubles as a merge-progress indicator and goes green as the stack lands. Follow-ups once green: extend the presubmit to MCO/CNO, add a conformance variant and a nightly periodic.

Rehearsals for the new job will fail by design (see above).


This PR was prepared with AI assistance. Please verify before acting on it.

Summary by CodeRabbit

Adds an optional, on-demand e2e-metal-ipi-bgp-vip presubmit lane to OpenShift CI for validating bare-metal IPI clusters with BGP-managed API and ingress VIPs.

The new workflow configures an IPv4, two-worker Equinix metal cluster with DevPreviewNoUpgrade, BGP VIP management, and BGP ToR support. Its verification step checks Infrastructure configuration, FRR/keepalived pod state, BGP advertisements, and console access through the routed VIP.

New baremetalds-e2e-bgp-vip workflow: dev-scripts baremetal IPI install
with BGP_VIP_MANAGEMENT=true + ENABLE_BGP_TOR=true (DevPreviewNoUpgrade,
v4, 2 workers), followed by a verification step asserting the feature's
acceptance criteria instead of the conformance suite: vipManagement=BGP
on the Infrastructure CR, frr-k8s static pods (and no keepalived) on the
control plane, the API VIP advertised to the ToR from every master and
the ingress VIP from the workers, and the console answering over the
BGP-routed path.

Wired as an optional, on-demand presubmit on openshift/installer. The
job is expected to fail until the feature PRs merge (installer#10718,
MCO#6326, CNO#3047) and the dev-scripts knob lands
(openshift-metal3/dev-scripts#1939); on installer#10718 itself the
payload carries the PR's installer, so /test e2e-metal-ipi-bgp-vip
exercises the flow end to end.

Assisted-By: Claude Fable 5
Signed-off-by: Mat Kowalski <mko@redhat.com>
@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 30, 2026
@openshift-ci-robot

openshift-ci-robot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@mkowalski: This pull request references OPNET-621 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:

Adds a CI lane for BGP-based VIP management on baremetal IPI (enhancement 1982, DevPreviewNoUpgrade):

  • baremetalds-e2e-bgp-vip workflow — standard baremetalds/ofcir install with BGP_VIP_MANAGEMENT=true + ENABLE_BGP_TOR=true (dev-scripts knob: OPNET-787: Add BGP_VIP_MANAGEMENT one-click knob openshift-metal3/dev-scripts#1939; ToR speaker: dev-scripts#1929), IPv4, 2 workers, FEATURE_SET=DevPreviewNoUpgrade
  • baremetalds-e2e-bgp-vip-verify step — replaces the conformance suite with the feature's acceptance criteria: vipManagement: BGP on the Infrastructure CR, frr-k8s static pods and zero keepalived pods on the control plane, the API VIP advertised to the hypervisor ToR from every master and the ingress VIP from the workers (BGP path counts via vtysh), console HTTP 200 over the BGP-routed VIP. The script body has been validated verbatim against a live BGP-VIP cluster (passes, and the failure branches trigger on synthetic bad input)
  • Optional on-demand presubmit e2e-metal-ipi-bgp-vip on openshift/installer (always_run: false, optional: true)

Expected red for now: the flow needs openshift/installer#10718 + openshift/machine-config-operator#6326 + openshift/cluster-network-operator#3047 and the dev-scripts knob to merge. On installer#10718 itself the ephemeral payload carries the PR's installer, so /test e2e-metal-ipi-bgp-vip there exercises the real flow — the lane doubles as a merge-progress indicator and goes green as the stack lands. Follow-ups once green: extend the presubmit to MCO/CNO, add a conformance variant and a nightly periodic.

Rehearsals for the new job will fail by design (see above).


This PR was prepared with AI assistance. Please verify before acting on it.

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.

@mkowalski

Copy link
Copy Markdown
Contributor Author

/pj-rehearse ack

@openshift-merge-bot

Copy link
Copy Markdown
Contributor

@mkowalski: now processing your pj-rehearse request. Please allow up to 10 minutes for jobs to trigger or cancel.

@openshift-merge-bot openshift-merge-bot Bot added the rehearsals-ack Signifies that rehearsal jobs have been acknowledged label Jul 30, 2026
@coderabbitai

coderabbitai Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Walkthrough

Adds an optional Metal IPI E2E job that configures BGP-based VIP management, verifies routing and console access, and runs on the equinix-ocp-metal cluster profile.

Changes

BGP VIP end-to-end test

Layer / File(s) Summary
BGP VIP verification step
ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/*
Adds strict Bash checks for BGP VIP status, FRR static pods, keepalived absence, VIP advertisements, and console HTTP access, with step metadata and ownership.
BGP VIP workflow wiring
ci-operator/step-registry/baremetalds/e2e/bgp-vip/*
Adds the workflow configuration, metadata, ownership, BGP-enabled dev-scripts settings, pre/post chains, and verification test stage.
Installer test registration
ci-operator/config/openshift/installer/openshift-installer-main.yaml
Registers the optional e2e-metal-ipi-bgp-vip job with the Equinix metal profile and new workflow.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant InstallerJob
  participant BgpVipWorkflow
  participant Cluster
  participant BgpVipVerify
  InstallerJob->>BgpVipWorkflow: Start optional Metal IPI BGP VIP test
  BgpVipWorkflow->>Cluster: Configure IPv4 BGP VIP management
  BgpVipWorkflow->>BgpVipVerify: Run verification step
  BgpVipVerify->>Cluster: Check VIP state, routes, pods, and console access
Loading

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
No-Sensitive-Data-In-Logs ❌ Error The new verify script uses set -x and logs VIPs/console URL in failures, which can expose internal hostnames and cluster IPs. Remove xtrace around sensitive commands and avoid printing VIPs/URLs in failure output; redact or summarize values instead.
Single Node Openshift (Sno) Test Compatibility ⚠️ Warning The new BGP VIP verify script assumes multi-node topology: it counts masters/workers, expects one BGP path per master, and has no SNO skip/guard. Add a [Skipped:SingleReplicaTopology] label or runtime topology check, and remove/guard assumptions about multiple masters/workers and per-node BGP path counts.
Ipv6 And Disconnected Network Test Compatibility ⚠️ Warning The new workflow hardcodes IP_STACK=v4, and the verify script assumes IPv4 BGP routes via show ip bgp and /32 VIPs. Make the job IP-family aware or explicitly skip it on IPv6-only clusters; use family-specific route/prefix handling instead of IPv4-only /32 assumptions.
✅ Passed checks (12 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly matches the main change: adding the e2e-metal-ipi-bgp-vip lane for BGP-based VIP management.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Stable And Deterministic Test Names ✅ Passed No Ginkgo test definitions were added; the PR only adds YAML/shell step-registry files with static names.
Test Structure And Quality ✅ Passed PR adds CI registry YAML and a shell verification script, not Ginkgo tests; the custom check is not applicable.
Microshift Test Compatibility ✅ Passed No new Ginkgo tests were added; the change is CI config plus a shell verification step, so this MicroShift check is not applicable.
Topology-Aware Scheduling Compatibility ✅ Passed No deployment manifests, operator code, or controllers were changed; only CI config, workflow metadata, and a verification script were added.
Ote Binary Stdout Contract ✅ Passed No OTE binary entrypoints were added; stdout writes exist only in a ci-operator shell ref, and no stdout-writing APIs appear in the changed subtree.
No-Weak-Crypto ✅ Passed No weak crypto, custom crypto, or secret/token comparisons found in the added workflow or verify script; diff scan had no MD5/SHA1/DES/RC4/3DES/Blowfish/ECB hits.
Container-Privileges ✅ Passed The added workflow, ref, and verify script contain no privileged:true, hostPID/Network/IPC, allowPrivilegeEscalation, SYS_ADMIN, or explicit root settings.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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

@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: mkowalski
Once this PR has been reviewed and has the lgtm label, please assign dtantsur for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found 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-merge-bot

Copy link
Copy Markdown
Contributor

[REHEARSALNOTIFIER]
@mkowalski: the pj-rehearse plugin accommodates running rehearsal tests for the changes in this PR. Expand 'Interacting with pj-rehearse' for usage details. The following rehearsable tests have been affected by this change:

Test name Repo Type Reason
pull-ci-openshift-installer-main-e2e-metal-ipi-bgp-vip openshift/installer presubmit Presubmit changed

Prior to this PR being merged, you will need to either run and acknowledge or opt to skip these rehearsals.

Interacting with pj-rehearse

Comment: /pj-rehearse to run up to 5 rehearsals
Comment: /pj-rehearse skip to opt-out of rehearsals
Comment: /pj-rehearse {test-name}, with each test separated by a space, to run one or more specific rehearsals
Comment: /pj-rehearse more to run up to 10 rehearsals
Comment: /pj-rehearse max to run up to 25 rehearsals
Comment: /pj-rehearse auto-ack to run up to 5 rehearsals, and add the rehearsals-ack label on success
Comment: /pj-rehearse list to get an up-to-date list of affected jobs
Comment: /pj-rehearse abort to abort all active rehearsals
Comment: /pj-rehearse network-access-allowed to allow rehearsals of tests that have the restrict_network_access field set to false. This must be executed by an openshift org member who is not the PR author

Once you are satisfied with the results of the rehearsals, comment: /pj-rehearse ack to unblock merge. When the rehearsals-ack label is present on your PR, merge will no longer be blocked by rehearsals.
If you would like the rehearsals-ack label removed, comment: /pj-rehearse reject to re-block merging.

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh (1)

1-4: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Use the required shell defaults and narrow tracing.

Use set -euo pipefail; the current script enables tracing twice (bash -x and set -x). Keep tracing off unless it is needed, and scope it narrowly.

As per coding guidelines, step-registry command scripts should default to set -euo pipefail without -x.

Also applies to: 12-17

🤖 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
`@ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh`
around lines 1 - 4, Update the script’s shell options to use the required
default `set -euo pipefail` without tracing, and remove any duplicate `bash -x`
or `set -x` usage in the referenced command sections. If debugging is necessary,
scope tracing only around the specific commands that require it.

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.

Inline comments:
In
`@ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh`:
- Around line 47-66: Update the VIP path assertions around paths_for, api_paths,
and ingress_paths to require exact counts: API paths must equal masters, and
ingress paths must equal workers. Always evaluate the ingress VIP assertion,
including when the worker pool is absent, and fail when the count is missing or
differs from the expected value.
- Around line 68-73: Update the console check near the final verification step
to invoke curl with --resolve for the console hostname mapped to ${ingress_vip},
and bypass configured proxies for this request. Preserve the existing HTTPS
request, timeout, status-code validation, and failure message while ensuring the
hostname is routed specifically through the BGP ingress VIP.
- Around line 33-38: Replace the pod-name count check in the frr-k8s
verification step with validation that each control-plane node has a ready
frr-k8s pod scheduled via spec.nodeName. Exclude Pending, CrashLoopBackOff,
duplicate, and stale pods, and fail unless every node selected by
node-role.kubernetes.io/master is covered by exactly one ready pod.

---

Nitpick comments:
In
`@ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh`:
- Around line 1-4: Update the script’s shell options to use the required default
`set -euo pipefail` without tracing, and remove any duplicate `bash -x` or `set
-x` usage in the referenced command sections. If debugging is necessary, scope
tracing only around the specific commands that require it.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

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

ℹ️ Review info
⚙️ Run configuration

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

Review profile: CHILL

Plan: Enterprise

Run ID: cbc42988-d2f4-4ac9-9ddf-7fcb125c5c8a

📥 Commits

Reviewing files that changed from the base of the PR and between 6fe98b2 and 6300fd8.

⛔ Files ignored due to path filters (1)
  • ci-operator/jobs/openshift/installer/openshift-installer-main-presubmits.yaml is excluded by !ci-operator/jobs/**
📒 Files selected for processing (8)
  • ci-operator/config/openshift/installer/openshift-installer-main.yaml
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/OWNERS
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/baremetalds-e2e-bgp-vip-workflow.metadata.json
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/baremetalds-e2e-bgp-vip-workflow.yaml
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/OWNERS
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-ref.metadata.json
  • ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-ref.yaml

Comment on lines +33 to +38
echo "[2/5] frr-k8s static pods run on every control plane node"
masters="$(oc get nodes -l node-role.kubernetes.io/master -o name | wc -l)"
static_pods="$(oc get pods -n openshift-frr-k8s -o name | grep -c 'frr-k8s-ostest-master' || true)"
if [[ "${static_pods}" -lt "${masters}" ]]; then
fail "expected ${masters} frr-k8s static pods on masters, found ${static_pods}"
fi

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Check frr-k8s readiness and node placement, not just pod-name counts.

A Pending or CrashLoopBackOff pod is counted, and duplicate/stale names can satisfy static_pods >= masters without one ready pod on every control-plane node. Validate pod readiness and spec.nodeName for each control-plane node. The step documentation requires frr-k8s pods to run on every control-plane node.

🤖 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
`@ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh`
around lines 33 - 38, Replace the pod-name count check in the frr-k8s
verification step with validation that each control-plane node has a ready
frr-k8s pod scheduled via spec.nodeName. Exclude Pending, CrashLoopBackOff,
duplicate, and stale pods, and fail unless every node selected by
node-role.kubernetes.io/master is covered by exactly one ready pod.

Comment on lines +47 to +66
echo "[4/5] ToR sees the VIP routes over BGP"
api_vip="$(oc get infrastructure cluster -o jsonpath='{.status.platformStatus.baremetal.apiServerInternalIPs[0]}')"
ingress_vip="$(oc get infrastructure cluster -o jsonpath='{.status.platformStatus.baremetal.ingressIPs[0]}')"
workers="$(oc get nodes -l node-role.kubernetes.io/worker -o name | wc -l)"
podman exec bgp-tor vtysh -c 'show ip bgp'
paths_for() {
podman exec bgp-tor vtysh -c "show ip bgp $1/32" | sed -n 's/^Paths: (\([0-9]*\) available.*/\1/p'
}
api_paths="$(paths_for "${api_vip}")"
if [[ -z "${api_paths}" ]]; then
fail "API VIP ${api_vip}/32 not advertised to the ToR"
elif [[ "${api_paths}" -lt "${masters}" ]]; then
fail "API VIP advertised from ${api_paths} node(s), expected ${masters} (one per master)"
fi
if [[ "${workers}" -gt 0 ]]; then
ingress_paths="$(paths_for "${ingress_vip}")"
if [[ -z "${ingress_paths}" ]]; then
fail "ingress VIP ${ingress_vip}/32 not advertised to the ToR"
fi
fi

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.

🎯 Functional Correctness | 🟠 Major | 🏗️ Heavy lift

Require the expected BGP path count for both VIPs.

Line 58 accepts any API path count greater than or equal to the master count. Lines 61-66 accept a single ingress path and skip the ingress assertion entirely when zero workers exist. Require the expected number of unique paths, and fail when the configured worker pool is absent.

🤖 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
`@ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh`
around lines 47 - 66, Update the VIP path assertions around paths_for,
api_paths, and ingress_paths to require exact counts: API paths must equal
masters, and ingress paths must equal workers. Always evaluate the ingress VIP
assertion, including when the worker pool is absent, and fail when the count is
missing or differs from the expected value.

Comment on lines +68 to +73
echo "[5/5] console answers over the BGP-routed VIP"
console_url="$(oc whoami --show-console)"
http_code="$(curl -sk -o /dev/null -w '%{http_code}' --max-time 30 "${console_url}")"
if [[ "${http_code}" != "200" ]]; then
fail "console at ${console_url} returned HTTP ${http_code}, expected 200"
fi

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.

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Prove that the console request used the BGP ingress VIP.

Curling the console hostname only proves that some HTTP endpoint returned 200; DNS or a proxy could route elsewhere. Pin the hostname to ${ingress_vip} with curl --resolve and bypass proxies for this check.

🤖 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
`@ci-operator/step-registry/baremetalds/e2e/bgp-vip/verify/baremetalds-e2e-bgp-vip-verify-commands.sh`
around lines 68 - 73, Update the console check near the final verification step
to invoke curl with --resolve for the console hostname mapped to ${ingress_vip},
and bypass configured proxies for this request. Preserve the existing HTTPS
request, timeout, status-code validation, and failure message while ensuring the
hostname is routed specifically through the BGP ingress VIP.

@openshift-ci

openshift-ci Bot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

@mkowalski: all tests passed!

Full PR test history. Your PR dashboard.

Details

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

jira/valid-reference Indicates that this PR references a valid Jira ticket of any type. rehearsals-ack Signifies that rehearsal jobs have been acknowledged

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants