blob: be0d58e0950606856fa8bd30cad751e0627b1cbc [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
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +02004#pragma once
5
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08006#include "account_service.hpp"
7#include "app.hpp"
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +02008#include "async_resp.hpp"
Ed Tanous11e8f602023-08-24 14:25:18 -07009#include "credential_pipe.hpp"
George Liu2b731192023-01-11 16:27:13 +080010#include "dbus_utility.hpp"
Ed Tanous739b87e2023-02-24 13:13:33 -080011#include "generated/enums/virtual_media.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "query.hpp"
13#include "registries/privilege_registry.hpp"
14#include "utils/json_utils.hpp"
15
Ed Tanousef4c65b2023-04-24 15:28:50 -070016#include <boost/url/format.hpp>
Anna Platash9e319cf2020-11-17 10:18:31 +010017#include <boost/url/url_view.hpp>
Ed Tanous4a7fbef2024-04-06 16:03:49 -070018#include <boost/url/url_view_base.hpp>
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020019
George Liu2b731192023-01-11 16:27:13 +080020#include <array>
Ed Tanous3544d2a2023-08-06 18:12:20 -070021#include <ranges>
George Liu2b731192023-01-11 16:27:13 +080022#include <string_view>
23
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020024namespace redfish
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020025{
Ed Tanous365a73f2023-02-24 12:16:49 -080026
27enum class VmMode
28{
29 Invalid,
30 Legacy,
31 Proxy
32};
33
Patrick Williamsbd79bce2024-08-16 15:22:20 -040034inline VmMode parseObjectPathAndGetMode(
35 const sdbusplus::message::object_path& itemPath, const std::string& resName)
Ed Tanous365a73f2023-02-24 12:16:49 -080036{
37 std::string thisPath = itemPath.filename();
Ed Tanous62598e32023-07-17 17:06:25 -070038 BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
Ed Tanous365a73f2023-02-24 12:16:49 -080039
40 if (thisPath.empty())
41 {
42 return VmMode::Invalid;
43 }
44
45 if (thisPath != resName)
46 {
47 return VmMode::Invalid;
48 }
49
50 auto mode = itemPath.parent_path();
51 auto type = mode.parent_path();
52
53 if (mode.filename().empty() || type.filename().empty())
54 {
55 return VmMode::Invalid;
56 }
57
58 if (type.filename() != "VirtualMedia")
59 {
60 return VmMode::Invalid;
61 }
62 std::string modeStr = mode.filename();
63 if (modeStr == "Legacy")
64 {
65 return VmMode::Legacy;
66 }
67 if (modeStr == "Proxy")
68 {
69 return VmMode::Proxy;
70 }
71 return VmMode::Invalid;
72}
73
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020074using CheckItemHandler =
75 std::function<void(const std::string& service, const std::string& resName,
76 const std::shared_ptr<bmcweb::AsyncResp>&,
George Liu70cbdf52023-03-04 12:07:25 +080077 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +000078 dbus::utility::DBusInterfacesMap>&)>;
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020079
Ed Tanousac106bf2023-06-07 09:24:59 -070080inline void
81 findAndParseObject(const std::string& service, const std::string& resName,
82 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
83 CheckItemHandler&& handler)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020084{
George Liu5eb468d2023-06-20 17:03:24 +080085 sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
86 dbus::utility::getManagedObjects(
87 service, path,
Ed Tanous8cb2c022024-03-27 16:31:46 -070088 [service, resName, asyncResp, handler = std::move(handler)](
89 const boost::system::error_code& ec,
90 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040091 if (ec)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020092 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -040093 BMCWEB_LOG_DEBUG("DBUS response error");
94
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020095 return;
96 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020097
Patrick Williamsbd79bce2024-08-16 15:22:20 -040098 for (const auto& item : subtree)
99 {
100 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
101 if (mode != VmMode::Invalid)
102 {
103 handler(service, resName, asyncResp, item);
104 return;
105 }
106 }
107
108 BMCWEB_LOG_DEBUG("Parent item not found");
109 asyncResp->res.result(boost::beast::http::status::not_found);
110 });
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200111}
112
Anna Platash9e319cf2020-11-17 10:18:31 +0100113/**
114 * @brief Function extracts transfer protocol name from URI.
115 */
Ed Tanous67df0732021-10-26 11:23:56 -0700116inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
117{
Ed Tanous6fd29552023-10-04 09:40:14 -0700118 boost::system::result<boost::urls::url_view> url =
Ed Tanous079360a2022-06-29 10:05:19 -0700119 boost::urls::parse_uri(imageUri);
Ed Tanous67df0732021-10-26 11:23:56 -0700120 if (!url)
121 {
122 return "None";
123 }
Ed Tanous079360a2022-06-29 10:05:19 -0700124 std::string_view scheme = url->scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700125 if (scheme == "smb")
126 {
127 return "CIFS";
128 }
129 if (scheme == "https")
130 {
131 return "HTTPS";
132 }
133
134 return "None";
135}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200136
137/**
138 * @brief Read all known properties from VM object interfaces
139 */
Ed Tanous22db1722021-06-09 10:53:51 -0700140inline void
Michael Shen80f79a42023-08-24 13:41:53 +0000141 vmParseInterfaceObject(const dbus::utility::DBusInterfacesMap& interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700142 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200143{
Ed Tanous8a592812022-06-04 09:06:59 -0700144 for (const auto& [interface, values] : interfaces)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200145 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800146 if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200147 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800148 for (const auto& [property, value] : values)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200149 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800150 if (property == "EndpointId")
151 {
152 const std::string* endpointIdValue =
153 std::get_if<std::string>(&value);
154 if (endpointIdValue == nullptr)
155 {
156 continue;
157 }
158 if (!endpointIdValue->empty())
159 {
160 // Proxy mode
Ed Tanousac106bf2023-06-07 09:24:59 -0700161 asyncResp->res
Ed Tanous711ac7a2021-12-20 09:34:41 -0800162 .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
163 *endpointIdValue;
Ed Tanousac106bf2023-06-07 09:24:59 -0700164 asyncResp->res.jsonValue["TransferProtocolType"] =
165 "OEM";
Ed Tanous711ac7a2021-12-20 09:34:41 -0800166 }
167 }
168 if (property == "ImageURL")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200169 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100170 const std::string* imageUrlValue =
Ed Tanous711ac7a2021-12-20 09:34:41 -0800171 std::get_if<std::string>(&value);
Ed Tanous26f69762022-01-25 09:49:11 -0800172 if (imageUrlValue != nullptr && !imageUrlValue->empty())
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100173 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100174 std::filesystem::path filePath = *imageUrlValue;
175 if (!filePath.has_filename())
176 {
177 // this will handle https share, which not
178 // necessarily has to have filename given.
Ed Tanousac106bf2023-06-07 09:24:59 -0700179 asyncResp->res.jsonValue["ImageName"] = "";
Anna Platash9e319cf2020-11-17 10:18:31 +0100180 }
181 else
182 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700183 asyncResp->res.jsonValue["ImageName"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100184 filePath.filename();
185 }
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100186
Ed Tanousac106bf2023-06-07 09:24:59 -0700187 asyncResp->res.jsonValue["Image"] = *imageUrlValue;
188 asyncResp->res.jsonValue["TransferProtocolType"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100189 getTransferProtocolTypeFromUri(*imageUrlValue);
190
Ed Tanousac106bf2023-06-07 09:24:59 -0700191 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800192 virtual_media::ConnectedVia::URI;
Anna Platash9e319cf2020-11-17 10:18:31 +0100193 }
194 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800195 if (property == "WriteProtected")
Anna Platash9e319cf2020-11-17 10:18:31 +0100196 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800197 const bool* writeProtectedValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800198 if (writeProtectedValue != nullptr)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200199 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700200 asyncResp->res.jsonValue["WriteProtected"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100201 *writeProtectedValue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200202 }
203 }
204 }
205 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800206 if (interface == "xyz.openbmc_project.VirtualMedia.Process")
207 {
208 for (const auto& [property, value] : values)
209 {
210 if (property == "Active")
211 {
212 const bool* activeValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800213 if (activeValue == nullptr)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800214 {
Ed Tanous62598e32023-07-17 17:06:25 -0700215 BMCWEB_LOG_DEBUG("Value Active not found");
Ed Tanous711ac7a2021-12-20 09:34:41 -0800216 return;
217 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700218 asyncResp->res.jsonValue["Inserted"] = *activeValue;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800219
Ed Tanouse05aec52022-01-25 10:28:56 -0800220 if (*activeValue)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800221 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700222 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800223 virtual_media::ConnectedVia::Applet;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800224 }
225 }
226 }
227 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200228 }
229}
230
231/**
232 * @brief Fill template for Virtual Media Item.
233 */
Ed Tanous22db1722021-06-09 10:53:51 -0700234inline nlohmann::json vmItemTemplate(const std::string& name,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500235 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200236{
237 nlohmann::json item;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700238 item["@odata.id"] = boost::urls::format(
239 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
Ed Tanous22db1722021-06-09 10:53:51 -0700240
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100241 item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200242 item["Name"] = "Virtual Removable Media";
243 item["Id"] = resName;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200244 item["WriteProtected"] = true;
Ed Tanous739b87e2023-02-24 13:13:33 -0800245 item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
Ed Tanous613dabe2022-07-09 11:17:36 -0700246 item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
Ed Tanous539d8c62024-06-19 14:38:27 -0700247 item["TransferMethod"] = virtual_media::TransferMethod::Stream;
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100248 item["Oem"]["OpenBMC"]["@odata.type"] =
Ed Tanousf958ed92024-07-12 11:16:59 -0700249 "#OpenBMCVirtualMedia.v1_0_0.VirtualMedia";
V-Sanjana15b89722023-05-11 16:27:03 +0530250 item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
251 "/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200252
253 return item;
254}
255
256/**
257 * @brief Fills collection data
258 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700259inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500260 const std::string& service,
261 const std::string& name)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200262{
Ed Tanous62598e32023-07-17 17:06:25 -0700263 BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
George Liu5eb468d2023-06-20 17:03:24 +0800264 sdbusplus::message::object_path objPath(
265 "/xyz/openbmc_project/VirtualMedia");
266 dbus::utility::getManagedObjects(
267 service, objPath,
Ed Tanousac106bf2023-06-07 09:24:59 -0700268 [name, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800269 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700270 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400271 if (ec)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200272 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400273 BMCWEB_LOG_DEBUG("DBUS response error");
274 return;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200275 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400276 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
277 members = nlohmann::json::array();
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200278
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400279 for (const auto& object : subtree)
280 {
281 nlohmann::json item;
282 std::string path = object.first.filename();
283 if (path.empty())
284 {
285 continue;
286 }
287
288 item["@odata.id"] = boost::urls::format(
289 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
290 members.emplace_back(std::move(item));
291 }
292 asyncResp->res.jsonValue["Members@odata.count"] = members.size();
293 });
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200294}
295
George Liu70cbdf52023-03-04 12:07:25 +0800296inline void
297 afterGetVmData(const std::string& name, const std::string& /*service*/,
298 const std::string& resName,
299 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
300 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +0000301 dbus::utility::DBusInterfacesMap>& item)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200302{
303 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
304 if (mode == VmMode::Invalid)
305 {
306 return;
307 }
308
309 asyncResp->res.jsonValue = vmItemTemplate(name, resName);
310
311 // Check if dbus path is Legacy type
312 if (mode == VmMode::Legacy)
313 {
Ed Tanousef4c65b2023-04-24 15:28:50 -0700314 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
315 ["target"] = boost::urls::format(
316 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
317 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200318 }
319
320 vmParseInterfaceObject(item.second, asyncResp);
321
Ed Tanousef4c65b2023-04-24 15:28:50 -0700322 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
323 ["target"] = boost::urls::format(
324 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
325 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200326}
327
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200328/**
329 * @brief Fills data for specific resource
330 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700331inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500332 const std::string& service, const std::string& name,
333 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200334{
Ed Tanous62598e32023-07-17 17:06:25 -0700335 BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200336
Ed Tanousac106bf2023-06-07 09:24:59 -0700337 findAndParseObject(service, resName, asyncResp,
George Liu70cbdf52023-03-04 12:07:25 +0800338 std::bind_front(afterGetVmData, name));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200339}
340
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200341/**
Ed Tanous22db1722021-06-09 10:53:51 -0700342 * @brief Transfer protocols supported for InsertMedia action.
343 *
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200344 */
Ed Tanous22db1722021-06-09 10:53:51 -0700345enum class TransferProtocol
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200346{
Ed Tanous22db1722021-06-09 10:53:51 -0700347 https,
348 smb,
349 invalid
350};
351
352/**
353 * @brief Function extracts transfer protocol type from URI.
354 *
355 */
Ed Tanous67df0732021-10-26 11:23:56 -0700356inline std::optional<TransferProtocol>
Ed Tanous4a7fbef2024-04-06 16:03:49 -0700357 getTransferProtocolFromUri(const boost::urls::url_view_base& imageUri)
Ed Tanous67df0732021-10-26 11:23:56 -0700358{
Ed Tanous079360a2022-06-29 10:05:19 -0700359 std::string_view scheme = imageUri.scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700360 if (scheme == "smb")
361 {
362 return TransferProtocol::smb;
363 }
364 if (scheme == "https")
365 {
366 return TransferProtocol::https;
367 }
368 if (!scheme.empty())
369 {
370 return TransferProtocol::invalid;
371 }
372
373 return {};
374}
Ed Tanous22db1722021-06-09 10:53:51 -0700375
376/**
377 * @brief Function convert transfer protocol from string param.
378 *
379 */
380inline std::optional<TransferProtocol> getTransferProtocolFromParam(
381 const std::optional<std::string>& transferProtocolType)
382{
Ed Tanouse01d0c32023-06-30 13:21:32 -0700383 if (!transferProtocolType)
Agata Olenderc6f4e012020-03-11 15:19:07 +0100384 {
Ed Tanous22db1722021-06-09 10:53:51 -0700385 return {};
Agata Olenderc6f4e012020-03-11 15:19:07 +0100386 }
387
Ed Tanous22db1722021-06-09 10:53:51 -0700388 if (*transferProtocolType == "CIFS")
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200389 {
Ed Tanous22db1722021-06-09 10:53:51 -0700390 return TransferProtocol::smb;
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200391 }
392
Ed Tanous22db1722021-06-09 10:53:51 -0700393 if (*transferProtocolType == "HTTPS")
394 {
395 return TransferProtocol::https;
396 }
397
398 return TransferProtocol::invalid;
399}
400
401/**
402 * @brief Function extends URI with transfer protocol type.
403 *
404 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400405inline std::string getUriWithTransferProtocol(
406 const std::string& imageUri, const TransferProtocol& transferProtocol)
Ed Tanous22db1722021-06-09 10:53:51 -0700407{
408 if (transferProtocol == TransferProtocol::smb)
409 {
410 return "smb://" + imageUri;
411 }
412
413 if (transferProtocol == TransferProtocol::https)
414 {
415 return "https://" + imageUri;
416 }
417
418 return imageUri;
419}
420
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200421struct InsertMediaActionParams
422{
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200423 std::optional<std::string> imageUrl;
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200424 std::optional<std::string> userName;
425 std::optional<std::string> password;
426 std::optional<std::string> transferMethod;
427 std::optional<std::string> transferProtocolType;
428 std::optional<bool> writeProtected = true;
429 std::optional<bool> inserted;
430};
431
Ed Tanous22db1722021-06-09 10:53:51 -0700432/**
433 * @brief Function transceives data with dbus directly.
434 *
435 * All BMC state properties will be retrieved before sending reset request.
436 */
437inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
438 const std::string& service, const std::string& name,
Ed Tanous11e8f602023-08-24 14:25:18 -0700439 const std::string& imageUrl, bool rw,
Ed Tanous22db1722021-06-09 10:53:51 -0700440 std::string&& userName, std::string&& password)
441{
Ed Tanous11e8f602023-08-24 14:25:18 -0700442 int fd = -1;
443 std::shared_ptr<CredentialsPipe> secretPipe;
Ed Tanous22db1722021-06-09 10:53:51 -0700444 if (!userName.empty() || !password.empty())
445 {
Ed Tanous22db1722021-06-09 10:53:51 -0700446 // Payload must contain data + NULL delimiters
Ed Tanous11e8f602023-08-24 14:25:18 -0700447 constexpr const size_t secretLimit = 1024;
448 if (userName.size() + password.size() + 2 > secretLimit)
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100449 {
Ed Tanous62598e32023-07-17 17:06:25 -0700450 BMCWEB_LOG_ERROR("Credentials too long to handle");
Ed Tanous22db1722021-06-09 10:53:51 -0700451 messages::unrecognizedRequestBody(asyncResp->res);
452 return;
453 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100454
Ed Tanous22db1722021-06-09 10:53:51 -0700455 // Open pipe
Ed Tanous11e8f602023-08-24 14:25:18 -0700456 secretPipe = std::make_shared<CredentialsPipe>(
457 crow::connections::systemBus->get_io_context());
Ed Tanous3bfa3b22024-01-31 12:18:03 -0800458 fd = secretPipe->releaseFd();
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100459
Ed Tanous22db1722021-06-09 10:53:51 -0700460 // Pass secret over pipe
461 secretPipe->asyncWrite(
Ed Tanous11e8f602023-08-24 14:25:18 -0700462 std::move(userName), std::move(password),
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400463 [asyncResp,
464 secretPipe](const boost::system::error_code& ec, std::size_t) {
465 if (ec)
466 {
467 BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
468 messages::internalError(asyncResp->res);
469 }
470 });
Ed Tanous22db1722021-06-09 10:53:51 -0700471 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100472
Ed Tanouse3648032024-10-16 18:06:39 -0700473 std::variant<sdbusplus::message::unix_fd> unixFd(
Ed Tanous11e8f602023-08-24 14:25:18 -0700474 std::in_place_type<sdbusplus::message::unix_fd>, fd);
475
476 sdbusplus::message::object_path path(
477 "/xyz/openbmc_project/VirtualMedia/Legacy");
478 path /= name;
Ed Tanous22db1722021-06-09 10:53:51 -0700479 crow::connections::systemBus->async_method_call(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400480 [asyncResp,
481 secretPipe](const boost::system::error_code& ec, bool success) {
482 if (ec)
483 {
484 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
485 messages::internalError(asyncResp->res);
486 return;
487 }
488 if (!success)
489 {
490 BMCWEB_LOG_ERROR("Service responded with error");
491 messages::internalError(asyncResp->res);
492 }
493 },
Ed Tanous11e8f602023-08-24 14:25:18 -0700494 service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
495 imageUrl, rw, unixFd);
Ed Tanous22db1722021-06-09 10:53:51 -0700496}
497
498/**
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200499 * @brief Function validate parameters of insert media request.
500 *
501 */
502inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
503 const std::string& service,
504 const std::string& resName,
505 InsertMediaActionParams& actionParams)
506{
Ed Tanous62598e32023-07-17 17:06:25 -0700507 BMCWEB_LOG_DEBUG("Validation started");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200508 // required param imageUrl must not be empty
509 if (!actionParams.imageUrl)
510 {
Ed Tanous62598e32023-07-17 17:06:25 -0700511 BMCWEB_LOG_ERROR("Request action parameter Image is empty.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200512
513 messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
514
515 return;
516 }
517
518 // optional param inserted must be true
Ed Tanouse01d0c32023-06-30 13:21:32 -0700519 if (actionParams.inserted && !*actionParams.inserted)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200520 {
Ed Tanous62598e32023-07-17 17:06:25 -0700521 BMCWEB_LOG_ERROR(
522 "Request action optional parameter Inserted must be true.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200523
524 messages::actionParameterNotSupported(asyncResp->res, "Inserted",
525 "InsertMedia");
526
527 return;
528 }
529
530 // optional param transferMethod must be stream
Ed Tanouse01d0c32023-06-30 13:21:32 -0700531 if (actionParams.transferMethod &&
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200532 (*actionParams.transferMethod != "Stream"))
533 {
Ed Tanous62598e32023-07-17 17:06:25 -0700534 BMCWEB_LOG_ERROR("Request action optional parameter "
535 "TransferMethod must be Stream.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200536
537 messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
538 "InsertMedia");
539
540 return;
541 }
Ed Tanous6fd29552023-10-04 09:40:14 -0700542 boost::system::result<boost::urls::url_view> url =
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200543 boost::urls::parse_uri(*actionParams.imageUrl);
544 if (!url)
545 {
546 messages::actionParameterValueFormatError(
547 asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
548 return;
549 }
550 std::optional<TransferProtocol> uriTransferProtocolType =
551 getTransferProtocolFromUri(*url);
552
553 std::optional<TransferProtocol> paramTransferProtocolType =
554 getTransferProtocolFromParam(actionParams.transferProtocolType);
555
556 // ImageUrl does not contain valid protocol type
Ed Tanouse01d0c32023-06-30 13:21:32 -0700557 if (uriTransferProtocolType &&
558 *uriTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200559 {
Ed Tanous62598e32023-07-17 17:06:25 -0700560 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
561 "contain specified protocol type from list: "
562 "(smb, https).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200563
564 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
565
566 return;
567 }
568
569 // transferProtocolType should contain value from list
Ed Tanouse01d0c32023-06-30 13:21:32 -0700570 if (paramTransferProtocolType &&
571 *paramTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200572 {
Ed Tanous62598e32023-07-17 17:06:25 -0700573 BMCWEB_LOG_ERROR("Request action parameter TransferProtocolType "
574 "must be provided with value from list: "
575 "(CIFS, HTTPS).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200576
Ed Tanouse01d0c32023-06-30 13:21:32 -0700577 messages::propertyValueNotInList(
578 asyncResp->res, actionParams.transferProtocolType.value_or(""),
579 "TransferProtocolType");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200580 return;
581 }
582
583 // valid transfer protocol not provided either with URI nor param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700584 if (!uriTransferProtocolType && !paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200585 {
Ed Tanous62598e32023-07-17 17:06:25 -0700586 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
587 "contain specified protocol type or param "
588 "TransferProtocolType must be provided.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200589
590 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
591
592 return;
593 }
594
595 // valid transfer protocol provided both with URI and param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700596 if (paramTransferProtocolType && uriTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200597 {
598 // check if protocol is the same for URI and param
599 if (*paramTransferProtocolType != *uriTransferProtocolType)
600 {
Ed Tanous62598e32023-07-17 17:06:25 -0700601 BMCWEB_LOG_ERROR("Request action parameter "
602 "TransferProtocolType must contain the "
603 "same protocol type as protocol type "
604 "provided with param imageUrl.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200605
606 messages::actionParameterValueTypeError(
Ed Tanouse01d0c32023-06-30 13:21:32 -0700607 asyncResp->res, actionParams.transferProtocolType.value_or(""),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200608 "TransferProtocolType", "InsertMedia");
609
610 return;
611 }
612 }
613
614 // validation passed, add protocol to URI if needed
Boleslaw Ogonczyk Makowski7ead48e2023-09-01 15:57:10 +0200615 if (!uriTransferProtocolType && paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200616 {
617 actionParams.imageUrl = getUriWithTransferProtocol(
618 *actionParams.imageUrl, *paramTransferProtocolType);
619 }
620
Jayaprakash Mutyala452bd8d2023-04-18 12:28:38 +0000621 if (!actionParams.userName)
622 {
623 actionParams.userName = "";
624 }
625
626 if (!actionParams.password)
627 {
628 actionParams.password = "";
629 }
630
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200631 doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
Ed Tanouse01d0c32023-06-30 13:21:32 -0700632 !(actionParams.writeProtected.value_or(false)),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200633 std::move(*actionParams.userName),
634 std::move(*actionParams.password));
635}
636
637/**
Ed Tanous22db1722021-06-09 10:53:51 -0700638 * @brief Function transceives data with dbus directly.
639 *
640 * All BMC state properties will be retrieved before sending reset request.
641 */
Ed Tanous24e740a2023-02-24 12:08:58 -0800642inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
643 const std::string& service, const std::string& name,
644 bool legacy)
Ed Tanous22db1722021-06-09 10:53:51 -0700645{
Ed Tanous22db1722021-06-09 10:53:51 -0700646 // Legacy mount requires parameter with image
647 if (legacy)
648 {
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100649 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800650 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400651 if (ec)
652 {
653 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700654
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400655 messages::internalError(asyncResp->res);
656 return;
657 }
658 },
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100659 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
Ed Tanous22db1722021-06-09 10:53:51 -0700660 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200661 }
Ed Tanous22db1722021-06-09 10:53:51 -0700662 else // proxy
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200663 {
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200664 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800665 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400666 if (ec)
667 {
668 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700669
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400670 messages::internalError(asyncResp->res);
671 return;
672 }
673 },
Ed Tanous22db1722021-06-09 10:53:51 -0700674 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
675 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
676 }
677}
678
Ed Tanous96825be2022-06-03 09:43:38 -0700679inline void handleManagersVirtualMediaActionInsertPost(
680 crow::App& app, const crow::Request& req,
681 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
682 const std::string& name, const std::string& resName)
683{
684 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
685 {
686 return;
687 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200688
689 constexpr std::string_view action = "VirtualMedia.InsertMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700690 if (name != "bmc")
691 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200692 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700693
694 return;
695 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200696 InsertMediaActionParams actionParams;
Ed Tanous96825be2022-06-03 09:43:38 -0700697
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200698 // Read obligatory parameters (url of image)
Myung Baeafc474a2024-10-09 00:53:29 -0700699 if (!json_util::readJsonAction( //
700 req, asyncResp->res, //
701 "Image", actionParams.imageUrl, //
702 "Inserted", actionParams.inserted, //
703 "Password", actionParams.password, //
704 "TransferMethod", actionParams.transferMethod, //
705 "TransferProtocolType", actionParams.transferProtocolType, //
706 "UserName", actionParams.userName, //
707 "WriteProtected", actionParams.writeProtected //
708 ))
Ed Tanous96825be2022-06-03 09:43:38 -0700709 {
710 return;
711 }
712
George Liu2b731192023-01-11 16:27:13 +0800713 dbus::utility::getDbusObject(
714 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200715 [asyncResp, action, actionParams,
George Liu2b731192023-01-11 16:27:13 +0800716 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700717 const dbus::utility::MapperGetObject& getObjectType) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400718 if (ec)
Ed Tanous96825be2022-06-03 09:43:38 -0700719 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400720 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200721 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700722
723 return;
724 }
Ed Tanous96825be2022-06-03 09:43:38 -0700725
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400726 std::string service = getObjectType.begin()->first;
727 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
728
729 sdbusplus::message::object_path path(
730 "/xyz/openbmc_project/VirtualMedia");
731 dbus::utility::getManagedObjects(
732 service, path,
733 [service, resName, action, actionParams, asyncResp](
734 const boost::system::error_code& ec2,
735 const dbus::utility::ManagedObjectType& subtree) mutable {
736 if (ec2)
737 {
738 // Not possible in proxy mode
739 BMCWEB_LOG_DEBUG("InsertMedia not "
740 "allowed in proxy mode");
741 messages::resourceNotFound(asyncResp->res, action,
742 resName);
743
744 return;
745 }
746 for (const auto& object : subtree)
747 {
748 VmMode mode =
749 parseObjectPathAndGetMode(object.first, resName);
750 if (mode == VmMode::Legacy)
751 {
752 validateParams(asyncResp, service, resName,
753 actionParams);
754
755 return;
756 }
757 }
758 BMCWEB_LOG_DEBUG("Parent item not found");
759 messages::resourceNotFound(asyncResp->res, "VirtualMedia",
760 resName);
761 });
George Liu2b731192023-01-11 16:27:13 +0800762 });
Ed Tanous96825be2022-06-03 09:43:38 -0700763}
764
765inline void handleManagersVirtualMediaActionEject(
766 crow::App& app, const crow::Request& req,
767 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
768 const std::string& managerName, const std::string& resName)
769{
770 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
771 {
772 return;
773 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200774
775 constexpr std::string_view action = "VirtualMedia.EjectMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700776 if (managerName != "bmc")
777 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200778 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700779
780 return;
781 }
782
George Liu2b731192023-01-11 16:27:13 +0800783 dbus::utility::getDbusObject(
784 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200785 [asyncResp, action,
George Liu2b731192023-01-11 16:27:13 +0800786 resName](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700787 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400788 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700789 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400790 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}",
791 ec2);
792 messages::internalError(asyncResp->res);
793
Ed Tanous96825be2022-06-03 09:43:38 -0700794 return;
795 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400796 std::string service = getObjectType.begin()->first;
797 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700798
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400799 sdbusplus::message::object_path path(
800 "/xyz/openbmc_project/VirtualMedia");
801 dbus::utility::getManagedObjects(
802 service, path,
803 [resName, service, action,
804 asyncResp](const boost::system::error_code& ec,
805 const dbus::utility::ManagedObjectType& subtree) {
806 if (ec)
807 {
808 BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
809 messages::resourceNotFound(asyncResp->res, action,
810 resName);
811 return;
812 }
813
814 for (const auto& object : subtree)
815 {
816 VmMode mode =
817 parseObjectPathAndGetMode(object.first, resName);
818 if (mode != VmMode::Invalid)
819 {
820 doEjectAction(asyncResp, service, resName,
821 mode == VmMode::Legacy);
822 return;
823 }
824 }
825 BMCWEB_LOG_DEBUG("Parent item not found");
826 messages::resourceNotFound(asyncResp->res, "VirtualMedia",
827 resName);
828 });
George Liu2b731192023-01-11 16:27:13 +0800829 });
Ed Tanous96825be2022-06-03 09:43:38 -0700830}
831
832inline void handleManagersVirtualMediaCollectionGet(
833 crow::App& app, const crow::Request& req,
834 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
835 const std::string& name)
836{
837 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
838 {
839 return;
840 }
841 if (name != "bmc")
842 {
843 messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
844
845 return;
846 }
847
848 asyncResp->res.jsonValue["@odata.type"] =
849 "#VirtualMediaCollection.VirtualMediaCollection";
850 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700851 asyncResp->res.jsonValue["@odata.id"] =
852 boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
Ed Tanous96825be2022-06-03 09:43:38 -0700853
George Liu2b731192023-01-11 16:27:13 +0800854 dbus::utility::getDbusObject(
855 "/xyz/openbmc_project/VirtualMedia", {},
856 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700857 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400858 if (ec)
859 {
860 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
861 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700862
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400863 return;
864 }
865 std::string service = getObjectType.begin()->first;
866 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700867
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400868 getVmResourceList(asyncResp, service, name);
869 });
Ed Tanous96825be2022-06-03 09:43:38 -0700870}
871
872inline void
873 handleVirtualMediaGet(crow::App& app, const crow::Request& req,
874 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
875 const std::string& name, const std::string& resName)
876{
877 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
878 {
879 return;
880 }
881 if (name != "bmc")
882 {
883 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
884
885 return;
886 }
887
George Liu2b731192023-01-11 16:27:13 +0800888 dbus::utility::getDbusObject(
889 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700890 [asyncResp, name,
George Liu2b731192023-01-11 16:27:13 +0800891 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700892 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400893 if (ec)
894 {
895 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
896 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700897
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400898 return;
899 }
900 std::string service = getObjectType.begin()->first;
901 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700902
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400903 getVmData(asyncResp, service, name, resName);
904 });
Ed Tanous96825be2022-06-03 09:43:38 -0700905}
906
Ed Tanous22db1722021-06-09 10:53:51 -0700907inline void requestNBDVirtualMediaRoutes(App& app)
908{
George Liu0fda0f12021-11-16 10:06:17 +0800909 BMCWEB_ROUTE(
910 app,
911 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700912 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700913 .methods(boost::beast::http::verb::post)(std::bind_front(
914 handleManagersVirtualMediaActionInsertPost, std::ref(app)));
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200915
George Liu0fda0f12021-11-16 10:06:17 +0800916 BMCWEB_ROUTE(
917 app,
918 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700919 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700920 .methods(boost::beast::http::verb::post)(std::bind_front(
921 handleManagersVirtualMediaActionEject, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -0700922
Ed Tanous22db1722021-06-09 10:53:51 -0700923 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
Ed Tanoused398212021-06-09 17:05:54 -0700924 .privileges(redfish::privileges::getVirtualMediaCollection)
Ed Tanous96825be2022-06-03 09:43:38 -0700925 .methods(boost::beast::http::verb::get)(std::bind_front(
926 handleManagersVirtualMediaCollectionGet, std::ref(app)));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200927
Ed Tanous22db1722021-06-09 10:53:51 -0700928 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700929 .privileges(redfish::privileges::getVirtualMedia)
Ed Tanous22db1722021-06-09 10:53:51 -0700930 .methods(boost::beast::http::verb::get)(
Ed Tanous96825be2022-06-03 09:43:38 -0700931 std::bind_front(handleVirtualMediaGet, std::ref(app)));
Ed Tanous22db1722021-06-09 10:53:51 -0700932}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200933
934} // namespace redfish