summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>2017-07-25 09:36:54 -0500
committerDhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>2017-07-28 13:42:44 -0500
commit61d3b6a1f283f0926cb3e92e14378175030da1b2 (patch)
tree3b8d8876351799d014d790d3053be3961e8d9c60
parentc15990a32063192e51c0c3ef5e65e149b2c44d70 (diff)
downloadphosphor-settingsd-61d3b6a1f283f0926cb3e92e14378175030da1b2.tar.gz
phosphor-settingsd-61d3b6a1f283f0926cb3e92e14378175030da1b2.zip
Validate changes to default settings.
Resolves openbmc/openbmc#1771 Change-Id: I763e811e88710425131ec504ff933e3c41c458e6 Signed-off-by: Dhruvaraj Subhashchandran <dhruvaraj@in.ibm.com>
-rwxr-xr-xMakefile.am4
-rw-r--r--configure.ac2
-rw-r--r--settings_example.yaml30
-rw-r--r--settings_manager.mako.hpp78
4 files changed, 106 insertions, 8 deletions
diff --git a/Makefile.am b/Makefile.am
index 55ea2d6..50c380e 100755
--- a/Makefile.am
+++ b/Makefile.am
@@ -26,9 +26,11 @@ phosphor_settings_manager_SOURCES = \
phosphor_settings_manager_CXXFLAGS = \
$(PHOSPHOR_DBUS_INTERFACES_CFLAGS) \
- $(SDBUSPLUS_CFLAGS)
+ $(SDBUSPLUS_CFLAGS) \
+ $(PHOSPHOR_LOGGING_CFLAGS)
phosphor_settings_manager_LDADD = \
$(PHOSPHOR_DBUS_INTERFACES_LIBS) \
$(SDBUSPLUS_LIBS) \
+ $(PHOSPHOR_LOGGING_LIBS) \
-lstdc++fs
diff --git a/configure.ac b/configure.ac
index 083d623..895ce17 100644
--- a/configure.ac
+++ b/configure.ac
@@ -16,6 +16,8 @@ PKG_CHECK_MODULES([PHOSPHOR_DBUS_INTERFACES], [phosphor-dbus-interfaces],,\
AC_MSG_ERROR(["Requires phosphor-dbus-interfaces package."]))
PKG_CHECK_MODULES([SDBUSPLUS], [sdbusplus],,
AC_MSG_ERROR(["Requires sdbusplus package."]))
+PKG_CHECK_MODULES([PHOSPHOR_LOGGING], [phosphor-logging],,\
+ AC_MSG_ERROR(["Requires phosphor-logging package."]))
LT_INIT
diff --git a/settings_example.yaml b/settings_example.yaml
index d6e7f88..82b63be 100644
--- a/settings_example.yaml
+++ b/settings_example.yaml
@@ -1,9 +1,31 @@
/xyz/openbmc_project/control/host0/boot_mode:
Interface: xyz.openbmc_project.Control.Boot.Mode
- Defaults:
- BootMode: Mode::Modes::Safe
+ Properties:
+ BootMode:
+ Default: Mode::Modes::Safe
/xyz/openbmc_project/control/host1/boot_mode:
Interface: xyz.openbmc_project.Control.Boot.Mode
- Defaults:
- BootMode: Mode::Modes::Regular
+ Properties:
+ BootMode:
+ Default: Mode::Modes::Regular
+
+/xyz/openbmc_project/network/host0/intf:
+ Interface: xyz.openbmc_project.Network.MACAddress
+ Properties:
+ MACAddress:
+ Default: '"00:00:00:00:00:00"'
+ Validation:
+ Type: "regex"
+ Validator: '^([0-9A-F]{2}[:-]){5}([0-9A-F]{2})$'
+/xyz/openbmc_project/control/host0/power_cap:
+ Interface: xyz.openbmc_project.Control.Power.Cap
+ Properties:
+ PowerCap:
+ Default: 0
+ Validation:
+ Type: "range"
+ Validator: "0..1000"
+ Unit: "Watts"
+ PowerCapEnable:
+ Default: 'false'
diff --git a/settings_manager.mako.hpp b/settings_manager.mako.hpp
index cc2ab5b..9fca3da 100644
--- a/settings_manager.mako.hpp
+++ b/settings_manager.mako.hpp
@@ -2,12 +2,14 @@
## into the rendered file; feel free to edit this file.
// WARNING: Generated header. Do not edit!
<%
+import re
from collections import defaultdict
objects = list(settingsDict.viewkeys())
sdbusplus_namespaces = []
sdbusplus_includes = []
interfaces = []
props = defaultdict(list)
+validators = defaultdict(tuple)
def get_setting_sdbusplus_type(setting_intf):
setting = "sdbusplus::" + setting_intf.replace('.', '::')
@@ -33,7 +35,12 @@ def get_setting_type(setting_intf):
#include <fstream>
#include <utility>
#include <experimental/filesystem>
+#include <regex>
+#include <phosphor-logging/elog.hpp>
+#include <phosphor-logging/elog-errors.hpp>
+#include <phosphor-logging/log.hpp>
#include "config.h"
+#include <xyz/openbmc_project/Common/error.hpp>
% for i in set(sdbusplus_includes):
#include "${i}"
@@ -64,8 +71,14 @@ using namespace ${n};
intf = settingsDict[object]['Interface']
interfaces.append(intf)
if intf not in props:
- for property, value in settingsDict[object]['Defaults'].items():
+ for property, property_metadata in settingsDict[object]['Properties'].items():
props[intf].append(property)
+ for attribute, value in property_metadata.items():
+ if attribute == 'Validation':
+ if value['Type'] == "range":
+ validators[property] = (value['Type'], value['Validator'], value['Unit'])
+ else:
+ validators[property] = (value['Type'], value['Validator'])
%>\
% endfor
% for intf in set(interfaces):
@@ -94,11 +107,29 @@ class Impl : public Parent
% for arg in props[intf]:
<% t = arg[:1].lower() + arg[1:] %>\
+<% fname = "validate"+arg %>\
decltype(std::declval<Base>().${t}()) ${t}(decltype(std::declval<Base>().${t}()) value) override
{
auto result = Base::${t}();
if (value != result)
{
+ % if arg in validators.keys():
+ if (!${fname}(value))
+ {
+ namespace error =
+ sdbusplus::xyz::openbmc_project::Common::Error;
+ namespace metadata =
+ phosphor::logging::xyz::openbmc_project::Common;
+ phosphor::logging::report<error::InvalidArgument>(
+ metadata::InvalidArgument::ARGUMENT_NAME("${t}"),
+ % if validators[arg][0] != "regex":
+ metadata::InvalidArgument::ARGUMENT_VALUE(std::to_string(value).c_str()));
+ % else:
+ metadata::InvalidArgument::ARGUMENT_VALUE(value.c_str()));
+ % endif
+ return result;
+ }
+ % endif
fs::path p(SETTINGS_PERSIST_PATH);
p /= path;
fs::create_directories(p.parent_path());
@@ -114,6 +145,46 @@ class Impl : public Parent
% endfor
private:
fs::path path;
+% for arg in props[intf]:
+% if arg in validators.keys():
+<% funcName = "validate"+arg %>\
+<% t = arg[:1].lower() + arg[1:] %>\
+
+ bool ${funcName}(decltype(std::declval<Base>().${t}()) value)
+ {
+ bool matched = false;
+ % if (arg in validators.keys()) and (validators[arg][0] == 'regex'):
+ std::regex regexToCheck("${validators[arg][1]}");
+ matched = std::regex_search(value, regexToCheck);
+ if (!matched)
+ {
+ std::string err = "Input parameter for ${arg} is invalid "
+ "Input: " + value + " not in the format of this regex: "
+ "${validators[arg][1]}";
+ using namespace phosphor::logging;
+ log<level::ERR>(err.c_str());
+ }
+ % elif (arg in validators.keys()) and (validators[arg][0] == 'range'):
+<% lowhigh = re.split('\.\.', validators[arg][1]) %>\
+ if ((value <= ${lowhigh[1]}) && (value >= ${lowhigh[0]}))
+ {
+ matched = true;
+ }
+ else
+ {
+ std::string err = "Input parameter for ${arg} is invalid "
+ "Input: " + std::to_string(value) + "in uint: "
+ "${validators[arg][2]} is not in range:${validators[arg][1]}";
+ using namespace phosphor::logging;
+ log<level::ERR>(err.c_str());
+ }
+ % elif (arg in validators.keys()):
+ <% assert("Unknown validation type: arg") %>\
+ % endif
+ return matched;
+ }
+% endif
+% endfor
};
template<class Archive>
@@ -184,8 +255,9 @@ class Manager
% endfor
% for index, object in enumerate(objects):
- % for property, value in settingsDict[object]['Defaults'].items():
+ % for property, value in settingsDict[object]['Properties'].items():
<% p = property[:1].lower() + property[1:] %>\
+<% defaultValue = value['Default'] %>\
path = fs::path(SETTINGS_PERSIST_PATH) / "${object}";
if (fs::exists(path))
{
@@ -196,7 +268,7 @@ class Manager
else
{
std::get<${index}>(settings)->
- ${get_setting_sdbusplus_type(settingsDict[object]['Interface'])}::${p}(${value});
+ ${get_setting_sdbusplus_type(settingsDict[object]['Interface'])}::${p}(${defaultValue});
}
% endfor
std::get<${index}>(settings)->emit_object_added();
OpenPOWER on IntegriCloud