AssetTag: Add PATCH support
Use the same AssetTag logic from the GET.
Look for xyz.openbmc_project.Inventory.Item.System interface then
call that service and path to set the AssetTag.
This assumes there is 1 "Item.System".
Considered something like
"if (!boost::ends_with(path, "system"))
continue;
"
but no where else does bmcweb check that the Item.System is named
"system" i.e. that /redfish/v1/Systems/system is actually named
"system" on D-Bus.
Considered looking that the service had the interface if not move
to the next service but the GET code does not so just followed it.
Tested:
curl -k-X PATCH -d '{"AssetTag": "Paramo"}' https://${bmc}/redfish/v1/Systems/system/
curl -k https://${bmc}/redfish/v1/Systems/system/
{
"@odata.id": "/redfish/v1/Systems/system",
"@odata.type": "#ComputerSystem.v1_12_0.ComputerSystem",
"Actions": {
"#ComputerSystem.Reset": {
"@Redfish.ActionInfo": "/redfish/v1/Systems/system/ResetActionInfo",
"target": "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"
}
},
"AssetTag": "Paramo",
...
Validator passes.
Change-Id: I45f80a8a69457f76e6e83ad2333856abe61de933
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index d042ca3..5f9801b 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -1296,6 +1296,83 @@
}
/**
+ * @brief Sets AssetTag
+ *
+ * @param[in] aResp Shared pointer for generating response message.
+ * @param[in] assetTag "AssetTag" from request.
+ *
+ * @return None.
+ */
+inline void setAssetTag(const std::shared_ptr<AsyncResp>& aResp,
+ const std::string& assetTag)
+{
+ crow::connections::systemBus->async_method_call(
+ [aResp, assetTag](
+ const boost::system::error_code ec,
+ const std::vector<std::pair<
+ std::string,
+ std::vector<std::pair<std::string, std::vector<std::string>>>>>&
+ subtree) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "D-Bus response error on GetSubTree " << ec;
+ messages::internalError(aResp->res);
+ return;
+ }
+ if (subtree.size() == 0)
+ {
+ BMCWEB_LOG_DEBUG << "Can't find system D-Bus object!";
+ messages::internalError(aResp->res);
+ return;
+ }
+ // Assume only 1 system D-Bus object
+ // Throw an error if there is more than 1
+ if (subtree.size() > 1)
+ {
+ BMCWEB_LOG_DEBUG << "Found more than 1 system D-Bus object!";
+ messages::internalError(aResp->res);
+ return;
+ }
+ if (subtree[0].first.empty() || subtree[0].second.size() != 1)
+ {
+ BMCWEB_LOG_DEBUG << "Asset Tag Set mapper error!";
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ const std::string& path = subtree[0].first;
+ const std::string& service = subtree[0].second.begin()->first;
+
+ if (service.empty())
+ {
+ BMCWEB_LOG_DEBUG << "Asset Tag Set service mapper error!";
+ messages::internalError(aResp->res);
+ return;
+ }
+
+ crow::connections::systemBus->async_method_call(
+ [aResp](const boost::system::error_code ec2) {
+ if (ec2)
+ {
+ BMCWEB_LOG_DEBUG
+ << "D-Bus response error on AssetTag Set " << ec2;
+ messages::internalError(aResp->res);
+ return;
+ }
+ },
+ service, path, "org.freedesktop.DBus.Properties", "Set",
+ "xyz.openbmc_project.Inventory.Decorator.AssetTag", "AssetTag",
+ std::variant<std::string>(assetTag));
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", int32_t(0),
+ std::array<const char*, 1>{
+ "xyz.openbmc_project.Inventory.Item.System"});
+}
+
+/**
* @brief Sets automaticRetry (Auto Reboot)
*
* @param[in] aResp Shared pointer for generating response message.
@@ -1984,18 +2061,25 @@
std::optional<std::string> indicatorLed;
std::optional<nlohmann::json> bootProps;
std::optional<nlohmann::json> wdtTimerProps;
+ std::optional<std::string> assetTag;
std::optional<std::string> powerRestorePolicy;
auto asyncResp = std::make_shared<AsyncResp>(res);
if (!json_util::readJson(req, res, "IndicatorLED", indicatorLed, "Boot",
bootProps, "WatchdogTimer", wdtTimerProps,
- "PowerRestorePolicy", powerRestorePolicy))
+ "PowerRestorePolicy", powerRestorePolicy,
+ "AssetTag", assetTag))
{
return;
}
res.result(boost::beast::http::status::no_content);
+ if (assetTag)
+ {
+ setAssetTag(asyncResp, *assetTag);
+ }
+
if (wdtTimerProps)
{
std::optional<bool> wdtEnable;