From 6a60fb8004d6b79c4ecb370602b015a04c05803b Mon Sep 17 00:00:00 2001 From: Teresa Ho Date: Wed, 16 Apr 2025 17:35:48 -0400 Subject: [PATCH] Fix deprecated mgmt IP when sharing IPv6 vlan When mgmt and cluster-host networks are on the same IPv6 vlan, the mgmt IP was deprecated causing a worker node from being unlocked. In this case, the cluster-host IP should have been deprecated and mgmt IP should be undeprecated. This commit is to ensure that mgmt IP is undeprecated when mgmt network is sharing a vlan with another network. Test Plan: PASS: install IPv6 AIO-DX with compute PASS: install IPv4 standard with mgmt and cluster-host on same interface Closes-Bug: 2107505 Change-Id: I3d695d63114849a46a5189f447849aaa0b870868 Signed-off-by: Teresa Ho --- .../sysinv/sysinv/sysinv/puppet/interface.py | 17 +++++-- .../sysinv/tests/puppet/test_interface.py | 50 +++++++++++++++++++ 2 files changed, 64 insertions(+), 3 deletions(-) diff --git a/sysinv/sysinv/sysinv/sysinv/puppet/interface.py b/sysinv/sysinv/sysinv/sysinv/puppet/interface.py index 2c28f952cd..6637d268e7 100644 --- a/sysinv/sysinv/sysinv/sysinv/puppet/interface.py +++ b/sysinv/sysinv/sysinv/sysinv/puppet/interface.py @@ -1594,7 +1594,7 @@ def process_interface_labels(config, context): # 2) if the interface have more that one label # - if the family is inet # - just keep the labeling - # - DHCPv4 can use a labeled interface (pxebbot for now is only IPv4), + # - DHCPv4 can use a labeled interface (pxeboot for now is only IPv4), # that was not the case when using CentOS # - if the family is inet6 # - interface needs to contain the static address that will be used as @@ -1609,7 +1609,9 @@ def process_interface_labels(config, context): # - cluster-host # - pxeboot # - storage - # - DHCPv6 cannot use label (pxebbot for now is only IPv4, so we don't + # - if a vlan is shared by mgmt and another network, + # the mgmt interface will not have the address deprecated + # - DHCPv6 cannot use label (pxeboot for now is only IPv4, so we don't # have a use case for now for platform interfaces), move the label # to interface @@ -1636,11 +1638,20 @@ def process_interface_labels(config, context): if (intf_data['family'] == 'inet6') and (intf_data['method'] == 'static'): name_net = intf_data['options']['stx-description'].split(',') ifname = (name_net[0].split(":"))[1] + net = (name_net[1].split(":"))[1] networktypelist = context['interfaces'][ifname].networktypelist undeprecate = "ip -6 addr replace" + \ f" {intf_data['ipaddress']}/{intf_data['netmask']}" + \ f" dev {intf} preferred_lft forever" - if constants.NETWORK_TYPE_OAM in networktypelist: + if ('vlan' in label and len(networktypelist) > 1 + and constants.NETWORK_TYPE_MGMT in networktypelist): + if net == constants.NETWORK_TYPE_MGMT: + fill_interface_config_option_operation(intf_data['options'], + IFACE_POST_UP_OP, undeprecate) + break + else: + continue + elif constants.NETWORK_TYPE_OAM in networktypelist: fill_interface_config_option_operation(intf_data['options'], IFACE_POST_UP_OP, undeprecate) break diff --git a/sysinv/sysinv/sysinv/sysinv/tests/puppet/test_interface.py b/sysinv/sysinv/sysinv/sysinv/tests/puppet/test_interface.py index 8a88321564..dc4a8ed846 100644 --- a/sysinv/sysinv/sysinv/sysinv/tests/puppet/test_interface.py +++ b/sysinv/sysinv/sysinv/sysinv/tests/puppet/test_interface.py @@ -4402,6 +4402,56 @@ class InterfaceConfigTestMixin(InterfaceTestCaseMixin): } self._validate_config(expected) + def test_controller_shared_vlan_over_pxeboot(self): + self._create_host(constants.CONTROLLER) + pxe0 = self._add_bond('pxe0', constants.INTERFACE_CLASS_PLATFORM, + constants.NETWORK_TYPE_PXEBOOT) + self._add_vlan(pxe0, 200, 'mgmt0', constants.INTERFACE_CLASS_PLATFORM, + [constants.NETWORK_TYPE_MGMT, constants.NETWORK_TYPE_CLUSTER_HOST]) + expected = { + 'pxe0': [ + {NET: constants.NETWORK_TYPE_PXEBOOT, FAMILY: INET, METHOD: STATIC, + OPTIONS: {'bond-lacp-rate': 'fast', 'bond-miimon': '100', + 'bond-mode': '802.3ad', 'bond-slaves': True, + 'bond-xmit-hash-policy': 'layer2', 'hwaddress': True, + POST_UP: [SET_TC, IPV6_CFG], UP: [SLEEP]}}], + 'eth0': [ + {NET: None, FAMILY: INET, METHOD: MANUAL, + OPTIONS: {ALLOW: True, 'bond-master': True, PRE_UP: [PROMISC_ON, IPV6_CFG]}}], + 'eth1': [ + {NET: None, FAMILY: INET, METHOD: MANUAL, + OPTIONS: {ALLOW: True, 'bond-master': True, PRE_UP: [PROMISC_ON, IPV6_CFG]}}], + 'mgmt0': [ + {NET: None, FAMILY: INET, METHOD: MANUAL, + OPTIONS: {'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_TC, SET_MTU, IPV6_CFG]}}, + {MODES: [SS_IPV4], + NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC, + OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_MTU, IPV6_CFG]}}, + {MODES: [DS_IPV4, DS_IPV6], + NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET, METHOD: STATIC, + OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_MTU, IPV6_CFG]}}, + {MODES: [SS_IPV6], + NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC, + OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_MTU, IPV6_CFG, UNDEPR]}}, + {MODES: [DS_IPV4, DS_IPV6], + NET: constants.NETWORK_TYPE_MGMT, FAMILY: INET6, METHOD: STATIC, + OPTIONS: {GATEWAY: True, 'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_MTU, IPV6_CFG, UNDEPR]}}, + {MODES: [SS_IPV4, DS_IPV4, DS_IPV6], + NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET, METHOD: STATIC, + OPTIONS: {'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_MTU, IPV6_CFG]}}, + {MODES: [SS_IPV6, DS_IPV4, DS_IPV6], + NET: constants.NETWORK_TYPE_CLUSTER_HOST, FAMILY: INET6, METHOD: STATIC, + OPTIONS: {'vlan-raw-device': True, PRE_UP: [VLAN_MOD], + POST_UP: [SET_MTU, IPV6_CFG]}}], + } + self._validate_config(expected) + def test_controller_duplex_direct_ethernet(self): self._create_host(constants.CONTROLLER) system_dict = self.system.as_dict()