diff --git a/roles/network_mgmt/README.md b/roles/network_mgmt/README.md index e0c434e..c949c8f 100644 --- a/roles/network_mgmt/README.md +++ b/roles/network_mgmt/README.md @@ -4,6 +4,50 @@ 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..dc506ee 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 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 # 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 }}" + }