From a72100201c2ebf3e8da33e9f325ae871bc4598bf Mon Sep 17 00:00:00 2001 From: George Liu Date: Wed, 5 Oct 2022 15:44:11 +0800 Subject: Implements PowerSupplies schema This commit implements the Redfish PowerSupplyCollection at /redfish/v1/Chassis//PowerSubsystem/PowerSupplies. It shall contain an array of links to resources of type PowerSupply that represent the power supplies that provide power to this chassis. For the association between power supply and chassis, refer to[1]. Also, the members property is implemented in the next commit with the PowerSupply implementation, this is so the validator will pass. [1] https://gerrit.openbmc.org/c/openbmc/phosphor-dbus-interfaces/+/57428 Tested: Validator passes 1. curl -k -H "X-Auth-Token: $token" -X GET https://${bmc}/redfish/v1/Chassis/chassis/PowerSubsystem/ PowerSupplies { "@odata.id": "/redfish/v1/Chassis/chassis/PowerSubsystem/ PowerSupplies" "@odata.type": "#PowerSupplyCollection.PowerSupplyCollection", "Description": "The collection of PowerSupply resource instances chassis", "Members": [ ], "Members@odata.count": 0, "Name": "Power Supply Collection" } 2. Bad chassisId curl -k -H "X-Auth-Token: $token" -X GET https://${bmc}/redfish/v1/Chassis/chassisError/PowerSubsystem/ PowerSupplies { "error": { "@Message.ExtendedInfo": [ { "@odata.type": "#Message.v1_1_1.Message", "Message": "The requested resource of type Chassis named 'chassisError' was not found.", "MessageArgs": [ "Chassis", "chassisError" ], "MessageId": "Base.1.13.0.ResourceNotFound", "MessageSeverity": "Critical", "Resolution": "Provide a valid resource identifier and resubmit the request." } ], "code": "Base.1.13.0.ResourceNotFound", "message": "The requested resource of type Chassis named 'chassisError' was not found." } } Signed-off-by: George Liu Change-Id: I48e087d6fb52013e3a96b44391cc4d86049ac176 --- Redfish.md | 6 ++ redfish-core/include/redfish.hpp | 2 + redfish-core/lib/power_subsystem.hpp | 3 + redfish-core/lib/power_supply.hpp | 123 +++++++++++++++++++++++++++++++++++ 4 files changed, 134 insertions(+) create mode 100644 redfish-core/lib/power_supply.hpp diff --git a/Redfish.md b/Redfish.md index 1714985938..65d405ff74 100644 --- a/Redfish.md +++ b/Redfish.md @@ -366,6 +366,12 @@ Fields common to all schemas - MinNumNeeded - MaxNumSupported +#### /redfish/v1/Chassis/{ChassisId}/PowerSubsystem/PowerSupplies + +##### PowerSupplies + +- Description + ### /redfish/v1/EventService/ #### EventService diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp index cf41824e81..ce09531c42 100644 --- a/redfish-core/include/redfish.hpp +++ b/redfish-core/include/redfish.hpp @@ -38,6 +38,7 @@ #include "pcie_slots.hpp" #include "power.hpp" #include "power_subsystem.hpp" +#include "power_supply.hpp" #include "processor.hpp" #include "redfish_sessions.hpp" #include "redfish_v1.hpp" @@ -90,6 +91,7 @@ class RedfishService #ifdef BMCWEB_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM requestRoutesEnvironmentMetrics(app); requestRoutesPowerSubsystem(app); + requestRoutesPowerSupplyCollection(app); requestRoutesThermalSubsystem(app); #endif requestRoutesManagerCollection(app); diff --git a/redfish-core/lib/power_subsystem.hpp b/redfish-core/lib/power_subsystem.hpp index 17ee1af608..52e1ec9d72 100644 --- a/redfish-core/lib/power_subsystem.hpp +++ b/redfish-core/lib/power_subsystem.hpp @@ -35,6 +35,9 @@ inline void doPowerSubsystemCollection( "redfish", "v1", "Chassis", chassisId, "PowerSubsystem"); asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; asyncResp->res.jsonValue["Status"]["Health"] = "OK"; + asyncResp->res.jsonValue["PowerSupplies"]["@odata.id"] = + crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId, + "PowerSubsystem", "PowerSupplies"); } inline void handlePowerSubsystemCollectionHead( diff --git a/redfish-core/lib/power_supply.hpp b/redfish-core/lib/power_supply.hpp new file mode 100644 index 0000000000..9fffa197c6 --- /dev/null +++ b/redfish-core/lib/power_supply.hpp @@ -0,0 +1,123 @@ +#pragma once + +#include "app.hpp" +#include "dbus_utility.hpp" +#include "query.hpp" +#include "registries/privilege_registry.hpp" +#include "utils/chassis_utils.hpp" + +#include +#include +#include + +namespace redfish +{ + +inline void updatePowerSupplyList( + const std::shared_ptr& /* 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 +} + +inline void + doPowerSupplyCollection(const std::shared_ptr& asyncResp, + const std::string& chassisId, + const std::optional& validChassisPath) +{ + if (!validChassisPath) + { + messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); + return; + } + + asyncResp->res.addHeader( + boost::beast::http::field::link, + "; rel=describedby"); + asyncResp->res.jsonValue["@odata.type"] = + "#PowerSupplyCollection.PowerSupplyCollection"; + asyncResp->res.jsonValue["Name"] = "Power Supply Collection"; + asyncResp->res.jsonValue["@odata.id"] = + crow::utility::urlFromPieces("redfish", "v1", "Chassis", chassisId, + "PowerSubsystem", "PowerSupplies"); + asyncResp->res.jsonValue["Description"] = + "The collection of PowerSupply resource instances."; + + std::string powerPath = *validChassisPath + "/powered_by"; + dbus::utility::getAssociationEndPoints( + powerPath, [asyncResp, chassisId]( + const boost::system::error_code& ec, + const dbus::utility::MapperEndPoints& endpoints) { + if (ec) + { + if (ec.value() != EBADR) + { + BMCWEB_LOG_ERROR << "DBUS response error" << ec.value(); + messages::internalError(asyncResp->res); + } + return; + } + + for (const auto& endpoint : endpoints) + { + updatePowerSupplyList(asyncResp, chassisId, endpoint); + } + }); +} + +inline void handlePowerSupplyCollectionHead( + App& app, const crow::Request& req, + const std::shared_ptr& asyncResp, + const std::string& chassisId) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + redfish::chassis_utils::getValidChassisPath( + asyncResp, chassisId, + [asyncResp, + chassisId](const std::optional& validChassisPath) { + if (!validChassisPath) + { + messages::resourceNotFound(asyncResp->res, "Chassis", chassisId); + return; + } + asyncResp->res.addHeader( + boost::beast::http::field::link, + "; rel=describedby"); + }); +} + +inline void handlePowerSupplyCollectionGet( + App& app, const crow::Request& req, + const std::shared_ptr& asyncResp, + const std::string& chassisId) +{ + if (!redfish::setUpRedfishRoute(app, req, asyncResp)) + { + return; + } + + redfish::chassis_utils::getValidChassisPath( + asyncResp, chassisId, + std::bind_front(doPowerSupplyCollection, asyncResp, chassisId)); +} + +inline void requestRoutesPowerSupplyCollection(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/Chassis//PowerSubsystem/PowerSupplies/") + .privileges(redfish::privileges::headPowerSupplyCollection) + .methods(boost::beast::http::verb::head)( + std::bind_front(handlePowerSupplyCollectionHead, std::ref(app))); + + BMCWEB_ROUTE(app, "/redfish/v1/Chassis//PowerSubsystem/PowerSupplies/") + .privileges(redfish::privileges::getPowerSupplyCollection) + .methods(boost::beast::http::verb::get)( + std::bind_front(handlePowerSupplyCollectionGet, std::ref(app))); +} + +} // namespace redfish -- cgit v1.2.3