blob: d5ca046e8cfcc0f5b822601e61732a6455240256 [file] [log] [blame]
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +01001/*
Ed Tanous6be832e2024-09-10 11:44:48 -07002Copyright (c) 2018 Intel Corporation
3
4Licensed under the Apache License, Version 2.0 (the "License");
5you may not use this file except in compliance with the License.
6You may obtain a copy of the License at
7
8 http://www.apache.org/licenses/LICENSE-2.0
9
10Unless required by applicable law or agreed to in writing, software
11distributed under the License is distributed on an "AS IS" BASIS,
12WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13See the License for the specific language governing permissions and
14limitations under the License.
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010015*/
16#pragma once
17
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "app.hpp"
George Liu7a1dbc42022-12-07 16:03:22 +080019#include "dbus_utility.hpp"
Ed Tanous539d8c62024-06-19 14:38:27 -070020#include "generated/enums/action_info.hpp"
21#include "generated/enums/chassis.hpp"
22#include "generated/enums/resource.hpp"
James Feist1c8fba92019-12-20 15:12:07 -080023#include "led.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "query.hpp"
Chau Ly7164bc62023-10-15 14:55:30 +000025#include "redfish_util.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080026#include "registries/privilege_registry.hpp"
27#include "utils/collection.hpp"
28#include "utils/dbus_utils.hpp"
Nan Zhoucf7eba02022-07-21 23:53:20 +000029#include "utils/json_utils.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070030
George Liue99073f2022-12-09 11:06:16 +080031#include <boost/system/error_code.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070032#include <boost/url/format.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070033#include <sdbusplus/asio/property.hpp>
Andrew Geisslerfc903b32023-05-31 14:15:42 -040034#include <sdbusplus/message.hpp>
Krzysztof Grobelny86d89ed2022-08-29 14:49:20 +020035#include <sdbusplus/unpack_properties.hpp>
Gunnar Mills1214b7e2020-06-04 10:11:30 -050036
George Liu7a1dbc42022-12-07 16:03:22 +080037#include <array>
Ed Tanous3544d2a2023-08-06 18:12:20 -070038#include <ranges>
George Liu7a1dbc42022-12-07 16:03:22 +080039#include <string_view>
40
Ed Tanous1abe55e2018-09-05 08:30:59 -070041namespace redfish
42{
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010043
44/**
Willy Tu5e577bc2022-07-26 00:41:55 +000045 * @brief Retrieves resources over dbus to link to the chassis
46 *
47 * @param[in] asyncResp - Shared pointer for completing asynchronous
48 * calls
49 * @param[in] path - Chassis dbus path to look for the storage.
50 *
51 * Calls the Association endpoints on the path + "/storage" and add the link of
52 * json["Links"]["Storage@odata.count"] =
53 * {"@odata.id", "/redfish/v1/Storage/" + resourceId}
54 *
55 * @return None.
56 */
57inline void getStorageLink(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
58 const sdbusplus::message::object_path& path)
59{
60 sdbusplus::asio::getProperty<std::vector<std::string>>(
61 *crow::connections::systemBus, "xyz.openbmc_project.ObjectMapper",
62 (path / "storage").str, "xyz.openbmc_project.Association", "endpoints",
Willy Tud4b054c2023-06-12 15:18:45 -070063 [asyncResp](const boost::system::error_code& ec,
Willy Tu5e577bc2022-07-26 00:41:55 +000064 const std::vector<std::string>& storageList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040065 if (ec)
Willy Tu5e577bc2022-07-26 00:41:55 +000066 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040067 BMCWEB_LOG_DEBUG("getStorageLink got DBUS response error");
68 return;
Willy Tu5e577bc2022-07-26 00:41:55 +000069 }
70
Patrick Williamsbd79bce2024-08-16 15:22:20 -040071 nlohmann::json::array_t storages;
72 for (const std::string& storagePath : storageList)
73 {
74 std::string id =
75 sdbusplus::message::object_path(storagePath).filename();
76 if (id.empty())
77 {
78 continue;
79 }
80
81 nlohmann::json::object_t storage;
82 storage["@odata.id"] =
83 boost::urls::format("/redfish/v1/Systems/{}/Storage/{}",
84 BMCWEB_REDFISH_SYSTEM_URI_NAME, id);
85 storages.emplace_back(std::move(storage));
86 }
87 asyncResp->res.jsonValue["Links"]["Storage@odata.count"] =
88 storages.size();
89 asyncResp->res.jsonValue["Links"]["Storage"] = std::move(storages);
90 });
Willy Tu5e577bc2022-07-26 00:41:55 +000091}
92
93/**
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060094 * @brief Retrieves chassis state properties over dbus
95 *
Ed Tanousac106bf2023-06-07 09:24:59 -070096 * @param[in] asyncResp - Shared pointer for completing asynchronous calls.
Gunnar Millsbeeca0a2019-02-14 16:30:45 -060097 *
98 * @return None.
99 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700100inline void getChassisState(std::shared_ptr<bmcweb::AsyncResp> asyncResp)
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600101{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700102 // crow::connections::systemBus->async_method_call(
103 sdbusplus::asio::getProperty<std::string>(
104 *crow::connections::systemBus, "xyz.openbmc_project.State.Chassis",
105 "/xyz/openbmc_project/state/chassis0",
106 "xyz.openbmc_project.State.Chassis", "CurrentPowerState",
Ed Tanousac106bf2023-06-07 09:24:59 -0700107 [asyncResp{std::move(asyncResp)}](const boost::system::error_code& ec,
108 const std::string& chassisState) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400109 if (ec)
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600110 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400111 if (ec == boost::system::errc::host_unreachable)
112 {
113 // Service not available, no error, just don't return
114 // chassis state info
115 BMCWEB_LOG_DEBUG("Service not available {}", ec);
116 return;
117 }
118 BMCWEB_LOG_DEBUG("DBUS response error {}", ec);
119 messages::internalError(asyncResp->res);
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600120 return;
121 }
122
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400123 BMCWEB_LOG_DEBUG("Chassis state: {}", chassisState);
124 // Verify Chassis State
125 if (chassisState ==
126 "xyz.openbmc_project.State.Chassis.PowerState.On")
127 {
128 asyncResp->res.jsonValue["PowerState"] =
129 resource::PowerState::On;
130 asyncResp->res.jsonValue["Status"]["State"] =
131 resource::State::Enabled;
132 }
133 else if (chassisState ==
134 "xyz.openbmc_project.State.Chassis.PowerState.Off")
135 {
136 asyncResp->res.jsonValue["PowerState"] =
137 resource::PowerState::Off;
138 asyncResp->res.jsonValue["Status"]["State"] =
139 resource::State::StandbyOffline;
140 }
141 });
Gunnar Millsbeeca0a2019-02-14 16:30:45 -0600142}
143
Qiang XUc1819422019-02-27 13:51:32 +0800144/**
145 * Retrieves physical security properties over dbus
146 */
Chau Ly7164bc62023-10-15 14:55:30 +0000147inline void handlePhysicalSecurityGetSubTree(
148 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
149 const boost::system::error_code& ec,
150 const dbus::utility::MapperGetSubTreeResponse& subtree)
Qiang XUc1819422019-02-27 13:51:32 +0800151{
Chau Ly7164bc62023-10-15 14:55:30 +0000152 if (ec)
153 {
154 // do not add err msg in redfish response, because this is not
155 // mandatory property
156 BMCWEB_LOG_INFO("DBUS error: no matched iface {}", ec);
157 return;
158 }
159 // Iterate over all retrieved ObjectPaths.
160 for (const auto& object : subtree)
161 {
162 if (!object.second.empty())
Ed Tanous002d39b2022-05-31 08:59:27 -0700163 {
Ed Tanous89144a32024-04-08 17:27:04 -0700164 const auto& service = object.second.front();
Chau Ly7164bc62023-10-15 14:55:30 +0000165
166 BMCWEB_LOG_DEBUG("Get intrusion status by service ");
167
168 sdbusplus::asio::getProperty<std::string>(
169 *crow::connections::systemBus, service.first, object.first,
170 "xyz.openbmc_project.Chassis.Intrusion", "Status",
171 [asyncResp](const boost::system::error_code& ec1,
172 const std::string& value) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400173 if (ec1)
174 {
175 // do not add err msg in redfish response, because this
176 // is not
177 // mandatory property
178 BMCWEB_LOG_ERROR("DBUS response error {}", ec1);
179 return;
180 }
181 asyncResp->res.jsonValue["PhysicalSecurity"]
182 ["IntrusionSensorNumber"] = 1;
183 asyncResp->res
184 .jsonValue["PhysicalSecurity"]["IntrusionSensor"] =
185 value;
186 });
Chau Ly7164bc62023-10-15 14:55:30 +0000187
Ed Tanous002d39b2022-05-31 08:59:27 -0700188 return;
189 }
Chau Ly7164bc62023-10-15 14:55:30 +0000190 }
Qiang XUc1819422019-02-27 13:51:32 +0800191}
192
Nan Zhoucf7eba02022-07-21 23:53:20 +0000193inline void handleChassisCollectionGet(
194 App& app, const crow::Request& req,
195 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
196{
197 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
198 {
199 return;
200 }
201 asyncResp->res.jsonValue["@odata.type"] =
202 "#ChassisCollection.ChassisCollection";
203 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
204 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
205
George Liu7a1dbc42022-12-07 16:03:22 +0800206 constexpr std::array<std::string_view, 2> interfaces{
207 "xyz.openbmc_project.Inventory.Item.Board",
208 "xyz.openbmc_project.Inventory.Item.Chassis"};
Nan Zhoucf7eba02022-07-21 23:53:20 +0000209 collection_util::getCollectionMembers(
Lakshmi Yadlapati36b5f1e2023-09-26 23:53:28 -0500210 asyncResp, boost::urls::url("/redfish/v1/Chassis"), interfaces,
211 "/xyz/openbmc_project/inventory");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000212}
213
Jie Yanga5617492021-06-29 12:59:14 -0700214inline void getChassisContainedBy(
215 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
216 const std::string& chassisId, const boost::system::error_code& ec,
Myung Bae28ee5632024-05-24 13:10:04 -0500217 const dbus::utility::MapperGetSubTreePathsResponse& upstreamChassisPaths)
Jie Yanga5617492021-06-29 12:59:14 -0700218{
219 if (ec)
220 {
221 if (ec.value() != EBADR)
222 {
Ed Tanous62598e32023-07-17 17:06:25 -0700223 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Jie Yanga5617492021-06-29 12:59:14 -0700224 messages::internalError(asyncResp->res);
225 }
226 return;
227 }
228 if (upstreamChassisPaths.empty())
229 {
230 return;
231 }
232 if (upstreamChassisPaths.size() > 1)
233 {
Ed Tanous8ece0e42024-01-02 13:16:50 -0800234 BMCWEB_LOG_ERROR("{} is contained by multiple chassis", chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700235 messages::internalError(asyncResp->res);
236 return;
237 }
238
239 sdbusplus::message::object_path upstreamChassisPath(
240 upstreamChassisPaths[0]);
241 std::string upstreamChassis = upstreamChassisPath.filename();
242 if (upstreamChassis.empty())
243 {
Ed Tanous62598e32023-07-17 17:06:25 -0700244 BMCWEB_LOG_WARNING("Malformed upstream Chassis path {} on {}",
245 upstreamChassisPath.str, chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700246 return;
247 }
248
249 asyncResp->res.jsonValue["Links"]["ContainedBy"]["@odata.id"] =
250 boost::urls::format("/redfish/v1/Chassis/{}", upstreamChassis);
251}
252
253inline void getChassisContains(
254 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
255 const std::string& chassisId, const boost::system::error_code& ec,
Myung Bae28ee5632024-05-24 13:10:04 -0500256 const dbus::utility::MapperGetSubTreePathsResponse& downstreamChassisPaths)
Jie Yanga5617492021-06-29 12:59:14 -0700257{
258 if (ec)
259 {
260 if (ec.value() != EBADR)
261 {
Ed Tanous62598e32023-07-17 17:06:25 -0700262 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
Jie Yanga5617492021-06-29 12:59:14 -0700263 messages::internalError(asyncResp->res);
264 }
265 return;
266 }
267 if (downstreamChassisPaths.empty())
268 {
269 return;
270 }
271 nlohmann::json& jValue = asyncResp->res.jsonValue["Links"]["Contains"];
272 if (!jValue.is_array())
273 {
274 // Create the array if it was empty
275 jValue = nlohmann::json::array();
276 }
277 for (const auto& p : downstreamChassisPaths)
278 {
279 sdbusplus::message::object_path downstreamChassisPath(p);
280 std::string downstreamChassis = downstreamChassisPath.filename();
281 if (downstreamChassis.empty())
282 {
Ed Tanous62598e32023-07-17 17:06:25 -0700283 BMCWEB_LOG_WARNING("Malformed downstream Chassis path {} on {}",
284 downstreamChassisPath.str, chassisId);
Jie Yanga5617492021-06-29 12:59:14 -0700285 continue;
286 }
287 nlohmann::json link;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400288 link["@odata.id"] =
289 boost::urls::format("/redfish/v1/Chassis/{}", downstreamChassis);
Jie Yanga5617492021-06-29 12:59:14 -0700290 jValue.push_back(std::move(link));
291 }
292 asyncResp->res.jsonValue["Links"]["Contains@odata.count"] = jValue.size();
293}
294
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400295inline void getChassisConnectivity(
296 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
297 const std::string& chassisId, const std::string& chassisPath)
Jie Yanga5617492021-06-29 12:59:14 -0700298{
Ed Tanous62598e32023-07-17 17:06:25 -0700299 BMCWEB_LOG_DEBUG("Get chassis connectivity");
Jie Yanga5617492021-06-29 12:59:14 -0700300
Myung Bae28ee5632024-05-24 13:10:04 -0500301 constexpr std::array<std::string_view, 2> interfaces{
302 "xyz.openbmc_project.Inventory.Item.Board",
303 "xyz.openbmc_project.Inventory.Item.Chassis"};
304
305 dbus::utility::getAssociatedSubTreePaths(
Jie Yanga5617492021-06-29 12:59:14 -0700306 chassisPath + "/contained_by",
Myung Bae28ee5632024-05-24 13:10:04 -0500307 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
308 interfaces,
Jie Yanga5617492021-06-29 12:59:14 -0700309 std::bind_front(getChassisContainedBy, asyncResp, chassisId));
310
Myung Bae28ee5632024-05-24 13:10:04 -0500311 dbus::utility::getAssociatedSubTreePaths(
Jie Yanga5617492021-06-29 12:59:14 -0700312 chassisPath + "/containing",
Myung Bae28ee5632024-05-24 13:10:04 -0500313 sdbusplus::message::object_path("/xyz/openbmc_project/inventory"), 0,
314 interfaces, std::bind_front(getChassisContains, asyncResp, chassisId));
Jie Yanga5617492021-06-29 12:59:14 -0700315}
316
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100317/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100318 * ChassisCollection derived class for delivering Chassis Collection Schema
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700319 * Functions triggers appropriate requests on DBus
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100320 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700321inline void requestRoutesChassisCollection(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700322{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700323 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/")
Ed Tanoused398212021-06-09 17:05:54 -0700324 .privileges(redfish::privileges::getChassisCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700325 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000326 std::bind_front(handleChassisCollectionGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700327}
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100328
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400329inline void getChassisLocationCode(
330 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
331 const std::string& connectionName, const std::string& path)
Willy Tu308f70c2021-09-28 20:24:52 -0700332{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700333 sdbusplus::asio::getProperty<std::string>(
334 *crow::connections::systemBus, connectionName, path,
335 "xyz.openbmc_project.Inventory.Decorator.LocationCode", "LocationCode",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800336 [asyncResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700337 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400338 if (ec)
339 {
340 BMCWEB_LOG_ERROR("DBUS response error for Location");
341 messages::internalError(asyncResp->res);
342 return;
343 }
Willy Tu308f70c2021-09-28 20:24:52 -0700344
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400345 asyncResp->res
346 .jsonValue["Location"]["PartLocation"]["ServiceLabel"] =
347 property;
348 });
Willy Tu308f70c2021-09-28 20:24:52 -0700349}
350
351inline void getChassisUUID(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
352 const std::string& connectionName,
353 const std::string& path)
354{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700355 sdbusplus::asio::getProperty<std::string>(
356 *crow::connections::systemBus, connectionName, path,
357 "xyz.openbmc_project.Common.UUID", "UUID",
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800358 [asyncResp](const boost::system::error_code& ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700359 const std::string& chassisUUID) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400360 if (ec)
361 {
362 BMCWEB_LOG_ERROR("DBUS response error for UUID");
363 messages::internalError(asyncResp->res);
364 return;
365 }
366 asyncResp->res.jsonValue["UUID"] = chassisUUID;
367 });
Willy Tu308f70c2021-09-28 20:24:52 -0700368}
369
Chau Ly7164bc62023-10-15 14:55:30 +0000370inline void handleDecoratorAssetProperties(
371 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
372 const std::string& chassisId, const std::string& path,
373 const dbus::utility::DBusPropertiesMap& propertiesList)
374{
375 const std::string* partNumber = nullptr;
376 const std::string* serialNumber = nullptr;
377 const std::string* manufacturer = nullptr;
378 const std::string* model = nullptr;
379 const std::string* sparePartNumber = nullptr;
380
381 const bool success = sdbusplus::unpackPropertiesNoThrow(
382 dbus_utils::UnpackErrorPrinter(), propertiesList, "PartNumber",
383 partNumber, "SerialNumber", serialNumber, "Manufacturer", manufacturer,
384 "Model", model, "SparePartNumber", sparePartNumber);
385
386 if (!success)
387 {
388 messages::internalError(asyncResp->res);
389 return;
390 }
391
392 if (partNumber != nullptr)
393 {
394 asyncResp->res.jsonValue["PartNumber"] = *partNumber;
395 }
396
397 if (serialNumber != nullptr)
398 {
399 asyncResp->res.jsonValue["SerialNumber"] = *serialNumber;
400 }
401
402 if (manufacturer != nullptr)
403 {
404 asyncResp->res.jsonValue["Manufacturer"] = *manufacturer;
405 }
406
407 if (model != nullptr)
408 {
409 asyncResp->res.jsonValue["Model"] = *model;
410 }
411
412 // SparePartNumber is optional on D-Bus
413 // so skip if it is empty
414 if (sparePartNumber != nullptr && !sparePartNumber->empty())
415 {
416 asyncResp->res.jsonValue["SparePartNumber"] = *sparePartNumber;
417 }
418
419 asyncResp->res.jsonValue["Name"] = chassisId;
420 asyncResp->res.jsonValue["Id"] = chassisId;
Ed Tanous25b54db2024-04-17 15:40:31 -0700421
422 if constexpr (BMCWEB_REDFISH_ALLOW_DEPRECATED_POWER_THERMAL)
423 {
424 asyncResp->res.jsonValue["Thermal"]["@odata.id"] =
425 boost::urls::format("/redfish/v1/Chassis/{}/Thermal", chassisId);
426 // Power object
427 asyncResp->res.jsonValue["Power"]["@odata.id"] =
428 boost::urls::format("/redfish/v1/Chassis/{}/Power", chassisId);
429 }
430
431 if constexpr (BMCWEB_REDFISH_NEW_POWERSUBSYSTEM_THERMALSUBSYSTEM)
432 {
433 asyncResp->res.jsonValue["ThermalSubsystem"]["@odata.id"] =
434 boost::urls::format("/redfish/v1/Chassis/{}/ThermalSubsystem",
435 chassisId);
436 asyncResp->res.jsonValue["PowerSubsystem"]["@odata.id"] =
437 boost::urls::format("/redfish/v1/Chassis/{}/PowerSubsystem",
438 chassisId);
439 asyncResp->res.jsonValue["EnvironmentMetrics"]["@odata.id"] =
440 boost::urls::format("/redfish/v1/Chassis/{}/EnvironmentMetrics",
441 chassisId);
442 }
Chau Ly7164bc62023-10-15 14:55:30 +0000443 // SensorCollection
444 asyncResp->res.jsonValue["Sensors"]["@odata.id"] =
445 boost::urls::format("/redfish/v1/Chassis/{}/Sensors", chassisId);
Ed Tanous539d8c62024-06-19 14:38:27 -0700446 asyncResp->res.jsonValue["Status"]["State"] = resource::State::Enabled;
Chau Ly7164bc62023-10-15 14:55:30 +0000447
448 nlohmann::json::array_t computerSystems;
449 nlohmann::json::object_t system;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400450 system["@odata.id"] =
451 std::format("/redfish/v1/Systems/{}", BMCWEB_REDFISH_SYSTEM_URI_NAME);
Chau Ly7164bc62023-10-15 14:55:30 +0000452 computerSystems.emplace_back(std::move(system));
453 asyncResp->res.jsonValue["Links"]["ComputerSystems"] =
454 std::move(computerSystems);
455
456 nlohmann::json::array_t managedBy;
457 nlohmann::json::object_t manager;
Ed Tanous253f11b2024-05-16 09:38:31 -0700458 manager["@odata.id"] = boost::urls::format("/redfish/v1/Managers/{}",
459 BMCWEB_REDFISH_MANAGER_URI_NAME);
Chau Ly7164bc62023-10-15 14:55:30 +0000460 managedBy.emplace_back(std::move(manager));
461 asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy);
462 getChassisState(asyncResp);
463 getStorageLink(asyncResp, path);
464}
465
466inline void handleChassisGetSubTree(
467 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
468 const std::string& chassisId, const boost::system::error_code& ec,
469 const dbus::utility::MapperGetSubTreeResponse& subtree)
470{
471 if (ec)
472 {
473 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
474 messages::internalError(asyncResp->res);
475 return;
476 }
477 // Iterate over all retrieved ObjectPaths.
478 for (const std::pair<
479 std::string,
480 std::vector<std::pair<std::string, std::vector<std::string>>>>&
481 object : subtree)
482 {
483 const std::string& path = object.first;
484 const std::vector<std::pair<std::string, std::vector<std::string>>>&
485 connectionNames = object.second;
486
487 sdbusplus::message::object_path objPath(path);
488 if (objPath.filename() != chassisId)
489 {
490 continue;
491 }
492
493 getChassisConnectivity(asyncResp, chassisId, path);
494
Chau Ly7164bc62023-10-15 14:55:30 +0000495 if (connectionNames.empty())
496 {
497 BMCWEB_LOG_ERROR("Got 0 Connection names");
498 continue;
499 }
500
501 asyncResp->res.jsonValue["@odata.type"] = "#Chassis.v1_22_0.Chassis";
502 asyncResp->res.jsonValue["@odata.id"] =
503 boost::urls::format("/redfish/v1/Chassis/{}", chassisId);
504 asyncResp->res.jsonValue["Name"] = "Chassis Collection";
Ed Tanous539d8c62024-06-19 14:38:27 -0700505 asyncResp->res.jsonValue["ChassisType"] =
506 chassis::ChassisType::RackMount;
Chau Ly7164bc62023-10-15 14:55:30 +0000507 asyncResp->res.jsonValue["Actions"]["#Chassis.Reset"]["target"] =
508 boost::urls::format("/redfish/v1/Chassis/{}/Actions/Chassis.Reset",
509 chassisId);
510 asyncResp->res
511 .jsonValue["Actions"]["#Chassis.Reset"]["@Redfish.ActionInfo"] =
512 boost::urls::format("/redfish/v1/Chassis/{}/ResetActionInfo",
513 chassisId);
Chau Ly7164bc62023-10-15 14:55:30 +0000514 dbus::utility::getAssociationEndPoints(
515 path + "/drive",
516 [asyncResp, chassisId](const boost::system::error_code& ec3,
517 const dbus::utility::MapperEndPoints& resp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400518 if (ec3 || resp.empty())
519 {
520 return; // no drives = no failures
521 }
Chau Ly7164bc62023-10-15 14:55:30 +0000522
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400523 nlohmann::json reference;
524 reference["@odata.id"] = boost::urls::format(
525 "/redfish/v1/Chassis/{}/Drives", chassisId);
526 asyncResp->res.jsonValue["Drives"] = std::move(reference);
527 });
Chau Ly7164bc62023-10-15 14:55:30 +0000528
529 const std::string& connectionName = connectionNames[0].first;
530
531 const std::vector<std::string>& interfaces2 = connectionNames[0].second;
George Liue5ae9c12021-11-16 10:31:23 +0800532 const std::array<const char*, 3> hasIndicatorLed = {
533 "xyz.openbmc_project.Inventory.Item.Chassis",
Chau Ly7164bc62023-10-15 14:55:30 +0000534 "xyz.openbmc_project.Inventory.Item.Panel",
535 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
536
537 const std::string assetTagInterface =
538 "xyz.openbmc_project.Inventory.Decorator.AssetTag";
539 const std::string replaceableInterface =
540 "xyz.openbmc_project.Inventory.Decorator.Replaceable";
Carson Labradob4d593f2024-02-16 22:34:32 +0000541 const std::string revisionInterface =
542 "xyz.openbmc_project.Inventory.Decorator.Revision";
Chau Ly7164bc62023-10-15 14:55:30 +0000543 for (const auto& interface : interfaces2)
544 {
545 if (interface == assetTagInterface)
546 {
547 sdbusplus::asio::getProperty<std::string>(
548 *crow::connections::systemBus, connectionName, path,
549 assetTagInterface, "AssetTag",
550 [asyncResp, chassisId](const boost::system::error_code& ec2,
551 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400552 if (ec2)
553 {
554 BMCWEB_LOG_ERROR(
555 "DBus response error for AssetTag: {}", ec2);
556 messages::internalError(asyncResp->res);
557 return;
558 }
559 asyncResp->res.jsonValue["AssetTag"] = property;
560 });
Chau Ly7164bc62023-10-15 14:55:30 +0000561 }
562 else if (interface == replaceableInterface)
563 {
564 sdbusplus::asio::getProperty<bool>(
565 *crow::connections::systemBus, connectionName, path,
566 replaceableInterface, "HotPluggable",
567 [asyncResp, chassisId](const boost::system::error_code& ec2,
568 const bool property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400569 if (ec2)
570 {
571 BMCWEB_LOG_ERROR(
572 "DBus response error for HotPluggable: {}",
573 ec2);
574 messages::internalError(asyncResp->res);
575 return;
576 }
577 asyncResp->res.jsonValue["HotPluggable"] = property;
578 });
Chau Ly7164bc62023-10-15 14:55:30 +0000579 }
Carson Labradob4d593f2024-02-16 22:34:32 +0000580 else if (interface == revisionInterface)
581 {
582 sdbusplus::asio::getProperty<std::string>(
583 *crow::connections::systemBus, connectionName, path,
584 revisionInterface, "Version",
585 [asyncResp, chassisId](const boost::system::error_code& ec2,
586 const std::string& property) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400587 if (ec2)
588 {
589 BMCWEB_LOG_ERROR(
590 "DBus response error for Version: {}", ec2);
591 messages::internalError(asyncResp->res);
592 return;
593 }
594 asyncResp->res.jsonValue["Version"] = property;
595 });
Carson Labradob4d593f2024-02-16 22:34:32 +0000596 }
Chau Ly7164bc62023-10-15 14:55:30 +0000597 }
598
599 for (const char* interface : hasIndicatorLed)
600 {
601 if (std::ranges::find(interfaces2, interface) != interfaces2.end())
602 {
603 getIndicatorLedState(asyncResp);
604 getSystemLocationIndicatorActive(asyncResp);
605 break;
606 }
607 }
608
609 sdbusplus::asio::getAllProperties(
610 *crow::connections::systemBus, connectionName, path,
611 "xyz.openbmc_project.Inventory.Decorator.Asset",
612 [asyncResp, chassisId,
613 path](const boost::system::error_code&,
614 const dbus::utility::DBusPropertiesMap& propertiesList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400615 handleDecoratorAssetProperties(asyncResp, chassisId, path,
616 propertiesList);
617 });
Chau Ly7164bc62023-10-15 14:55:30 +0000618
619 for (const auto& interface : interfaces2)
620 {
621 if (interface == "xyz.openbmc_project.Common.UUID")
622 {
623 getChassisUUID(asyncResp, connectionName, path);
624 }
625 else if (interface ==
626 "xyz.openbmc_project.Inventory.Decorator.LocationCode")
627 {
628 getChassisLocationCode(asyncResp, connectionName, path);
629 }
630 }
631
632 return;
633 }
634
635 // Couldn't find an object with that name. return an error
636 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
637}
638
Nan Zhoucf7eba02022-07-21 23:53:20 +0000639inline void
640 handleChassisGet(App& app, const crow::Request& req,
641 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
642 const std::string& chassisId)
643{
644 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
645 {
646 return;
647 }
George Liue99073f2022-12-09 11:06:16 +0800648 constexpr std::array<std::string_view, 2> interfaces = {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000649 "xyz.openbmc_project.Inventory.Item.Board",
650 "xyz.openbmc_project.Inventory.Item.Chassis"};
651
George Liue99073f2022-12-09 11:06:16 +0800652 dbus::utility::getSubTree(
653 "/xyz/openbmc_project/inventory", 0, interfaces,
Chau Ly7164bc62023-10-15 14:55:30 +0000654 std::bind_front(handleChassisGetSubTree, asyncResp, chassisId));
Nan Zhoucf7eba02022-07-21 23:53:20 +0000655
Chau Ly7164bc62023-10-15 14:55:30 +0000656 constexpr std::array<std::string_view, 1> interfaces2 = {
657 "xyz.openbmc_project.Chassis.Intrusion"};
Nan Zhoucf7eba02022-07-21 23:53:20 +0000658
Chau Ly7164bc62023-10-15 14:55:30 +0000659 dbus::utility::getSubTree(
660 "/xyz/openbmc_project", 0, interfaces2,
661 std::bind_front(handlePhysicalSecurityGetSubTree, asyncResp));
Nan Zhoucf7eba02022-07-21 23:53:20 +0000662}
663
664inline void
665 handleChassisPatch(App& app, const crow::Request& req,
666 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
667 const std::string& param)
668{
669 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
670 {
671 return;
672 }
673 std::optional<bool> locationIndicatorActive;
674 std::optional<std::string> indicatorLed;
675
676 if (param.empty())
677 {
678 return;
679 }
680
Myung Baeafc474a2024-10-09 00:53:29 -0700681 if (!json_util::readJsonPatch( //
682 req, asyncResp->res, //
683 "IndicatorLED", indicatorLed, //
684 "LocationIndicatorActive", locationIndicatorActive //
685 ))
Nan Zhoucf7eba02022-07-21 23:53:20 +0000686 {
687 return;
688 }
689
690 // TODO (Gunnar): Remove IndicatorLED after enough time has passed
691 if (!locationIndicatorActive && !indicatorLed)
692 {
693 return; // delete this when we support more patch properties
694 }
695 if (indicatorLed)
696 {
697 asyncResp->res.addHeader(
698 boost::beast::http::field::warning,
699 "299 - \"IndicatorLED is deprecated. Use LocationIndicatorActive instead.\"");
700 }
701
George Liue99073f2022-12-09 11:06:16 +0800702 constexpr std::array<std::string_view, 2> interfaces = {
Nan Zhoucf7eba02022-07-21 23:53:20 +0000703 "xyz.openbmc_project.Inventory.Item.Board",
704 "xyz.openbmc_project.Inventory.Item.Chassis"};
705
706 const std::string& chassisId = param;
707
George Liue99073f2022-12-09 11:06:16 +0800708 dbus::utility::getSubTree(
709 "/xyz/openbmc_project/inventory", 0, interfaces,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000710 [asyncResp, chassisId, locationIndicatorActive,
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800711 indicatorLed](const boost::system::error_code& ec,
Nan Zhoucf7eba02022-07-21 23:53:20 +0000712 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400713 if (ec)
Nan Zhoucf7eba02022-07-21 23:53:20 +0000714 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400715 BMCWEB_LOG_ERROR("DBUS response error {}", ec);
716 messages::internalError(asyncResp->res);
717 return;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000718 }
719
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400720 // Iterate over all retrieved ObjectPaths.
721 for (const std::pair<std::string,
722 std::vector<std::pair<
723 std::string, std::vector<std::string>>>>&
724 object : subtree)
Nan Zhoucf7eba02022-07-21 23:53:20 +0000725 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400726 const std::string& path = object.first;
727 const std::vector<
728 std::pair<std::string, std::vector<std::string>>>&
729 connectionNames = object.second;
730
731 sdbusplus::message::object_path objPath(path);
732 if (objPath.filename() != chassisId)
733 {
734 continue;
735 }
736
737 if (connectionNames.empty())
738 {
739 BMCWEB_LOG_ERROR("Got 0 Connection names");
740 continue;
741 }
742
743 const std::vector<std::string>& interfaces3 =
744 connectionNames[0].second;
745
746 const std::array<const char*, 3> hasIndicatorLed = {
747 "xyz.openbmc_project.Inventory.Item.Chassis",
748 "xyz.openbmc_project.Inventory.Item.Panel",
749 "xyz.openbmc_project.Inventory.Item.Board.Motherboard"};
750 bool indicatorChassis = false;
751 for (const char* interface : hasIndicatorLed)
752 {
753 if (std::ranges::find(interfaces3, interface) !=
754 interfaces3.end())
755 {
756 indicatorChassis = true;
757 break;
758 }
759 }
760 if (locationIndicatorActive)
761 {
762 if (indicatorChassis)
763 {
764 setSystemLocationIndicatorActive(
765 asyncResp, *locationIndicatorActive);
766 }
767 else
768 {
769 messages::propertyUnknown(asyncResp->res,
770 "LocationIndicatorActive");
771 }
772 }
773 if (indicatorLed)
774 {
775 if (indicatorChassis)
776 {
777 setIndicatorLedState(asyncResp, *indicatorLed);
778 }
779 else
780 {
781 messages::propertyUnknown(asyncResp->res,
782 "IndicatorLED");
783 }
784 }
785 return;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000786 }
787
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400788 messages::resourceNotFound(asyncResp->res, "Chassis", chassisId);
789 });
Nan Zhoucf7eba02022-07-21 23:53:20 +0000790}
791
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100792/**
793 * Chassis override class for delivering Chassis Schema
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700794 * Functions triggers appropriate requests on DBus
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100795 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700796inline void requestRoutesChassis(App& app)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700797{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700798 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700799 .privileges(redfish::privileges::getChassis)
Ed Tanous002d39b2022-05-31 08:59:27 -0700800 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000801 std::bind_front(handleChassisGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700802
803 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700804 .privileges(redfish::privileges::patchChassis)
Ed Tanous002d39b2022-05-31 08:59:27 -0700805 .methods(boost::beast::http::verb::patch)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000806 std::bind_front(handleChassisPatch, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700807}
P.K. Leedd99e042020-06-17 19:43:16 +0800808
zhanghch058d1b46d2021-04-01 11:18:24 +0800809inline void
810 doChassisPowerCycle(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
P.K. Leedd99e042020-06-17 19:43:16 +0800811{
George Liu7a1dbc42022-12-07 16:03:22 +0800812 constexpr std::array<std::string_view, 1> interfaces = {
Vijay Khemkac3b3c922020-09-22 23:00:12 -0700813 "xyz.openbmc_project.State.Chassis"};
814
815 // Use mapper to get subtree paths.
George Liu7a1dbc42022-12-07 16:03:22 +0800816 dbus::utility::getSubTreePaths(
817 "/", 0, interfaces,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800818 [asyncResp](
George Liu7a1dbc42022-12-07 16:03:22 +0800819 const boost::system::error_code& ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -0800820 const dbus::utility::MapperGetSubTreePathsResponse& chassisList) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400821 if (ec)
822 {
823 BMCWEB_LOG_ERROR("[mapper] Bad D-Bus request error: {}", ec);
824 messages::internalError(asyncResp->res);
825 return;
826 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700827
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400828 const char* processName = "xyz.openbmc_project.State.Chassis";
829 const char* interfaceName = "xyz.openbmc_project.State.Chassis";
830 const char* destProperty = "RequestedPowerTransition";
831 const std::string propertyValue =
832 "xyz.openbmc_project.State.Chassis.Transition.PowerCycle";
833 std::string objectPath =
834 "/xyz/openbmc_project/state/chassis_system0";
Ed Tanous002d39b2022-05-31 08:59:27 -0700835
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400836 /* Look for system reset chassis path */
837 if ((std::ranges::find(chassisList, objectPath)) ==
838 chassisList.end())
839 {
840 /* We prefer to reset the full chassis_system, but if it doesn't
841 * exist on some platforms, fall back to a host-only power reset
842 */
843 objectPath = "/xyz/openbmc_project/state/chassis0";
844 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700845
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400846 setDbusProperty(asyncResp, "ResetType", processName, objectPath,
847 interfaceName, destProperty, propertyValue);
848 });
P.K. Leedd99e042020-06-17 19:43:16 +0800849}
850
Nan Zhoucf7eba02022-07-21 23:53:20 +0000851inline void handleChassisResetActionInfoPost(
852 App& app, const crow::Request& req,
853 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
854 const std::string& /*chassisId*/)
855{
856 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
857 {
858 return;
859 }
Ed Tanous62598e32023-07-17 17:06:25 -0700860 BMCWEB_LOG_DEBUG("Post Chassis Reset.");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000861
862 std::string resetType;
863
864 if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType))
865 {
866 return;
867 }
868
869 if (resetType != "PowerCycle")
870 {
Ed Tanous62598e32023-07-17 17:06:25 -0700871 BMCWEB_LOG_DEBUG("Invalid property value for ResetType: {}", resetType);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000872 messages::actionParameterNotSupported(asyncResp->res, resetType,
873 "ResetType");
874
875 return;
876 }
877 doChassisPowerCycle(asyncResp);
878}
879
P.K. Leedd99e042020-06-17 19:43:16 +0800880/**
881 * ChassisResetAction class supports the POST method for the Reset
882 * action.
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700883 * Function handles POST method request.
884 * Analyzes POST body before sending Reset request data to D-Bus.
P.K. Leedd99e042020-06-17 19:43:16 +0800885 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700886
887inline void requestRoutesChassisResetAction(App& app)
P.K. Leedd99e042020-06-17 19:43:16 +0800888{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700889 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/Actions/Chassis.Reset/")
Ed Tanoused398212021-06-09 17:05:54 -0700890 .privileges(redfish::privileges::postChassis)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700891 .methods(boost::beast::http::verb::post)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000892 std::bind_front(handleChassisResetActionInfoPost, std::ref(app)));
893}
P.K. Leedd99e042020-06-17 19:43:16 +0800894
Nan Zhoucf7eba02022-07-21 23:53:20 +0000895inline void handleChassisResetActionInfoGet(
896 App& app, const crow::Request& req,
897 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
898 const std::string& chassisId)
899{
900 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
901 {
902 return;
903 }
904 asyncResp->res.jsonValue["@odata.type"] = "#ActionInfo.v1_1_2.ActionInfo";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700905 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
906 "/redfish/v1/Chassis/{}/ResetActionInfo", chassisId);
Nan Zhoucf7eba02022-07-21 23:53:20 +0000907 asyncResp->res.jsonValue["Name"] = "Reset Action Info";
P.K. Leedd99e042020-06-17 19:43:16 +0800908
Nan Zhoucf7eba02022-07-21 23:53:20 +0000909 asyncResp->res.jsonValue["Id"] = "ResetActionInfo";
910 nlohmann::json::array_t parameters;
911 nlohmann::json::object_t parameter;
912 parameter["Name"] = "ResetType";
913 parameter["Required"] = true;
Ed Tanous539d8c62024-06-19 14:38:27 -0700914 parameter["DataType"] = action_info::ParameterTypes::String;
Nan Zhoucf7eba02022-07-21 23:53:20 +0000915 nlohmann::json::array_t allowed;
Patrick Williamsad539542023-05-12 10:10:08 -0500916 allowed.emplace_back("PowerCycle");
Nan Zhoucf7eba02022-07-21 23:53:20 +0000917 parameter["AllowableValues"] = std::move(allowed);
Patrick Williamsad539542023-05-12 10:10:08 -0500918 parameters.emplace_back(std::move(parameter));
P.K. Leedd99e042020-06-17 19:43:16 +0800919
Nan Zhoucf7eba02022-07-21 23:53:20 +0000920 asyncResp->res.jsonValue["Parameters"] = std::move(parameters);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700921}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530922
923/**
924 * ChassisResetActionInfo derived class for delivering Chassis
925 * ResetType AllowableValues using ResetInfo schema.
926 */
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700927inline void requestRoutesChassisResetActionInfo(App& app)
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530928{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700929 BMCWEB_ROUTE(app, "/redfish/v1/Chassis/<str>/ResetActionInfo/")
Ed Tanoused398212021-06-09 17:05:54 -0700930 .privileges(redfish::privileges::getActionInfo)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700931 .methods(boost::beast::http::verb::get)(
Nan Zhoucf7eba02022-07-21 23:53:20 +0000932 std::bind_front(handleChassisResetActionInfoGet, std::ref(app)));
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700933}
AppaRao Puli1cb1a9e2020-07-17 23:38:57 +0530934
Ed Tanous1abe55e2018-09-05 08:30:59 -0700935} // namespace redfish