diff --git a/src/lib/python/isc/config/config_data.py b/src/lib/python/isc/config/config_data.py index 48d7c1f279..346585b458 100644 --- a/src/lib/python/isc/config/config_data.py +++ b/src/lib/python/isc/config/config_data.py @@ -42,7 +42,7 @@ def spec_part_is_map(spec_part): def spec_part_is_named_set(spec_part): """Returns True if the given spec_part is a dict that contains a named_set specification, and False otherwise.""" - return (type(spec_part) == dict and 'named_map_item_spec' in spec_part) + return (type(spec_part) == dict and 'named_set_item_spec' in spec_part) def check_type(spec_part, value): """Does nothing if the value is of the correct type given the @@ -730,6 +730,15 @@ class MultiConfigData: cur_id_part + id, cur_value) cur_id_part = cur_id_part + id_part + "/" + + # We also need to copy to local if we are changing a named set, + # so that the other items in the set do not disappear + if spec_part_is_named_set(self.find_spec_part(cur_id_part)): + ns_value, ns_status = self.get_value(cur_id_part) + if ns_status != MultiConfigData.LOCAL: + isc.cc.data.set(self._local_changes, + cur_id_part, + ns_value) isc.cc.data.set(self._local_changes, identifier, value) def _get_list_items(self, item_name): diff --git a/src/lib/python/isc/config/tests/config_data_test.py b/src/lib/python/isc/config/tests/config_data_test.py index 46d27b1cb3..864fe708ed 100644 --- a/src/lib/python/isc/config/tests/config_data_test.py +++ b/src/lib/python/isc/config/tests/config_data_test.py @@ -720,6 +720,12 @@ class TestMultiConfigData(unittest.TestCase): config_items = self.mcd.get_config_item_list("Spec2", True) self.assertEqual(['Spec2/item1', 'Spec2/item2', 'Spec2/item3', 'Spec2/item4', 'Spec2/item5', 'Spec2/item6/value1', 'Spec2/item6/value2'], config_items) + def test_is_named_set(self): + module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + "spec32.spec") + self.mcd.set_specification(module_spec) + spec_part = self.mcd.find_spec_part("Spec32/named_set_item") + self.assertTrue(spec_part_is_named_set(spec_part)) + def test_get_config_item_list_named_set(self): config_items = self.mcd.get_config_item_list() self.assertEqual([], config_items) @@ -738,6 +744,20 @@ class TestMultiConfigData(unittest.TestCase): 'Spec32/named_set_item/bbbb', ], config_items) + def test_set_named_set_nonlocal(self): + # Test whether a default named set is copied to local if a subitem + # is changed, and that other items in the set do not get lost + module_spec = isc.config.module_spec_from_file(self.data_path + os.sep + 'spec32.spec') + self.mcd.set_specification(module_spec) + value, status = self.mcd.get_value('Spec32/named_set_item') + self.assertEqual({'a': 1, 'b': 2}, value) + self.assertEqual(MultiConfigData.DEFAULT, status) + + self.mcd.set_value('Spec32/named_set_item/b', 3) + value, status = self.mcd.get_value('Spec32/named_set_item') + self.assertEqual({'a': 1, 'b': 3}, value) + self.assertEqual(MultiConfigData.LOCAL, status) + if __name__ == '__main__': unittest.main()