diff options
-rw-r--r-- | redfish-core/include/utils/json_utils.hpp | 124 | ||||
-rw-r--r-- | redfish-core/lib/account_service.hpp | 235 | ||||
-rw-r--r-- | redfish-core/lib/redfish_sessions.hpp | 46 | ||||
-rw-r--r-- | redfish-core/lib/systems.hpp | 348 | ||||
-rw-r--r-- | redfish-core/src/utils/json_utils.cpp | 3 |
5 files changed, 325 insertions, 431 deletions
diff --git a/redfish-core/include/utils/json_utils.hpp b/redfish-core/include/utils/json_utils.hpp index bde81ce72d..3263c739a8 100644 --- a/redfish-core/include/utils/json_utils.hpp +++ b/redfish-core/include/utils/json_utils.hpp @@ -14,11 +14,13 @@ // limitations under the License. */ #pragma once + #include <crow/http_request.h> #include <crow/http_response.h> +#include <bitset> +#include <error_messages.hpp> #include <nlohmann/json.hpp> - namespace redfish { @@ -296,7 +298,125 @@ Result getDouble(const char* fieldName, const nlohmann::json& json, */ bool processJsonFromRequest(crow::Response& res, const crow::Request& req, nlohmann::json& reqJson); +namespace details +{ +template <typename Type> struct unpackValue +{ + using isRequired = std::true_type; + using JsonType = std::add_const_t<std::add_pointer_t<Type>>; +}; -} // namespace json_util +template <typename OptionalType> +struct unpackValue<boost::optional<OptionalType>> +{ + using isRequired = std::false_type; + using JsonType = std::add_const_t<std::add_pointer_t<OptionalType>>; +}; + +template <size_t Count, size_t Index> +void readJsonValues(const std::string& key, nlohmann::json& jsonValue, + crow::Response& res, std::bitset<Count>& handled) +{ + BMCWEB_LOG_DEBUG << "Unable to find variable for key" << key; + messages::addMessageToErrorJson(res.jsonValue, + messages::propertyUnknown(key)); + res.result(boost::beast::http::status::bad_request); +} + +template <size_t Count, size_t Index, typename ValueType, + typename... UnpackTypes> +void readJsonValues(const std::string& key, nlohmann::json& jsonValue, + crow::Response& res, std::bitset<Count>& handled, + const char* keyToCheck, ValueType& valueToFill, + UnpackTypes&... in) +{ + if (key != keyToCheck) + { + readJsonValues<Count, Index + 1>(key, jsonValue, res, handled, in...); + return; + } + + handled.set(Index); + + using UnpackType = typename unpackValue<ValueType>::JsonType; + UnpackType value = jsonValue.get_ptr<UnpackType>(); + if (value == nullptr) + { + BMCWEB_LOG_DEBUG << "Value for key " << key + << " was incorrect type: " << jsonValue.type_name(); + messages::addMessageToErrorJson( + res.jsonValue, + messages::propertyValueTypeError(jsonValue.dump(), key)); + res.result(boost::beast::http::status::bad_request); + return; + } + + valueToFill = *value; +} + +template <size_t Index = 0, size_t Count> +void handleMissing(std::bitset<Count>& handled, crow::Response& res) +{ +} + +template <size_t Index = 0, size_t Count, typename ValueType, + typename... UnpackTypes> +void handleMissing(std::bitset<Count>& handled, crow::Response& res, + const char* key, ValueType& unused, UnpackTypes&... in) +{ + if (!handled.test(Index) && unpackValue<ValueType>::isRequired::value) + { + messages::addMessageToErrorJson(res.jsonValue, + messages::propertyMissing(key)); + res.result(boost::beast::http::status::bad_request); + } + details::handleMissing<Index + 1, Count>(handled, res, in...); +} +} // namespace details + +template <typename... UnpackTypes> +bool readJson(const crow::Request& req, crow::Response& res, const char* key, + UnpackTypes&... in) +{ + nlohmann::json jsonRequest; + if (!json_util::processJsonFromRequest(res, req, jsonRequest)) + { + BMCWEB_LOG_DEBUG << "Json value not readable"; + return false; + } + if (!jsonRequest.is_object()) + { + BMCWEB_LOG_DEBUG << "Json value is not an object"; + messages::addMessageToErrorJson(res.jsonValue, + messages::unrecognizedRequestBody()); + res.result(boost::beast::http::status::bad_request); + return false; + } + + if (jsonRequest.empty()) + { + BMCWEB_LOG_DEBUG << "Json value is empty"; + messages::addMessageToErrorJson(res.jsonValue, messages::emptyJSON()); + res.result(boost::beast::http::status::bad_request); + return false; + } + + std::bitset<(sizeof...(in) + 1) / 2> handled(0); + for (const auto& item : jsonRequest.items()) + { + details::readJsonValues<(sizeof...(in) + 1) / 2, 0, UnpackTypes...>( + item.key(), item.value(), res, handled, key, in...); + } + + if (!handled.all()) + { + details::handleMissing(handled, res, key, in...); + + return false; + } + return res.result() == boost::beast::http::status::ok; +} + +} // namespace json_util } // namespace redfish diff --git a/redfish-core/lib/account_service.hpp b/redfish-core/lib/account_service.hpp index 3d442789e6..cc375914ec 100644 --- a/redfish-core/lib/account_service.hpp +++ b/redfish-core/lib/account_service.hpp @@ -139,121 +139,30 @@ class AccountsCollection : public Node { auto asyncResp = std::make_shared<AsyncResp>(res); - nlohmann::json patchRequest; - if (!json_util::processJsonFromRequest(res, req, patchRequest)) + std::string username; + std::string password; + boost::optional<std::string> roleId("User"); + boost::optional<bool> enabled = true; + if (!json_util::readJson(req, res, "UserName", username, "Password", + password, "RoleId", roleId, "Enabled", + enabled)) { return; } - const std::string* username = nullptr; - const std::string* password = nullptr; - // Default to user - std::string privilege = "priv-user"; - // default to enabled - bool enabled = true; - for (const auto& item : patchRequest.items()) - { - if (item.key() == "UserName") - { - username = item.value().get_ptr<const std::string*>(); - if (username == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError(item.value().dump(), - item.key())); - asyncResp->res.result( - boost::beast::http::status::bad_request); - return; - } - } - else if (item.key() == "Enabled") - { - const bool* enabledJson = item.value().get_ptr<const bool*>(); - if (enabledJson == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError(item.value().dump(), - item.key())); - asyncResp->res.result( - boost::beast::http::status::bad_request); - return; - } - enabled = *enabledJson; - } - else if (item.key() == "Password") - { - password = item.value().get_ptr<const std::string*>(); - if (password == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError(item.value().dump(), - item.key())); - asyncResp->res.result( - boost::beast::http::status::bad_request); - return; - } - } - else if (item.key() == "RoleId") - { - const std::string* roleIdJson = - item.value().get_ptr<const std::string*>(); - if (roleIdJson == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError(item.value().dump(), - item.key())); - asyncResp->res.result( - boost::beast::http::status::bad_request); - return; - } - const char* priv = getRoleIdFromPrivilege(*roleIdJson); - if (priv == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueNotInList(*roleIdJson, - item.key())); - asyncResp->res.result( - boost::beast::http::status::bad_request); - return; - } - privilege = priv; - } - else - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyNotWritable(item.key())); - asyncResp->res.result(boost::beast::http::status::bad_request); - return; - } - } - - if (username == nullptr) + const char* priv = getRoleIdFromPrivilege(*roleId); + if (priv == nullptr) { messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::createFailedMissingReqProperties("UserName")); - asyncResp->res.result(boost::beast::http::status::bad_request); - return; - } - - if (password == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::createFailedMissingReqProperties("Password")); - asyncResp->res.result(boost::beast::http::status::bad_request); + res.jsonValue, + messages::propertyValueNotInList(*roleId, "RoleId")); + res.result(boost::beast::http::status::bad_request); return; } + roleId = priv; crow::connections::systemBus->async_method_call( - [asyncResp, username{std::string(*username)}, - password{std::string(*password)}]( + [asyncResp, username, password{std::move(password)}]( const boost::system::error_code ec) { if (ec) { @@ -300,9 +209,9 @@ class AccountsCollection : public Node "/redfish/v1/AccountService/Accounts/" + username); }, "xyz.openbmc_project.User.Manager", "/xyz/openbmc_project/user", - "xyz.openbmc_project.User.Manager", "CreateUser", *username, + "xyz.openbmc_project.User.Manager", "CreateUser", username, std::array<const char*, 4>{"ipmi", "redfish", "ssh", "web"}, - privilege, enabled); + *roleId, *enabled); } static const char* getRoleIdFromPrivilege(boost::beast::string_view role) @@ -472,15 +381,16 @@ class ManagerAccount : public Node const std::vector<std::string>& params) override { auto asyncResp = std::make_shared<AsyncResp>(res); - if (params.size() != 1) { res.result(boost::beast::http::status::internal_server_error); return; } - nlohmann::json patchRequest; - if (!json_util::processJsonFromRequest(res, req, patchRequest)) + boost::optional<std::string> password; + boost::optional<bool> enabled; + if (!json_util::readJson(req, res, "Password", password, "Enabled", + enabled)) { return; } @@ -488,9 +398,8 @@ class ManagerAccount : public Node // Check the user exists before updating the fields checkDbusPathExists( "/xyz/openbmc_project/users/" + params[0], - [username{std::string(params[0])}, - patchRequest(std::move(patchRequest)), - asyncResp](bool userExists) { + [username{std::string(params[0])}, password(std::move(password)), + enabled(std::move(enabled)), asyncResp](bool userExists) { if (!userExists) { messages::addMessageToErrorJson( @@ -503,78 +412,44 @@ class ManagerAccount : public Node return; } - for (const auto& item : patchRequest.items()) + if (password) { - if (item.key() == "Password") + if (!pamUpdatePassword(username, *password)) { - const std::string* passStr = - item.value().get_ptr<const std::string*>(); - if (passStr == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError( - item.value().dump(), "Password")); - return; - } - BMCWEB_LOG_DEBUG << "Updating user: " << username - << " to password " << *passStr; - if (!pamUpdatePassword(username, *passStr)) - { - BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; - asyncResp->res.result(boost::beast::http::status:: - internal_server_error); - return; - } - } - else if (item.key() == "Enabled") - { - const bool* enabledBool = - item.value().get_ptr<const bool*>(); - - if (enabledBool == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError( - item.value().dump(), "Enabled")); - return; - } - crow::connections::systemBus->async_method_call( - [asyncResp](const boost::system::error_code ec) { - if (ec) - { - BMCWEB_LOG_ERROR - << "D-Bus responses error: " << ec; - asyncResp->res.result( - boost::beast::http::status:: - internal_server_error); - return; - } - // TODO Consider support polling mechanism to - // verify status of host and chassis after - // execute the requested action. - BMCWEB_LOG_DEBUG << "Response with no content"; - asyncResp->res.result( - boost::beast::http::status::no_content); - }, - "xyz.openbmc_project.User.Manager", - "/xyz/openbmc_project/users/" + username, - "org.freedesktop.DBus.Properties", "Set", - "xyz.openbmc_project.User.Attributes" - "UserEnabled", - sdbusplus::message::variant<bool>{*enabledBool}); - } - else - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyNotWritable(item.key())); + BMCWEB_LOG_ERROR << "pamUpdatePassword Failed"; asyncResp->res.result( - boost::beast::http::status::bad_request); + boost::beast::http::status::internal_server_error); return; } } + + if (enabled) + { + crow::connections::systemBus->async_method_call( + [asyncResp](const boost::system::error_code ec) { + if (ec) + { + BMCWEB_LOG_ERROR << "D-Bus responses error: " + << ec; + asyncResp->res.result( + boost::beast::http::status:: + internal_server_error); + return; + } + // TODO Consider support polling mechanism to + // verify status of host and chassis after + // execute the requested action. + BMCWEB_LOG_DEBUG << "Response with no content"; + asyncResp->res.result( + boost::beast::http::status::no_content); + }, + "xyz.openbmc_project.User.Manager", + "/xyz/openbmc_project/users/" + username, + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.User.Attributes" + "UserEnabled", + sdbusplus::message::variant<bool>{*enabled}); + } }); } @@ -611,6 +486,6 @@ class ManagerAccount : public Node "xyz.openbmc_project.User.Manager", userPath, "xyz.openbmc_project.Object.Delete", "Delete"); } -}; +}; // namespace redfish } // namespace redfish diff --git a/redfish-core/lib/redfish_sessions.hpp b/redfish-core/lib/redfish_sessions.hpp index 145bbb1755..4922724516 100644 --- a/redfish-core/lib/redfish_sessions.hpp +++ b/redfish-core/lib/redfish_sessions.hpp @@ -168,51 +168,13 @@ class SessionCollection : public Node void doPost(crow::Response& res, const crow::Request& req, const std::vector<std::string>& params) override { - nlohmann::json postRequest; - if (!json_util::processJsonFromRequest(res, req, postRequest)) - { - res.end(); - return; - } - std::string username; std::string password; - for (const auto& item : postRequest.items()) + if (!json_util::readJson(req, res, "UserName", username, "Password", + password)) { - const std::string* strVal = - item.value().get_ptr<const std::string*>(); - if (item.key() == "UserName") - { - if (strVal == nullptr) - { - res.result(boost::beast::http::status::bad_request); - messages::addMessageToErrorJson( - res.jsonValue, messages::propertyValueTypeError( - item.value().dump(), item.key())); - continue; - } - username = *strVal; - } - else if (item.key() == "Password") - { - if (strVal == nullptr) - { - res.result(boost::beast::http::status::bad_request); - messages::addMessageToErrorJson( - res.jsonValue, messages::propertyValueTypeError( - item.value().dump(), item.key())); - continue; - } - - password = *strVal; - } - else - { - res.result(boost::beast::http::status::bad_request); - messages::addMessageToErrorJson( - res.jsonValue, messages::propertyUnknown(item.key())); - continue; - } + res.end(); + return; } if (password.empty() || username.empty() || diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp index 2268897320..7097cfcac6 100644 --- a/redfish-core/lib/systems.hpp +++ b/redfish-core/lib/systems.hpp @@ -15,9 +15,8 @@ */ #pragma once -#include "boost/container/flat_map.hpp" -#include "node.hpp" - +#include <boost/container/flat_map.hpp> +#include <node.hpp> #include <utils/json_utils.hpp> namespace redfish @@ -580,121 +579,85 @@ class SystemActionsReset : public Node void doPost(crow::Response &res, const crow::Request &req, const std::vector<std::string> ¶ms) override { - // Parse JSON request body. - nlohmann::json post; - if (!json_util::processJsonFromRequest(res, req, post)) + auto asyncResp = std::make_shared<AsyncResp>(res); + + std::string resetType; + if (!json_util::readJson(req, res, "ResetType", resetType)) { return; } - auto asyncResp = std::make_shared<AsyncResp>(res); - - for (const auto &item : post.items()) + if (resetType == "ForceOff") { - if (item.key() == "ResetType") - { - const std::string *reqResetType = - item.value().get_ptr<const std::string *>(); - if (reqResetType == nullptr) - { - res.result(boost::beast::http::status::bad_request); - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::actionParameterValueFormatError( - item.value().dump(), "ResetType", - "ComputerSystem.Reset")); - res.end(); - return; - } + // Force off acts on the chassis + crow::connections::systemBus->async_method_call( + [asyncResp](const boost::system::error_code ec) { + if (ec) + { + BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return; + } + // TODO Consider support polling mechanism to verify + // status of host and chassis after execute the + // requested action. + BMCWEB_LOG_DEBUG << "Response with no content"; + asyncResp->res.result( + boost::beast::http::status::no_content); + }, + "xyz.openbmc_project.State.Chassis", + "/xyz/openbmc_project/state/chassis0", + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.State.Chassis", "RequestedPowerTransition", + sdbusplus::message::variant<std::string>{ + "xyz.openbmc_project.State.Chassis.Transition.Off"}); + return; + } + // all other actions operate on the host + std::string command; + // Execute Reset Action regarding to each reset type. + if (resetType == "On") + { + command = "xyz.openbmc_project.State.Host.Transition.On"; + } + else if (resetType == "GracefulShutdown") + { + command = "xyz.openbmc_project.State.Host.Transition.Off"; + } + else if (resetType == "GracefulRestart") + { + command = "xyz.openbmc_project.State.Host.Transition.Reboot"; + } + else + { + res.result(boost::beast::http::status::bad_request); + messages::addMessageToErrorJson( + asyncResp->res.jsonValue, + messages::actionParameterUnknown("Reset", resetType)); + return; + } - if (*reqResetType == "ForceOff") - { - // Force off acts on the chassis - crow::connections::systemBus->async_method_call( - [asyncResp](const boost::system::error_code ec) { - if (ec) - { - BMCWEB_LOG_ERROR << "D-Bus responses error: " - << ec; - asyncResp->res.result( - boost::beast::http::status:: - internal_server_error); - return; - } - // TODO Consider support polling mechanism to verify - // status of host and chassis after execute the - // requested action. - BMCWEB_LOG_DEBUG << "Response with no content"; - asyncResp->res.result( - boost::beast::http::status::no_content); - }, - "xyz.openbmc_project.State.Chassis", - "/xyz/openbmc_project/state/chassis0", - "org.freedesktop.DBus.Properties", "Set", - "RequestedPowerTransition", - "xyz.openbmc_project.State.Chassis", - sdbusplus::message::variant<std::string>{ - "xyz.openbmc_project.State.Chassis.Transition." - "Off"}); - return; - } - // all other actions operate on the host - std::string command; - // Execute Reset Action regarding to each reset type. - if (*reqResetType == "On") - { - command = "xyz.openbmc_project.State.Host.Transition.On"; - } - else if (*reqResetType == "GracefulShutdown") - { - command = "xyz.openbmc_project.State.Host.Transition.Off"; - } - else if (*reqResetType == "GracefulRestart") - { - command = - "xyz.openbmc_project.State.Host.Transition.Reboot"; - } - else + crow::connections::systemBus->async_method_call( + [asyncResp](const boost::system::error_code ec) { + if (ec) { - res.result(boost::beast::http::status::bad_request); - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::actionParameterUnknown("Reset", - *reqResetType)); - res.end(); + BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; + asyncResp->res.result( + boost::beast::http::status::internal_server_error); return; } - - crow::connections::systemBus->async_method_call( - [asyncResp](const boost::system::error_code ec) { - if (ec) - { - BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; - asyncResp->res.result(boost::beast::http::status:: - internal_server_error); - return; - } - // TODO Consider support polling mechanism to verify - // status of host and chassis after execute the - // requested action. - BMCWEB_LOG_DEBUG << "Response with no content"; - asyncResp->res.result( - boost::beast::http::status::no_content); - }, - "xyz.openbmc_project.State.Host", - "/xyz/openbmc_project/state/host0", - "org.freedesktop.DBus.Properties", "Set", - "RequestedHostTransition", "xyz.openbmc_project.State.Host", - sdbusplus::message::variant<std::string>{command}); - } - else - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::actionParameterUnknown("ComputerSystem.Reset", - item.key())); - } - } + // TODO Consider support polling mechanism to verify + // status of host and chassis after execute the + // requested action. + BMCWEB_LOG_DEBUG << "Response with no content"; + asyncResp->res.result(boost::beast::http::status::no_content); + }, + "xyz.openbmc_project.State.Host", + "/xyz/openbmc_project/state/host0", + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.State.Host", "RequestedHostTransition", + sdbusplus::message::variant<std::string>{command}); } }; @@ -805,114 +768,91 @@ class Systems : public Node res.result(boost::beast::http::status::internal_server_error); return; } - // Parse JSON request body - nlohmann::json patch; - if (!json_util::processJsonFromRequest(res, req, patch)) - { - return; - } const std::string &name = params[0]; res.jsonValue = Node::json; res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name; - for (const auto &item : patch.items()) + std::string indicatorLedTemp; + boost::optional<std::string> indicatorLed = indicatorLedTemp; + if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed)) { - if (item.key() == "IndicatorLed") - { - const std::string *reqLedState = - item.value().get_ptr<const std::string *>(); - if (reqLedState == nullptr) - { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyValueFormatError(item.value().dump(), - item.key())); - return; - } - - // Verify key value - std::string dbusLedState; - if (*reqLedState == "On") - { - dbusLedState = - "xyz.openbmc_project.Led.Physical.Action.Lit"; - } - else if (*reqLedState == "Blink") - { - dbusLedState = - "xyz.openbmc_project.Led.Physical.Action.Blinking"; - } - else if (*reqLedState == "Off") - { - dbusLedState = - "xyz.openbmc_project.Led.Physical.Action.Off"; - } - else - { - messages::addMessageToJsonRoot( - res.jsonValue, messages::propertyValueNotInList( - *reqLedState, "IndicatorLED")); - return; - } - - getHostState(asyncResp); - getComputerSystem(asyncResp, name); + return; + } - // Update led group - BMCWEB_LOG_DEBUG << "Update led group."; - crow::connections::systemBus->async_method_call( - [asyncResp{std::move(asyncResp)}]( - const boost::system::error_code ec) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; - asyncResp->res.result(boost::beast::http::status:: - internal_server_error); - return; - } - BMCWEB_LOG_DEBUG << "Led group update done."; - }, - "xyz.openbmc_project.LED.GroupManager", - "/xyz/openbmc_project/led/groups/enclosure_identify", - "org.freedesktop.DBus.Properties", "Set", - "xyz.openbmc_project.Led.Group", "Asserted", - sdbusplus::message::variant<bool>( - (dbusLedState == - "xyz.openbmc_project.Led.Physical.Action.Off" - ? false - : true))); - // Update identify led status - BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; - crow::connections::systemBus->async_method_call( - [asyncResp{std::move(asyncResp)}, - reqLedState{std::move(*reqLedState)}]( - const boost::system::error_code ec) { - if (ec) - { - BMCWEB_LOG_DEBUG << "DBUS response error " << ec; - asyncResp->res.result(boost::beast::http::status:: - internal_server_error); - return; - } - BMCWEB_LOG_DEBUG << "Led state update done."; - asyncResp->res.jsonValue["IndicatorLED"] = - std::move(reqLedState); - }, - "xyz.openbmc_project.LED.Controller.identify", - "/xyz/openbmc_project/led/physical/identify", - "org.freedesktop.DBus.Properties", "Set", - "xyz.openbmc_project.Led.Physical", "State", - sdbusplus::message::variant<std::string>(dbusLedState)); + if (indicatorLed) + { + std::string dbusLedState; + if (*indicatorLed == "On") + { + dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Lit"; + } + else if (*indicatorLed == "Blink") + { + dbusLedState = + "xyz.openbmc_project.Led.Physical.Action.Blinking"; + } + else if (*indicatorLed == "Off") + { + dbusLedState = "xyz.openbmc_project.Led.Physical.Action.Off"; } else { - messages::addMessageToErrorJson( - asyncResp->res.jsonValue, - messages::propertyNotWritable(item.key())); + messages::addMessageToJsonRoot( + res.jsonValue, messages::propertyValueNotInList( + *indicatorLed, "IndicatorLED")); return; } + + getHostState(asyncResp); + getComputerSystem(asyncResp, name); + + // Update led group + BMCWEB_LOG_DEBUG << "Update led group."; + crow::connections::systemBus->async_method_call( + [asyncResp{std::move(asyncResp)}]( + const boost::system::error_code ec) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error " << ec; + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return; + } + BMCWEB_LOG_DEBUG << "Led group update done."; + }, + "xyz.openbmc_project.LED.GroupManager", + "/xyz/openbmc_project/led/groups/enclosure_identify", + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Led.Group", "Asserted", + sdbusplus::message::variant<bool>( + (dbusLedState == + "xyz.openbmc_project.Led.Physical.Action.Off" + ? false + : true))); + // Update identify led status + BMCWEB_LOG_DEBUG << "Update led SoftwareInventoryCollection."; + crow::connections::systemBus->async_method_call( + [asyncResp{std::move(asyncResp)}, + indicatorLed{std::move(*indicatorLed)}]( + const boost::system::error_code ec) { + if (ec) + { + BMCWEB_LOG_DEBUG << "DBUS response error " << ec; + asyncResp->res.result( + boost::beast::http::status::internal_server_error); + return; + } + BMCWEB_LOG_DEBUG << "Led state update done."; + asyncResp->res.jsonValue["IndicatorLED"] = + std::move(indicatorLed); + }, + "xyz.openbmc_project.LED.Controller.identify", + "/xyz/openbmc_project/led/physical/identify", + "org.freedesktop.DBus.Properties", "Set", + "xyz.openbmc_project.Led.Physical", "State", + sdbusplus::message::variant<std::string>(dbusLedState)); } } }; diff --git a/redfish-core/src/utils/json_utils.cpp b/redfish-core/src/utils/json_utils.cpp index 868601f72d..e14131713a 100644 --- a/redfish-core/src/utils/json_utils.cpp +++ b/redfish-core/src/utils/json_utils.cpp @@ -15,8 +15,6 @@ */ #include "utils/json_utils.hpp" -#include <error_messages.hpp> - namespace redfish { @@ -521,5 +519,4 @@ bool processJsonFromRequest(crow::Response& res, const crow::Request& req, } } // namespace json_util - } // namespace redfish |