diff --git a/manila/share/drivers/netapp/dataontap/client/client_cmode_rest.py b/manila/share/drivers/netapp/dataontap/client/client_cmode_rest.py index e5645977cd..c51c45b048 100644 --- a/manila/share/drivers/netapp/dataontap/client/client_cmode_rest.py +++ b/manila/share/drivers/netapp/dataontap/client/client_cmode_rest.py @@ -2589,14 +2589,9 @@ class NetAppRestClient(object): } if autosize_attributes: - attributes = autosize_attributes - body['autosize'] = { - 'mode': attributes['mode'], - 'grow_threshold': attributes['grow-threshold-percent'], - 'shrink_threshold': attributes['shrink-threshold-percent'], - 'maximum': attributes['maximum-size'], - 'minimum': attributes['minimum-size'], - } + autosize = self._build_autosize_attributes(autosize_attributes) + if autosize: + body['autosize'] = autosize if language: body['language'] = language @@ -2639,6 +2634,35 @@ class NetAppRestClient(object): if self._is_snaplock_enabled_volume(volume_name): self.set_snaplock_attributes(volume_name, **options) + @na_utils.trace + def _build_autosize_attributes(self, autosize_attributes): + """Build autosize attributes dict from autosize_attributes.""" + reset_val = autosize_attributes.get('reset', '') + if str(reset_val).lower() == 'true': + return None + + src = autosize_attributes + + # Build autosize dict directly + autosize_key_map = { + 'grow-threshold-percent': 'grow_threshold', + 'shrink-threshold-percent': 'shrink_threshold', + 'maximum-size': 'maximum', + 'minimum-size': 'minimum', + } + + autosize = { + dest_key: src[src_key] + for src_key, dest_key in autosize_key_map.items() + if src_key in src + } + + # Add mode if present + if 'mode' in src: + autosize['mode'] = src['mode'] + + return autosize if autosize else None + @na_utils.trace def start_volume_move(self, volume_name, vserver, destination_aggregate, cutover_action='wait', encrypt_destination=None): diff --git a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode_rest.py b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode_rest.py index 8bb2af29b2..972b792a1f 100644 --- a/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode_rest.py +++ b/manila/tests/share/drivers/netapp/dataontap/client/test_client_cmode_rest.py @@ -2488,6 +2488,89 @@ class NetAppRestCmodeClientTestCase(test.TestCase): self.client._parse_timestamp, test_time_str) + def test__build_autosize_attributes(self): + """Test _build_autosize_attributes with various input scenarios.""" + + # Test case 1: Basic functionality with all supported attributes + autosize_attrs = { + 'grow-threshold-percent': 90, + 'shrink-threshold-percent': 50, + 'maximum-size': '10GB', + 'minimum-size': '1GB', + 'mode': 'grow' + } + + result = self.client._build_autosize_attributes(autosize_attrs) + + expected = { + 'grow_threshold': 90, + 'shrink_threshold': 50, + 'maximum': '10GB', + 'minimum': '1GB', + 'mode': 'grow' + } + self.assertEqual(expected, result) + + def test__build_autosize_attributes_reset_true(self): + """Test _build_autosize_attributes returns None when reset is true.""" + autosize_attrs = { + 'reset': 'true', + 'grow-threshold-percent': 90, + 'maximum-size': '10GB' + } + + result = self.client._build_autosize_attributes(autosize_attrs) + + self.assertIsNone(result) + + def test__build_autosize_attributes_partial_attrs(self): + """Test _build_autosize_attributes with only some attributes.""" + autosize_attrs = { + 'grow-threshold-percent': 85, + 'maximum-size': '5GB' + } + + result = self.client._build_autosize_attributes(autosize_attrs) + + expected = { + 'grow_threshold': 85, + 'maximum': '5GB' + } + self.assertEqual(expected, result) + + def test__build_autosize_attributes_empty_dict(self): + """Test _build_autosize_attributes returns None for empty dict.""" + autosize_attrs = {} + + result = self.client._build_autosize_attributes(autosize_attrs) + + self.assertIsNone(result) + + def test__build_autosize_attributes_with_mode_only(self): + """Test _build_autosize_attributes with only mode attribute.""" + autosize_attrs = { + 'mode': 'grow_shrink' + } + + result = self.client._build_autosize_attributes(autosize_attrs) + + expected = { + 'mode': 'grow_shrink' + } + self.assertEqual(expected, result) + autosize_attrs = { + 'grow-threshold-percent': 90, + 'maximum-size': '10GB' + } + + result = self.client._build_autosize_attributes(autosize_attrs) + + expected = { + 'grow_threshold': 90, + 'maximum': '10GB' + } + self.assertEqual(expected, result) + def test_start_volume_move(self): mock__send_volume_move_request = self.mock_object( diff --git a/releasenotes/notes/bug-2130717-auto-attribute-mode-key-error-for-rest-e7958807a5e2e0e5.yaml b/releasenotes/notes/bug-2130717-auto-attribute-mode-key-error-for-rest-e7958807a5e2e0e5.yaml new file mode 100644 index 0000000000..f06a3a6dcb --- /dev/null +++ b/releasenotes/notes/bug-2130717-auto-attribute-mode-key-error-for-rest-e7958807a5e2e0e5.yaml @@ -0,0 +1,9 @@ +--- + +fixes: + - | + Fixed an issue that caused the share replica promotion to fail due to + missing replica attributes in the NetApp driver while using the REST API. + For more details, please refer to + `launchpad bug #2130717 `_. +