BIND 10 trac3363, updated. 98df1691016eddedaf2370ac85d1611f10adc6ea [3363] Remove map level enable-updates default from Kea spec files

BIND 10 source code commits bind10-changes at lists.isc.org
Fri Mar 7 15:47:17 UTC 2014


The branch, trac3363 has been updated
       via  98df1691016eddedaf2370ac85d1611f10adc6ea (commit)
       via  a45a6657443d56c1d131b92399ca6aca8514b070 (commit)
      from  305e3c4cd191f091c4e961b0ecd17cf21b836a43 (commit)

Those revisions listed above that are new to this repository have
not appeared on any other notification email; so we list those
revisions in full, below.

- Log -----------------------------------------------------------------
commit 98df1691016eddedaf2370ac85d1611f10adc6ea
Author: Thomas Markwalder <tmark at isc.org>
Date:   Fri Mar 7 10:44:43 2014 -0500

    [3363] Remove map level enable-updates default from Kea spec files
    
    Removed the map level default value for "enable-updates" from the
    "dhcp-ddns" spec files for DHCP servers.  The default value now comes
    from the item level default, with the change in ConfigData::getFullConfig.

commit a45a6657443d56c1d131b92399ca6aca8514b070
Author: Thomas Markwalder <tmark at isc.org>
Date:   Fri Mar 7 10:36:28 2014 -0500

    [3363] ConfigData::getFullConfig now merges top level maps
    
    Altered config::ConfigData::getFullConfig to properly populate
    top level map items with default and configured values.  Prior to
    this if a map item had any configured values, the map returned would
    contain only the configured values.

-----------------------------------------------------------------------

Summary of changes:
 src/bin/dhcp4/dhcp4.spec                           |    2 +-
 src/bin/dhcp6/dhcp6.spec                           |    2 +-
 src/lib/config/config_data.cc                      |   67 +++++++++++++++++++-
 src/lib/config/config_data.h                       |   22 ++++++-
 src/lib/config/tests/config_data_unittests.cc      |   22 +++++--
 .../tests/testdata/{spec2.spec => spec43.spec}     |    4 +-
 6 files changed, 109 insertions(+), 10 deletions(-)
 copy src/lib/config/tests/testdata/{spec2.spec => spec43.spec} (95%)

-----------------------------------------------------------------------
diff --git a/src/bin/dhcp4/dhcp4.spec b/src/bin/dhcp4/dhcp4.spec
index 5de65b2..6333c40 100644
--- a/src/bin/dhcp4/dhcp4.spec
+++ b/src/bin/dhcp4/dhcp4.spec
@@ -319,7 +319,7 @@
       { "item_name": "dhcp-ddns",
         "item_type": "map",
         "item_optional": false,
-        "item_default": {"enable-updates": false},
+        "item_default": {},
         "item_description" : "Contains parameters pertaining DHCP-driven DDNS updates",
         "map_item_spec": [
             {
diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec
index 7462daa..a760674 100644
--- a/src/bin/dhcp6/dhcp6.spec
+++ b/src/bin/dhcp6/dhcp6.spec
@@ -356,7 +356,7 @@
       { "item_name": "dhcp-ddns",
         "item_type": "map",
         "item_optional": false,
-        "item_default": {"enable-updates": false},
+        "item_default": {},
         "item_description" : "Contains parameters pertaining DHCP-driven DDNS updates",
         "map_item_spec": [
             {
diff --git a/src/lib/config/config_data.cc b/src/lib/config/config_data.cc
index fb5dd75..ce94157 100644
--- a/src/lib/config/config_data.cc
+++ b/src/lib/config/config_data.cc
@@ -205,6 +205,69 @@ ConfigData::getValue(bool& is_default, const std::string& identifier) const {
     return (value);
 }
 
+typedef std::pair<std::string, isc::data::ConstElementPtr> ConfigPair;
+
+ConstElementPtr
+ConfigData::getFullValue(bool& is_default, const std::string& identifier) const {
+    // Check the item spec.
+    ConstElementPtr spec_part =
+            find_spec_part(_module_spec.getConfigSpec(), identifier);
+
+    // If the item is not a map item, then use the flat version of
+    // getValue.
+    std::string item_type = spec_part->get("item_type")->stringValue();
+    if (item_type != "map") {
+        return (getValue(is_default, identifier));
+    }
+
+    /// @todo in order to make this handle maps with maps
+    /// You would need to loop thru all the items in this map,
+    /// and call getFullValue() them, using the returned map
+    /// as its "full" value.
+
+    // The item is a map item, so we need to return a merge of the
+    // its default values and configured values.
+    boost::shared_ptr<MapElement> merged_map(new MapElement());
+
+    // Check for map-level defaults.  These are preferred over
+    // item level defaults.
+    if (spec_part->contains("item_default")) {
+        ConstElementPtr map_defaults = spec_part->get("item_default");
+        BOOST_FOREACH(ConfigPair dflt_pair, map_defaults->mapValue()) {
+            merged_map->set(dflt_pair.first, dflt_pair.second);
+        }
+    }
+
+    // If there were no map level defaults, then we need to look at
+    // item level defaults.
+    if (merged_map->mapValue().empty()) {
+        // Loop thru the map spec
+        ConstElementPtr map_item_spec = spec_part->get("map_item_spec");
+        BOOST_FOREACH(ConstElementPtr map_item, map_item_spec->listValue()) {
+            // get the next item in map's spec
+            if (map_item->contains("item_name")) {
+                std::string item_name = map_item->
+                                        get("item_name")->stringValue();
+                if (map_item->contains("item_default")) {
+                    ConstElementPtr default_value = map_item->
+                                                    get("item_default");
+                    merged_map->set(item_name, default_value);
+                }
+            }
+        }
+    }
+
+    // Get the any non-default values for the map items
+    ConstElementPtr configged_map = _config->find(identifier);
+    if (configged_map) {
+        // Merge the non-defualt map into the default map
+        merge(merged_map, configged_map);
+    }
+
+    return (merged_map);
+}
+
+
 ConstElementPtr
 ConfigData::getDefaultValue(const std::string& identifier) const {
     ConstElementPtr spec_part =
@@ -237,7 +300,9 @@ ConfigData::getFullConfig() const {
     ElementPtr result = Element::createMap();
     ConstElementPtr items = getItemList("", false);
     BOOST_FOREACH(ConstElementPtr item, items->listValue()) {
-        result->set(item->stringValue(), getValue(item->stringValue()));
+        bool fake;
+        ConstElementPtr value = getFullValue(fake, item->stringValue());
+        result->set(item->stringValue(), value);
     }
     return (result);
 }
diff --git a/src/lib/config/config_data.h b/src/lib/config/config_data.h
index 7900aa9..8ca7226 100644
--- a/src/lib/config/config_data.h
+++ b/src/lib/config/config_data.h
@@ -80,6 +80,27 @@ public:
     isc::data::ConstElementPtr getValue(bool& is_default,
                                         const std::string& identifier) const;
 
+    /// Returns the "full" value for the given identifier
+    /// If the item referredt toyidentifier is not a map item, then it simply
+    /// returns the value yielded by getValue() .  If the identifier
+    /// refers to a map item, then it returns a merged map of the map
+    /// items' defaults and configured values.
+    /// The default values for the items in the map are taken from the
+    /// map's default value if not empty (i.e. not "{}").  If the map defualt
+    /// is empty, then the item default values are taken from each item spec
+    /// within the map spec.
+    ///
+    /// @todo This method should be made to recurse into maps of maps.
+    ///
+    /// Raises a DataNotFoundError if the identifier is bad.
+    /// \param is_default will be set to true if the value is taken
+    ///                   from the specifications item_default setting,
+    ///                   false otherwise
+    /// \param identifier The identifier pointing to the configuration
+    ///        value that is to be returned
+    isc::data::ConstElementPtr getFullValue(bool& is_default,
+                                            const std::string& identifier) const;
+
     /// Returns the ModuleSpec associated with this ConfigData object
     const ModuleSpec& getModuleSpec() const { return (_module_spec); }
 
@@ -116,7 +137,6 @@ public:
     /// \return An ElementPtr pointing to a MapElement containing
     ///         the top-level configuration items
     isc::data::ConstElementPtr getFullConfig() const;
-
 private:
     isc::data::ElementPtr _config;
     ModuleSpec _module_spec;
diff --git a/src/lib/config/tests/config_data_unittests.cc b/src/lib/config/tests/config_data_unittests.cc
index 4b83e5c..22e4726 100644
--- a/src/lib/config/tests/config_data_unittests.cc
+++ b/src/lib/config/tests/config_data_unittests.cc
@@ -140,16 +140,30 @@ TEST(ConfigData, getItemList) {
 TEST(ConfigData, getFullConfig) {
     ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec2.spec");
     ConfigData cd = ConfigData(spec2);
-
-    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": {  } }", cd.getFullConfig()->str());
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"default\" } }", cd.getFullConfig()->str());
     ElementPtr my_config = Element::fromJSON("{ \"item1\": 2 }");
     cd.setLocalConfig(my_config);
-    EXPECT_EQ("{ \"item1\": 2, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": {  } }", cd.getFullConfig()->str());
+    EXPECT_EQ("{ \"item1\": 2, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"default\" } }", cd.getFullConfig()->str());
     ElementPtr my_config2 = Element::fromJSON("{ \"item6\": { \"value1\": \"a\" } }");
     cd.setLocalConfig(my_config2);
     EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"a\" } }", cd.getFullConfig()->str());
     ElementPtr my_config3 = Element::fromJSON("{ \"item6\": { \"value2\": 123 } }");
     cd.setLocalConfig(my_config3);
-    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value2\": 123 } }", cd.getFullConfig()->str());
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"default\", \"value2\": 123 } }" , cd.getFullConfig()->str());
 }
 
+
+TEST(ConfigData, getFullConfigMapLevelDefault) {
+    ModuleSpec spec2 = moduleSpecFromFile(std::string(TEST_DATA_PATH) + "/spec43.spec");
+    ConfigData cd = ConfigData(spec2);
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"default-A\", \"value2\": 77 } }", cd.getFullConfig()->str());
+    ElementPtr my_config = Element::fromJSON("{ \"item1\": 2 }");
+    cd.setLocalConfig(my_config);
+    EXPECT_EQ("{ \"item1\": 2, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"default-A\", \"value2\": 77 } }", cd.getFullConfig()->str());
+    ElementPtr my_config2 = Element::fromJSON("{ \"item6\": { \"value1\": \"a\" } }");
+    cd.setLocalConfig(my_config2);
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"a\", \"value2\": 77 } }", cd.getFullConfig()->str());
+    ElementPtr my_config3 = Element::fromJSON("{ \"item6\": { \"value2\": 123 } }");
+    cd.setLocalConfig(my_config3);
+    EXPECT_EQ("{ \"item1\": 1, \"item2\": 1.1, \"item3\": true, \"item4\": \"test\", \"item5\": [ \"a\", \"b\" ], \"item6\": { \"value1\": \"default-A\", \"value2\": 123 } }" , cd.getFullConfig()->str());
+}
diff --git a/src/lib/config/tests/testdata/spec43.spec b/src/lib/config/tests/testdata/spec43.spec
new file mode 100644
index 0000000..c03306b
--- /dev/null
+++ b/src/lib/config/tests/testdata/spec43.spec
@@ -0,0 +1,83 @@
+{
+  "module_spec": {
+    "module_name": "Spec2",
+    "config_data": [
+      { "item_name": "item1",
+        "item_type": "integer",
+        "item_optional": false,
+        "item_default": 1
+      },
+      { "item_name": "item2",
+        "item_type": "real",
+        "item_optional": false,
+        "item_default": 1.1
+      },
+      { "item_name": "item3",
+        "item_type": "boolean",
+        "item_optional": false,
+        "item_default": true
+      },
+      { "item_name": "item4",
+        "item_type": "string",
+        "item_optional": false,
+        "item_default": "test"
+      },
+      { "item_name": "item5",
+        "item_type": "list",
+        "item_optional": false,
+        "item_default": [ "a", "b" ],
+        "list_item_spec": {
+          "item_name": "list_element",
+          "item_type": "string",
+          "item_optional": false,
+          "item_default": ""
+        }
+      },
+      { "item_name": "item6",
+        "item_type": "map",
+        "item_optional": false,
+        "item_default": { "value1": "default-A", "value2" : 77},
+        "map_item_spec": [
+          { "item_name": "value1",
+            "item_type": "string",
+            "item_optional": true,
+            "item_default": "default-B"
+          },
+          { "item_name": "value2",
+            "item_type": "integer",
+            "item_optional": true
+          }
+        ]
+      }
+    ],
+    "commands": [
+      {
+        "command_name": "print_message",
+        "command_description": "Print the given message to stdout",
+        "command_args": [ {
+          "item_name": "message",
+          "item_type": "string",
+          "item_optional": false,
+          "item_default": ""
+        } ]
+      },
+      {
+        "command_name": "shutdown",
+        "command_description": "Shut down BIND 10",
+        "command_args": []
+      }
+    ],
+    "statistics": [
+      {
+        "item_name": "dummy_time",
+        "item_type": "string",
+        "item_optional": false,
+        "item_default": "1970-01-01T00:00:00Z",
+        "item_title": "Dummy Time",
+        "item_description": "A dummy date time",
+        "item_format": "date-time"
+      }
+    ]
+  }
+}
+



More information about the bind10-changes mailing list