]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
common: enforce min/max/enum on config options
authorJohn Spray <john.spray@redhat.com>
Wed, 12 Jul 2017 21:58:19 +0000 (17:58 -0400)
committerJohn Spray <john.spray@redhat.com>
Fri, 21 Jul 2017 10:27:27 +0000 (06:27 -0400)
Signed-off-by: John Spray <john.spray@redhat.com>
src/common/config.cc

index 4b720f355bdf50f912699260e0731cc653c57878..857fa4bd44f00a4e7dd9e2c62f175c85f99486a9 100644 (file)
@@ -865,7 +865,7 @@ int md_config_t::_get_val(const std::string &key, std::string *value) const {
     if (bool *flag = boost::get<bool>(&config_value)) {
       oss << (*flag ? "true" : "false");
     } else if (double *dp = boost::get<double>(&config_value)) {
-      oss << std::fixed << *dp ;
+      oss << std::fixed << *dp;
     } else {
       oss << config_value;
     }
@@ -995,6 +995,8 @@ int md_config_t::set_val_impl(const std::string &raw_val, const Option &opt,
   assert(lock.is_locked());
 
   std::string val = raw_val;
+
+  // Special validator callback?
   if (opt.validator) {
     int r = opt.validator(&val, error_message);
     if (r < 0) {
@@ -1052,6 +1054,41 @@ int md_config_t::set_val_impl(const std::string &raw_val, const Option &opt,
     ceph_abort();
   }
 
+  // Generic validation: min
+  if (!boost::get<boost::blank>(&(opt.min))) {
+    if (new_value < opt.min) {
+      std::ostringstream oss;
+      oss << "Value '" << new_value << "' is below minimum " << opt.min;
+      *error_message = oss.str();
+      return -EINVAL;
+    }
+  }
+
+  // Generic validation: max
+  if (!boost::get<boost::blank>(&(opt.max))) {
+    if (new_value > opt.max) {
+      std::ostringstream oss;
+      oss << "Value '" << new_value << "' exceeds maximum " << opt.max;
+      *error_message = oss.str();
+      return -EINVAL;
+    }
+  }
+
+  // Generic validation: enum
+  if (!opt.enum_allowed.empty() && opt.type == Option::TYPE_STR) {
+    auto found = std::find(opt.enum_allowed.begin(), opt.enum_allowed.end(),
+                           boost::get<std::string>(new_value));
+    if (found == opt.enum_allowed.end()) {
+      std::ostringstream oss;
+      oss << "'" << new_value << "' is not one of the permitted "
+                 "values: " << joinify(opt.enum_allowed.begin(),
+                                       opt.enum_allowed.end(),
+                                       std::string(", "));
+      *error_message = oss.str();
+      return -EINVAL;
+    }
+  }
+
   // Apply the value to its entry in the `values` map
   values[opt.name] = new_value;