From 5c541fc6c0f7af09c706a45ccd8bdbb3f0054556 Mon Sep 17 00:00:00 2001 From: Alberto Florez Date: Mon, 8 Jun 2026 21:40:45 +0200 Subject: [PATCH 1/2] Add OVN layer2 topology support to network_mgmt role --- roles/network_mgmt/README.md | 39 +++++++++++++++++++ roles/network_mgmt/defaults/main.yml | 7 +++- roles/network_mgmt/tasks/automatic.yml | 3 ++ roles/network_mgmt/tasks/manual.yml | 19 ++++++++- .../templates/manual-lb/nad.yaml.j2 | 12 +++++- .../templates/ovn-layer2/nad.yaml.j2 | 19 +++++++++ 6 files changed, 96 insertions(+), 3 deletions(-) create mode 100644 roles/network_mgmt/templates/ovn-layer2/nad.yaml.j2 diff --git a/roles/network_mgmt/README.md b/roles/network_mgmt/README.md index e0c434e..4d7908e 100644 --- a/roles/network_mgmt/README.md +++ b/roles/network_mgmt/README.md @@ -4,6 +4,45 @@ This will not be overwritten by Docsible --> # 📃 Role overview This role performs network management in two modes: Manual and Automatic. It performs tasks that include gathering network information in the vCenter environment, migrate the Port Groups by creating NetworkAttachementDefinitions (NAD), and migrate distributed switches by creating NodeNetworkConfigurationPolicy (NNCP). + +## Network Bridge Modes + +This role supports three network bridge modes: + +### 1. linux-bridge +Uses CNV bridge (cnv-bridge) for network attachment. This mode requires NNCP (NodeNetworkConfigurationPolicy) to configure the bridge on worker nodes. + +### 2. ovs-bridge +Uses OVN-Kubernetes CNI overlay with `localnet` topology. This mode requires NNCP to configure the OVS bridge and localnet mapping on worker nodes. + +### 3. ovn-layer2 +Uses OVN-Kubernetes CNI overlay with `layer2` topology. This mode creates isolated layer2 networks without requiring NNCP or physical node network configuration. + +Example NAD for ovn-layer2 mode: +```yaml +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + annotations: + infra.openshift-virtualization-migration/source-portgroup: example-portgroup-name + name: example-network + namespace: example-namespace +spec: + config: |- + { + "cniVersion": "0.3.1", + "name": "example-network", + "type": "ovn-k8s-cni-overlay", + "netAttachDefName": "example-namespace/example-network", + "topology": "layer2" + } +``` + +To use ovn-layer2 mode, set: +```yaml +network_mgmt_openshift_network_bridge_mode: ovn-layer2 +network_mgmt_ovn_topology: layer2 +``` diff --git a/roles/network_mgmt/defaults/main.yml b/roles/network_mgmt/defaults/main.yml index 11e6605..a02a2d8 100644 --- a/roles/network_mgmt/defaults/main.yml +++ b/roles/network_mgmt/defaults/main.yml @@ -23,13 +23,18 @@ network_mgmt_vcenter_datacenter: '' # title: OpenShift Network Bridge Mode # required: True # description: OpenShift Network Bridge Mode -network_mgmt_openshift_network_bridge_mode: linux-bridge ## This can be 'linux-bridge' or 'ovs-bridge' +network_mgmt_openshift_network_bridge_mode: linux-bridge ## This can be 'linux-bridge', 'ovs-bridge', or 'ovn-layer2' # title: OVN Bridge # required: True # description: Boolean value defines usage of OVN bridge network_mgmt_use_default_ovn_bridge: false +# title: OVN Topology Type +# required: False +# description: OVN topology type for ovn-k8s-cni-overlay (only used when network_mgmt_openshift_network_bridge_mode is 'ovn-layer2') +network_mgmt_ovn_topology: layer2 ## This can be 'layer2' or 'localnet' + # https://docs.openshift.com/container-platform/4.16/networking/k8s_nmstate/\ # k8s-nmstate-updating-node-network-config.html # virt-example-bond-nncp_k8s_nmstate-updating-node-network-config diff --git a/roles/network_mgmt/tasks/automatic.yml b/roles/network_mgmt/tasks/automatic.yml index eae3fdc..6265286 100644 --- a/roles/network_mgmt/tasks/automatic.yml +++ b/roles/network_mgmt/tasks/automatic.yml @@ -31,6 +31,7 @@ - network_mgmt_openshift_node_network_ports | default([]) | length > 0 - network_mgmt_vcenter_dvswitch | default('', true) | trim | length > 0 - network_mgmt_vcenter_datacenter | default('', true) | trim | length > 0 + - network_mgmt_openshift_network_bridge_mode != 'ovn-layer2' - name: automatic | Include tasks from automatic_nad.yml ansible.builtin.include_tasks: @@ -44,4 +45,6 @@ or (network_mgmt_nad_auto_bridge_name is defined and network_mgmt_nad_auto_bridge_name |length > 0) + or + network_mgmt_openshift_network_bridge_mode == 'ovn-layer2' ... diff --git a/roles/network_mgmt/tasks/manual.yml b/roles/network_mgmt/tasks/manual.yml index 20ec618..9ae30e2 100644 --- a/roles/network_mgmt/tasks/manual.yml +++ b/roles/network_mgmt/tasks/manual.yml @@ -31,6 +31,21 @@ that: - network_mgmt_manual_bridge_name is string - (network_mgmt_manual_bridge_name | default('') | length) > 0 + when: + - network_mgmt_openshift_network_bridge_mode == 'linux-bridge' + +- name: manual | Validate ovn-layer2 NAD entries + ansible.builtin.assert: + that: + - "'name' in nad" + - nad.name is string + - nad.name | length > 0 + fail_msg: "Each NAD entry must have a 'name' field for ovn-layer2 mode" + loop: "{{ network_mgmt_manual_nad_list }}" + when: + - network_mgmt_openshift_network_bridge_mode == 'ovn-layer2' + loop_control: + loop_var: nad ## Only create the NNCP if the bridge and the bond is defined, the template looks for the ports to put in the bond. - name: manual | Apply NodeNetworkConfigurationPolicy @@ -51,6 +66,7 @@ - nad.vlan.vlan_id is string or nad.vlan.vlan_id is integer loop: "{{ network_mgmt_manual_nad_list }}" when: + - network_mgmt_openshift_network_bridge_mode != 'ovn-layer2' - ('trunk' not in nad) or (not nad.trunk) loop_control: loop_var: nad @@ -64,9 +80,10 @@ - nad.vlan.vlan_id is iterable - nad.vlan.vlan_id is not string - "network_mgmt_openshift_network_bridge_mode == 'linux-bridge'" - ## Only allow trunks with linux-bridge not supported with ovs-bridge + ## Only allow trunks with linux-bridge not supported with ovs-bridge or ovn-layer2 loop: "{{ network_mgmt_manual_nad_list }}" when: + - network_mgmt_openshift_network_bridge_mode != 'ovn-layer2' - "'trunk' in nad" - nad.trunk loop_control: diff --git a/roles/network_mgmt/templates/manual-lb/nad.yaml.j2 b/roles/network_mgmt/templates/manual-lb/nad.yaml.j2 index 7550b97..258c727 100644 --- a/roles/network_mgmt/templates/manual-lb/nad.yaml.j2 +++ b/roles/network_mgmt/templates/manual-lb/nad.yaml.j2 @@ -33,7 +33,7 @@ spec: "vlan": {{ nad.vlan.vlan_id | int }} {% endif %} } -{% else %} +{% elif network_mgmt_openshift_network_bridge_mode == 'ovs-bridge' %} spec: config: | {"cniVersion": "0.4.0", @@ -46,4 +46,14 @@ spec: "physicalNetworkName": "{{ network_mgmt_manual_localnet_name }}", "netAttachDefName": "{{ nad.namespace | default(network_mgmt_nad_namespace) }}/{{ nad.name }}" } +{% else %} +spec: + config: |- + { + "cniVersion": "0.3.1", + "name": "{{ nad.name }}", + "type": "ovn-k8s-cni-overlay", + "netAttachDefName": "{{ nad.namespace | default(network_mgmt_nad_namespace) }}/{{ nad.name }}", + "topology": "{{ network_mgmt_ovn_topology }}" + } {% endif %} diff --git a/roles/network_mgmt/templates/ovn-layer2/nad.yaml.j2 b/roles/network_mgmt/templates/ovn-layer2/nad.yaml.j2 new file mode 100644 index 0000000..4619db8 --- /dev/null +++ b/roles/network_mgmt/templates/ovn-layer2/nad.yaml.j2 @@ -0,0 +1,19 @@ +apiVersion: k8s.cni.cncf.io/v1 +kind: NetworkAttachmentDefinition +metadata: + name: {{ portgroup.name | infra.openshift_virtualization_migration.rfc1123(network_mgmt_nad_name_prefix, "^[\d]+") }} + namespace: {{ network_mgmt_nad_namespace }} + annotations: + infra.openshift-virtualization-migration/source-portgroup: {{ portgroup.name }} + infra.openshift-virtualization-migration/source-switch: {{ portgroup.switch }} + infra.openshift-virtualization-migration/provider-hostname: {{ network_mgmt_vcenter_hostname }} + infra.openshift-virtualization-migration/provider-type: vmware +spec: + config: |- + { + "cniVersion": "0.3.1", + "name": "{{ portgroup.name | infra.openshift_virtualization_migration.rfc1123(network_mgmt_nad_name_prefix, "^[\d]+") }}", + "type": "ovn-k8s-cni-overlay", + "netAttachDefName": "{{ network_mgmt_nad_namespace }}/{{ portgroup.name | infra.openshift_virtualization_migration.rfc1123(network_mgmt_nad_name_prefix, "^[\d]+") }}", + "topology": "{{ network_mgmt_ovn_topology }}" + } From 60efb8afd453ca5f7b2485f1118ba2b97b970bdc Mon Sep 17 00:00:00 2001 From: Alberto Florez Date: Mon, 8 Jun 2026 21:51:35 +0200 Subject: [PATCH 2/2] Trigger CI/CD pipeline --- roles/network_mgmt/defaults/main.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/roles/network_mgmt/defaults/main.yml b/roles/network_mgmt/defaults/main.yml index a02a2d8..dc506ee 100644 --- a/roles/network_mgmt/defaults/main.yml +++ b/roles/network_mgmt/defaults/main.yml @@ -32,8 +32,8 @@ network_mgmt_use_default_ovn_bridge: false # title: OVN Topology Type # required: False -# description: OVN topology type for ovn-k8s-cni-overlay (only used when network_mgmt_openshift_network_bridge_mode is 'ovn-layer2') -network_mgmt_ovn_topology: layer2 ## This can be 'layer2' or 'localnet' +# description: OVN topology type for ovn-k8s-cni-overlay (only used with ovn-layer2 mode) +network_mgmt_ovn_topology: layer2 ## layer2 or localnet # https://docs.openshift.com/container-platform/4.16/networking/k8s_nmstate/\ # k8s-nmstate-updating-node-network-config.html