summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Redfish.md8
-rw-r--r--meson.build1
-rw-r--r--redfish-core/lib/systems.hpp123
-rw-r--r--test/redfish-core/lib/system_test.cpp132
4 files changed, 245 insertions, 19 deletions
diff --git a/Redfish.md b/Redfish.md
index cdec1f90c0..93105ebfce 100644
--- a/Redfish.md
+++ b/Redfish.md
@@ -936,6 +936,14 @@ other.
- TotalThreads
- Version
+### /redfish/v1/Systems/system/ResetActionInfo/
+
+#### ActionInfo
+
+- Parameters/AllowableValues
+- Parameters/DataType
+- Parameters/Required
+
### /redfish/v1/Systems/system/Storage/
#### StorageCollection
diff --git a/meson.build b/meson.build
index f4976c1f9b..65aa99a939 100644
--- a/meson.build
+++ b/meson.build
@@ -455,6 +455,7 @@ srcfiles_unittest = files(
'test/redfish-core/include/utils/time_utils_test.cpp',
'test/redfish-core/lib/chassis_test.cpp',
'test/redfish-core/lib/sensors_test.cpp',
+ 'test/redfish-core/lib/system_test.cpp',
'test/redfish-core/lib/log_services_dump_test.cpp',
'test/redfish-core/lib/log_services_test.cpp',
'test/redfish-core/lib/update_service_test.cpp',
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index 24a8752a2e..37599e7d96 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -21,6 +21,7 @@
#include "dbus_singleton.hpp"
#include "dbus_utility.hpp"
#include "generated/enums/computer_system.hpp"
+#include "generated/enums/resource.hpp"
#include "health.hpp"
#include "hypervisor_system.hpp"
#include "led.hpp"
@@ -36,6 +37,7 @@
#include <boost/asio/error.hpp>
#include <boost/container/flat_map.hpp>
#include <boost/system/error_code.hpp>
+#include <boost/system/linux_error.hpp>
#include <boost/url/format.hpp>
#include <generated/enums/computer_system.hpp>
#include <sdbusplus/asio/property.hpp>
@@ -43,6 +45,7 @@
#include <sdbusplus/unpack_properties.hpp>
#include <array>
+#include <memory>
#include <string>
#include <string_view>
#include <variant>
@@ -3585,6 +3588,98 @@ inline void handleSystemCollectionResetActionHead(
boost::beast::http::field::link,
"</redfish/v1/JsonSchemas/ActionInfo/ActionInfo.json>; rel=describedby");
}
+
+/**
+ * @brief Translates allowed host transitions to redfish string
+ *
+ * @param[in] dbusAllowedHostTran The allowed host transition on dbus
+ * @param[out] allowableValues The translated host transition(s)
+ *
+ * @return Emplaces correpsonding Redfish translated value(s) in
+ * allowableValues. If translation not possible, does nothing to
+ * allowableValues.
+ */
+inline void
+ dbusToRfAllowedHostTransitions(const std::string& dbusAllowedHostTran,
+ nlohmann::json::array_t& allowableValues)
+{
+ if (dbusAllowedHostTran == "xyz.openbmc_project.State.Host.Transition.On")
+ {
+ allowableValues.emplace_back(resource::ResetType::On);
+ allowableValues.emplace_back(resource::ResetType::ForceOn);
+ }
+ else if (dbusAllowedHostTran ==
+ "xyz.openbmc_project.State.Host.Transition.Off")
+ {
+ allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
+ }
+ else if (dbusAllowedHostTran ==
+ "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot")
+ {
+ allowableValues.emplace_back(resource::ResetType::GracefulRestart);
+ }
+ else if (dbusAllowedHostTran ==
+ "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot")
+ {
+ allowableValues.emplace_back(resource::ResetType::ForceRestart);
+ }
+ else
+ {
+ BMCWEB_LOG_WARNING("Unsupported host tran {}", dbusAllowedHostTran);
+ }
+}
+
+inline void afterGetAllowedHostTransitions(
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const boost::system::error_code& ec,
+ const std::vector<std::string>& allowedHostTransitions)
+{
+ nlohmann::json::array_t allowableValues;
+
+ // Supported on all systems currently
+ allowableValues.emplace_back(resource::ResetType::ForceOff);
+ allowableValues.emplace_back(resource::ResetType::PowerCycle);
+ allowableValues.emplace_back(resource::ResetType::Nmi);
+
+ if (ec)
+ {
+ if (ec == boost::system::linux_error::bad_request_descriptor ||
+ ec == boost::asio::error::basic_errors::host_unreachable)
+ {
+ // Property not implemented so just return defaults
+ BMCWEB_LOG_DEBUG("Property not available {}", ec);
+ allowableValues.emplace_back(resource::ResetType::On);
+ allowableValues.emplace_back(resource::ResetType::ForceOn);
+ allowableValues.emplace_back(resource::ResetType::ForceRestart);
+ allowableValues.emplace_back(resource::ResetType::GracefulRestart);
+ allowableValues.emplace_back(resource::ResetType::GracefulShutdown);
+ }
+ else
+ {
+ BMCWEB_LOG_ERROR("DBUS response error {}", ec);
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ }
+ else
+ {
+ for (const std::string& transition : allowedHostTransitions)
+ {
+ BMCWEB_LOG_DEBUG("Found allowed host tran {}", transition);
+ dbusToRfAllowedHostTransitions(transition, allowableValues);
+ }
+ }
+
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = "String";
+ parameter["AllowableValues"] = std::move(allowableValues);
+ nlohmann::json::array_t parameters;
+ parameters.emplace_back(std::move(parameter));
+ asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
+}
+
inline void handleSystemCollectionResetActionGet(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
@@ -3625,25 +3720,15 @@ inline void handleSystemCollectionResetActionGet(
asyncResp->res.jsonValue["Name"] = "Reset Action Info";
asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
- nlohmann::json::array_t parameters;
- nlohmann::json::object_t parameter;
-
- parameter["Name"] = "ResetType";
- parameter["Required"] = true;
- parameter["DataType"] = "String";
- nlohmann::json::array_t allowableValues;
- allowableValues.emplace_back("On");
- allowableValues.emplace_back("ForceOff");
- allowableValues.emplace_back("ForceOn");
- allowableValues.emplace_back("ForceRestart");
- allowableValues.emplace_back("GracefulRestart");
- allowableValues.emplace_back("GracefulShutdown");
- allowableValues.emplace_back("PowerCycle");
- allowableValues.emplace_back("Nmi");
- parameter["AllowableValues"] = std::move(allowableValues);
- parameters.emplace_back(std::move(parameter));
-
- asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
+ // Look to see if system defines AllowedHostTransitions
+ sdbusplus::asio::getProperty<std::vector<std::string>>(
+ *crow::connections::systemBus, "xyz.openbmc_project.State.Host",
+ "/xyz/openbmc_project/state/host0", "xyz.openbmc_project.State.Host",
+ "AllowedHostTransitions",
+ [asyncResp](const boost::system::error_code& ec,
+ const std::vector<std::string>& allowedHostTransitions) {
+ afterGetAllowedHostTransitions(asyncResp, ec, allowedHostTransitions);
+ });
}
/**
* SystemResetActionInfo derived class for delivering Computer Systems
diff --git a/test/redfish-core/lib/system_test.cpp b/test/redfish-core/lib/system_test.cpp
new file mode 100644
index 0000000000..481c0df746
--- /dev/null
+++ b/test/redfish-core/lib/system_test.cpp
@@ -0,0 +1,132 @@
+#include "app.hpp"
+#include "async_resp.hpp"
+#include "http_request.hpp"
+#include "http_response.hpp"
+#include "systems.hpp"
+
+#include <boost/beast/core/string_type.hpp>
+#include <boost/beast/http/message.hpp>
+#include <boost/system/error_code.hpp>
+#include <nlohmann/json.hpp>
+
+#include <memory>
+#include <string>
+#include <system_error>
+#include <vector>
+
+#include <gtest/gtest.h>
+
+namespace redfish
+{
+namespace
+{
+
+TEST(GetAllowedHostTransition, UnexpectedError)
+{
+ auto response = std::make_shared<bmcweb::AsyncResp>();
+ boost::system::error_code ec = boost::asio::error::invalid_argument;
+ std::vector<std::string> allowedHostTransitions;
+
+ afterGetAllowedHostTransitions(response, ec, allowedHostTransitions);
+
+ EXPECT_EQ(response->res.result(),
+ boost::beast::http::status::internal_server_error);
+}
+
+TEST(GetAllowedHostTransition, NoPropOnDbus)
+{
+ auto response = std::make_shared<bmcweb::AsyncResp>();
+ boost::system::error_code ec =
+ boost::system::linux_error::bad_request_descriptor;
+ std::vector<std::string> allowedHostTransitions;
+
+ afterGetAllowedHostTransitions(response, ec, allowedHostTransitions);
+
+ nlohmann::json::array_t parameters;
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = "String";
+ nlohmann::json::array_t allowed;
+ allowed.emplace_back(resource::ResetType::ForceOff);
+ allowed.emplace_back(resource::ResetType::PowerCycle);
+ allowed.emplace_back(resource::ResetType::Nmi);
+ allowed.emplace_back(resource::ResetType::On);
+ allowed.emplace_back(resource::ResetType::ForceOn);
+ allowed.emplace_back(resource::ResetType::ForceRestart);
+ allowed.emplace_back(resource::ResetType::GracefulRestart);
+ allowed.emplace_back(resource::ResetType::GracefulShutdown);
+ parameter["AllowableValues"] = std::move(allowed);
+ parameters.emplace_back(std::move(parameter));
+
+ EXPECT_EQ(response->res.jsonValue["Parameters"], parameters);
+}
+
+TEST(GetAllowedHostTransition, NoForceRestart)
+{
+ auto response = std::make_shared<bmcweb::AsyncResp>();
+ boost::system::error_code ec;
+
+ std::vector<std::string> allowedHostTransitions = {
+ "xyz.openbmc_project.State.Host.Transition.On",
+ "xyz.openbmc_project.State.Host.Transition.Off",
+ "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot",
+ };
+
+ afterGetAllowedHostTransitions(response, ec, allowedHostTransitions);
+
+ nlohmann::json::array_t parameters;
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = "String";
+ nlohmann::json::array_t allowed;
+ allowed.emplace_back(resource::ResetType::ForceOff);
+ allowed.emplace_back(resource::ResetType::PowerCycle);
+ allowed.emplace_back(resource::ResetType::Nmi);
+ allowed.emplace_back(resource::ResetType::On);
+ allowed.emplace_back(resource::ResetType::ForceOn);
+ allowed.emplace_back(resource::ResetType::GracefulShutdown);
+ allowed.emplace_back(resource::ResetType::GracefulRestart);
+ parameter["AllowableValues"] = std::move(allowed);
+ parameters.emplace_back(std::move(parameter));
+
+ EXPECT_EQ(response->res.jsonValue["Parameters"], parameters);
+}
+
+TEST(GetAllowedHostTransition, AllSupported)
+{
+ auto response = std::make_shared<bmcweb::AsyncResp>();
+ boost::system::error_code ec;
+
+ std::vector<std::string> allowedHostTransitions = {
+ "xyz.openbmc_project.State.Host.Transition.On",
+ "xyz.openbmc_project.State.Host.Transition.Off",
+ "xyz.openbmc_project.State.Host.Transition.GracefulWarmReboot",
+ "xyz.openbmc_project.State.Host.Transition.ForceWarmReboot",
+ };
+
+ afterGetAllowedHostTransitions(response, ec, allowedHostTransitions);
+
+ nlohmann::json::array_t parameters;
+ nlohmann::json::object_t parameter;
+ parameter["Name"] = "ResetType";
+ parameter["Required"] = true;
+ parameter["DataType"] = "String";
+ nlohmann::json::array_t allowed;
+ allowed.emplace_back(resource::ResetType::ForceOff);
+ allowed.emplace_back(resource::ResetType::PowerCycle);
+ allowed.emplace_back(resource::ResetType::Nmi);
+ allowed.emplace_back(resource::ResetType::On);
+ allowed.emplace_back(resource::ResetType::ForceOn);
+ allowed.emplace_back(resource::ResetType::GracefulShutdown);
+ allowed.emplace_back(resource::ResetType::GracefulRestart);
+ allowed.emplace_back(resource::ResetType::ForceRestart);
+ parameter["AllowableValues"] = std::move(allowed);
+ parameters.emplace_back(std::move(parameter));
+
+ EXPECT_EQ(response->res.jsonValue["Parameters"], parameters);
+}
+
+} // namespace
+} // namespace redfish