blob: 698f697006f69833972eee73c733053583d1a66d [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
Borawski.Lukasz9c3106852018-02-09 15:24:22 +01004#pragma once
5
Willy Tu13451e32023-05-24 16:08:18 -07006#include "bmcweb_config.h"
7
Sui Chena51fc2d2022-07-14 17:21:53 -07008#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08009#include "async_resp.hpp"
10#include "dbus_singleton.hpp"
Sui Chena51fc2d2022-07-14 17:21:53 -070011#include "dbus_utility.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080012#include "error_messages.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070013#include "generated/enums/action_info.hpp"
14#include "generated/enums/manager.hpp"
15#include "generated/enums/resource.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080016#include "http_request.hpp"
George Liu79f3b6a2021-05-13 18:08:44 +080017#include "led.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080018#include "logging.hpp"
19#include "persistent_data.hpp"
Sui Chena51fc2d2022-07-14 17:21:53 -070020#include "query.hpp"
rohitpaic1a75eb2025-01-03 19:13:36 +053021#include "redfish.hpp"
Jennifer Leec5d03ff2019-03-08 15:42:58 -080022#include "redfish_util.hpp"
Sui Chena51fc2d2022-07-14 17:21:53 -070023#include "registries/privilege_registry.hpp"
Krzysztof Grobelnyfac6e532022-08-04 12:42:45 +020024#include "utils/dbus_utils.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080025#include "utils/json_utils.hpp"
Corey Ethingtone30d3342025-06-24 11:25:11 -040026#include "utils/manager_utils.hpp"
Sui Chena51fc2d2022-07-14 17:21:53 -070027#include "utils/sw_utils.hpp"
28#include "utils/systemd_utils.hpp"
Ed Tanous2b829372022-08-03 14:22:34 -070029#include "utils/time_utils.hpp"
Borawski.Lukasz9c3106852018-02-09 15:24:22 +010030
Ed Tanousd7857202025-01-28 15:32:26 -080031#include <systemd/sd-bus.h>
32
Ed Tanousd7857202025-01-28 15:32:26 -080033#include <boost/beast/http/status.hpp>
34#include <boost/beast/http/verb.hpp>
George Liue99073f2022-12-09 11:06:16 +080035#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070036#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080037#include <boost/url/url.hpp>
38#include <nlohmann/json.hpp>
Krzysztof Grobelnyfac6e532022-08-04 12:42:45 +020039#include <sdbusplus/asio/property.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080040#include <sdbusplus/message.hpp>
41#include <sdbusplus/message/native_types.hpp>
Krzysztof Grobelnyfac6e532022-08-04 12:42:45 +020042#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050043
Ed Tanousd7857202025-01-28 15:32:26 -080044#include <cstddef>
Gunnar Mills4bfefa72020-07-30 13:54:29 -050045#include <cstdint>
Ed Tanousd7857202025-01-28 15:32:26 -080046#include <format>
47#include <functional>
48#include <map>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050049#include <memory>
Konstantin Aladyshev9970e932024-02-20 09:51:29 +030050#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070051#include <ranges>
Konstantin Aladyshev9970e932024-02-20 09:51:29 +030052#include <string>
George Liue99073f2022-12-09 11:06:16 +080053#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080054#include <utility>
James Feist5b4aa862018-08-16 14:07:01 -070055
Ed Tanous1abe55e2018-09-05 08:30:59 -070056namespace redfish
57{
Jennifer Leeed5befb2018-08-10 11:29:45 -070058
George Liu79f3b6a2021-05-13 18:08:44 +080059/**
60 * Set the locationIndicatorActive.
61 *
62 * @param[in,out] asyncResp Async HTTP response.
63 * @param[in] locationIndicatorActive Value of the property
64 */
65inline void setLocationIndicatorActiveState(
66 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
67 bool locationIndicatorActive, const std::string& managerId)
68{
Myung Bae07754492025-08-22 16:03:40 -040069 manager_utils::getValidManagerPath(
70 asyncResp, managerId,
71 [asyncResp, locationIndicatorActive](
72 const std::string& managerPath,
73 const dbus::utility::MapperServiceMap& serviceMap) {
74 if (managerPath.empty() || serviceMap.size() != 1)
75 {
76 BMCWEB_LOG_DEBUG("Error getting bmc D-Bus object!");
77 messages::internalError(asyncResp->res);
78 return;
79 }
80 setLocationIndicatorActive(asyncResp, managerPath,
81 locationIndicatorActive);
82 });
George Liu79f3b6a2021-05-13 18:08:44 +080083}
84
Jagpal Singh Gilld27c31e2024-10-15 15:10:19 -070085inline std::string getBMCUpdateServiceName()
86{
87 if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
88 {
89 return "xyz.openbmc_project.Software.Manager";
90 }
91 return "xyz.openbmc_project.Software.BMC.Updater";
92}
93
94inline std::string getBMCUpdateServicePath()
95{
96 if constexpr (BMCWEB_REDFISH_UPDATESERVICE_USE_DBUS)
97 {
98 return "/xyz/openbmc_project/software/bmc";
99 }
100 return "/xyz/openbmc_project/software";
101}
102
Jennifer Leeed5befb2018-08-10 11:29:45 -0700103/**
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500104 * Function reboots the BMC.
105 *
106 * @param[in] asyncResp - Shared pointer for completing asynchronous calls
Jennifer Leeed5befb2018-08-10 11:29:45 -0700107 */
Patrick Williams504af5a2025-02-03 14:29:03 -0500108inline void doBMCGracefulRestart(
109 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500110{
111 const char* processName = "xyz.openbmc_project.State.BMC";
112 const char* objectPath = "/xyz/openbmc_project/state/bmc0";
113 const char* interfaceName = "xyz.openbmc_project.State.BMC";
114 const std::string& propertyValue =
115 "xyz.openbmc_project.State.BMC.Transition.Reboot";
116 const char* destProperty = "RequestedBMCTransition";
117
118 // Create the D-Bus variant for D-Bus call.
George Liu9ae226f2023-06-21 17:56:46 +0800119 sdbusplus::asio::setProperty(
120 *crow::connections::systemBus, processName, objectPath, interfaceName,
121 destProperty, propertyValue,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800122 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400123 // Use "Set" method to set the property value.
124 if (ec)
125 {
126 BMCWEB_LOG_DEBUG("[Set] Bad D-Bus request error: {}", ec);
127 messages::internalError(asyncResp->res);
128 return;
129 }
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500130
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400131 messages::success(asyncResp->res);
132 });
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500133}
134
Patrick Williams504af5a2025-02-03 14:29:03 -0500135inline void doBMCForceRestart(
136 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Jayaprakash Mutyalaf92af382020-06-16 23:29:41 +0000137{
138 const char* processName = "xyz.openbmc_project.State.BMC";
139 const char* objectPath = "/xyz/openbmc_project/state/bmc0";
140 const char* interfaceName = "xyz.openbmc_project.State.BMC";
141 const std::string& propertyValue =
142 "xyz.openbmc_project.State.BMC.Transition.HardReboot";
143 const char* destProperty = "RequestedBMCTransition";
144
145 // Create the D-Bus variant for D-Bus call.
George Liu9ae226f2023-06-21 17:56:46 +0800146 sdbusplus::asio::setProperty(
147 *crow::connections::systemBus, processName, objectPath, interfaceName,
148 destProperty, propertyValue,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800149 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400150 // Use "Set" method to set the property value.
151 if (ec)
152 {
153 BMCWEB_LOG_DEBUG("[Set] Bad D-Bus request error: {}", ec);
154 messages::internalError(asyncResp->res);
155 return;
156 }
Jayaprakash Mutyalaf92af382020-06-16 23:29:41 +0000157
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400158 messages::success(asyncResp->res);
159 });
Jayaprakash Mutyalaf92af382020-06-16 23:29:41 +0000160}
161
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500162/**
Myung Bae64acd262025-08-21 15:51:21 -0400163 * ManagerResetAction handles POST method request.
164 * Analyzes POST body before sending Reset (Reboot) request data to D-Bus.
165 * OpenBMC supports ResetType "GracefulRestart" and "ForceRestart".
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500166 */
Myung Bae64acd262025-08-21 15:51:21 -0400167
168inline void handleManagerResetAction(
169 crow::App& app, const crow::Request& req,
170 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
171 const std::string& managerId)
Jennifer Leeed5befb2018-08-10 11:29:45 -0700172{
Myung Bae64acd262025-08-21 15:51:21 -0400173 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
174 {
175 return;
176 }
177 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
178 {
179 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
180 return;
181 }
Jennifer Leeed5befb2018-08-10 11:29:45 -0700182
Myung Bae64acd262025-08-21 15:51:21 -0400183 BMCWEB_LOG_DEBUG("Post Manager Reset.");
Ed Tanous253f11b2024-05-16 09:38:31 -0700184
Myung Bae64acd262025-08-21 15:51:21 -0400185 std::string resetType;
Gunnar Mills2a5c4402020-05-19 09:07:24 -0500186
Myung Bae64acd262025-08-21 15:51:21 -0400187 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
188 {
189 return;
190 }
Jennifer Leeed5befb2018-08-10 11:29:45 -0700191
Myung Bae64acd262025-08-21 15:51:21 -0400192 if (resetType == "GracefulRestart")
193 {
194 BMCWEB_LOG_DEBUG("Proceeding with {}", resetType);
195 doBMCGracefulRestart(asyncResp);
196 return;
197 }
198 if (resetType == "ForceRestart")
199 {
200 BMCWEB_LOG_DEBUG("Proceeding with {}", resetType);
201 doBMCForceRestart(asyncResp);
202 return;
203 }
204 BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}", resetType);
205 messages::actionParameterNotSupported(asyncResp->res, resetType,
206 "ResetType");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700207}
Jennifer Leeed5befb2018-08-10 11:29:45 -0700208
Gunnar Mills3e40fc72020-05-19 19:18:17 -0500209/**
Myung Bae64acd262025-08-21 15:51:21 -0400210 * Function handles ResetToDefaults POST method request.
211 *
212 * Analyzes POST body message and factory resets BMC by calling
213 * BMC code updater factory reset followed by a BMC reboot.
214 *
215 * BMC code updater factory reset wipes the whole BMC read-write
216 * filesystem which includes things like the network settings.
217 *
218 * OpenBMC only supports ResetType "ResetAll".
Gunnar Mills3e40fc72020-05-19 19:18:17 -0500219 */
Myung Bae64acd262025-08-21 15:51:21 -0400220
221inline void handleManagerResetToDefaultsAction(
222 crow::App& app, const crow::Request& req,
223 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
224 const std::string& managerId)
Gunnar Mills3e40fc72020-05-19 19:18:17 -0500225{
Myung Bae64acd262025-08-21 15:51:21 -0400226 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
227 {
228 return;
229 }
Gunnar Mills3e40fc72020-05-19 19:18:17 -0500230
Myung Bae64acd262025-08-21 15:51:21 -0400231 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
232 {
233 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
234 return;
235 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400236
Myung Bae64acd262025-08-21 15:51:21 -0400237 BMCWEB_LOG_DEBUG("Post ResetToDefaults.");
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400238
Myung Bae64acd262025-08-21 15:51:21 -0400239 std::optional<std::string> resetType;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400240
Myung Bae64acd262025-08-21 15:51:21 -0400241 if (!json_util::readJsonAction( //
242 req, asyncResp->res, //
243 "ResetType", resetType //
244 ))
245 {
246 BMCWEB_LOG_DEBUG("Missing property ResetType.");
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400247
Myung Bae64acd262025-08-21 15:51:21 -0400248 messages::actionParameterMissing(asyncResp->res, "ResetToDefaults",
249 "ResetType");
250 return;
251 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400252
Myung Bae64acd262025-08-21 15:51:21 -0400253 if (resetType.value_or("") != "ResetAll")
254 {
255 BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}",
256 resetType.value_or(""));
257 messages::actionParameterNotSupported(
258 asyncResp->res, resetType.value_or(""), "ResetType");
259 return;
260 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400261
Myung Bae64acd262025-08-21 15:51:21 -0400262 crow::connections::systemBus->async_method_call(
263 [asyncResp](const boost::system::error_code& ec) {
264 if (ec)
265 {
266 BMCWEB_LOG_DEBUG("Failed to ResetToDefaults: {}", ec);
267 messages::internalError(asyncResp->res);
268 return;
269 }
270 // Factory Reset doesn't actually happen until a reboot
271 // Can't erase what the BMC is running on
272 doBMCGracefulRestart(asyncResp);
273 },
274 getBMCUpdateServiceName(), getBMCUpdateServicePath(),
275 "xyz.openbmc_project.Common.FactoryReset", "Reset");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700276}
Gunnar Mills3e40fc72020-05-19 19:18:17 -0500277
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530278/**
279 * ManagerResetActionInfo derived class for delivering Manager
280 * ResetType AllowableValues using ResetInfo schema.
281 */
Myung Bae64acd262025-08-21 15:51:21 -0400282inline void handleManagerResetActionInfo(
283 crow::App& app, const crow::Request& req,
284 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
285 const std::string& managerId)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530286{
Myung Bae64acd262025-08-21 15:51:21 -0400287 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
288 {
289 return;
290 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700291
Myung Bae64acd262025-08-21 15:51:21 -0400292 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
293 {
294 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
295 return;
296 }
Ed Tanous14766872022-03-15 10:44:42 -0700297
Myung Bae64acd262025-08-21 15:51:21 -0400298 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
299 asyncResp->res.jsonValue["@odata.id"] =
300 boost::urls::format("/redfish/v1/Managers/{}/ResetActionInfo",
301 BMCWEB_REDFISH_MANAGER_URI_NAME);
302 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
303 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
304 nlohmann::json::object_t parameter;
305 parameter["Name"] = "ResetType";
306 parameter["Required"] = true;
307 parameter["DataType"] = action_info::ParameterTypes::String;
Ed Tanous253f11b2024-05-16 09:38:31 -0700308
Myung Bae64acd262025-08-21 15:51:21 -0400309 nlohmann::json::array_t allowableValues;
310 allowableValues.emplace_back("GracefulRestart");
311 allowableValues.emplace_back("ForceRestart");
312 parameter["AllowableValues"] = std::move(allowableValues);
Ed Tanous14766872022-03-15 10:44:42 -0700313
Myung Bae64acd262025-08-21 15:51:21 -0400314 nlohmann::json::array_t parameters;
315 parameters.emplace_back(std::move(parameter));
Ed Tanous14766872022-03-15 10:44:42 -0700316
Myung Bae64acd262025-08-21 15:51:21 -0400317 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700318}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530319
SunnySrivastava1984071d8fd2020-10-28 02:20:30 -0500320/**
321 * @brief Retrieves BMC manager location data over DBus
322 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700323 * @param[in] asyncResp Shared pointer for completing asynchronous calls
SunnySrivastava1984071d8fd2020-10-28 02:20:30 -0500324 * @param[in] connectionName - service name
325 * @param[in] path - object path
326 * @return none
327 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700328inline void getLocation(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
SunnySrivastava1984071d8fd2020-10-28 02:20:30 -0500329 const std::string& connectionName,
330 const std::string& path)
331{
Ed Tanous62598e32023-07-17 17:06:25 -0700332 BMCWEB_LOG_DEBUG("Get BMC manager Location data.");
SunnySrivastava1984071d8fd2020-10-28 02:20:30 -0500333
Ed Tanousdeae6a72024-11-11 21:58:57 -0800334 dbus::utility::getProperty<std::string>(
335 connectionName, path,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700336 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanousac106bf2023-06-07 09:24:59 -0700337 [asyncResp](const boost::system::error_code& ec,
338 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400339 if (ec)
340 {
341 BMCWEB_LOG_DEBUG("DBUS response error for "
342 "Location");
343 messages::internalError(asyncResp->res);
344 return;
345 }
SunnySrivastava1984071d8fd2020-10-28 02:20:30 -0500346
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400347 asyncResp->res
348 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
349 property;
350 });
SunnySrivastava1984071d8fd2020-10-28 02:20:30 -0500351}
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700352// avoid name collision systems.hpp
Patrick Williams504af5a2025-02-03 14:29:03 -0500353inline void managerGetLastResetTime(
354 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700355{
Ed Tanous62598e32023-07-17 17:06:25 -0700356 BMCWEB_LOG_DEBUG("Getting Manager Last Reset Time");
Ed Tanous52cc1122020-07-18 13:51:21 -0700357
Ed Tanousdeae6a72024-11-11 21:58:57 -0800358 dbus::utility::getProperty<uint64_t>(
359 "xyz.openbmc_project.State.BMC", "/xyz/openbmc_project/state/bmc0",
360 "xyz.openbmc_project.State.BMC", "LastRebootTime",
Ed Tanousac106bf2023-06-07 09:24:59 -0700361 [asyncResp](const boost::system::error_code& ec,
362 const uint64_t lastResetTime) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400363 if (ec)
364 {
365 BMCWEB_LOG_DEBUG("D-BUS response error {}", ec);
366 return;
367 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700368
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400369 // LastRebootTime is epoch time, in milliseconds
370 // https://github.com/openbmc/phosphor-dbus-interfaces/blob/7f9a128eb9296e926422ddc312c148b625890bb6/xyz/openbmc_project/State/BMC.interface.yaml#L19
371 uint64_t lastResetTimeStamp = lastResetTime / 1000;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700372
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400373 // Convert to ISO 8601 standard
374 asyncResp->res.jsonValue["LastResetTime"] =
375 redfish::time_utils::getDateTimeUint(lastResetTimeStamp);
376 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700377}
378
379/**
380 * @brief Set the running firmware image
381 *
Ed Tanousac106bf2023-06-07 09:24:59 -0700382 * @param[i,o] asyncResp - Async response object
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700383 * @param[i] runningFirmwareTarget - Image to make the running image
384 *
385 * @return void
386 */
Patrick Williams504af5a2025-02-03 14:29:03 -0500387inline void setActiveFirmwareImage(
388 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
389 const std::string& runningFirmwareTarget)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700390{
391 // Get the Id from /redfish/v1/UpdateService/FirmwareInventory/<Id>
392 std::string::size_type idPos = runningFirmwareTarget.rfind('/');
393 if (idPos == std::string::npos)
394 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700395 messages::propertyValueNotInList(asyncResp->res, runningFirmwareTarget,
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700396 "@odata.id");
Ed Tanous62598e32023-07-17 17:06:25 -0700397 BMCWEB_LOG_DEBUG("Can't parse firmware ID!");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700398 return;
399 }
400 idPos++;
401 if (idPos >= runningFirmwareTarget.size())
402 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700403 messages::propertyValueNotInList(asyncResp->res, runningFirmwareTarget,
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700404 "@odata.id");
Ed Tanous62598e32023-07-17 17:06:25 -0700405 BMCWEB_LOG_DEBUG("Invalid firmware ID.");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700406 return;
407 }
408 std::string firmwareId = runningFirmwareTarget.substr(idPos);
409
410 // Make sure the image is valid before setting priority
George Liu5eb468d2023-06-20 17:03:24 +0800411 sdbusplus::message::object_path objPath("/xyz/openbmc_project/software");
412 dbus::utility::getManagedObjects(
Jagpal Singh Gilld27c31e2024-10-15 15:10:19 -0700413 getBMCUpdateServiceName(), objPath,
George Liu5eb468d2023-06-20 17:03:24 +0800414 [asyncResp, firmwareId, runningFirmwareTarget](
415 const boost::system::error_code& ec,
416 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400417 if (ec)
Ed Tanous002d39b2022-05-31 08:59:27 -0700418 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400419 BMCWEB_LOG_DEBUG("D-Bus response error getting objects.");
Ed Tanousac106bf2023-06-07 09:24:59 -0700420 messages::internalError(asyncResp->res);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700421 return;
422 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400423
424 if (subtree.empty())
425 {
426 BMCWEB_LOG_DEBUG("Can't find image!");
427 messages::internalError(asyncResp->res);
428 return;
429 }
430
431 bool foundImage = false;
432 for (const auto& object : subtree)
433 {
434 const std::string& path =
435 static_cast<const std::string&>(object.first);
436 std::size_t idPos2 = path.rfind('/');
437
438 if (idPos2 == std::string::npos)
439 {
440 continue;
441 }
442
443 idPos2++;
444 if (idPos2 >= path.size())
445 {
446 continue;
447 }
448
449 if (path.substr(idPos2) == firmwareId)
450 {
451 foundImage = true;
452 break;
453 }
454 }
455
456 if (!foundImage)
457 {
458 messages::propertyValueNotInList(
459 asyncResp->res, runningFirmwareTarget, "@odata.id");
460 BMCWEB_LOG_DEBUG("Invalid firmware ID.");
461 return;
462 }
463
464 BMCWEB_LOG_DEBUG("Setting firmware version {} to priority 0.",
465 firmwareId);
466
467 // Only support Immediate
468 // An addition could be a Redfish Setting like
469 // ActiveSoftwareImageApplyTime and support OnReset
470 sdbusplus::asio::setProperty(
Jagpal Singh Gilld27c31e2024-10-15 15:10:19 -0700471 *crow::connections::systemBus, getBMCUpdateServiceName(),
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400472 "/xyz/openbmc_project/software/" + firmwareId,
473 "xyz.openbmc_project.Software.RedundancyPriority", "Priority",
474 static_cast<uint8_t>(0),
475 [asyncResp](const boost::system::error_code& ec2) {
476 if (ec2)
477 {
478 BMCWEB_LOG_DEBUG("D-Bus response error setting.");
479 messages::internalError(asyncResp->res);
480 return;
481 }
482 doBMCGracefulRestart(asyncResp);
483 });
George Liu5eb468d2023-06-20 17:03:24 +0800484 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700485}
Ed Tanous1abe55e2018-09-05 08:30:59 -0700486
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400487inline void afterSetDateTime(
488 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
489 const boost::system::error_code& ec, const sdbusplus::message_t& msg)
Ed Tanousc51afd52024-03-07 10:13:14 -0800490{
491 if (ec)
492 {
493 BMCWEB_LOG_DEBUG("Failed to set elapsed time. DBUS response error {}",
494 ec);
495 const sd_bus_error* dbusError = msg.get_error();
496 if (dbusError != nullptr)
497 {
498 std::string_view errorName(dbusError->name);
499 if (errorName ==
500 "org.freedesktop.timedate1.AutomaticTimeSyncEnabled")
501 {
502 BMCWEB_LOG_DEBUG("Setting conflict");
503 messages::propertyValueConflict(
504 asyncResp->res, "DateTime",
505 "Managers/NetworkProtocol/NTPProcotolEnabled");
506 return;
507 }
508 }
509 messages::internalError(asyncResp->res);
510 return;
511 }
512 asyncResp->res.result(boost::beast::http::status::no_content);
513}
514
515inline void setDateTime(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
516 const std::string& datetime)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700517{
Ed Tanous62598e32023-07-17 17:06:25 -0700518 BMCWEB_LOG_DEBUG("Set date time: {}", datetime);
Borawski.Lukasz9c3106852018-02-09 15:24:22 +0100519
Ed Tanousc2e32002023-01-07 22:05:08 -0800520 std::optional<redfish::time_utils::usSinceEpoch> us =
521 redfish::time_utils::dateStringToEpoch(datetime);
522 if (!us)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700523 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700524 messages::propertyValueFormatError(asyncResp->res, datetime,
525 "DateTime");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700526 return;
527 }
Ed Tanousc51afd52024-03-07 10:13:14 -0800528 // Set the absolute datetime
529 bool relative = false;
530 bool interactive = false;
531 crow::connections::systemBus->async_method_call(
532 [asyncResp](const boost::system::error_code& ec,
533 const sdbusplus::message_t& msg) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400534 afterSetDateTime(asyncResp, ec, msg);
535 },
Ed Tanousc51afd52024-03-07 10:13:14 -0800536 "org.freedesktop.timedate1", "/org/freedesktop/timedate1",
537 "org.freedesktop.timedate1", "SetTime", us->count(), relative,
538 interactive);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700539}
540
Patrick Williams504af5a2025-02-03 14:29:03 -0500541inline void checkForQuiesced(
542 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Ed Tanous75815e52022-10-05 17:21:13 -0700543{
Ed Tanousdeae6a72024-11-11 21:58:57 -0800544 dbus::utility::getProperty<std::string>(
545 "org.freedesktop.systemd1",
Ed Tanous75815e52022-10-05 17:21:13 -0700546 "/org/freedesktop/systemd1/unit/obmc-bmc-service-quiesce@0.target",
547 "org.freedesktop.systemd1.Unit", "ActiveState",
548 [asyncResp](const boost::system::error_code& ec,
549 const std::string& val) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400550 if (!ec)
Ed Tanous75815e52022-10-05 17:21:13 -0700551 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400552 if (val == "active")
553 {
554 asyncResp->res.jsonValue["Status"]["Health"] =
555 resource::Health::Critical;
556 asyncResp->res.jsonValue["Status"]["State"] =
557 resource::State::Quiesced;
558 return;
559 }
Ed Tanous75815e52022-10-05 17:21:13 -0700560 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400561 asyncResp->res.jsonValue["Status"]["Health"] = resource::Health::OK;
562 asyncResp->res.jsonValue["Status"]["State"] =
563 resource::State::Enabled;
564 });
Ed Tanous75815e52022-10-05 17:21:13 -0700565}
566
Janet Adkinse2cdf062025-06-18 11:17:35 -0500567inline void getPhysicalAssets(
568 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
569 const boost::system::error_code& ec,
570 const dbus::utility::DBusPropertiesMap& propertiesList)
571{
572 if (ec)
573 {
574 BMCWEB_LOG_DEBUG("Can't get bmc asset!");
575 return;
576 }
577
578 const std::string* partNumber = nullptr;
579 const std::string* serialNumber = nullptr;
580 const std::string* manufacturer = nullptr;
581 const std::string* model = nullptr;
582 const std::string* sparePartNumber = nullptr;
583
584 const bool success = sdbusplus::unpackPropertiesNoThrow(
585 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
586 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
587 "Model", model, "SparePartNumber", sparePartNumber);
588
589 if (!success)
590 {
591 messages::internalError(asyncResp->res);
592 return;
593 }
594
595 if (partNumber != nullptr)
596 {
597 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
598 }
599
600 if (serialNumber != nullptr)
601 {
602 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
603 }
604
605 if (manufacturer != nullptr)
606 {
607 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
608 }
609
610 if (model != nullptr)
611 {
612 asyncResp->res.jsonValue["Model"] = *model;
613 }
614
615 if (sparePartNumber != nullptr)
616 {
617 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
618 }
619}
620
621inline void getManagerData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Myung Bae07754492025-08-22 16:03:40 -0400622 const std::string& managerId,
Janet Adkinse2cdf062025-06-18 11:17:35 -0500623 const std::string& managerPath,
624 const dbus::utility::MapperServiceMap& serviceMap)
625{
626 if (managerPath.empty() || serviceMap.size() != 1)
627 {
628 BMCWEB_LOG_DEBUG("Error getting bmc D-Bus object!");
629 messages::internalError(asyncResp->res);
630 return;
631 }
632
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700633 std::string uuid = persistent_data::getConfig().systemUuid;
634
Myung Bae07754492025-08-22 16:03:40 -0400635 asyncResp->res.jsonValue["@odata.id"] =
636 boost::urls::format("/redfish/v1/Managers/{}", managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400637 asyncResp->res.jsonValue["@odata.type"] = "#Manager.v1_15_0.Manager";
Myung Bae07754492025-08-22 16:03:40 -0400638 asyncResp->res.jsonValue["Id"] = managerId;
Myung Bae96153bd2025-08-20 15:20:49 -0400639 asyncResp->res.jsonValue["Name"] = "OpenBmc Manager";
640 asyncResp->res.jsonValue["Description"] = "Baseboard Management Controller";
641 asyncResp->res.jsonValue["PowerState"] = resource::PowerState::On;
642
643 asyncResp->res.jsonValue["ManagerType"] = manager::ManagerType::BMC;
644 asyncResp->res.jsonValue["UUID"] = systemd_utils::getUuid();
645 asyncResp->res.jsonValue["ServiceEntryPointUUID"] = uuid;
646 asyncResp->res.jsonValue["Model"] = "OpenBmc"; // TODO(ed), get model
647
Myung Bae07754492025-08-22 16:03:40 -0400648 asyncResp->res.jsonValue["LogServices"]["@odata.id"] =
649 boost::urls::format("/redfish/v1/Managers/{}/LogServices", managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400650 asyncResp->res.jsonValue["NetworkProtocol"]["@odata.id"] =
651 boost::urls::format("/redfish/v1/Managers/{}/NetworkProtocol",
Myung Bae07754492025-08-22 16:03:40 -0400652 managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400653 asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] =
654 boost::urls::format("/redfish/v1/Managers/{}/EthernetInterfaces",
Myung Bae07754492025-08-22 16:03:40 -0400655 managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400656
657 manager_utils::getServiceIdentification(asyncResp, false);
658
659 if constexpr (BMCWEB_VM_NBDPROXY)
660 {
661 asyncResp->res.jsonValue["VirtualMedia"]["@odata.id"] =
662 boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia",
Myung Bae07754492025-08-22 16:03:40 -0400663 managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400664 }
665
666 // Manager.Reset (an action) can be many values, OpenBMC only
667 // supports BMC reboot.
668 nlohmann::json& managerReset =
669 asyncResp->res.jsonValue["Actions"]["#Manager.Reset"];
Myung Bae07754492025-08-22 16:03:40 -0400670 managerReset["target"] = boost::urls::format(
671 "/redfish/v1/Managers/{}/Actions/Manager.Reset", managerId);
672 managerReset["@Redfish.ActionInfo"] = boost::urls::format(
673 "/redfish/v1/Managers/{}/ResetActionInfo", managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400674
675 // ResetToDefaults (Factory Reset) has values like
676 // PreserveNetworkAndUsers and PreserveNetwork that aren't supported
677 // on OpenBMC
678 nlohmann::json& resetToDefaults =
679 asyncResp->res.jsonValue["Actions"]["#Manager.ResetToDefaults"];
680 resetToDefaults["target"] = boost::urls::format(
Myung Bae07754492025-08-22 16:03:40 -0400681 "/redfish/v1/Managers/{}/Actions/Manager.ResetToDefaults", managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400682 resetToDefaults["ResetType@Redfish.AllowableValues"] =
683 nlohmann::json::array_t({"ResetAll"});
684
685 std::pair<std::string, std::string> redfishDateTimeOffset =
686 redfish::time_utils::getDateTimeOffsetNow();
687
688 asyncResp->res.jsonValue["DateTime"] = redfishDateTimeOffset.first;
689 asyncResp->res.jsonValue["DateTimeLocalOffset"] =
690 redfishDateTimeOffset.second;
691
692 if constexpr (BMCWEB_KVM)
693 {
694 // Fill in GraphicalConsole info
695 asyncResp->res.jsonValue["GraphicalConsole"]["ServiceEnabled"] = true;
696 asyncResp->res.jsonValue["GraphicalConsole"]["MaxConcurrentSessions"] =
697 4;
698 asyncResp->res.jsonValue["GraphicalConsole"]["ConnectTypesSupported"] =
699 nlohmann::json::array_t({"KVMIP"});
700 }
701 if constexpr (!BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM)
702 {
703 asyncResp->res.jsonValue["Links"]["ManagerForServers@odata.count"] = 1;
704
705 nlohmann::json::array_t managerForServers;
706 nlohmann::json::object_t manager;
707 manager["@odata.id"] = std::format("/redfish/v1/Systems/{}",
708 BMCWEB_REDFISH_SYSTEM_URI_NAME);
709 managerForServers.emplace_back(std::move(manager));
710
711 asyncResp->res.jsonValue["Links"]["ManagerForServers"] =
712 std::move(managerForServers);
713 }
714
715 sw_util::populateSoftwareInformation(asyncResp, sw_util::bmcPurpose,
716 "FirmwareVersion", true);
717
718 managerGetLastResetTime(asyncResp);
719
720 // ManagerDiagnosticData is added for all BMCs.
721 nlohmann::json& managerDiagnosticData =
722 asyncResp->res.jsonValue["ManagerDiagnosticData"];
Myung Bae07754492025-08-22 16:03:40 -0400723 managerDiagnosticData["@odata.id"] = boost::urls::format(
724 "/redfish/v1/Managers/{}/ManagerDiagnosticData", managerId);
Myung Bae96153bd2025-08-20 15:20:49 -0400725
726 getMainChassisId(
727 asyncResp, [](const std::string& chassisId,
728 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
729 aRsp->res.jsonValue["Links"]["ManagerForChassis@odata.count"] = 1;
730 nlohmann::json::array_t managerForChassis;
731 nlohmann::json::object_t managerObj;
732 boost::urls::url chassiUrl =
733 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
734 managerObj["@odata.id"] = chassiUrl;
735 managerForChassis.emplace_back(std::move(managerObj));
736 aRsp->res.jsonValue["Links"]["ManagerForChassis"] =
737 std::move(managerForChassis);
738 aRsp->res.jsonValue["Links"]["ManagerInChassis"]["@odata.id"] =
739 chassiUrl;
740 });
741
742 dbus::utility::getProperty<double>(
743 "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
744 "org.freedesktop.systemd1.Manager", "Progress",
745 [asyncResp](const boost::system::error_code& ec, double val) {
746 if (ec)
747 {
748 BMCWEB_LOG_ERROR("Error while getting progress");
749 messages::internalError(asyncResp->res);
750 return;
751 }
752 if (val < 1.0)
753 {
754 asyncResp->res.jsonValue["Status"]["Health"] =
755 resource::Health::OK;
756 asyncResp->res.jsonValue["Status"]["State"] =
757 resource::State::Starting;
758 return;
759 }
760 checkForQuiesced(asyncResp);
761 });
762
Myung Bae07754492025-08-22 16:03:40 -0400763 for (const auto& [connectionName, interfaces] : serviceMap)
764 {
765 for (const auto& interfaceName : interfaces)
766 {
767 if (interfaceName ==
768 "xyz.openbmc_project.Inventory.Decorator.Asset")
769 {
770 dbus::utility::getAllProperties(
771 *crow::connections::systemBus, connectionName, managerPath,
772 "xyz.openbmc_project.Inventory.Decorator.Asset",
773 std::bind_front(getPhysicalAssets, asyncResp));
774 }
775 else if (interfaceName ==
776 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
777 {
778 getLocation(asyncResp, connectionName, managerPath);
779 }
780 else if (interfaceName ==
781 "xyz.openbmc_project.Association.Definitions")
782 {
783 getLocationIndicatorActive(asyncResp, managerPath);
784 }
785 }
786 }
787}
788
789inline void handleManagerGet(
790 App& app, const crow::Request& req,
791 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
792 const std::string& managerId)
793{
794 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
795 {
796 return;
797 }
798
799 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
800 {
801 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
802 return;
803 }
804
805 manager_utils::getValidManagerPath(
806 asyncResp, managerId,
807 std::bind_front(getManagerData, asyncResp, managerId));
Myung Bae96153bd2025-08-20 15:20:49 -0400808
809 RedfishService::getInstance(app).handleSubRoute(req, asyncResp);
810}
811
812inline void handleManagerPatch(
813 App& app, const crow::Request& req,
814 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
815 const std::string& managerId)
816{
817 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
818 {
819 return;
820 }
821
822 if (managerId != BMCWEB_REDFISH_MANAGER_URI_NAME)
823 {
824 messages::resourceNotFound(asyncResp->res, "Manager", managerId);
825 return;
826 }
827
828 std::optional<std::string> activeSoftwareImageOdataId;
829 std::optional<std::string> datetime;
830 std::optional<bool> locationIndicatorActive;
831 std::optional<nlohmann::json::object_t> pidControllers;
832 std::optional<nlohmann::json::object_t> fanControllers;
833 std::optional<nlohmann::json::object_t> fanZones;
834 std::optional<nlohmann::json::object_t> stepwiseControllers;
835 std::optional<std::string> profile;
836 std::optional<std::string> serviceIdentification;
837
838 if (!json_util::readJsonPatch( //
839 req, asyncResp->res, //
840 "DateTime", datetime, //
841 "Links/ActiveSoftwareImage/@odata.id",
842 activeSoftwareImageOdataId, //
843 "LocationIndicatorActive",
844 locationIndicatorActive, //
845 "Oem/OpenBmc/Fan/FanControllers", fanControllers, //
846 "Oem/OpenBmc/Fan/FanZones", fanZones, //
847 "Oem/OpenBmc/Fan/PidControllers", pidControllers, //
848 "Oem/OpenBmc/Fan/Profile", profile, //
849 "Oem/OpenBmc/Fan/StepwiseControllers",
850 stepwiseControllers, //
851 "ServiceIdentification", serviceIdentification //
852 ))
853 {
854 return;
855 }
856
857 if (activeSoftwareImageOdataId)
858 {
859 setActiveFirmwareImage(asyncResp, *activeSoftwareImageOdataId);
860 }
861
862 if (datetime)
863 {
864 setDateTime(asyncResp, *datetime);
865 }
866
867 if (locationIndicatorActive)
868 {
869 setLocationIndicatorActiveState(asyncResp, *locationIndicatorActive,
870 managerId);
871 }
872
873 if (serviceIdentification)
874 {
875 manager_utils::setServiceIdentification(asyncResp,
876 serviceIdentification.value());
877 }
878
879 RedfishService::getInstance(app).handleSubRoute(req, asyncResp);
880}
881
882inline void handleManagerCollectionGet(
883 crow::App& app, const crow::Request& req,
884 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
885{
886 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
887 {
888 return;
889 }
890 // Collections don't include the static data added by SubRoute
891 // because it has a duplicate entry for members
892 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Managers";
893 asyncResp->res.jsonValue["@odata.type"] =
894 "#ManagerCollection.ManagerCollection";
895 asyncResp->res.jsonValue["Name"] = "Manager Collection";
896 asyncResp->res.jsonValue["Members@odata.count"] = 1;
897 nlohmann::json::array_t members;
898 nlohmann::json& bmc = members.emplace_back();
899 bmc["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
900 BMCWEB_REDFISH_MANAGER_URI_NAME);
901 asyncResp->res.jsonValue["Members"] = std::move(members);
902}
903
904inline void requestRoutesManager(App& app)
905{
Ed Tanous253f11b2024-05-16 09:38:31 -0700906 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700907 .privileges(redfish::privileges::getManager)
Myung Bae96153bd2025-08-20 15:20:49 -0400908 .methods(boost::beast::http::verb::get)(
909 std::bind_front(handleManagerGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700910
Ed Tanous253f11b2024-05-16 09:38:31 -0700911 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700912 .privileges(redfish::privileges::patchManager)
Ed Tanous45ca1b82022-03-25 13:07:27 -0700913 .methods(boost::beast::http::verb::patch)(
Myung Bae96153bd2025-08-20 15:20:49 -0400914 std::bind_front(handleManagerPatch, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700915
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700916 BMCWEB_ROUTE(app, "/redfish/v1/Managers/")
Ed Tanoused398212021-06-09 17:05:54 -0700917 .privileges(redfish::privileges::getManagerCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700918 .methods(boost::beast::http::verb::get)(
Myung Bae96153bd2025-08-20 15:20:49 -0400919 std::bind_front(handleManagerCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700920}
Myung Bae64acd262025-08-21 15:51:21 -0400921
922inline void requestRoutesManagerResetAction(App& app)
923{
924 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/Actions/Manager.Reset/")
925 .privileges(redfish::privileges::postManager)
926 .methods(boost::beast::http::verb::post)(
927 std::bind_front(handleManagerResetAction, std::ref(app)));
928
929 BMCWEB_ROUTE(app,
930 "/redfish/v1/Managers/<str>/Actions/Manager.ResetToDefaults/")
931 .privileges(redfish::privileges::postManager)
932 .methods(boost::beast::http::verb::post)(
933 std::bind_front(handleManagerResetToDefaultsAction, std::ref(app)));
934
935 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/ResetActionInfo/")
936 .privileges(redfish::privileges::getActionInfo)
937 .methods(boost::beast::http::verb::get)(
938 std::bind_front(handleManagerResetActionInfo, std::ref(app)));
939}
940
Ed Tanous1abe55e2018-09-05 08:30:59 -0700941} // namespace redfish