diff --git a/playbooks/infra.yml b/playbooks/infra.yml
index 4e5f65d1..f39ab476 100644
--- a/playbooks/infra.yml
+++ b/playbooks/infra.yml
@@ -7,7 +7,7 @@
- role: helper/online
# This installs the interpreter only.
- # Extra OS/PyPI packages should not required by this playbook.
+ # Extra OS/PyPI packages should not be required by this playbook.
- role: helper/python3
- role: helper/facts
diff --git a/plugins/filter/ipv4_mac.yml b/plugins/filter/ipv4_mac.yml
new file mode 100644
index 00000000..58bc7cf1
--- /dev/null
+++ b/plugins/filter/ipv4_mac.yml
@@ -0,0 +1,35 @@
+---
+# Copyright: OpenNebula Project, OpenNebula Systems
+# Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+
+DOCUMENTATION:
+ name: ipv4_mac
+ short_description: Convert IPv4 into MAC
+ description:
+ - Convert IPv4 (A.B.C.D) into MAC (02:01:A:B:C:D).
+ options:
+ _input:
+ description:
+ - String to convert.
+ type: str
+ required: true
+ fmt:
+ description:
+ - Format string (e.g. 02:01:%02x:%02x:%02x:%02x).
+ type: str
+ required: false
+ default: '02:01:%02x:%02x:%02x:%02x'
+ author:
+ - Michal Opala (@sk4zuzu)
+
+EXAMPLES: |
+ # '10.11.12.13' -> '02:01:0a:0b:0c:0d'
+ - name: Conversion example
+ ansible.builtin.debug:
+ msg: >-
+ {{ '10.11.12.13' | opennebula.deploy.ipv4_mac }}
+
+RETURN:
+ _value:
+ description: String containing MAC.
+ type: str
diff --git a/plugins/filter/main.py b/plugins/filter/main.py
index 0f0a1bda..b0b0a0cf 100644
--- a/plugins/filter/main.py
+++ b/plugins/filter/main.py
@@ -1,7 +1,13 @@
-from ansible_collections.opennebula.deploy.plugins.module_utils.main import to_one
+from ansible_collections.opennebula.deploy.plugins.module_utils.main import (
+ ipv4_mac,
+ to_one,
+)
class FilterModule(object):
def filters(self):
- return dict(to_one=to_one)
+ return dict(
+ ipv4_mac=ipv4_mac,
+ to_one=to_one,
+ )
diff --git a/plugins/module_utils/main.py b/plugins/module_utils/main.py
index f697eaf9..386378d5 100644
--- a/plugins/module_utils/main.py
+++ b/plugins/module_utils/main.py
@@ -3,6 +3,16 @@
# Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
+# EXAMPLES:
+# '10.11.12.13' -> '02:01:0a:0b:0c:0d'
+def ipv4_mac(ipv4, fmt='02:01:%02x:%02x:%02x:%02x'):
+ """Converts IPv4 (string) into MAC."""
+
+ import ipaddress
+
+ return fmt % tuple(ipaddress.IPv4Address(ipv4).packed)
+
+
# NOTE: It does not validate character classes or character count!
# EXAMPLES:
# pci -> match_address('0000:0*:00.*', sep='[:.]')
diff --git a/roles/infra/README.md b/roles/infra/README.md
index 7f8215a9..9df1aec4 100644
--- a/roles/infra/README.md
+++ b/roles/infra/README.md
@@ -11,38 +11,40 @@ Pre-installed Libvirt software (in the case of `infra` and `node` groups share h
Role Variables
--------------
-| Name | Type | Default | Example | Description |
-|--------------------------------------|--------|--------------------|---------------------|-------------------------------------------------------------------|
-| `frontend_group` | `str` | `frontend` | | Custom name of the Frontend group in the inventory. |
-| `infra_group` | `str` | `infra` | | Custom name of the Infra group in the inventory. |
-| | | | | |
-| `runtime_dir` | `str` | `/var/one-deploy/` | | Directory used to store QCOW2 and ISO images. |
-| `os_image_url` | `str` | | | HTTP(S) link to Debian/RedHat-like image running `one-contextd`. |
-| `os_image_size` | `str` | `20G` | | The size to which one-deploy will **try** to adjust the OS image. |
-| `memory_KiB` | `str` | `2097152` | | Memory amount to be set in XML in Libvirt. |
-| `vcpu_static` | `str` | `1` | | VCPU amount to be set in XML in Libvirt. |
-| `cputune_shares_base` | `int` | `200` | | Base value used to compute PWS (assuming CGv2). |
-| `cputune_shares_max` | `int` | `10000` | | PWS value cap (assuming CGv2). |
-| `cputune_shares` | `int` | computed | | The proportional weighted share (PWS) for the domain. |
-| `vnc_max_port` | `str` | `65535` | | Upper limit for VNC ports to start counting-down from. |
-| `passthrough_fs` | `list` | `[]` | (check below) | Shared HV filesystems to attach to the Front-end VMs. |
-| | | | | |
-| `infra_bridge` | `str` | `br0` | | Pre-defined bridge interface to insert VM NICs to. |
-| `infra_bridge_type` | `str` | `bridge` | | Supported values: bridge, openvswitch, openvswitch_dpdk |
-| `infra_dpdk_socket_path` | `str` | | | Path for existing socket when using OVS with DPDK. |
-| `infra_vlan_id` | `str` | | | Optionally set the VLAN ID for the bridge. |
-| `infra_hostname` | `str` | | `n1a1` | Defines on which HV machine the Front-end VM should be deployed. |
-| `context.ETH0_DNS` | `str` | | `1.1.1.1` | DNS server. |
-| `context.ETH0_SEARCH_DOMAIN` | `str` | | `1.1.1.1` | DNS search domain. |
-| `context.ETH0_GATEWAY` | `str` | | `10.2.50.1` | Gateway. |
-| `context.ETH0_IP` | `str` | | `10.2.50.100` | IPv4 address to be set on eth0. |
-| `context.ETH0_MAC` | `str` | | `02:01:0a:02:32:64` | MAC address to be set on eth0 (**MUST** match MAC set in XML.) |
-| `context.ETH0_MASK` | `str` | | `255.255.255.0` | Network mask. |
-| `context.ETH0_NETWORK` | `str` | | `10.2.50.0` | Network address. |
-| `context.GROW_FS` | `str` | `/` | | Filesystems to grow. |
-| `context.PASSWORD` | `str` | `opennebula` | | Root's password. |
-| `context.SET_HOSTNAME` | `str` | name of the FE VM | | Hostname. |
-| `context.SSH_PUBLIC_KEY` | `str` | | (check below) | Root's extra authorized keys. |
+| Name | Type | Default | Example | Description |
+|--------------------------------------|--------|------------------------------------------|---------------------|-------------------------------------------------------------------|
+| `frontend_group` | `str` | `frontend` | | Custom name of the Frontend group in the inventory. |
+| `infra_group` | `str` | `infra` | | Custom name of the Infra group in the inventory. |
+| | | | | |
+| `runtime_dir` | `str` | `/var/one-deploy/` | | Directory used to store QCOW2 and ISO images. |
+| `os_image_url` | `str` | | | HTTP(S) link to Debian/RedHat-like image running `one-contextd`. |
+| `os_image_size` | `str` | `20G` | | The size to which one-deploy will **try** to adjust the OS image. |
+| `memory_KiB` | `str` | `2097152` | | Memory amount to be set in XML in Libvirt. |
+| `vnc_max_port` | `str` | `65535` | | Upper limit for VNC ports to start counting-down from. |
+| `passthrough_fs` | `list` | `[]` | (check below) | Shared HV filesystems to attach to the Front-end VMs. |
+| | | | | |
+| `vcpu_static` | `str` | `1` | | VCPU amount to be set in XML in Libvirt. |
+| `vcpu_shares` | `str` | `200` | | The total CPU share for the domain. |
+| | | | | |
+| `infra_bridge` | `str` | `br0` | | Pre-defined bridge interface to insert VM NICs to. |
+| `infra_vlan_id` | `str` | | | Optionally set the VLAN ID for the bridge. |
+| `dpdk_socket_path` | `str` | `/var/run/one/vhost-socks/frontend.sock` | | Path for existing socket when using OVS with DPDK. |
+| | | | | |
+| `infra_hostname` | `str` | | `n1a1` | Defines on which HV machine the Front-end VM should be deployed. |
+| `infra_xml_variant` | `str` | `default` | | Defined which domain XML variant will be used in Libvirt. |
+| | | | | |
+| `context.ETH0_DNS` | `str` | | `1.1.1.1` | DNS server. |
+| `context.ETH0_SEARCH_DOMAIN` | `str` | | `1.1.1.1` | DNS search domain. |
+| `context.ETH0_GATEWAY` | `str` | | `10.2.50.1` | Gateway. |
+| `context.ETH0_IP` | `str` | | `10.2.50.100` | IPv4 address to be set on eth0. |
+| `context.ETH0_MAC` | `str` | | `02:01:0a:02:32:64` | MAC address to be set on eth0 (**MUST** match MAC set in XML.) |
+| `context.ETH0_MASK` | `str` | | `255.255.255.0` | Network mask. |
+| `context.ETH0_NETWORK` | `str` | | `10.2.50.0` | Network address. |
+| `context.GROW_FS` | `str` | `/` | | Filesystems to grow. |
+| `context.PASSWORD` | `str` | `opennebula` | | Root's password. |
+| `context.SET_HOSTNAME` | `str` | name of the FE VM | | Hostname. |
+| `context.SSH_PUBLIC_KEY` | `str` | | (check below) | Root's extra authorized keys. |
+| `context.START_SCRIPT_BASE64` | `str` | | | Start script (base64-encoded automatically). |
**NOTE**: The `infra_hostname` and `context` dictionary should be set for members of the `frontend` group (please check the `inventory/infra.yml` example).
@@ -57,7 +59,7 @@ Example Playbook
- hosts: infra
vars:
- os_image_url: https://d24fmfybwxpuhu.cloudfront.net/ubuntu2204-6.10.0-1-20240514.qcow2
+ os_image_url: https://d24fmfybwxpuhu.cloudfront.net/ubuntu2404-7.4.0-0-20260714.qcow2
passthrough_fs:
- driver_type: virtiofs
source_dir: /var/lib/one/datastores
@@ -66,6 +68,140 @@ Example Playbook
- role: opennebula.deploy.helper.facts
- role: opennebula.deploy.infra
+Example Inventory
+-----------------
+
+ # --- VARIANT: default ---
+
+ infra:
+ vars:
+ os_image_url: http://10.2.11.1/images/ubuntu2404-7.4.0-0-20260714.qcow2
+ os_image_size: 20G
+ memory_KiB: 2097152 # 2 GiB
+ hosts:
+ u1q20: { ansible_host: 10.3.10.20 }
+ u1q30: { ansible_host: 10.3.10.30 }
+
+ frontend:
+ vars:
+ context:
+ ETH0_DNS: 10.3.10.1
+ ETH0_GATEWAY: 10.3.10.1
+ ETH0_MASK: 255.255.255.0
+ ETH0_NETWORK: 10.3.10.0
+ ETH0_IP: "{{ ansible_host }}"
+ PASSWORD: asd
+ SSH_PUBLIC_KEY: |-
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5ndznuZTNZ8u7FCYKgv6Q3/HUVxnaha3tPDUXPfIIw
+ hosts:
+ u1q40: { ansible_host: 10.3.10.40, infra_hostname: u1q20 }
+ u1q50: { ansible_host: 10.3.10.50, infra_hostname: u1q30 }
+
+ node:
+ hosts:
+ u1q20: { ansible_host: 10.3.10.20 }
+ u1q30: { ansible_host: 10.3.10.30 }
+
+ # --- VARIANT: openvswitch ---
+
+ infra:
+ vars:
+ os_image_url: http://10.2.11.1/images/ubuntu2404-7.4.0-0-20260714.qcow2
+ os_image_size: 20G
+ memory_KiB: 2097152 # 2 GiB
+ infra_xml_variant: openvswitch
+ infra_bridge: ovsbr0
+ hosts:
+ u1q20: { ansible_host: 10.3.10.20 }
+
+ frontend:
+ vars:
+ context:
+ ETH0_DNS: 10.3.10.1
+ ETH0_SEARCH_DOMAIN: u1q.lh
+ ETH0_GATEWAY: 10.3.10.1
+ ETH0_MASK: 255.255.255.0
+ ETH0_NETWORK: 10.3.10.0
+ ETH0_IP: "{{ ansible_host }}"
+ PASSWORD: asd
+ SSH_PUBLIC_KEY: |-
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5ndznuZTNZ8u7FCYKgv6Q3/HUVxnaha3tPDUXPfIIw
+ hosts:
+ u1q40: { ansible_host: 10.3.10.40, infra_hostname: u1q20 }
+
+ node:
+ vars:
+ ovs:
+ iface:
+ eth1: {}
+ br:
+ ovsbr0:
+ ports: [eth1]
+ hosts:
+ u1q20: { ansible_host: 10.3.10.20 }
+
+ # --- VARIANT: openvswitch_dpdk ---
+
+ infra:
+ vars:
+ os_image_url: http://10.2.11.1/images/ubuntu2404-7.4.0-0-20260714.qcow2
+ os_image_size: 20G
+ memory_KiB: 2097152 # 2 GiB
+ infra_xml_variant: openvswitch_dpdk
+ hosts:
+ u1q20: { ansible_host: 10.3.10.20, dpdk_socket_path: /var/run/one/vhost-socks/u1q40.sock }
+
+ frontend:
+ vars:
+ context:
+ ETH0_DNS: 10.3.10.1
+ ETH0_SEARCH_DOMAIN: u1q.lh
+ ETH0_GATEWAY: 10.3.10.1
+ ETH0_MASK: 255.255.255.0
+ ETH0_NETWORK: 10.3.10.0
+ ETH0_IP: "{{ ansible_host }}"
+ PASSWORD: asd
+ SSH_PUBLIC_KEY: |-
+ ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIF5ndznuZTNZ8u7FCYKgv6Q3/HUVxnaha3tPDUXPfIIw
+ hosts:
+ u1q40: { ansible_host: 10.3.10.40, infra_hostname: u1q20 }
+
+ node:
+ vars:
+ kernel_ok_to_reboot: true
+ kernel_params:
+ - default_hugepagesz: '1G'
+ - hugepages: '0:4,1:4'
+ - intel_iommu: 'on'
+ kernel_modules:
+ - load: vfio-pci
+ - load: vfio_iommu_type1
+ options: ['allow_unsafe_interrupts=1']
+
+ pci_devices:
+ - address: '0000:40:00.0'
+
+ ovs:
+ set:
+ - other_config:dpdk-init: 'true'
+ - other_config:dpdk-socket-mem: '2048,2048'
+ iface:
+ dpdk-p0:
+ set:
+ - type: dpdk
+ - options:dpdk-devargs: '0000:40:00.0'
+ dpdk-p1:
+ set:
+ - type: dpdkvhostuserclient
+ - options:vhost-server-path: "{{ dpdk_socket_path }}"
+ br:
+ ovsbr1:
+ ports: [dpdk-p0, dpdk-p1]
+ set:
+ - datapath_type: netdev
+ hosts:
+ u1q20: { ansible_host: 10.3.10.20 }
+
License
-------
diff --git a/roles/infra/defaults/main.yml b/roles/infra/defaults/main.yml
index 0d7ac641..72d44b4d 100644
--- a/roles/infra/defaults/main.yml
+++ b/roles/infra/defaults/main.yml
@@ -1,13 +1,229 @@
---
runtime_dir: /var/one-deploy/
-os_image_url: https://d24fmfybwxpuhu.cloudfront.net/ubuntu2204-6.8.1-1-20240131.qcow2
+os_image_url: https://d24fmfybwxpuhu.cloudfront.net/ubuntu2404-7.4.0-0-20260714.qcow2
os_image_size: 20G
-memory_KiB: 2097152 # 2 GiB
-vcpu_static: 1
vnc_max_port: 65535
-infra_bridge: br0
-infra_bridge_type: bridge
passthrough_fs: []
-cputune_shares_base: 200 # twice the OpenNebula's default (for CGv2)
-cputune_shares_max: 10000
-cputune_shares: "{{ ((vcpu_static | int) * (cputune_shares_base | int)) | round(0, 'ceil') }}"
+
+infra_bridge: br0
+
+# NOTE: We assume that no more than a single FE VM is deployed on a HV
+# (which should be considered a regular / default setup).
+# More FE VMs can be deployed on a HV of course, but in such a case,
+# please handle it directly in your inventory.
+dpdk_socket_path: /var/run/one/vhost-socks/frontend.sock
+
+memory_KiB: 2097152 # 2 GiB
+
+vcpu_static: 1
+vcpu_shares: "{{ ((vcpu_static | int) * 200) | int }}"
+
+infra_xml_variant: default
+
+infra_xml:
+ default:
+ - "{{ infra_xml_base.default }}"
+ - "{{ infra_xml_cputune.default }}"
+ - "{{ infra_xml_memoryBacking.default }}"
+ - "{{ infra_xml_interfaces.default }}"
+ - "{{ infra_xml_filesystems.default }}"
+ openvswitch:
+ - "{{ infra_xml_base.default }}"
+ - "{{ infra_xml_cputune.default }}"
+ - "{{ infra_xml_memoryBacking.default }}"
+ - "{{ infra_xml_interfaces.openvswitch }}"
+ - "{{ infra_xml_filesystems.default }}"
+ openvswitch_dpdk:
+ - "{{ infra_xml_base.default }}"
+ - "{{ infra_xml_cputune.default }}"
+ - "{{ infra_xml_memoryBacking.hugepages }}"
+ - "{{ infra_xml_interfaces.openvswitch_dpdk }}"
+ - "{{ infra_xml_filesystems.default }}"
+
+infra_xml_cputune:
+ default: |
+
+
+ {{ [vcpu_shares | int, 10000] | min }}
+
+
+
+infra_xml_memoryBacking:
+ default: |
+
+
+
+
+
+ hugepages: |
+
+
+
+
+
+
+
+infra_xml_interfaces:
+ default: |
+
+
+
+
+
+ {% if infra_vlan_id is defined %}
+
+
+
+ {% endif %}
+
+
+
+
+
+ openvswitch: |
+
+
+
+
+
+
+ {% if infra_vlan_id is defined %}
+
+
+
+ {% endif %}
+
+
+
+
+
+ openvswitch_dpdk: |
+
+
+
+
+
+
+ {% if infra_vlan_id is defined %}
+
+
+
+ {% endif %}
+
+
+
+
+
+
+infra_xml_filesystems:
+ default: |
+
+
+ {% for fs in passthrough_fs %}
+
+ {% if fs.driver_type is defined %}
+
+ {% endif %}
+
+
+
+ {% endfor %}
+
+
+
+infra_xml_base:
+ default: |
+
+ {{ frontend }}
+ {{ frontend }}
+
+ {{ memory_KiB }}
+ {{ vcpu_static }}
+
+
+
+ /machine
+
+
+ hvm
+
+
+
+
+
+
+
+
+
+
+
+ destroy
+ restart
+ destroy
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/roles/infra/tasks/deploy.yml b/roles/infra/tasks/deploy.yml
index fc83ec55..afbf9f98 100644
--- a/roles/infra/tasks/deploy.yml
+++ b/roles/infra/tasks/deploy.yml
@@ -90,7 +90,7 @@
- name: Compute VNC ports
ansible.builtin.set_fact:
- frontends_to_vnc_ports: >-
+ frontend_vnc_ports: >-
{{ dict(_frontends | zip(_ports)) }}
vars:
_ports: >-
@@ -103,9 +103,20 @@
- name: Define Front-end VMs
community.libvirt.virt:
command: define
- xml: "{{ lookup('template', 'frontend.xml.jinja') }}"
+ xml: >-
+ {{ _variant | map('ansible.utils.from_xml')
+ | map('combine', _fixup, recursive=true)
+ | combine(recursive=true)
+ | ansible.utils.to_xml(full_document=false) }}
autostart: true
vars:
+ _variant: >-
+ {{ infra_xml.get(infra_xml_variant, undef(hint='Unknown variant "{}"'.format(infra_xml_variant))) }}
+ # NOTE: This is required because (for example) '' produces '{"devices": null}'
+ # which cannot be merged correctly.
+ _fixup:
+ domain:
+ devices: {}
context: "{{ hostvars[frontend].context }}"
loop_control: { loop_var: frontend }
loop: "{{ infra_to_frontends[inventory_hostname] }}"
diff --git a/roles/infra/templates/context.sh.jinja b/roles/infra/templates/context.sh.jinja
index 77cac65e..24ad3ca3 100644
--- a/roles/infra/templates/context.sh.jinja
+++ b/roles/infra/templates/context.sh.jinja
@@ -1,18 +1,22 @@
# Context variables generated by one-deploy
DISK_ID='1'
-ETH0_DNS='{{ context.ETH0_DNS }}'
-ETH0_SEARCH_DOMAIN='{{ context.ETH0_SEARCH_DOMAIN | d("") }}'
-ETH0_GATEWAY='{{ context.ETH0_GATEWAY }}'
ETH0_IP='{{ context.ETH0_IP }}'
-ETH0_MAC='{{ context.ETH0_MAC | d("02:01:%02x:%02x:%02x:%02x" | format(*(context.ETH0_IP.split(".") | map("int")))) }}'
+ETH0_MAC='{{ context.ETH0_MAC | d(context.ETH0_IP | opennebula.deploy.ipv4_mac) }}'
ETH0_MASK='{{ context.ETH0_MASK }}'
ETH0_NETWORK='{{ context.ETH0_NETWORK }}'
+ETH0_GATEWAY='{{ context.ETH0_GATEWAY }}'
GROW_FS='{{ context.GROW_FS | d("/") }}'
NETWORK='YES'
PASSWORD='{{ context.PASSWORD | d("opennebula") }}'
SET_HOSTNAME='{{ context.SET_HOSTNAME | d(frontend) }}'
SSH_PUBLIC_KEY='{{ context.SSH_PUBLIC_KEY | d("") }}'
TARGET='hda'
-{% if context.START_SCRIPT_BASE64 is defined %}
+{% if context.ETH0_DNS | d('') %}
+ETH0_DNS='{{ context.ETH0_DNS }}'
+{% endif %}
+{% if context.ETH0_SEARCH_DOMAIN | d('') %}
+ETH0_SEARCH_DOMAIN='{{ context.ETH0_SEARCH_DOMAIN }}'
+{% endif %}
+{% if context.START_SCRIPT_BASE64 | d('') %}
START_SCRIPT_BASE64='{{ context.START_SCRIPT_BASE64 | b64encode }}'
{% endif %}
diff --git a/roles/infra/templates/frontend.xml.jinja b/roles/infra/templates/frontend.xml.jinja
deleted file mode 100644
index b407e975..00000000
--- a/roles/infra/templates/frontend.xml.jinja
+++ /dev/null
@@ -1,146 +0,0 @@
-
- {{ frontend }}
- {{ frontend }}
-
- {{ memory_KiB }}
- {{ vcpu_static }}
-
-
- {{ (cputune_shares if (cputune_shares | int) < (cputune_shares_max | int) else cputune_shares_max) | int }}
-
-
-
- /machine
-
-
- hvm
-
-
-
-
-
-
-
-
-
-
-
- destroy
- restart
- destroy
-
-{% set use_dpdk = (infra_bridge_type is defined and infra_bridge_type == 'openvswitch_dpdk') %}
-{% set use_virtiofs = ('virtiofs' in (passthrough_fs | map(attribute='driver_type') | map('default', None) | select | map('lower'))) %}
-
-{% if use_dpdk or use_virtiofs %}
-
-{% if use_dpdk %}
-
-{% endif %}
-{% if use_virtiofs and not use_dpdk %}
-
-{% endif %}
-
-
-{% endif %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-{% for fs in passthrough_fs %}
-
-{% if fs.driver_type is defined and fs.driver_type is truthy %}
-
-{% endif %}
-
-
-
-{% endfor %}
-
-
-
-
-
-{% if infra_bridge_type is defined and infra_bridge_type in ['bridge', 'openvswitch', 'openvswitch_dpdk'] %}
-{% if infra_bridge_type in ['bridge', 'openvswitch'] %}
-
-
-
-{% elif infra_bridge_type == 'openvswitch_dpdk' %}
-
-
-{% endif %}
-
-{% if infra_bridge_type == 'openvswitch' %}
-
-{% endif %}
-{% if infra_vlan_id is defined and infra_vlan_id %}
-
-
-
-{% endif %}
-
-
-
-
-{% endif %}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-