summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Redfish.md6
-rw-r--r--redfish-core/include/redfish.hpp1
-rw-r--r--redfish-core/lib/power_supply.hpp170
3 files changed, 171 insertions, 6 deletions
diff --git a/Redfish.md b/Redfish.md
index 9fec4ed4b6..1cdce980aa 100644
--- a/Redfish.md
+++ b/Redfish.md
@@ -371,6 +371,12 @@ Fields common to all schemas
##### PowerSupplies
- Description
+- Members
+- Members@odata.count
+
+#### /redfish/v1/Chassis/{ChassisId}/PowerSubsystem/PowerSupplies/{PowerSupplyId}
+
+##### PowerSupply
### /redfish/v1/EventService/
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index ce09531c42..2bf0f4578e 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -91,6 +91,7 @@ class RedfishService
#ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM
requestRoutesEnvironmentMetrics(app);
requestRoutesPowerSubsystem(app);
+ requestRoutesPowerSupply(app);
requestRoutesPowerSupplyCollection(app);
requestRoutesThermalSubsystem(app);
#endif
diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp
index 430a29a632..ebc61c50ab 100644
--- a/redfish-core/lib/power_supply.hpp
+++ b/redfish-core/lib/power_supply.hpp
@@ -15,13 +15,26 @@
namespace redfish
{
-inline void updatePowerSupplyList(
- const std::shared_ptr<bmcweb::AsyncResp>& /* asyncResp */,
- const std::string& /* chassisId */,
- const std::string& /* powerSupplyPath */)
+inline void
+ updatePowerSupplyList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId,
+ const std::string& powerSupplyPath)
{
- // TODO In order for the validator to pass, the Members property will be
- // implemented on the next commit
+ std::string powerSupplyName =
+ sdbusplus::message::object_path(powerSupplyPath).filename();
+ if (powerSupplyName.empty())
+ {
+ return;
+ }
+
+ nlohmann::json item = nlohmann::json::object();
+ item["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
+ powerSupplyName);
+
+ nlohmann::json& powerSupplyList = asyncResp->res.jsonValue["Members"];
+ powerSupplyList.emplace_back(std::move(item));
+ asyncResp->res.jsonValue["Members@odata.count"] = powerSupplyList.size();
}
inline void
@@ -123,4 +136,149 @@ inline void requestRoutesPowerSupplyCollection(App& app)
std::bind_front(handlePowerSupplyCollectionGet, std::ref(app)));
}
+inline bool checkPowerSupplyId(const std::string& powerSupplyPath,
+ const std::string& powerSupplyId)
+{
+ std::string powerSupplyName =
+ sdbusplus::message::object_path(powerSupplyPath).filename();
+
+ return !(powerSupplyName.empty() || powerSupplyName != powerSupplyId);
+}
+
+inline void
+ getValidPowerSupplyPath(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& validChassisPath,
+ const std::string& powerSupplyId,
+ std::function<void()>&& callback)
+{
+ std::string powerPath = validChassisPath + "/powered_by";
+ dbus::utility::getAssociationEndPoints(
+ powerPath, [asyncResp, powerSupplyId, callback{std::move(callback)}](
+ const boost::system::error_code& ec,
+ const dbus::utility::MapperEndPoints& endpoints) {
+ if (ec)
+ {
+ if (ec.value() != EBADR)
+ {
+ BMCWEB_LOG_ERROR
+ << "DBUS response error for getAssociationEndPoints"
+ << ec.value();
+ messages::internalError(asyncResp->res);
+ return;
+ }
+ messages::resourceNotFound(asyncResp->res, "PowerSupplies",
+ powerSupplyId);
+ return;
+ }
+
+ for (const auto& endpoint : endpoints)
+ {
+ if (checkPowerSupplyId(endpoint, powerSupplyId))
+ {
+ callback();
+ return;
+ }
+ }
+
+ if (!endpoints.empty())
+ {
+ BMCWEB_LOG_WARNING << "Power supply not found: "
+ << powerSupplyId;
+ messages::resourceNotFound(asyncResp->res, "PowerSupplies",
+ powerSupplyId);
+ return;
+ }
+ });
+}
+
+inline void
+ doPowerSupplyGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId,
+ const std::string& powerSupplyId,
+ const std::optional<std::string>& validChassisPath)
+{
+ if (!validChassisPath)
+ {
+ messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+ return;
+ }
+
+ // Get the correct Path and Service that match the input parameters
+ getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
+ [asyncResp, chassisId, powerSupplyId]() {
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#PowerSupply.v1_5_0.PowerSupply";
+ asyncResp->res.jsonValue["Name"] = "Power Supply";
+ asyncResp->res.jsonValue["Id"] = powerSupplyId;
+ asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
+ "/redfish/v1/Chassis/{}/PowerSubsystem/PowerSupplies/{}", chassisId,
+ powerSupplyId);
+ });
+}
+
+inline void
+ handlePowerSupplyHead(App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId,
+ const std::string& powerSupplyId)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ redfish::chassis_utils::getValidChassisPath(
+ asyncResp, chassisId,
+ [asyncResp, chassisId,
+ powerSupplyId](const std::optional<std::string>& validChassisPath) {
+ if (!validChassisPath)
+ {
+ messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
+ return;
+ }
+
+ // Get the correct Path and Service that match the input parameters
+ getValidPowerSupplyPath(asyncResp, *validChassisPath, powerSupplyId,
+ [asyncResp]() {
+ asyncResp->res.addHeader(
+ boost::beast::http::field::link,
+ "</redfish/v1/JsonSchemas/PowerSupply/PowerSupply.json>; rel=describedby");
+ });
+ });
+}
+
+inline void
+ handlePowerSupplyGet(App& app, const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& chassisId,
+ const std::string& powerSupplyId)
+{
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
+ {
+ return;
+ }
+
+ redfish::chassis_utils::getValidChassisPath(
+ asyncResp, chassisId,
+ std::bind_front(doPowerSupplyGet, asyncResp, chassisId, powerSupplyId));
+}
+
+inline void requestRoutesPowerSupply(App& app)
+{
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
+ .privileges(redfish::privileges::headPowerSupply)
+ .methods(boost::beast::http::verb::head)(
+ std::bind_front(handlePowerSupplyHead, std::ref(app)));
+
+ BMCWEB_ROUTE(
+ app, "/redfish/v1/Chassis/<str>/PowerSubsystem/PowerSupplies/<str>/")
+ .privileges(redfish::privileges::getPowerSupply)
+ .methods(boost::beast::http::verb::get)(
+ std::bind_front(handlePowerSupplyGet, std::ref(app)));
+}
+
} // namespace redfish