Browse Source

[1491] copy default named-set data to local when editing

if a child member is set, and the named-set data is default, it would 'lose' the other default values if it wasn't copied to local. For succesful operations this wouldn't be a problem (as this only happens 'locally' in bindctl), but it can cause problems when updates fail due to mistyped data
Jelte Jansen 13 years ago
parent
commit
b0a028bf38

+ 10 - 1
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):
 def spec_part_is_named_set(spec_part):
     """Returns True if the given spec_part is a dict that contains a
     """Returns True if the given spec_part is a dict that contains a
        named_set specification, and False otherwise."""
        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):
 def check_type(spec_part, value):
     """Does nothing if the value is of the correct type given the
     """Does nothing if the value is of the correct type given the
@@ -720,6 +720,15 @@ class MultiConfigData:
                                     cur_id_part + id,
                                     cur_id_part + id,
                                     cur_value)
                                     cur_value)
             cur_id_part = cur_id_part + id_part + "/"
             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)
         isc.cc.data.set(self._local_changes, identifier, value)
 
 
     def _get_list_items(self, item_name):
     def _get_list_items(self, item_name):

+ 14 - 0
src/lib/python/isc/config/tests/config_data_test.py

@@ -697,6 +697,20 @@ class TestMultiConfigData(unittest.TestCase):
                           'Spec32/named_set_item/bbbb',
                           'Spec32/named_set_item/bbbb',
                          ], config_items)
                          ], 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__':
 if __name__ == '__main__':
     unittest.main()
     unittest.main()