diff options
-rw-r--r-- | Redfish.md | 11 | ||||
-rw-r--r-- | redfish-core/include/redfish.hpp | 3 | ||||
-rw-r--r-- | redfish-core/lib/fabric_adapters.hpp | 208 | ||||
-rw-r--r-- | redfish-core/lib/systems.hpp | 2 |
4 files changed, 224 insertions, 0 deletions
diff --git a/Redfish.md b/Redfish.md index 3f65de81df..ba58c55ba0 100644 --- a/Redfish.md +++ b/Redfish.md @@ -664,6 +664,17 @@ other. - Members@odata.count - Description +### /redfish/v1/Systems/system/FabricAdapters/ + +#### FabricAdapterCollection + +- Members +- Members@odata.count + +### /redfish/v1/Systems/system/FabricAdapters/{FabricAdapterId}/ + +#### FabricAdapter + ### /redfish/v1/Systems/system/LogServices/ #### LogServiceCollection diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp index e98a04cd62..cf385100bf 100644 --- a/redfish-core/include/redfish.hpp +++ b/redfish-core/include/redfish.hpp @@ -23,6 +23,7 @@ #include "environment_metrics.hpp" #include "ethernet.hpp" #include "event_service.hpp" +#include "fabric_adapters.hpp" #include "hypervisor_system.hpp" #include "log_services.hpp" #include "manager_diagnostic_data.hpp" @@ -213,6 +214,8 @@ class RedfishService requestRoutesEventService(app); requestRoutesEventDestinationCollection(app); requestRoutesEventDestination(app); + requestRoutesFabricAdapters(app); + requestRoutesFabricAdapterCollection(app); requestRoutesSubmitTestEvent(app); hypervisor::requestRoutesHypervisorSystems(app); diff --git a/redfish-core/lib/fabric_adapters.hpp b/redfish-core/lib/fabric_adapters.hpp new file mode 100644 index 0000000000..aacb056184 --- /dev/null +++ b/redfish-core/lib/fabric_adapters.hpp @@ -0,0 +1,208 @@ +#pragma once + +#include "app.hpp" +#include "dbus_utility.hpp" +#include "utils/collection.hpp" +#include "utils/json_utils.hpp" + +#include <boost/system/error_code.hpp> + +#include <array> +#include <functional> +#include <memory> +#include <string> +#include <string_view> + +namespace redfish +{ + +inline void handleAdapterError(const boost::system::error_code& ec, + crow::Response& res, + const std::string& adapterId) +{ + + if (ec.value() == boost::system::errc::io_error) + { + messages::resourceNotFound(res, "#FabricAdapter.v1_0_0.FabricAdapter", + adapterId); + return; + } + + BMCWEB_LOG_ERROR << "DBus method call failed with error " << ec.value(); + messages::internalError(res); +} + +inline void doAdapterGet(const std::shared_ptr<bmcweb::AsyncResp>& aResp, + const std::string& systemName, + const std::string& adapterId) +{ + aResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); + aResp->res.jsonValue["@odata.type"] = "#FabricAdapter.v1_0_0.FabricAdapter"; + aResp->res.jsonValue["Name"] = "Fabric Adapter"; + aResp->res.jsonValue["Id"] = adapterId; + aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces( + "redfish", "v1", "Systems", systemName, "FabricAdapters", adapterId); +} + +inline bool checkFabricAdapterId(const std::string& adapterPath, + const std::string& adapterId) +{ + std::string fabricAdapterName = + sdbusplus::message::object_path(adapterPath).filename(); + + return !(fabricAdapterName.empty() || fabricAdapterName != adapterId); +} + +inline void getValidFabricAdapterPath( + const std::string& adapterId, const std::string& systemName, + const std::shared_ptr<bmcweb::AsyncResp>& aResp, + std::function<void(const std::string& fabricAdapterPath, + const std::string& serviceName)>&& callback) +{ + if (systemName != "system") + { + messages::resourceNotFound(aResp->res, "ComputerSystem", systemName); + return; + } + constexpr std::array<std::string_view, 1> interfaces{ + "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; + + dbus::utility::getSubTree( + "/xyz/openbmc_project/inventory", 0, interfaces, + [adapterId, aResp, + callback](const boost::system::error_code& ec, + const dbus::utility::MapperGetSubTreeResponse& subtree) { + if (ec) + { + handleAdapterError(ec, aResp->res, adapterId); + return; + } + for (const auto& [adapterPath, serviceMap] : subtree) + { + if (checkFabricAdapterId(adapterPath, adapterId)) + { + callback(adapterPath, serviceMap.begin()->first); + return; + } + } + BMCWEB_LOG_WARNING << "Adapter not found"; + messages::resourceNotFound(aResp->res, "FabricAdapter", adapterId); + }); +} + +inline void + handleFabricAdapterGet(App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& aResp, + const std::string& systemName, + const std::string& adapterId) +{ + if (!redfish::setUpRedfishRoute(app, req, aResp)) + { + return; + } + + getValidFabricAdapterPath( + adapterId, systemName, aResp, + [aResp, systemName, adapterId](const std::string&, const std::string&) { + doAdapterGet(aResp, systemName, adapterId); + }); +} + +inline void handleFabricAdapterCollectionGet( + crow::App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& aResp, + const std::string& systemName) +{ + if (!redfish::setUpRedfishRoute(app, req, aResp)) + { + return; + } + if (systemName != "system") + { + messages::resourceNotFound(aResp->res, "ComputerSystem", systemName); + return; + } + + aResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); + aResp->res.jsonValue["@odata.type"] = + "#FabricAdapterCollection.FabricAdapterCollection"; + aResp->res.jsonValue["Name"] = "Fabric Adapter Collection"; + aResp->res.jsonValue["@odata.id"] = crow::utility::urlFromPieces( + "redfish", "v1", "Systems", systemName, "FabricAdapters"); + + constexpr std::array<std::string_view, 1> interfaces{ + "xyz.openbmc_project.Inventory.Item.FabricAdapter"}; + collection_util::getCollectionMembers( + aResp, boost::urls::url("/redfish/v1/Systems/system/FabricAdapters"), + interfaces); +} + +inline void handleFabricAdapterCollectionHead( + crow::App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& aResp, + const std::string& systemName) +{ + if (!redfish::setUpRedfishRoute(app, req, aResp)) + { + return; + } + if (systemName != "system") + { + messages::resourceNotFound(aResp->res, "ComputerSystem", systemName); + return; + } + aResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/FabricAdapterCollection/FabricAdapterCollection.json>; rel=describedby"); +} + +inline void + handleFabricAdapterHead(crow::App& app, const crow::Request& req, + const std::shared_ptr<bmcweb::AsyncResp>& aResp, + const std::string& systemName, + const std::string& adapterId) +{ + if (!redfish::setUpRedfishRoute(app, req, aResp)) + { + return; + } + + getValidFabricAdapterPath( + adapterId, systemName, aResp, + [aResp, systemName, adapterId](const std::string&, const std::string&) { + aResp->res.addHeader( + boost::beast::http::field::link, + "</redfish/v1/JsonSchemas/FabricAdapter/FabricAdapter.json>; rel=describedby"); + }); +} + +inline void requestRoutesFabricAdapterCollection(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") + .privileges(redfish::privileges::getFabricAdapterCollection) + .methods(boost::beast::http::verb::get)( + std::bind_front(handleFabricAdapterCollectionGet, std::ref(app))); + + BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/") + .privileges(redfish::privileges::headFabricAdapterCollection) + .methods(boost::beast::http::verb::head)( + std::bind_front(handleFabricAdapterCollectionHead, std::ref(app))); +} + +inline void requestRoutesFabricAdapters(App& app) +{ + BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") + .privileges(redfish::privileges::getFabricAdapter) + .methods(boost::beast::http::verb::get)( + std::bind_front(handleFabricAdapterGet, std::ref(app))); + + BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/FabricAdapters/<str>/") + .privileges(redfish::privileges::headFabricAdapter) + .methods(boost::beast::http::verb::head)( + std::bind_front(handleFabricAdapterHead, std::ref(app))); +} +} // namespace redfish diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp index 864a8d963e..d6f4fba7ad 100644 --- a/redfish-core/lib/systems.hpp +++ b/redfish-core/lib/systems.hpp @@ -2930,6 +2930,8 @@ inline void requestRoutesSystems(App& app) "/redfish/v1/Systems/system/Memory"; asyncResp->res.jsonValue["Storage"]["@odata.id"] = "/redfish/v1/Systems/system/Storage"; + asyncResp->res.jsonValue["FabricAdapters"]["@odata.id"] = + "/redfish/v1/Systems/system/FabricAdapters"; asyncResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]["target"] = "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"; |