diff --git a/README.md b/README.md index ad87d60f85..eec6b96e45 100644 --- a/README.md +++ b/README.md @@ -157,6 +157,18 @@ OVNKubernetes supports the following configuration options, all of which are opt * `egressIPConfig`: holds the configuration for EgressIP options. * `reachabilityTotalTimeoutSeconds`: Set EgressIP node reachability total timeout in seconds, 0 means disable reachability check and the default is 1 second. +#### DPU Host Mode Support + +OVN-Kubernetes supports specialized hardware deployments such as DPU (Data Processing Unit) hosts through the `OVN_NODE_MODE` environment variable. In `dpu-host` mode, certain features are automatically disabled on those nodes regardless of cluster-wide configuration: + +- Egress IP and related features (egress firewall, egress QoS, egress service) +- Multicast support +- Multi-external gateway support +- Multi-network policies and admin network policies +- Network segmentation features + +This per-node feature enforcement is implemented through conditional logic in the startup scripts, allowing the same cluster configuration to work across heterogeneous node types. For detailed information about node modes and the technical implementation, see `docs/ovn_node_mode.md`. + These configuration flags are only in the Operator configuration object. Example from the `manifests/cluster-network-03-config.yml` file: diff --git a/bindata/network/ovn-kubernetes/common/008-script-lib.yaml b/bindata/network/ovn-kubernetes/common/008-script-lib.yaml index b244e6b3f8..f9fd9a6e32 100644 --- a/bindata/network/ovn-kubernetes/common/008-script-lib.yaml +++ b/bindata/network/ovn-kubernetes/common/008-script-lib.yaml @@ -539,8 +539,16 @@ data: echo "I$(date "+%m%d %H:%M:%S.%N") - starting ovnkube-node" + # enable egress ip, egress firewall, egress qos, egress service + egress_features_enable_flag="--enable-egress-ip=true --enable-egress-firewall=true --enable-egress-qos=true --enable-egress-service=true" init_ovnkube_controller="--init-ovnkube-controller ${K8S_NODE}" - gateway_interface="br-ex" + multi_external_gateway_enable_flag="--enable-multi-external-gateway=true" + gateway_interface=br-ex + + # enable multicast + enable_multicast_flag="--enable-multicast" + + # Use OVN_NODE_MODE environment variable, default to "full" if not set OVN_NODE_MODE=${OVN_NODE_MODE:-full} # We check only dpu-host mode and not smart-nic mode here as currently we do not support it yet # Once we support it, we will need to check for it here and add relevant code. @@ -549,10 +557,17 @@ data: # https://github.com/ovn-kubernetes/ovn-kubernetes/pull/5327/files gateway_interface="derive-from-mgmt-port" ovnkube_node_mode="--ovnkube-node-mode dpu-host" + # disable egress ip for dpu-host mode as it is not supported + egress_features_enable_flag="" + + # disable multicast for dpu-host mode as it is not supported + enable_multicast_flag="" # disable init-ovnkube-controller for dpu-host mode as it is not supported init_ovnkube_controller="" + # disable multi-external-gateway for dpu-host mode as it is not supported + multi_external_gateway_enable_flag="" fi if [[ -n "${OVNKUBE_NODE_LEASE_RENEW_INTERVAL}" ]]; then @@ -604,6 +619,17 @@ data: node_mgmt_port_netdev_flags="$node_mgmt_port_netdev_flags --ovnkube-node-mgmt-port-dp-resource-name ${OVNKUBE_NODE_MGMT_PORT_DP_RESOURCE_NAME}" fi + multi_network_enabled_flag= + if [[ "{{.OVN_MULTI_NETWORK_ENABLE}}" == "true" && "${OVN_NODE_MODE}" != "dpu-host" ]]; then + multi_network_enabled_flag="--enable-multi-network" + fi + + network_segmentation_enabled_flag= + if [[ "${OVN_NODE_MODE}" != "dpu-host" ]]; then + multi_network_enabled_flag="--enable-multi-network" + network_segmentation_enabled_flag="--enable-network-segmentation" + fi + route_advertisements_enable_flag= if [[ "{{.OVN_ROUTE_ADVERTISEMENTS_ENABLE}}" == "true" ]]; then route_advertisements_enable_flag="--enable-route-advertisements" @@ -613,12 +639,34 @@ data: if [[ "{{.OVN_EVPN_ENABLE}}" == "true" ]]; then evpn_enable_flag="--enable-evpn" fi + + preconfigured_udn_addresses_enable_flag="--enable-preconfigured-udn-addresses" + + network_connect_enabled_flag= + if [[ "{{.OVN_NETWORK_CONNECT_ENABLE}}" == "true" ]]; then + network_connect_enabled_flag="--enable-network-connect" + fi network_observability_enabled_flag= if [[ "{{.OVN_OBSERVABILITY_ENABLE}}" == "true" ]]; then network_observability_enabled_flag="--enable-observability" fi + multi_network_policy_enabled_flag= + if [[ "{{.OVN_MULTI_NETWORK_POLICY_ENABLE}}" == "true"&& "${OVN_NODE_MODE}" != "dpu-host" ]]; then + multi_network_policy_enabled_flag="--enable-multi-networkpolicy" + fi + + admin_network_policy_enabled_flag= + if [[ "${OVN_NODE_MODE}" != "dpu-host" ]]; then + admin_network_policy_enabled_flag="--enable-admin-network-policy" + fi + + dns_name_resolver_enabled_flag= + if [[ "{{.DNS_NAME_RESOLVER_ENABLE}}" == "true" ]]; then + dns_name_resolver_enabled_flag="--enable-dns-name-resolver" + fi + # If IP Forwarding mode is global set it in the host here. IPv6 IP Forwarding shuld be # enabled for all interfaces at all times if cluster is configured as single stack IPv6 # or dual stack. This will be taken care by ovn-kubernetes(ovn-org/ovn-kubernetes#4376). @@ -705,9 +753,17 @@ data: --export-ovs-metrics \ --disable-snat-multiple-gws \ ${export_network_flows_flags} \ + ${multi_network_enabled_flag} \ + ${network_segmentation_enabled_flag} \ + ${network_connect_enabled_flag} \ ${route_advertisements_enable_flag} \ ${evpn_enable_flag} \ + ${preconfigured_udn_addresses_enable_flag} \ + ${multi_network_policy_enabled_flag} \ + ${admin_network_policy_enabled_flag} \ + ${dns_name_resolver_enabled_flag} \ ${network_observability_enabled_flag} \ + ${enable_multicast_flag} \ --zone ${K8S_NODE} \ ${enable_interconnect_flag} \ --enable-multicast \ @@ -724,5 +780,6 @@ data: ${ovn_v6_masquerade_subnet_opt} \ ${ovn_v4_transit_switch_subnet_opt} \ ${ovn_v6_transit_switch_subnet_opt} \ - ${dpu_lease_flags} + ${egress_features_enable_flag} \ + ${multi_external_gateway_enable_flag} } diff --git a/bindata/network/ovn-kubernetes/managed/004-config.yaml b/bindata/network/ovn-kubernetes/managed/004-config.yaml index 5c790c9c6e..0033fe209a 100644 --- a/bindata/network/ovn-kubernetes/managed/004-config.yaml +++ b/bindata/network/ovn-kubernetes/managed/004-config.yaml @@ -33,14 +33,12 @@ data: dns-service-name="dns-default" [ovnkubernetesfeature] - enable-egress-ip=true - enable-egress-firewall=true - enable-egress-qos=true - enable-egress-service=true {{- if .ReachabilityNodePort }} egressip-node-healthcheck-port={{.ReachabilityNodePort}} {{- end }} + {{- if not .OVN_MULTI_NETWORK_ENABLE }} enable-multi-network=true + {{- end }} enable-network-segmentation=true enable-preconfigured-udn-addresses=true @@ -49,6 +47,7 @@ data: {{- end }} enable-admin-network-policy=true enable-multi-external-gateway=true + enable-multicast=true {{- if .DNS_NAME_RESOLVER_ENABLE }} enable-dns-name-resolver=true {{- end }} @@ -128,7 +127,12 @@ data: {{- if .ReachabilityNodePort }} egressip-node-healthcheck-port={{.ReachabilityNodePort}} {{- end }} +{{- if .OVN_MULTI_NETWORK_ENABLE }} + enable-multi-network=true +{{- end }} + {{- if not .OVN_MULTI_NETWORK_ENABLE }} enable-multi-network=true + {{- end }} enable-network-segmentation=true enable-preconfigured-udn-addresses=true {{- if .OVN_MULTI_NETWORK_POLICY_ENABLE }} @@ -136,6 +140,7 @@ data: {{- end }} enable-admin-network-policy=true enable-multi-external-gateway=true + enable-multicast=true {{- if .DNS_NAME_RESOLVER_ENABLE }} enable-dns-name-resolver=true {{- end }} diff --git a/bindata/network/ovn-kubernetes/managed/ovnkube-control-plane.yaml b/bindata/network/ovn-kubernetes/managed/ovnkube-control-plane.yaml index 55817fe7ce..0e50562b17 100644 --- a/bindata/network/ovn-kubernetes/managed/ovnkube-control-plane.yaml +++ b/bindata/network/ovn-kubernetes/managed/ovnkube-control-plane.yaml @@ -183,8 +183,19 @@ spec: ovn_v6_masquerade_subnet_opt="--gateway-v6-masquerade-subnet {{.V6MasqueradeSubnet}}" fi + dns_name_resolver_enabled_flag= + if [[ "{{.DNS_NAME_RESOLVER_ENABLE}}" == "true" ]]; then + dns_name_resolver_enabled_flag="--enable-dns-name-resolver" + fi + persistent_ips_enabled_flag="--enable-persistent-ips" + # This is needed so that converting clusters from GA to TP + # will rollout control plane pods as well + network_segmentation_enabled_flag= + multi_network_enabled_flag="--enable-multi-network" + network_segmentation_enabled_flag="--enable-network-segmentation" + route_advertisements_enable_flag= if [[ "{{.OVN_ROUTE_ADVERTISEMENTS_ENABLE}}" == "true" ]]; then route_advertisements_enable_flag="--enable-route-advertisements" @@ -195,6 +206,22 @@ spec: evpn_enable_flag="--enable-evpn" fi + preconfigured_udn_addresses_enable_flag="--enable-preconfigured-udn-addresses" + + # Enable multi-network policy if configured (control-plane always full mode) + multi_network_policy_enabled_flag= + if [[ "{{.OVN_MULTI_NETWORK_POLICY_ENABLE}}" == "true" ]]; then + multi_network_policy_enabled_flag="--enable-multi-networkpolicy" + fi + + # Enable admin network policy if configured (control-plane always full mode) + admin_network_policy_enabled_flag="--enable-admin-network-policy" + + network_connect_enabled_flag= + if [[ "{{.OVN_NETWORK_CONNECT_ENABLE}}" == "true" ]]; then + network_connect_enabled_flag="--enable-network-connect" + fi + # DROP: remove when older OVN-K images that require --enable-interconnect are no longer supported enable_interconnect_flag= if /usr/bin/ovnkube --help 2>&1 | grep -q -- '--enable-interconnect'; then @@ -220,9 +247,22 @@ spec: ${ovn_v6_transit_switch_subnet_opt} \ ${ovn_v4_masquerade_subnet_opt} \ ${ovn_v6_masquerade_subnet_opt} \ + ${dns_name_resolver_enabled_flag} \ ${persistent_ips_enabled_flag} \ + ${multi_network_enabled_flag} \ + ${network_segmentation_enabled_flag} \ + ${network_connect_enabled_flag} \ ${route_advertisements_enable_flag} \ - ${evpn_enable_flag} + ${evpn_enable_flag} \ + ${preconfigured_udn_addresses_enable_flag} \ + --enable-egress-ip=true \ + --enable-egress-firewall=true \ + --enable-egress-qos=true \ + --enable-egress-service=true \ + --enable-multicast \ + --enable-multi-external-gateway=true \ + ${multi_network_policy_enabled_flag} \ + ${admin_network_policy_enabled_flag} volumeMounts: - mountPath: /run/ovnkube-config/ name: ovnkube-config diff --git a/bindata/network/ovn-kubernetes/self-hosted/004-config.yaml b/bindata/network/ovn-kubernetes/self-hosted/004-config.yaml index 6c1944f7b8..7131953bb5 100644 --- a/bindata/network/ovn-kubernetes/self-hosted/004-config.yaml +++ b/bindata/network/ovn-kubernetes/self-hosted/004-config.yaml @@ -36,17 +36,16 @@ data: dns-service-name="dns-default" [ovnkubernetesfeature] - enable-egress-ip=true - enable-egress-firewall=true - enable-egress-qos=true - enable-egress-service=true + {{- if .ReachabilityTotalTimeoutSeconds }} egressip-reachability-total-timeout={{.ReachabilityTotalTimeoutSeconds}} {{- end }} {{- if .ReachabilityNodePort }} egressip-node-healthcheck-port={{.ReachabilityNodePort}} {{- end }} + {{- if not .OVN_MULTI_NETWORK_ENABLE }} enable-multi-network=true + {{- end }} enable-network-segmentation=true enable-preconfigured-udn-addresses=true {{- if .OVN_MULTI_NETWORK_POLICY_ENABLE }} @@ -54,6 +53,7 @@ data: {{- end }} enable-admin-network-policy=true enable-multi-external-gateway=true + enable-multicast=true {{- if .DNS_NAME_RESOLVER_ENABLE }} enable-dns-name-resolver=true {{- end }} diff --git a/bindata/network/ovn-kubernetes/self-hosted/ovnkube-control-plane.yaml b/bindata/network/ovn-kubernetes/self-hosted/ovnkube-control-plane.yaml index 3521ed08ac..f793e07ec0 100644 --- a/bindata/network/ovn-kubernetes/self-hosted/ovnkube-control-plane.yaml +++ b/bindata/network/ovn-kubernetes/self-hosted/ovnkube-control-plane.yaml @@ -130,8 +130,19 @@ spec: ovn_v6_masquerade_subnet_opt="--gateway-v6-masquerade-subnet {{.V6MasqueradeSubnet}}" fi + dns_name_resolver_enabled_flag= + if [[ "{{.DNS_NAME_RESOLVER_ENABLE}}" == "true" ]]; then + dns_name_resolver_enabled_flag="--enable-dns-name-resolver" + fi + persistent_ips_enabled_flag="--enable-persistent-ips" + # This is needed so that converting clusters from GA to TP + # will rollout control plane pods as well + network_segmentation_enabled_flag= + multi_network_enabled_flag="--enable-multi-network" + network_segmentation_enabled_flag="--enable-network-segmentation" + route_advertisements_enable_flag= if [[ "{{.OVN_ROUTE_ADVERTISEMENTS_ENABLE}}" == "true" ]]; then route_advertisements_enable_flag="--enable-route-advertisements" @@ -141,6 +152,22 @@ spec: if [[ "{{.OVN_EVPN_ENABLE}}" == "true" ]]; then evpn_enable_flag="--enable-evpn" fi + + preconfigured_udn_addresses_enable_flag="--enable-preconfigured-udn-addresses" + + # Enable multi-network policy if configured (control-plane always full mode) + multi_network_policy_enabled_flag= + if [[ "{{.OVN_MULTI_NETWORK_POLICY_ENABLE}}" == "true" ]]; then + multi_network_policy_enabled_flag="--enable-multi-networkpolicy" + fi + + # Enable admin network policy if configured (control-plane always full mode) + admin_network_policy_enabled_flag="--enable-admin-network-policy" + + network_connect_enabled_flag= + if [[ "{{.OVN_NETWORK_CONNECT_ENABLE}}" == "true" ]]; then + network_connect_enabled_flag="--enable-network-connect" + fi if [ "{{.OVN_GATEWAY_MODE}}" == "shared" ]; then gateway_mode_flags="--gateway-mode shared" @@ -173,10 +200,23 @@ spec: ${ovn_v6_transit_switch_subnet_opt} \ ${ovn_v4_masquerade_subnet_opt} \ ${ovn_v6_masquerade_subnet_opt} \ + ${dns_name_resolver_enabled_flag} \ ${persistent_ips_enabled_flag} \ + ${multi_network_enabled_flag} \ + ${network_segmentation_enabled_flag} \ ${gateway_mode_flags} \ + ${network_connect_enabled_flag} \ ${route_advertisements_enable_flag} \ - ${evpn_enable_flag} + ${evpn_enable_flag} \ + ${preconfigured_udn_addresses_enable_flag} \ + --enable-egress-ip=true \ + --enable-egress-firewall=true \ + --enable-egress-qos=true \ + --enable-egress-service=true \ + --enable-multicast \ + --enable-multi-external-gateway=true \ + ${multi_network_policy_enabled_flag} \ + ${admin_network_policy_enabled_flag} volumeMounts: - mountPath: /run/ovnkube-config/ name: ovnkube-config diff --git a/docs/architecture.md b/docs/architecture.md index fbcdaeb5c9..2ff3abea19 100644 --- a/docs/architecture.md +++ b/docs/architecture.md @@ -141,6 +141,12 @@ The Network operator needs to make sure that the input configuration doesn't cha The persisted configuration must **make all defaults explicit**. This protects against inadvertent code changes that could destabilize an existing cluster. +### Per-Node Configuration + +For certain specialized deployments (e.g., DPU host nodes), some features need to be disabled on a per-node basis even when enabled cluster-wide. Since ConfigMap values cannot be reliably overridden per-node, the CNO implements per-node feature enforcement through conditional logic in the startup scripts. + +The `OVN_NODE_MODE` environment variable is injected into `ovnkube-node` pods and consumed by the startup script (`008-script-lib.yaml`) to conditionally enable or disable features based on the node's operational mode. This ensures that unsupported features are deterministically disabled on specialized hardware regardless of cluster-wide configuration. + ## Egress Router **Input:** `EgressRouter.network.operator.openshift.io` diff --git a/docs/operands.md b/docs/operands.md index 64016fff6b..a64a00bd0d 100644 --- a/docs/operands.md +++ b/docs/operands.md @@ -91,6 +91,26 @@ configuration object (which in turn is copied there from the configuration) is "`OVNKubernetes`". If the specified network type is not "`OVNKubernetes`", the CNO will not render any network plugin. +### OVN-Kubernetes Node Modes + +OVN-Kubernetes supports different node operational modes through the `OVN_NODE_MODE` +environment variable. This allows per-node feature enforcement, particularly for +specialized hardware like DPU (Data Processing Unit) hosts where certain features +must be disabled. + +The startup script (`008-script-lib.yaml`) contains conditional logic that adjusts +feature enablement based on the node mode: + +- **`full` mode (default)**: All features enabled as configured +- **`dpu-host` mode**: Certain features like egress IP, multicast, multi-network + policies, and admin network policies are automatically disabled regardless of + cluster-wide configuration + +This approach was necessary because ConfigMap values (`004-config.yaml`) cannot be +reliably overridden on a per-node basis, but startup script logic can be conditional. + +For detailed information, see `docs/ovn_node_mode.md`. + ## Multus Multus is deployed as long as `.spec.disableMultiNetwork` is not set. diff --git a/docs/ovn_node_mode.md b/docs/ovn_node_mode.md index b511eea598..d64861b10b 100644 --- a/docs/ovn_node_mode.md +++ b/docs/ovn_node_mode.md @@ -1,18 +1,100 @@ -## OVN node modes +## OVN node modes and per-node feature enforcement -The `OVN_NODE_MODE` environment variable is injected into the `ovnkube-node` Pod to identify the node's operational mode. It is consumed by the startup script rendered from `bindata/network/ovn-kubernetes/common/008-script-lib.yaml`. +This change introduces `OVN_NODE_MODE` as an environment variable injected into the `ovnkube-node` Pod. The value is consumed by the startup script rendered from `bindata/network/ovn-kubernetes/common/008-script-lib.yaml` to tailor behavior per node mode at runtime. + +### Why move flags from the config map into the script? + +- The INI-based config (`004-config.yaml`) is rendered cluster-wide. Those values are not reliably overridable on a per-node or per-mode basis. +- In DPU host mode, some features are not supported and must be deterministically disabled on those nodes even if the cluster-wide config enables them. +- Moving the enablement logic to the entrypoint script allows per-node enforcement using `OVN_NODE_MODE`, preventing unsupported features from being turned on by cluster defaults. ### Behavior by mode - `full` (default): - - `gateway_interface="br-ex"` + - `gateway_interface=br-ex` - `init_ovnkube_controller="--init-ovnkube-controller ${K8S_NODE}"` + - `enable_multicast_flag="--enable-multicast"` + - `egress_features_enable_flag="--enable-egress-ip=true --enable-egress-firewall=true --enable-egress-qos=true --enable-egress-service=true"` + - `multi_external_gateway_enable_flag="--enable-multi-external-gateway=true"` - `dpu-host`: - - `gateway_interface="derive-from-mgmt-port"` ([ovn-kubernetes#5327](https://github.com/ovn-kubernetes/ovn-kubernetes/pull/5327)) + - `gateway_interface="derive-from-mgmt-port"` - `ovnkube_node_mode="--ovnkube-node-mode dpu-host"` - `init_ovnkube_controller=""` (disabled) + - `enable_multicast_flag=""` (disabled) + - `egress_features_enable_flag=""` (egress IP and related features disabled) + - `multi_external_gateway_enable_flag=""` (multi-external gateway disabled) + - Multi-network, network segmentation, and multi-network policy/admin network policy are gated and not enabled in this mode. + +### Manifests + +- `ovnkube-node.yaml` (managed and self-hosted) now inject `OVN_NODE_MODE` into the Pod env so the script can apply mode-aware logic. +- `ovnkube-control-plane.yaml` (managed and self-hosted) have feature flags moved from ConfigMap to inline script logic. +- `004-config.yaml` drops hard-coded feature enables that conflict with per-node enforcement. + +**Note**: Control-plane components always run in "full" mode since they don't run on DPU hosts and need all features enabled for cluster coordination. Always-enabled features (egress, multicast, multi-external-gateway) are added directly to the command line, while conditional features use script variables. + +### Implementation Details + +#### Environment Variable Injection + +The `OVN_NODE_MODE` environment variable is injected into `ovnkube-node` pods through the DaemonSet specification in both managed and self-hosted variants: + +- `bindata/network/ovn-kubernetes/managed/ovnkube-node.yaml` +- `bindata/network/ovn-kubernetes/self-hosted/ovnkube-node.yaml` + +The value is typically derived from node labels or annotations that identify the node's hardware type. + +#### Script Logic Flow + +The startup script (`008-script-lib.yaml`) implements the following conditional logic: + +```bash +if [[ "${OVN_NODE_MODE}" != "dpu-host" ]]; then + # Enable features for full mode + egress_ip_enable_flag="--enable-egress-ip=true --enable-egress-firewall=true --enable-egress-qos=true --enable-egress-service=true" + enable_multicast_flag="--enable-multicast" + # ... other feature flags +else + # DPU host mode - disable features + egress_ip_enable_flag="" + enable_multicast_flag="" + gateway_interface="derive-from-mgmt-port" + ovnkube_node_mode="--ovnkube-node-mode dpu-host" +fi +``` + +#### Feature Flag Mapping + +The following table shows how cluster-wide configuration translates to per-node enforcement: + +| Feature | ConfigMap (004-config.yaml) | Script Variable | DPU Host Behavior | +|---------|----------------------------|-----------------|-------------------| +| Egress IP | `enable-egress-ip=true` | `egress_features_enable_flag` | Force disabled | +| Multicast | `enable-multicast=true` | `enable_multicast_flag` | Force disabled | +| Multi External Gateway | `enable-multi-external-gateway=true` | `multi_external_gateway_enable_flag` | Force disabled | +| Multi-network | `enable-multi-network=true` | `multi_network_enabled_flag` | Conditionally disabled | +| Admin Network Policy | `enable-admin-network-policy=true` | `admin_network_policy_enabled_flag` | Conditionally disabled | +| Network Segmentation | `enable-network-segmentation=true` | `network_segmentation_enabled_flag` | Conditionally disabled | + +### Testing + +- Unit tests assert that the rendered script contains the correct assignments for `gateway_interface`, `init_ovnkube_controller`, `enable_multicast_flag`, `egress_features_enable_flag`, and `ovnkube_node_mode` across modes. +- The comprehensive test `TestOVNKubernetesScriptLibCombined` validates all conditional logic paths and feature flag assignments for node scripts. +- The test `TestOVNKubernetesControlPlaneFlags` validates that control-plane scripts have: + - Always-enabled features added directly to the command line (egress, multicast, multi-external-gateway) + - Conditional features handled via script variables (multi-network, network policies, etc.) + - Correct multi-network enablement logic (OVN_MULTI_NETWORK_ENABLE) +- Tests verify both positive cases (features enabled in full mode) and negative cases (features disabled in DPU host mode). + +### Migration Notes + +When upgrading clusters that previously relied on ConfigMap-based feature control: + +1. Existing ConfigMap values in `004-config.yaml` have been removed for features that require per-node control +2. The startup scripts (both node and control-plane) now contain the authoritative feature enablement logic +3. Control-plane components automatically enable all features (always run in "full" mode) +4. DPU host nodes will automatically have incompatible features disabled regardless of previous ConfigMap settings +5. No manual intervention is required - the migration is handled automatically during the upgrade process -### Feature configuration -Feature enablement (egress IP, multicast, multi-network, network segmentation, admin network policy, etc.) is managed through the cluster-wide ConfigMap (`004-config.yaml`) which is passed to ovnkube via `--config-file`. These features are not gated per node mode. diff --git a/pkg/network/ovn_kubernetes.go b/pkg/network/ovn_kubernetes.go index 3467c702a4..bb75f79c7d 100644 --- a/pkg/network/ovn_kubernetes.go +++ b/pkg/network/ovn_kubernetes.go @@ -461,8 +461,13 @@ func renderOVNKubernetes(conf *operv1.NetworkSpec, bootstrapResult *bootstrap.Bo data.Data["NorthdThreads"] = 1 data.Data["IsSNO"] = bootstrapResult.OVN.ControlPlaneReplicaCount == 1 + data.Data["OVN_MULTI_NETWORK_ENABLE"] = true data.Data["OVN_MULTI_NETWORK_POLICY_ENABLE"] = false - if conf.UseMultiNetworkPolicy != nil && *conf.UseMultiNetworkPolicy { + if conf.DisableMultiNetwork != nil && *conf.DisableMultiNetwork { + data.Data["OVN_MULTI_NETWORK_ENABLE"] = false + } else if conf.UseMultiNetworkPolicy != nil && *conf.UseMultiNetworkPolicy { + // Multi-network policy support requires multi-network support to be + // enabled data.Data["OVN_MULTI_NETWORK_POLICY_ENABLE"] = true } diff --git a/pkg/network/ovn_kubernetes_test.go b/pkg/network/ovn_kubernetes_test.go index 6c06d16f16..8b3fad953d 100644 --- a/pkg/network/ovn_kubernetes_test.go +++ b/pkg/network/ovn_kubernetes_test.go @@ -97,12 +97,10 @@ func TestRenderOVNKubernetes(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -223,12 +221,10 @@ func TestRenderOVNKubernetesIPv6(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -246,12 +242,10 @@ func TestRenderOVNKubernetesIPv6(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -312,6 +306,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -358,6 +353,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=local @@ -418,6 +414,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=local @@ -480,6 +477,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=local @@ -541,6 +539,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=local @@ -602,6 +601,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -652,6 +652,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -705,6 +706,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -752,6 +754,7 @@ enable-preconfigured-udn-addresses=true enable-multi-networkpolicy=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -800,6 +803,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -895,6 +899,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true enable-dns-name-resolver=true [gateway] @@ -942,6 +947,7 @@ enable-network-segmentation=true enable-preconfigured-udn-addresses=true enable-admin-network-policy=true enable-multi-external-gateway=true +enable-multicast=true [gateway] mode=shared @@ -1042,12 +1048,10 @@ logfile-maxage=0`, bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: tc.controlPlaneReplicaCount, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -2246,12 +2250,10 @@ status: ControlPlaneUpdateStatus: controlPlaneStatus, NodeUpdateStatus: nodeStatus, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -2553,12 +2555,10 @@ func TestRenderOVNKubernetesEnableIPsec(t *testing.T) { IPFamilyMode: names.IPFamilySingleStack, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -2782,12 +2782,10 @@ func TestRenderOVNKubernetesEnableIPsecForHostedControlPlane(t *testing.T) { IPFamilyMode: names.IPFamilySingleStack, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -2885,12 +2883,10 @@ func TestRenderOVNKubernetesIPsecUpgradeWithMachineConfig(t *testing.T) { IsOVNIPsecActiveOrRollingOut: true, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -2999,12 +2995,10 @@ func TestRenderOVNKubernetesIPsecUpgradeWithNoMachineConfig(t *testing.T) { IsOVNIPsecActiveOrRollingOut: true, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -3149,12 +3143,10 @@ func TestRenderOVNKubernetesIPsecUpgradeWithHypershiftHostedCluster(t *testing.T IsOVNIPsecActiveOrRollingOut: true, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -3254,12 +3246,10 @@ func TestRenderOVNKubernetesDisableIPsec(t *testing.T) { IsOVNIPsecActiveOrRollingOut: true, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -3466,12 +3456,10 @@ func TestRenderOVNKubernetesEnableIPsecWithUserInstalledIPsecMachineConfigs(t *t IPFamilyMode: names.IPFamilySingleStack, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -3614,12 +3602,10 @@ func TestRenderOVNKubernetesDisableIPsecWithUserInstalledIPsecMachineConfigs(t * IsOVNIPsecActiveOrRollingOut: true, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -3755,12 +3741,10 @@ func TestRenderOVNKubernetesDualStackPrecedenceOverUpgrade(t *testing.T) { IPFamilyMode: names.IPFamilySingleStack, }, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -4000,12 +3984,10 @@ func TestRenderOVNKubernetesEnablePersistentIPs(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -4180,12 +4162,10 @@ func Test_renderOVNKubernetes(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -4323,12 +4303,10 @@ func TestRenderOVNKubernetes_AdvertisedUDNIsolationModeOverride(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -4366,12 +4344,10 @@ func TestRenderOVNKubernetes_OpenFlowProbeOverride(t *testing.T) { bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ ControlPlaneReplicaCount: 3, OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - DpuNodeLeaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, + DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, + DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, + SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, + MgmtPortResourceName: "", HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ Enabled: false, }, @@ -4780,85 +4756,6 @@ func TestRenderOVNKubernetesNoOverlay(t *testing.T) { } } -func TestDpuLeaseConfig(t *testing.T) { - for _, tc := range []struct { - name string - leaseRenewInterval int - leaseDuration int - expectedRenewInterval string - expectedDuration string - expectPresent bool - }{ - { - name: "custom values are rendered", - leaseRenewInterval: 15, - leaseDuration: 60, - expectedRenewInterval: "15", - expectedDuration: "60", - expectPresent: true, - }, - { - name: "defaults are rendered", - leaseRenewInterval: DPU_NODE_LEASE_RENEW_INTERVAL_DEFAULT, - leaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, - expectedRenewInterval: "10", - expectedDuration: "40", - expectPresent: true, - }, - { - name: "zero renew interval disables health check", - leaseRenewInterval: 0, - leaseDuration: DPU_NODE_LEASE_DURATION_DEFAULT, - expectedRenewInterval: "0", - expectedDuration: strconv.Itoa(DPU_NODE_LEASE_DURATION_DEFAULT), - expectPresent: true, - }, - } { - t.Run(tc.name, func(t *testing.T) { - g := NewGomegaWithT(t) - - crd := OVNKubernetesConfig.DeepCopy() - config := &crd.Spec - errs := validateOVNKubernetes(config) - g.Expect(errs).To(HaveLen(0)) - fillDefaults(config, nil) - - bootstrapResult := fakeBootstrapResult() - bootstrapResult.OVN = bootstrap.OVNBootstrapResult{ - ControlPlaneReplicaCount: 3, - OVNKubernetesConfig: &bootstrap.OVNConfigBoostrapResult{ - DpuHostModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU_HOST, - DpuModeLabel: OVN_NODE_SELECTOR_DEFAULT_DPU, - SmartNicModeLabel: OVN_NODE_SELECTOR_DEFAULT_SMART_NIC, - MgmtPortResourceName: "", - DpuNodeLeaseRenewInterval: tc.leaseRenewInterval, - DpuNodeLeaseDuration: tc.leaseDuration, - DpuHostModeNodes: []string{"dpu-host-node-1"}, - HyperShiftConfig: &bootstrap.OVNHyperShiftBootstrapResult{ - Enabled: false, - }, - }, - } - - featureGatesCNO := getDefaultFeatureGates() - fakeClient := cnofake.NewFakeClient() - objs, _, err := renderOVNKubernetes(config, bootstrapResult, manifestDirOvn, fakeClient, featureGatesCNO) - g.Expect(err).NotTo(HaveOccurred()) - - envVars := extractDaemonSetEnvVars(g, objs, "ovnkube-node-dpu-host", "ovnkube-controller") - if tc.expectPresent { - g.Expect(envVars["OVNKUBE_NODE_LEASE_RENEW_INTERVAL"]).To(Equal(tc.expectedRenewInterval)) - g.Expect(envVars["OVNKUBE_NODE_LEASE_DURATION"]).To(Equal(tc.expectedDuration)) - } else { - _, hasInterval := envVars["OVNKUBE_NODE_LEASE_RENEW_INTERVAL"] - _, hasDuration := envVars["OVNKUBE_NODE_LEASE_DURATION"] - g.Expect(hasInterval).To(BeFalse(), "OVNKUBE_NODE_LEASE_RENEW_INTERVAL should not be set when disabled") - g.Expect(hasDuration).To(BeFalse(), "OVNKUBE_NODE_LEASE_DURATION should not be set when disabled") - } - }) - } -} - // TestFillOVNKubernetesDefaultsMTUNoOverlay tests that MTU is set correctly for no-overlay mode func TestFillOVNKubernetesDefaultsMTUNoOverlay(t *testing.T) { g := NewGomegaWithT(t) @@ -4971,38 +4868,3 @@ func TestValidateMTUForNoOverlay(t *testing.T) { g.Expect(err).To(BeNil()) }) } - -// extractDaemonSetEnvVars finds a DaemonSet by name in the rendered objects and returns -// env vars for the specified container as a map. -func extractDaemonSetEnvVars(g *WithT, objs []*uns.Unstructured, dsName, containerName string) map[string]string { - envVars := map[string]string{} - for _, obj := range objs { - if obj.GetKind() != "DaemonSet" || obj.GetName() != dsName { - continue - } - containers, found, err := uns.NestedSlice(obj.Object, "spec", "template", "spec", "containers") - g.Expect(err).NotTo(HaveOccurred()) - g.Expect(found).To(BeTrue()) - for _, c := range containers { - cmap := c.(map[string]interface{}) - name, _, _ := uns.NestedString(cmap, "name") - if name != containerName { - continue - } - envList, found, err := uns.NestedSlice(cmap, "env") - g.Expect(err).NotTo(HaveOccurred()) - if !found { - return envVars - } - for _, e := range envList { - emap := e.(map[string]interface{}) - eName, _, _ := uns.NestedString(emap, "name") - eVal, _, _ := uns.NestedString(emap, "value") - envVars[eName] = eVal - } - return envVars - } - } - g.Expect(true).To(BeFalse(), "could not find DaemonSet %s with container %s", dsName, containerName) - return envVars -}