Parcourir la source

[2559] Add semantic checks on the lease-database/type keyword value

Stephen Morris il y a 12 ans
Parent
commit
99d1141934

+ 19 - 0
src/bin/dhcp6/dbaccess_parser.cc

@@ -33,6 +33,25 @@ typedef pair<string, ConstElementPtr> ConfigPair;
 // Parse the configuration and check that the various keywords are consistent.
 void
 DbAccessParser::build(isc::data::ConstElementPtr config_value) {
+    const ConfigPairMap& config_map = config_value->mapValue();
+
+    // Check if the "type" keyword exists and thrown an exception if not.
+    ConfigPairMap::const_iterator type_ptr = config_map.find("type");
+    if (type_ptr == config_map.end()) {
+        isc_throw(TypeKeywordMissing, "lease database access parameters must "
+                  "include the keyword 'type' to determine type of database "
+                  "to be accessed");
+    }
+
+    // Check if the 'type; keyword known and throw an exception if not.
+    string dbtype = type_ptr->second->stringValue();
+    if ((dbtype != "memfile") && (dbtype != "mysql")) {
+        isc_throw(BadValue, "unknown backend database type: " << dbtype);
+    }
+
+    /// @todo Log a warning if the type is memfile and there are other keywords.
+    ///       This will be done when the module is moved to libdhcpsrv
+
 
     // All OK, build up the access string
     dbaccess_ = "";

+ 14 - 0
src/bin/dhcp6/dbaccess_parser.h

@@ -17,12 +17,23 @@
 
 #include <cc/data.h>
 #include <dhcp6/config_parser.h>
+#include <exceptions/exceptions.h>
 
 #include <string>
 
 namespace isc {
 namespace dhcp {
 
+/// @brief Exception thrown when 'type' keyword is missing from string
+///
+/// This condition is checked, but should never occur because 'type' is marked
+/// as mandatory in the .spec file for the server.
+class TypeKeywordMissing : public isc::Exception {
+public:
+    TypeKeywordMissing(const char* file, size_t line, const char* what) :
+        isc::Exception(file, line, what) {}
+};
+
 /// @brief Parse Lease Database Parameters
 ///
 /// This class is the parser for the lease database configuration.  This is a
@@ -57,6 +68,9 @@ public:
     ///
     /// @param config_value The configuration value for the "lease-database"
     ///        identifier.
+    ///
+    /// @throw isc::dhcp::MissingTypeKeyword The 'type' keyword is missing from
+    ///        the list of database access keywords.
     virtual void build(isc::data::ConstElementPtr config_value);
 
     /// @brief Apply the prepared configuration value to the server.

+ 40 - 3
src/bin/dhcp6/tests/dbaccess_parser_unittest.cc

@@ -44,6 +44,9 @@ public:
     /// value, keyword, value, ... and terminated by a NULL, return a string
     /// that represents the JSON map for the keywords and values.
     ///
+    /// E.g. given the array of strings: alpha, one, beta, two, NULL, it would
+    /// return the string '{ "alpha": "one", "beta": "two" }'
+    ///
     /// @param keyval Array of "const char*" strings in the order keyword,
     ///        value, keyword, value ...  A NULL entry terminates the list.
     ///
@@ -147,7 +150,7 @@ public:
 };
 
 // Check that the parser works with a simple configuration.
-TEST_F(DbAccessParserTest, validMemfile) {
+TEST_F(DbAccessParserTest, validTypeMemfile) {
     const char* config[] = {"type", "memfile",
                             NULL};
 
@@ -162,8 +165,8 @@ TEST_F(DbAccessParserTest, validMemfile) {
     checkAccessString("Valid memfile", dbaccess, config);
 }
 
-// Check that it works with a valid MySQL configuration
-TEST_F(DbAccessParserTest, validMySql) {
+// Check that the parser works with a valid MySQL configuration
+TEST_F(DbAccessParserTest, validTypeMysql) {
     const char* config[] = {"type",     "mysql",
                             "host",     "erewhon",
                             "user",     "kea",
@@ -182,4 +185,38 @@ TEST_F(DbAccessParserTest, validMySql) {
     checkAccessString("Valid mysql", dbaccess, config);
 }
 
+// A missing 'type' keyword should cause an exception to be thrown.
+TEST_F(DbAccessParserTest, missingTypeKeyword) {
+    const char* config[] = {"host",     "erewhon",
+                            "user",     "kea",
+                            "password", "keapassword",
+                            "name",     "keatest",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    DbAccessParser parser;
+    EXPECT_THROW(parser.build(json_elements), TypeKeywordMissing);
+}
+
+// If the value of the "type" keyword is unknown, a BadValue exception should
+// be thrown.
+TEST_F(DbAccessParserTest, badTypeKeyword) {
+    const char* config[] = {"type",     "invalid",
+                            "host",     "erewhon",
+                            "user",     "kea",
+                            "password", "keapassword",
+                            "name",     "keatest",
+                            NULL};
+
+    string json_config = toJson(config);
+    ConstElementPtr json_elements = Element::fromJSON(json_config);
+    EXPECT_TRUE(json_elements);
+
+    DbAccessParser parser;
+    EXPECT_THROW(parser.build(json_elements), BadValue);
+}
+
 };  // Anonymous namespace