Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
a4e8358
Add BGPCloudConfiguration UI
jpinsonneau Oct 28, 2026
501adf4
Add BGPRouting UI
jpinsonneau Oct 28, 2026
e6e8aae
Fix BGP edit form updates
jpinsonneau Oct 29, 2026
c6ae362
Rename BGP navigation entry
jpinsonneau Oct 29, 2026
2c74a69
Translate BGP Cloud Connector views
jpinsonneau Oct 29, 2026
1ddeaca
Preserve BGP form resource entries
jpinsonneau Oct 29, 2026
9711a98
Simplify BGP README references
jpinsonneau Oct 29, 2026
901f97f
Add BGP form and Cypress coverage
jpinsonneau Oct 29, 2026
b60eadc
Cover BGP list filters and CIDRs
jpinsonneau Oct 29, 2026
bd302d8
Fix BGP CIDR and selector validation
jpinsonneau Oct 29, 2026
06c8bf8
Address BGP review feedback
jpinsonneau Oct 29, 2026
46bad25
Sync BGP locale keys
jpinsonneau Oct 29, 2026
3e4f5a3
Address BGP form review feedback
jpinsonneau Nov 2, 2026
12cb8b4
Fix BGP form runtime and tab visibility
jpinsonneau Nov 2, 2026
1a249ae
Adapt BGP UI to namespace status removal
jpinsonneau Nov 5, 2026
a5904f3
Sync generated locale catalogs
jpinsonneau Nov 5, 2026
cd89296
Fix BGP Cypress form assertions
jpinsonneau Nov 5, 2026
4bdeb19
Keep BGP navigation translation key
jpinsonneau Nov 5, 2026
8dccc27
Apply BGP review fixes to base PR
jpinsonneau Nov 13, 2026
0617865
Preserve BGP form configuration fields
jpinsonneau Nov 13, 2026
a1e4717
Add CUDN namespace membership details
jpinsonneau Nov 5, 2026
9eb215b
Fix BGP and CUDN review findings
jpinsonneau Nov 5, 2026
b61ab3c
Fix CUDN routing and BGP validation review
jpinsonneau Nov 13, 2026
d10d1f3
Fix BGP fixture ownership and OLM tabs
jpinsonneau Nov 13, 2026
5ff6739
Fix rebased BGP and CUDN imports
jpinsonneau Nov 13, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# Networking Console Plugin

An OpenShift Console dynamic plugin that provides the Networking section UI for the OpenShift web console. It manages
views for Services, Routes, Ingresses, NetworkPolicies, NetworkAttachmentDefinitions (NADs), and UserDefinedNetworks (
UDNs).
views for Services, Routes, Ingresses, NetworkPolicies, NetworkAttachmentDefinitions (NADs), UserDefinedNetworks (
UDNs), `BGPCloudConfiguration`, and `BGPRouting`.

The plugin integrates with the [OpenShift Console](https://github.com/openshift/console)
via [webpack module federation](https://webpack.js.org/concepts/module-federation/) and
Expand Down
17 changes: 17 additions & 0 deletions integration-tests/fixtures/bgp-routing-card.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
apiVersion: v1
kind: Namespace
metadata:
name: e2e-bgp-card-ns
labels:
cluster-udn: e2e-bgp-card-cudn
k8s.ovn.org/primary-user-defined-network: ''
---
apiVersion: networking.openshift.io/v1beta1
kind: BGPRouting
metadata:
name: e2e-bgp-card-routing
spec:
network:
name: e2e-bgp-card-cudn
subnets:
- 10.253.0.0/24
216 changes: 216 additions & 0 deletions integration-tests/tests/bgp.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,216 @@
import { checkErrors } from '../support';
import { MINUTE } from '../support/commands';
import { expectYamlToContain, switchToYamlView } from '../support/service-form';

const CLOUD_CREATE_URL =
'/k8s/cluster/networking.openshift.io~v1beta1~BGPCloudConfiguration/~new/form';
const ROUTING_CREATE_URL = '/k8s/cluster/networking.openshift.io~v1beta1~BGPRouting/~new/form';
const BGP_CARD_CUDN_NAME = 'cluster-udn-e2e-bgp-card-cudn';
const BGP_CARD_NETWORK_NAME = 'e2e-bgp-card-cudn';
const BGP_CARD_CUDN_URL = `/k8s/cluster/k8s.ovn.org~v1~ClusterUserDefinedNetwork/${BGP_CARD_CUDN_NAME}`;
const BGP_CARD_FIXTURE = 'fixtures/bgp-routing-card.yaml';

const selectFormEditor = () => {
cy.get('#form', { timeout: MINUTE }).check({ force: true });
};

const switchBGPFormView = (fieldId: string) => {
cy.contains('label', 'Form view').click();
cy.get(`#${fieldId}`, { timeout: MINUTE }).should('be.visible');
};

describe('BGP forms', () => {
before(() => {
cy.login();
cy.applyFixtureFile(BGP_CARD_FIXTURE);
});

afterEach(() => {
checkErrors();
});

after(() => {
cy.exec(
'oc delete bgprouting e2e-bgp-card-routing --ignore-not-found && ' +
`oc delete clusteruserdefinednetwork ${BGP_CARD_CUDN_NAME} --ignore-not-found && ` +
'oc delete namespace e2e-bgp-card-ns --ignore-not-found --wait=false',
{ failOnNonZeroExit: false, timeout: MINUTE },
);
cy.logout();
});

it('shows typed cloud fields and only the selected platform section', () => {
cy.visit(CLOUD_CREATE_URL);
cy.contains('h1', 'Create BGPCloudConfiguration', { timeout: MINUTE }).should('be.visible');
selectFormEditor();

cy.get('#name').should('be.disabled');
cy.get('#name').should('have.value', 'cluster');
cy.get('#localASN').should('have.attr', 'type', 'text');
cy.get('#localASN').type('abc');
cy.contains('Enter a valid ASN between 1 and 4294967295.').should('be.visible');
cy.get('button[type="submit"]').should('be.disabled');
cy.get('#localASN').clear();
cy.get('#localASN').type('64512');
cy.get('#awsRegion').should('be.visible');
cy.get('#awsRouteServerIDs').should('be.visible');
cy.get('#azureSubscriptionID').should('not.exist');
cy.get('#enableNestedVirtualization').should('not.exist');

cy.get('#platform').click();
cy.contains('[role="menuitem"]', 'Azure').click();
cy.get('#azureSubscriptionID').should('be.visible');
cy.get('#azureResourceGroup').should('be.visible');
cy.get('#azureRouteServerName').should('be.visible');
cy.get('#awsRegion').should('not.exist');

cy.get('#platform').click();
cy.contains('[role="menuitem"]', 'GCP').click();
cy.get('#gcpProject').should('be.visible');
cy.get('#gcpRegion').should('be.visible');
cy.get('#cloudRouterName').should('be.visible');
cy.get('#enableNestedVirtualization').should('have.attr', 'type', 'checkbox');
cy.get('#awsRegion').should('not.exist');

cy.get('#platform').click();
cy.contains('[role="menuitem"]', 'Manual').click();
cy.get('#peerSelectorKey').should('be.visible');
cy.get('#peerSelectorValue').should('be.visible');
cy.get('#neighborAddress').should('be.visible');
cy.get('#remoteASN').should('have.attr', 'type', 'text');
cy.get('#remoteASN').type('4294967296');
cy.contains('Enter a valid ASN between 1 and 4294967295.').should('be.visible');
cy.get('#remoteASN').clear();
cy.get('#remoteASN').type('64513');
cy.get('#ebgpMultiHop').should('have.attr', 'type', 'checkbox');
});

it('allows selector labels with an empty value', () => {
cy.visit(CLOUD_CREATE_URL);
selectFormEditor();

cy.get('#localASN').type('64512');
cy.get('#platform').click();
cy.contains('[role="menuitem"]', 'Manual').click();
cy.get('#peerSelectorKey').type('k8s.ovn.org/primary-user-defined-network');
cy.get('#peerSelectorValue').should('have.value', '');
cy.get('#neighborAddress').type('192.0.2.1');
cy.get('#remoteASN').type('64513');
cy.get('#routerSelectorKey').type('node-role.kubernetes.io/bgp');
cy.get('#routerSelectorValue').should('have.value', '');

cy.get('button[type="submit"]').should('not.be.disabled');
});

it('supports switching between the guided form and YAML editor', () => {
cy.visit(CLOUD_CREATE_URL);
selectFormEditor();
cy.get('#localASN').type('64512');
cy.get('#platform').click();
cy.contains('[role="menuitem"]', 'Manual').click();
cy.get('#peerSelectorKey').type('node-role.kubernetes.io/bgp');
cy.get('#neighborAddress').type('192.0.2.1');
cy.get('#remoteASN').type('64513');
cy.get('#routerSelectorKey').type('node-role.kubernetes.io/worker');

switchToYamlView();
expectYamlToContain(
'kind: BGPCloudConfiguration',
'platform: Manual',
'localASN: 64512',
'address: 192.0.2.1',
);
switchBGPFormView('localASN');
cy.get('#localASN').should('have.value', '64512');
cy.get('#platform').should('contain', 'Manual');
cy.get('#neighborAddress').should('have.value', '192.0.2.1');
});

it('supports switching between the BGPRouting form and YAML editor', () => {
cy.visit(ROUTING_CREATE_URL);
selectFormEditor();
cy.get('#name').type('e2e-routing');
cy.get('#network').type('e2e-network');
cy.get('#subnet1').type('10.20.0.0/16');
cy.get('#subnet2').type('2001:db8:20::/64');

switchToYamlView();
expectYamlToContain(
'kind: BGPRouting',
'name: e2e-routing',
'name: e2e-network',
'10.20.0.0/16',
'2001:db8:20::/64',
);
switchBGPFormView('name');
cy.get('#name').should('have.value', 'e2e-routing');
cy.get('#network').should('have.value', 'e2e-network');
cy.get('#subnet1').should('have.value', '10.20.0.0/16');
cy.get('#subnet2').should('have.value', '2001:db8:20::/64');
});

it('shows the routing tab disabled until a cloud configuration exists', () => {
cy.visit('/k8s/cluster/networking.openshift.io~v1beta1~BGPCloudConfiguration');
cy.contains('h1', 'BGP', { timeout: MINUTE }).should('be.visible');
cy.get('button[role="tab"]', { timeout: MINUTE })
.contains('BGPRouting')
.should(($tab) => {
const configurationExists =
$tab.closest('body').find('a[href*="BGPCloudConfiguration/"]').length > 0;
if (configurationExists) {
expect($tab).not.to.be.disabled;
} else {
expect($tab).to.be.disabled;
}
});
});

it('validates BGPRouting CIDRs and refreshes namespace guidance', () => {
cy.visit(ROUTING_CREATE_URL);
cy.contains('h1', 'Create BGPRouting', { timeout: MINUTE }).should('be.visible');
selectFormEditor();

cy.get('#name').should('have.attr', 'type', 'text').type('e2e-routing-validation');
cy.get('#network').type('prod');
cy.contains('code', 'cluster-udn=prod').should('be.visible');
cy.get('#subnet1').type('abc.def/24');
cy.contains('Enter a valid IPv4 or IPv6 CIDR.').should('be.visible');
cy.get('button[type="submit"]').should('be.disabled');

cy.get('#subnet1').clear();
cy.get('#subnet1').type('10.20.0.0/16');
cy.get('#subnet2').type('2001:db8:20::/64');
cy.get('#subnet3').should('not.exist');
cy.get('button[type="submit"]').should('not.be.disabled');
});

it('exposes a name filter on the BGPRouting list view', () => {
cy.visit('/k8s/cluster/networking.openshift.io~v1beta1~BGPCloudConfiguration');
cy.contains('h1', 'BGP', { timeout: MINUTE }).should('be.visible');

cy.visit('/k8s/cluster/networking.openshift.io~v1beta1~BGPRouting');
cy.get('body', { timeout: MINUTE })
.should(($body) => {
expect(
$body.find('[data-test-id="item-filter"]').length ||
$body.find(':contains("No BGPRouting found")').length,
).to.be.greaterThan(0);
})
.then(($body) => {
if ($body.find('[data-test-id="item-filter"]').length) {
cy.get('[data-test-id="item-filter"]').should('be.visible');
} else cy.contains('No BGPRouting found').should('be.visible');
});
});

it('shows related BGPRouting details on the CUDN page', () => {
cy.visit(BGP_CARD_CUDN_URL);
cy.contains('h1', BGP_CARD_CUDN_NAME, { timeout: MINUTE }).should('be.visible');
cy.contains('h2', 'BGP routings', { timeout: MINUTE }).scrollIntoView();
cy.contains('h2', 'BGP routings', { timeout: MINUTE }).should('be.visible');
cy.contains('a', 'e2e-bgp-card-routing').should('be.visible');
cy.contains('dt', 'Network').parent().contains(BGP_CARD_NETWORK_NAME).should('be.visible');
cy.contains('Phase').should('be.visible');
cy.contains('Availability').should('be.visible');
});
});
34 changes: 34 additions & 0 deletions integration-tests/tests/list-pages.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,36 @@ const LIST_PAGES = [
},
];

const BGP_LIST_PAGES = [
{
h1: 'BGP',
name: 'BGPCloudConfigurations',
url: '/k8s/cluster/networking.openshift.io~v1beta1~BGPCloudConfiguration',
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Resolved
},
{
h1: 'BGP',
name: 'BGPRoutings',
url: '/k8s/cluster/networking.openshift.io~v1beta1~BGPRouting',
},
];

describe('List page smoke tests', { testIsolation: false }, () => {
before(() => {
cy.login();
});

let bgpEnabled = false;
before(() => {
cy.exec(
'oc get crd bgpcloudconfigurations.networking.openshift.io bgproutings.networking.openshift.io --ignore-not-found -o name',
{ failOnNonZeroExit: false },
).then(({ stdout }) => {
bgpEnabled =
stdout.includes('bgpcloudconfigurations.networking.openshift.io') &&
stdout.includes('bgproutings.networking.openshift.io');
});
});

afterEach(() => {
checkErrors();
});
Expand All @@ -54,4 +79,13 @@ describe('List page smoke tests', { testIsolation: false }, () => {
cy.contains('h1', h1, { timeout: MINUTE }).should('be.visible');
});
});

BGP_LIST_PAGES.forEach(({ h1, name, url }) => {
it(`loads the ${name} list page when BGP is available`, function () {
if (!bgpEnabled) this.skip();
cy.visit(url);
cy.dismissWelcomeTourIfPresent();
cy.contains('h1', h1, { timeout: MINUTE }).should('be.visible');
});
});
});
Loading
Loading