blob: 7f1e0de7b21ffdc8f52b4d1b1d560178a9f47b94 [file] [log] [blame]
Nikhil Potadea25aecc2019-08-23 16:35:26 -07001/*
2// Copyright (c) 2019 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
James Feist2ad9c2f2019-10-29 16:26:48 -070018#include "health.hpp"
James Feiste284a7c2019-11-20 16:20:23 -080019#include "openbmc_dbus_rest.hpp"
James Feist2ad9c2f2019-10-29 16:26:48 -070020
John Edward Broadbent7e860f12021-04-08 15:57:16 -070021#include <app.hpp>
Ed Tanous168e20c2021-12-13 14:39:53 -080022#include <dbus_utility.hpp>
Ed Tanous45ca1b82022-03-25 13:07:27 -070023#include <query.hpp>
Ed Tanoused398212021-06-09 17:05:54 -070024#include <registries/privilege_registry.hpp>
Jonathan Doman1e1e5982021-06-11 09:36:17 -070025#include <sdbusplus/asio/property.hpp>
Nikhil Potadea25aecc2019-08-23 16:35:26 -070026
27namespace redfish
28{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070029inline void requestRoutesStorageCollection(App& app)
Nikhil Potadea25aecc2019-08-23 16:35:26 -070030{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070031 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/")
Ed Tanoused398212021-06-09 17:05:54 -070032 .privileges(redfish::privileges::getStorageCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -070033 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -070034 [&app](const crow::Request& req,
35 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
36 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
37 {
38 return;
39 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -070040 asyncResp->res.jsonValue["@odata.type"] =
41 "#StorageCollection.StorageCollection";
42 asyncResp->res.jsonValue["@odata.id"] =
43 "/redfish/v1/Systems/system/Storage";
44 asyncResp->res.jsonValue["Name"] = "Storage Collection";
45 asyncResp->res.jsonValue["Members"] = {
46 {{"@odata.id", "/redfish/v1/Systems/system/Storage/1"}}};
47 asyncResp->res.jsonValue["Members@odata.count"] = 1;
48 });
49}
Nikhil Potadea25aecc2019-08-23 16:35:26 -070050
John Edward Broadbent7e860f12021-04-08 15:57:16 -070051inline void requestRoutesStorage(App& app)
Nikhil Potadea25aecc2019-08-23 16:35:26 -070052{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070053 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/")
Ed Tanoused398212021-06-09 17:05:54 -070054 .privileges(redfish::privileges::getStorage)
Ed Tanous45ca1b82022-03-25 13:07:27 -070055 .methods(boost::beast::http::verb::get)([&app](const crow::Request& req,
56 const std::shared_ptr<
57 bmcweb::AsyncResp>&
58 asyncResp) {
59 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
60 {
61 return;
62 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -070063 asyncResp->res.jsonValue["@odata.type"] = "#Storage.v1_7_1.Storage";
64 asyncResp->res.jsonValue["@odata.id"] =
65 "/redfish/v1/Systems/system/Storage/1";
66 asyncResp->res.jsonValue["Name"] = "Storage";
67 asyncResp->res.jsonValue["Id"] = "1";
68 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
Nikhil Potadea25aecc2019-08-23 16:35:26 -070069
John Edward Broadbent7e860f12021-04-08 15:57:16 -070070 auto health = std::make_shared<HealthPopulate>(asyncResp);
71 health->populate();
Nikhil Potadea25aecc2019-08-23 16:35:26 -070072
John Edward Broadbent7e860f12021-04-08 15:57:16 -070073 crow::connections::systemBus->async_method_call(
74 [asyncResp,
75 health](const boost::system::error_code ec,
Ed Tanousb9d36b42022-02-26 21:42:46 -080076 const dbus::utility::MapperGetSubTreePathsResponse&
77 storageList) {
John Edward Broadbent7e860f12021-04-08 15:57:16 -070078 nlohmann::json& storageArray =
79 asyncResp->res.jsonValue["Drives"];
80 storageArray = nlohmann::json::array();
81 auto& count =
82 asyncResp->res.jsonValue["Drives@odata.count"];
83 count = 0;
James Feiste284a7c2019-11-20 16:20:23 -080084
John Edward Broadbent7e860f12021-04-08 15:57:16 -070085 if (ec)
Nikhil Potadea25aecc2019-08-23 16:35:26 -070086 {
John Edward Broadbent7e860f12021-04-08 15:57:16 -070087 BMCWEB_LOG_ERROR << "Drive mapper call error";
88 messages::internalError(asyncResp->res);
James Feiste284a7c2019-11-20 16:20:23 -080089 return;
90 }
91
John Edward Broadbent7e860f12021-04-08 15:57:16 -070092 health->inventory.insert(health->inventory.end(),
93 storageList.begin(),
94 storageList.end());
95
96 for (const std::string& objpath : storageList)
97 {
98 std::size_t lastPos = objpath.rfind('/');
99 if (lastPos == std::string::npos ||
100 (objpath.size() <= lastPos + 1))
101 {
102 BMCWEB_LOG_ERROR << "Failed to find '/' in "
103 << objpath;
104 continue;
105 }
106
107 storageArray.push_back(
108 {{"@odata.id",
109 "/redfish/v1/Systems/system/Storage/1/Drives/" +
110 objpath.substr(lastPos + 1)}});
111 }
112
113 count = storageArray.size();
114 },
115 "xyz.openbmc_project.ObjectMapper",
116 "/xyz/openbmc_project/object_mapper",
117 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
118 "/xyz/openbmc_project/inventory", int32_t(0),
119 std::array<const char*, 1>{
120 "xyz.openbmc_project.Inventory.Item.Drive"});
121
122 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -0800123 [asyncResp, health](
124 const boost::system::error_code ec,
125 const dbus::utility::MapperGetSubTreeResponse& subtree) {
Ed Tanous26f69762022-01-25 09:49:11 -0800126 if (ec || subtree.empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700127 {
128 // doesn't have to be there
129 return;
130 }
131
132 nlohmann::json& root =
133 asyncResp->res.jsonValue["StorageControllers"];
134 root = nlohmann::json::array();
135 for (const auto& [path, interfaceDict] : subtree)
136 {
137 std::size_t lastPos = path.rfind('/');
138 if (lastPos == std::string::npos ||
139 (path.size() <= lastPos + 1))
140 {
141 BMCWEB_LOG_ERROR << "Failed to find '/' in "
142 << path;
143 return;
144 }
145
146 if (interfaceDict.size() != 1)
147 {
148 BMCWEB_LOG_ERROR << "Connection size "
149 << interfaceDict.size()
150 << ", greater than 1";
151 messages::internalError(asyncResp->res);
152 return;
153 }
154
155 const std::string& connectionName =
156 interfaceDict.front().first;
157
158 size_t index = root.size();
159 nlohmann::json& storageController =
160 root.emplace_back(nlohmann::json::object());
161
162 std::string id = path.substr(lastPos + 1);
163
164 storageController["@odata.type"] =
165 "#Storage.v1_7_0.StorageController";
166 storageController["@odata.id"] =
George Liu0fda0f12021-11-16 10:06:17 +0800167 "/redfish/v1/Systems/system/Storage/1#/StorageControllers/" +
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700168 std::to_string(index);
169 storageController["Name"] = id;
170 storageController["MemberId"] = id;
171 storageController["Status"]["State"] = "Enabled";
172
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700173 sdbusplus::asio::getProperty<bool>(
174 *crow::connections::systemBus, connectionName, path,
175 "xyz.openbmc_project.Inventory.Item", "Present",
176 [asyncResp,
177 index](const boost::system::error_code ec2,
178 bool enabled) {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700179 // this interface isn't necessary, only check it
180 // if we get a good return
181 if (ec2)
182 {
183 return;
184 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700185 if (!enabled)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700186 {
187 asyncResp->res
188 .jsonValue["StorageControllers"][index]
189 ["Status"]["State"] =
190 "Disabled";
191 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700192 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700193
194 crow::connections::systemBus->async_method_call(
195 [asyncResp, index](
196 const boost::system::error_code ec2,
Ed Tanous168e20c2021-12-13 14:39:53 -0800197 const std::vector<
198 std::pair<std::string,
199 dbus::utility::DbusVariantType>>&
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700200 propertiesList) {
201 if (ec2)
202 {
203 // this interface isn't necessary
204 return;
205 }
206 for (const std::pair<
207 std::string,
Ed Tanous168e20c2021-12-13 14:39:53 -0800208 dbus::utility::DbusVariantType>&
209 property : propertiesList)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700210 {
211 // Store DBus properties that are also
212 // Redfish properties with same name and a
213 // string value
214 const std::string& propertyName =
215 property.first;
216 nlohmann::json& object =
217 asyncResp->res
218 .jsonValue["StorageControllers"]
219 [index];
220 if ((propertyName == "PartNumber") ||
221 (propertyName == "SerialNumber") ||
222 (propertyName == "Manufacturer") ||
223 (propertyName == "Model"))
224 {
225 const std::string* value =
226 std::get_if<std::string>(
227 &property.second);
228 if (value == nullptr)
229 {
230 // illegal property
231 messages::internalError(
232 asyncResp->res);
233 return;
234 }
235 object[propertyName] = *value;
236 }
237 }
238 },
239 connectionName, path,
240 "org.freedesktop.DBus.Properties", "GetAll",
241 "xyz.openbmc_project.Inventory.Decorator.Asset");
242 }
243
244 // this is done after we know the json array will no longer
245 // be resized, as json::array uses vector underneath and we
246 // need references to its members that won't change
247 size_t count = 0;
248 for (const auto& [path, interfaceDict] : subtree)
249 {
250 auto subHealth = std::make_shared<HealthPopulate>(
251 asyncResp, root[count]["Status"]);
252 subHealth->inventory.emplace_back(path);
253 health->inventory.emplace_back(path);
254 health->children.emplace_back(subHealth);
255 count++;
256 }
257 },
258 "xyz.openbmc_project.ObjectMapper",
259 "/xyz/openbmc_project/object_mapper",
260 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
261 "/xyz/openbmc_project/inventory", int32_t(0),
262 std::array<const char*, 1>{
263 "xyz.openbmc_project.Inventory.Item.StorageController"});
264 });
265}
266
Willy Tu03913172021-11-08 02:03:19 -0800267inline void getDriveAsset(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
268 const std::string& connectionName,
269 const std::string& path)
270{
271 crow::connections::systemBus->async_method_call(
Ed Tanous168e20c2021-12-13 14:39:53 -0800272 [asyncResp](const boost::system::error_code ec,
273 const std::vector<
274 std::pair<std::string, dbus::utility::DbusVariantType>>&
275 propertiesList) {
Willy Tu03913172021-11-08 02:03:19 -0800276 if (ec)
277 {
278 // this interface isn't necessary
279 return;
280 }
Ed Tanous168e20c2021-12-13 14:39:53 -0800281 for (const std::pair<std::string, dbus::utility::DbusVariantType>&
Willy Tu03913172021-11-08 02:03:19 -0800282 property : propertiesList)
283 {
284 // Store DBus properties that are also
285 // Redfish properties with same name and a
286 // string value
287 const std::string& propertyName = property.first;
288 if ((propertyName == "PartNumber") ||
289 (propertyName == "SerialNumber") ||
290 (propertyName == "Manufacturer") ||
291 (propertyName == "Model"))
292 {
293 const std::string* value =
294 std::get_if<std::string>(&property.second);
295 if (value == nullptr)
296 {
297 // illegal property
298 messages::internalError(asyncResp->res);
299 return;
300 }
301 asyncResp->res.jsonValue[propertyName] = *value;
302 }
303 }
304 },
305 connectionName, path, "org.freedesktop.DBus.Properties", "GetAll",
306 "xyz.openbmc_project.Inventory.Decorator.Asset");
307}
308
309inline void getDrivePresent(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
310 const std::string& connectionName,
311 const std::string& path)
312{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700313 sdbusplus::asio::getProperty<bool>(
314 *crow::connections::systemBus, connectionName, path,
315 "xyz.openbmc_project.Inventory.Item", "Present",
Willy Tu03913172021-11-08 02:03:19 -0800316 [asyncResp, path](const boost::system::error_code ec,
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700317 const bool enabled) {
Willy Tu03913172021-11-08 02:03:19 -0800318 // this interface isn't necessary, only check it if
319 // we get a good return
320 if (ec)
321 {
322 return;
323 }
324
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700325 if (!enabled)
Willy Tu03913172021-11-08 02:03:19 -0800326 {
327 asyncResp->res.jsonValue["Status"]["State"] = "Disabled";
328 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700329 });
Willy Tu03913172021-11-08 02:03:19 -0800330}
331
332inline void getDriveState(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
333 const std::string& connectionName,
334 const std::string& path)
335{
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700336 sdbusplus::asio::getProperty<bool>(
337 *crow::connections::systemBus, connectionName, path,
338 "xyz.openbmc_project.State.Drive", "Rebuilding",
339 [asyncResp](const boost::system::error_code ec, const bool updating) {
Willy Tu03913172021-11-08 02:03:19 -0800340 // this interface isn't necessary, only check it
341 // if we get a good return
342 if (ec)
343 {
344 return;
345 }
346
Willy Tu03913172021-11-08 02:03:19 -0800347 // updating and disabled in the backend shouldn't be
348 // able to be set at the same time, so we don't need
349 // to check for the race condition of these two
350 // calls
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700351 if (updating)
Willy Tu03913172021-11-08 02:03:19 -0800352 {
353 asyncResp->res.jsonValue["Status"]["State"] = "Updating";
354 }
Jonathan Doman1e1e5982021-06-11 09:36:17 -0700355 });
Willy Tu03913172021-11-08 02:03:19 -0800356}
357
Willy Tu19b8e9a2021-11-08 02:55:03 -0800358inline std::optional<std::string> convertDriveType(const std::string& type)
359{
360 if (type == "xyz.openbmc_project.Inventory.Item.Drive.DriveType.HDD")
361 {
362 return "HDD";
363 }
364 if (type == "xyz.openbmc_project.Inventory.Item.Drive.DriveType.SSD")
365 {
366 return "SSD";
367 }
368
369 return std::nullopt;
370}
371
372inline std::optional<std::string> convertDriveProtocol(const std::string& proto)
373{
374 if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.SAS")
375 {
376 return "SAS";
377 }
378 if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.SATA")
379 {
380 return "SATA";
381 }
382 if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.NVMe")
383 {
384 return "NVMe";
385 }
386 if (proto == "xyz.openbmc_project.Inventory.Item.Drive.DriveProtocol.FC")
387 {
388 return "FC";
389 }
390
391 return std::nullopt;
392}
393
394inline void
395 getDriveItemProperties(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
396 const std::string& connectionName,
397 const std::string& path)
398{
399 sdbusplus::asio::getAllProperties(
400 *crow::connections::systemBus, connectionName, path,
401 "xyz.openbmc_project.Inventory.Item.Drive",
402 [asyncResp](const boost::system::error_code ec,
403 const std::vector<
404 std::pair<std::string, dbus::utility::DbusVariantType>>&
405 propertiesList) {
406 if (ec)
407 {
408 // this interface isn't required
409 return;
410 }
411 for (const std::pair<std::string, dbus::utility::DbusVariantType>&
412 property : propertiesList)
413 {
414 const std::string& propertyName = property.first;
415 if (propertyName == "Type")
416 {
417 const std::string* value =
418 std::get_if<std::string>(&property.second);
419 if (value == nullptr)
420 {
421 // illegal property
422 BMCWEB_LOG_ERROR << "Illegal property: Type";
423 messages::internalError(asyncResp->res);
424 return;
425 }
426
427 std::optional<std::string> mediaType =
428 convertDriveType(*value);
429 if (!mediaType)
430 {
431 BMCWEB_LOG_ERROR << "Unsupported DriveType Interface: "
432 << *value;
433 messages::internalError(asyncResp->res);
434 return;
435 }
436
437 asyncResp->res.jsonValue["MediaType"] = *mediaType;
438 }
439 else if (propertyName == "Capacity")
440 {
441 const uint64_t* capacity =
442 std::get_if<uint64_t>(&property.second);
443 if (capacity == nullptr)
444 {
445 BMCWEB_LOG_ERROR << "Illegal property: Capacity";
446 messages::internalError(asyncResp->res);
447 return;
448 }
449 if (*capacity == 0)
450 {
451 // drive capacity not known
452 continue;
453 }
454
455 asyncResp->res.jsonValue["CapacityBytes"] = *capacity;
456 }
457 else if (propertyName == "Protocol")
458 {
459 const std::string* value =
460 std::get_if<std::string>(&property.second);
461 if (value == nullptr)
462 {
463 BMCWEB_LOG_ERROR << "Illegal property: Protocol";
464 messages::internalError(asyncResp->res);
465 return;
466 }
467
468 std::optional<std::string> proto =
469 convertDriveProtocol(*value);
470 if (!proto)
471 {
472 BMCWEB_LOG_ERROR
473 << "Unsupported DrivePrototype Interface: "
474 << *value;
475 messages::internalError(asyncResp->res);
476 return;
477 }
478 asyncResp->res.jsonValue["Protocol"] = *proto;
479 }
480 }
481 });
482}
483
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700484inline void requestRoutesDrive(App& app)
485{
486 BMCWEB_ROUTE(app, "/redfish/v1/Systems/system/Storage/1/Drives/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700487 .privileges(redfish::privileges::getDrive)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700488 .methods(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700489 boost::beast::http::verb::
490 get)([&app](const crow::Request& req,
491 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
492 const std::string& driveId) {
493 if (!redfish::setUpRedfishRoute(app, req, asyncResp->res))
494 {
495 return;
496 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700497 crow::connections::systemBus->async_method_call(
Ed Tanousb9d36b42022-02-26 21:42:46 -0800498 [asyncResp, driveId](
499 const boost::system::error_code ec,
500 const dbus::utility::MapperGetSubTreeResponse& subtree) {
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700501 if (ec)
502 {
503 BMCWEB_LOG_ERROR << "Drive mapper call error";
504 messages::internalError(asyncResp->res);
505 return;
506 }
507
Willy Tu03913172021-11-08 02:03:19 -0800508 auto drive = std::find_if(
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700509 subtree.begin(), subtree.end(),
Willy Tu03913172021-11-08 02:03:19 -0800510 [&driveId](const std::pair<
511 std::string,
512 std::vector<std::pair<
513 std::string, std::vector<std::string>>>>&
514 object) {
515 return sdbusplus::message::object_path(object.first)
516 .filename() == driveId;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700517 });
518
Willy Tu03913172021-11-08 02:03:19 -0800519 if (drive == subtree.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700520 {
521 messages::resourceNotFound(asyncResp->res, "Drive",
522 driveId);
523 return;
524 }
525
Willy Tu03913172021-11-08 02:03:19 -0800526 const std::string& path = drive->first;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700527 const std::vector<
528 std::pair<std::string, std::vector<std::string>>>&
Willy Tu03913172021-11-08 02:03:19 -0800529 connectionNames = drive->second;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700530
531 asyncResp->res.jsonValue["@odata.type"] =
532 "#Drive.v1_7_0.Drive";
533 asyncResp->res.jsonValue["@odata.id"] =
534 "/redfish/v1/Systems/system/Storage/1/Drives/" +
535 driveId;
536 asyncResp->res.jsonValue["Name"] = driveId;
537 asyncResp->res.jsonValue["Id"] = driveId;
538
539 if (connectionNames.size() != 1)
James Feiste284a7c2019-11-20 16:20:23 -0800540 {
541 BMCWEB_LOG_ERROR << "Connection size "
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700542 << connectionNames.size()
Willy Tu03913172021-11-08 02:03:19 -0800543 << ", not equal to 1";
James Feiste284a7c2019-11-20 16:20:23 -0800544 messages::internalError(asyncResp->res);
545 return;
546 }
547
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700548 getMainChassisId(
549 asyncResp,
550 [](const std::string& chassisId,
551 const std::shared_ptr<bmcweb::AsyncResp>& aRsp) {
552 aRsp->res.jsonValue["Links"]["Chassis"] = {
553 {"@odata.id",
554 "/redfish/v1/Chassis/" + chassisId}};
555 });
556
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700557 // default it to Enabled
558 asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
559
560 auto health = std::make_shared<HealthPopulate>(asyncResp);
James Feiste284a7c2019-11-20 16:20:23 -0800561 health->inventory.emplace_back(path);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700562 health->populate();
Nikhil Potadea25aecc2019-08-23 16:35:26 -0700563
Willy Tu03913172021-11-08 02:03:19 -0800564 const std::string& connectionName =
565 connectionNames[0].first;
Nikhil Potadea25aecc2019-08-23 16:35:26 -0700566
Willy Tu03913172021-11-08 02:03:19 -0800567 getDriveAsset(asyncResp, connectionName, path);
568 getDrivePresent(asyncResp, connectionName, path);
569 getDriveState(asyncResp, connectionName, path);
Willy Tu19b8e9a2021-11-08 02:55:03 -0800570 getDriveItemProperties(asyncResp, connectionName, path);
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700571 },
572 "xyz.openbmc_project.ObjectMapper",
573 "/xyz/openbmc_project/object_mapper",
574 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
575 "/xyz/openbmc_project/inventory", int32_t(0),
576 std::array<const char*, 1>{
577 "xyz.openbmc_project.Inventory.Item.Drive"});
578 });
579}
Nikhil Potadea25aecc2019-08-23 16:35:26 -0700580} // namespace redfish