diff --git a/devstack/plugin.sh b/devstack/plugin.sh index d000a990..477c74ce 100644 --- a/devstack/plugin.sh +++ b/devstack/plugin.sh @@ -183,6 +183,7 @@ function add_generic_switch_to_ml2_config { if [[ -n "$key_file" ]]; then populate_ml2_config $GENERIC_SWITCH_INI_FILE $switch_name key_file=$key_file + populate_ml2_config $GENERIC_SWITCH_INI_FILE $switch_name use_keys=True elif [[ -n "$password" ]]; then populate_ml2_config $GENERIC_SWITCH_INI_FILE $switch_name password=$password fi diff --git a/doc/source/configuration.rst b/doc/source/configuration.rst index fd781e2f..9c07dfbc 100644 --- a/doc/source/configuration.rst +++ b/doc/source/configuration.rst @@ -14,6 +14,7 @@ Switch configuration format:: port = username = password = + use_keys = key_file = secret = ngs_allowed_vlans = diff --git a/networking_generic_switch/devices/netmiko_devices/__init__.py b/networking_generic_switch/devices/netmiko_devices/__init__.py index 5c372ef8..ca76fb37 100644 --- a/networking_generic_switch/devices/netmiko_devices/__init__.py +++ b/networking_generic_switch/devices/netmiko_devices/__init__.py @@ -144,6 +144,31 @@ def __init__(self, device_cfg, *args, **kwargs): self.config['session_log_record_writes'] = True self.config['session_log_file_mode'] = 'append' + _NUMERIC_CAST = { + "port": int, + "global_delay_factor": float, + "conn_timeout": float, + "auth_timeout": float, + "banner_timeout": float, + "blocking_timeout": float, + "timeout": float, + "session_timeout": float, + "read_timeout_override": float, + "keepalive": int, + } + + for key, expected_type in _NUMERIC_CAST.items(): + value = self.config.get(key) + if isinstance(value, str): + try: + self.config[key] = expected_type(value) + except ValueError: + LOG.error( + "Invalid value %s for %s; expected %s", + value, key, expected_type.__name__, + ) + raise exc.GenericSwitchNetmikoConfigError() + self.lock_kwargs = { 'locks_pool_size': int(self.ngs_config['ngs_max_connections']), 'locks_prefix': self.config.get( @@ -435,7 +460,7 @@ def unplug_bond_from_network(self, bond, segmentation_id, segmentation_id=segmentation_id) for sub_port in trunk_details.get('sub_ports', []): cmds += self._format_commands( - self.ADD_NETWORK_TO_BOND_TRUNK, bond=bond, + self.DELETE_NETWORK_ON_BOND_TRUNK, bond=bond, segmentation_id=sub_port['segmentation_id']) if ngs_port_default_vlan: diff --git a/networking_generic_switch/tests/unit/test_devices.py b/networking_generic_switch/tests/unit/test_devices.py index 4486c364..dc971007 100644 --- a/networking_generic_switch/tests/unit/test_devices.py +++ b/networking_generic_switch/tests/unit/test_devices.py @@ -267,3 +267,24 @@ def test__get_ssh_disabled_algorithms(self): "ciphers": ["blowfish-cbc", "3des-cbc"], } self.assertEqual(expected, algos) + + def test_float_params_cast(self): + config = { + "device_type": 'netmiko_ovs_linux', + "ip": "10.1.2.3", + "username": "u", + "password": "p", + "conn_timeout": "20.0", + "global_delay_factor": "2.5", + "port": "2222", + } + device = devices.device_manager(config) + + self.assertIsInstance(device.config["conn_timeout"], float) + self.assertEqual(device.config["conn_timeout"], 20.0) + + self.assertIsInstance(device.config["global_delay_factor"], float) + self.assertEqual(device.config["global_delay_factor"], 2.5) + + self.assertIsInstance(device.config["port"], int) + self.assertEqual(device.config["port"], 2222) diff --git a/releasenotes/notes/fix-unplugging-trunk-subports-66d8496b43c55130.yaml b/releasenotes/notes/fix-unplugging-trunk-subports-66d8496b43c55130.yaml new file mode 100644 index 00000000..c7915aad --- /dev/null +++ b/releasenotes/notes/fix-unplugging-trunk-subports-66d8496b43c55130.yaml @@ -0,0 +1,8 @@ +--- +fixes: + - | + Fixed incorrect command when unplugging bond subports. + Previously, when a bond was unplugged from a network with trunk subports, + the system would incorrectly try to add subports instead of removing them. + This bug has been fixed, and the system now uses the correct command to remove subports, + ensuring proper bond cleanup.