blob: f67af8e9dd0e5d75547f78e6859c4d834bab29f9 [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 "app.hpp"
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +02007#include "async_resp.hpp"
Ed Tanous11e8f602023-08-24 14:25:18 -07008#include "credential_pipe.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08009#include "dbus_singleton.hpp"
George Liu2b731192023-01-11 16:27:13 +080010#include "dbus_utility.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080011#include "error_messages.hpp"
Ed Tanous739b87e2023-02-24 13:13:33 -080012#include "generated/enums/virtual_media.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080013#include "http_request.hpp"
14#include "logging.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080015#include "query.hpp"
16#include "registries/privilege_registry.hpp"
17#include "utils/json_utils.hpp"
18
Ed Tanousd7857202025-01-28 15:32:26 -080019#include <boost/beast/http/status.hpp>
20#include <boost/beast/http/verb.hpp>
21#include <boost/system/result.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070022#include <boost/url/format.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080023#include <boost/url/parse.hpp>
Anna Platash9e319cf2020-11-17 10:18:31 +010024#include <boost/url/url_view.hpp>
Ed Tanous4a7fbef2024-04-06 16:03:49 -070025#include <boost/url/url_view_base.hpp>
Ed Tanousd7857202025-01-28 15:32:26 -080026#include <sdbusplus/message/native_types.hpp>
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020027
Ed Tanousd7857202025-01-28 15:32:26 -080028#include <cstddef>
Ed Tanous4bbf2a12025-02-11 07:51:38 -080029#include <cstdint>
Ed Tanousd7857202025-01-28 15:32:26 -080030#include <filesystem>
31#include <functional>
32#include <memory>
33#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070034#include <ranges>
Ed Tanousd7857202025-01-28 15:32:26 -080035#include <string>
George Liu2b731192023-01-11 16:27:13 +080036#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080037#include <utility>
38#include <variant>
George Liu2b731192023-01-11 16:27:13 +080039
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020040namespace redfish
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020041{
Ed Tanous365a73f2023-02-24 12:16:49 -080042
43enum class VmMode
44{
45 Invalid,
46 Legacy,
47 Proxy
48};
49
Patrick Williamsbd79bce2024-08-16 15:22:20 -040050inline VmMode parseObjectPathAndGetMode(
51 const sdbusplus::message::object_path& itemPath, const std::string& resName)
Ed Tanous365a73f2023-02-24 12:16:49 -080052{
53 std::string thisPath = itemPath.filename();
Ed Tanous62598e32023-07-17 17:06:25 -070054 BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
Ed Tanous365a73f2023-02-24 12:16:49 -080055
56 if (thisPath.empty())
57 {
58 return VmMode::Invalid;
59 }
60
61 if (thisPath != resName)
62 {
63 return VmMode::Invalid;
64 }
65
66 auto mode = itemPath.parent_path();
67 auto type = mode.parent_path();
68
69 if (mode.filename().empty() || type.filename().empty())
70 {
71 return VmMode::Invalid;
72 }
73
74 if (type.filename() != "VirtualMedia")
75 {
76 return VmMode::Invalid;
77 }
78 std::string modeStr = mode.filename();
79 if (modeStr == "Legacy")
80 {
81 return VmMode::Legacy;
82 }
83 if (modeStr == "Proxy")
84 {
85 return VmMode::Proxy;
86 }
87 return VmMode::Invalid;
88}
89
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020090using CheckItemHandler =
91 std::function<void(const std::string& service, const std::string& resName,
92 const std::shared_ptr<bmcweb::AsyncResp>&,
George Liu70cbdf52023-03-04 12:07:25 +080093 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +000094 dbus::utility::DBusInterfacesMap>&)>;
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020095
Patrick Williams504af5a2025-02-03 14:29:03 -050096inline void findAndParseObject(
97 const std::string& service, const std::string& resName,
98 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
99 CheckItemHandler&& handler)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200100{
George Liu5eb468d2023-06-20 17:03:24 +0800101 sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
102 dbus::utility::getManagedObjects(
103 service, path,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700104 [service, resName, asyncResp, handler = std::move(handler)](
105 const boost::system::error_code& ec,
106 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400107 if (ec)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200108 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400109 BMCWEB_LOG_DEBUG("DBUS response error");
110
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200111 return;
112 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200113
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400114 for (const auto& item : subtree)
115 {
116 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
117 if (mode != VmMode::Invalid)
118 {
119 handler(service, resName, asyncResp, item);
120 return;
121 }
122 }
123
124 BMCWEB_LOG_DEBUG("Parent item not found");
125 asyncResp->res.result(boost::beast::http::status::not_found);
126 });
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200127}
128
Anna Platash9e319cf2020-11-17 10:18:31 +0100129/**
130 * @brief Function extracts transfer protocol name from URI.
131 */
Ed Tanous67df0732021-10-26 11:23:56 -0700132inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
133{
Ed Tanous6fd29552023-10-04 09:40:14 -0700134 boost::system::result<boost::urls::url_view> url =
Ed Tanous079360a2022-06-29 10:05:19 -0700135 boost::urls::parse_uri(imageUri);
Ed Tanous67df0732021-10-26 11:23:56 -0700136 if (!url)
137 {
138 return "None";
139 }
Ed Tanous079360a2022-06-29 10:05:19 -0700140 std::string_view scheme = url->scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700141 if (scheme == "smb")
142 {
143 return "CIFS";
144 }
145 if (scheme == "https")
146 {
147 return "HTTPS";
148 }
149
150 return "None";
151}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200152
153/**
154 * @brief Read all known properties from VM object interfaces
155 */
Patrick Williams504af5a2025-02-03 14:29:03 -0500156inline void vmParseInterfaceObject(
157 const dbus::utility::DBusInterfacesMap& interfaces,
158 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200159{
Ed Tanous8a592812022-06-04 09:06:59 -0700160 for (const auto& [interface, values] : interfaces)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200161 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800162 if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200163 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800164 for (const auto& [property, value] : values)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200165 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800166 if (property == "EndpointId")
167 {
168 const std::string* endpointIdValue =
169 std::get_if<std::string>(&value);
170 if (endpointIdValue == nullptr)
171 {
172 continue;
173 }
174 if (!endpointIdValue->empty())
175 {
176 // Proxy mode
Ed Tanousac106bf2023-06-07 09:24:59 -0700177 asyncResp->res
Ed Tanous711ac7a2021-12-20 09:34:41 -0800178 .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
179 *endpointIdValue;
Ed Tanousac106bf2023-06-07 09:24:59 -0700180 asyncResp->res.jsonValue["TransferProtocolType"] =
181 "OEM";
Ed Tanous711ac7a2021-12-20 09:34:41 -0800182 }
183 }
184 if (property == "ImageURL")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200185 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100186 const std::string* imageUrlValue =
Ed Tanous711ac7a2021-12-20 09:34:41 -0800187 std::get_if<std::string>(&value);
Ed Tanous26f69762022-01-25 09:49:11 -0800188 if (imageUrlValue != nullptr && !imageUrlValue->empty())
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100189 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100190 std::filesystem::path filePath = *imageUrlValue;
191 if (!filePath.has_filename())
192 {
193 // this will handle https share, which not
194 // necessarily has to have filename given.
Ed Tanousac106bf2023-06-07 09:24:59 -0700195 asyncResp->res.jsonValue["ImageName"] = "";
Anna Platash9e319cf2020-11-17 10:18:31 +0100196 }
197 else
198 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700199 asyncResp->res.jsonValue["ImageName"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100200 filePath.filename();
201 }
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100202
Ed Tanousac106bf2023-06-07 09:24:59 -0700203 asyncResp->res.jsonValue["Image"] = *imageUrlValue;
204 asyncResp->res.jsonValue["TransferProtocolType"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100205 getTransferProtocolTypeFromUri(*imageUrlValue);
206
Ed Tanousac106bf2023-06-07 09:24:59 -0700207 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800208 virtual_media::ConnectedVia::URI;
Anna Platash9e319cf2020-11-17 10:18:31 +0100209 }
210 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800211 if (property == "WriteProtected")
Anna Platash9e319cf2020-11-17 10:18:31 +0100212 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800213 const bool* writeProtectedValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800214 if (writeProtectedValue != nullptr)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200215 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700216 asyncResp->res.jsonValue["WriteProtected"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100217 *writeProtectedValue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200218 }
219 }
220 }
221 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800222 if (interface == "xyz.openbmc_project.VirtualMedia.Process")
223 {
224 for (const auto& [property, value] : values)
225 {
226 if (property == "Active")
227 {
228 const bool* activeValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800229 if (activeValue == nullptr)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800230 {
Ed Tanous62598e32023-07-17 17:06:25 -0700231 BMCWEB_LOG_DEBUG("Value Active not found");
Ed Tanous711ac7a2021-12-20 09:34:41 -0800232 return;
233 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700234 asyncResp->res.jsonValue["Inserted"] = *activeValue;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800235
Ed Tanouse05aec52022-01-25 10:28:56 -0800236 if (*activeValue)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800237 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700238 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800239 virtual_media::ConnectedVia::Applet;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800240 }
241 }
242 }
243 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200244 }
245}
246
247/**
248 * @brief Fill template for Virtual Media Item.
249 */
Ed Tanous22db1722021-06-09 10:53:51 -0700250inline nlohmann::json vmItemTemplate(const std::string& name,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500251 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200252{
253 nlohmann::json item;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700254 item["@odata.id"] = boost::urls::format(
255 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
Ed Tanous22db1722021-06-09 10:53:51 -0700256
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100257 item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200258 item["Name"] = "Virtual Removable Media";
259 item["Id"] = resName;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200260 item["WriteProtected"] = true;
Ed Tanous739b87e2023-02-24 13:13:33 -0800261 item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
Ed Tanous613dabe2022-07-09 11:17:36 -0700262 item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
Ed Tanous539d8c62024-06-19 14:38:27 -0700263 item["TransferMethod"] = virtual_media::TransferMethod::Stream;
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100264 item["Oem"]["OpenBMC"]["@odata.type"] =
Ed Tanousf958ed92024-07-12 11:16:59 -0700265 "#OpenBMCVirtualMedia.v1_0_0.VirtualMedia";
V-Sanjana15b89722023-05-11 16:27:03 +0530266 item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
267 "/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200268
269 return item;
270}
271
272/**
273 * @brief Fills collection data
274 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700275inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500276 const std::string& service,
277 const std::string& name)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200278{
Ed Tanous62598e32023-07-17 17:06:25 -0700279 BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
George Liu5eb468d2023-06-20 17:03:24 +0800280 sdbusplus::message::object_path objPath(
281 "/xyz/openbmc_project/VirtualMedia");
282 dbus::utility::getManagedObjects(
283 service, objPath,
Ed Tanousac106bf2023-06-07 09:24:59 -0700284 [name, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800285 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700286 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400287 if (ec)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200288 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400289 BMCWEB_LOG_DEBUG("DBUS response error");
290 return;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200291 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400292 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
293 members = nlohmann::json::array();
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200294
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400295 for (const auto& object : subtree)
296 {
297 nlohmann::json item;
298 std::string path = object.first.filename();
299 if (path.empty())
300 {
301 continue;
302 }
303
304 item["@odata.id"] = boost::urls::format(
305 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
306 members.emplace_back(std::move(item));
307 }
308 asyncResp->res.jsonValue["Members@odata.count"] = members.size();
309 });
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200310}
311
Patrick Williams504af5a2025-02-03 14:29:03 -0500312inline void afterGetVmData(
313 const std::string& name, const std::string& /*service*/,
314 const std::string& resName,
315 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
316 const std::pair<sdbusplus::message::object_path,
317 dbus::utility::DBusInterfacesMap>& item)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200318{
319 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
320 if (mode == VmMode::Invalid)
321 {
322 return;
323 }
324
325 asyncResp->res.jsonValue = vmItemTemplate(name, resName);
326
327 // Check if dbus path is Legacy type
328 if (mode == VmMode::Legacy)
329 {
Ed Tanousef4c65b2023-04-24 15:28:50 -0700330 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
331 ["target"] = boost::urls::format(
332 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
333 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200334 }
335
336 vmParseInterfaceObject(item.second, asyncResp);
337
Ed Tanousef4c65b2023-04-24 15:28:50 -0700338 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
339 ["target"] = boost::urls::format(
340 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
341 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200342}
343
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200344/**
345 * @brief Fills data for specific resource
346 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700347inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500348 const std::string& service, const std::string& name,
349 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200350{
Ed Tanous62598e32023-07-17 17:06:25 -0700351 BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200352
Ed Tanousac106bf2023-06-07 09:24:59 -0700353 findAndParseObject(service, resName, asyncResp,
George Liu70cbdf52023-03-04 12:07:25 +0800354 std::bind_front(afterGetVmData, name));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200355}
356
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200357/**
Ed Tanous22db1722021-06-09 10:53:51 -0700358 * @brief Transfer protocols supported for InsertMedia action.
359 *
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200360 */
Ed Tanous22db1722021-06-09 10:53:51 -0700361enum class TransferProtocol
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200362{
Ed Tanous22db1722021-06-09 10:53:51 -0700363 https,
364 smb,
365 invalid
366};
367
368/**
369 * @brief Function extracts transfer protocol type from URI.
370 *
371 */
Patrick Williams504af5a2025-02-03 14:29:03 -0500372inline std::optional<TransferProtocol> getTransferProtocolFromUri(
373 const boost::urls::url_view_base& imageUri)
Ed Tanous67df0732021-10-26 11:23:56 -0700374{
Ed Tanous079360a2022-06-29 10:05:19 -0700375 std::string_view scheme = imageUri.scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700376 if (scheme == "smb")
377 {
378 return TransferProtocol::smb;
379 }
380 if (scheme == "https")
381 {
382 return TransferProtocol::https;
383 }
384 if (!scheme.empty())
385 {
386 return TransferProtocol::invalid;
387 }
388
389 return {};
390}
Ed Tanous22db1722021-06-09 10:53:51 -0700391
392/**
393 * @brief Function convert transfer protocol from string param.
394 *
395 */
396inline std::optional<TransferProtocol> getTransferProtocolFromParam(
397 const std::optional<std::string>& transferProtocolType)
398{
Ed Tanouse01d0c32023-06-30 13:21:32 -0700399 if (!transferProtocolType)
Agata Olenderc6f4e012020-03-11 15:19:07 +0100400 {
Ed Tanous22db1722021-06-09 10:53:51 -0700401 return {};
Agata Olenderc6f4e012020-03-11 15:19:07 +0100402 }
403
Ed Tanous22db1722021-06-09 10:53:51 -0700404 if (*transferProtocolType == "CIFS")
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200405 {
Ed Tanous22db1722021-06-09 10:53:51 -0700406 return TransferProtocol::smb;
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200407 }
408
Ed Tanous22db1722021-06-09 10:53:51 -0700409 if (*transferProtocolType == "HTTPS")
410 {
411 return TransferProtocol::https;
412 }
413
414 return TransferProtocol::invalid;
415}
416
417/**
418 * @brief Function extends URI with transfer protocol type.
419 *
420 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400421inline std::string getUriWithTransferProtocol(
422 const std::string& imageUri, const TransferProtocol& transferProtocol)
Ed Tanous22db1722021-06-09 10:53:51 -0700423{
424 if (transferProtocol == TransferProtocol::smb)
425 {
426 return "smb://" + imageUri;
427 }
428
429 if (transferProtocol == TransferProtocol::https)
430 {
431 return "https://" + imageUri;
432 }
433
434 return imageUri;
435}
436
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200437struct InsertMediaActionParams
438{
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200439 std::optional<std::string> imageUrl;
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200440 std::optional<std::string> userName;
441 std::optional<std::string> password;
442 std::optional<std::string> transferMethod;
443 std::optional<std::string> transferProtocolType;
444 std::optional<bool> writeProtected = true;
445 std::optional<bool> inserted;
446};
447
Ed Tanous22db1722021-06-09 10:53:51 -0700448/**
449 * @brief Function transceives data with dbus directly.
450 *
451 * All BMC state properties will be retrieved before sending reset request.
452 */
453inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
454 const std::string& service, const std::string& name,
Ed Tanous11e8f602023-08-24 14:25:18 -0700455 const std::string& imageUrl, bool rw,
Ed Tanous22db1722021-06-09 10:53:51 -0700456 std::string&& userName, std::string&& password)
457{
Ed Tanous4bbf2a12025-02-11 07:51:38 -0800458 if (userName.contains('\0'))
Ed Tanous22db1722021-06-09 10:53:51 -0700459 {
Ed Tanous4bbf2a12025-02-11 07:51:38 -0800460 messages::actionParameterValueFormatError(
461 asyncResp->res, userName, "Username", "VirtualMedia.InsertMedia");
462 return;
Ed Tanous22db1722021-06-09 10:53:51 -0700463 }
Ed Tanous4bbf2a12025-02-11 07:51:38 -0800464 constexpr uint64_t limit = 512;
465 if (userName.size() > limit)
466 {
467 messages::stringValueTooLong(asyncResp->res, userName, limit);
468 return;
469 }
470 if (password.contains('\0'))
471 {
472 messages::actionParameterValueFormatError(
473 asyncResp->res, password, "Password", "VirtualMedia.InsertMedia");
474 return;
475 }
476 if (password.size() > limit)
477 {
478 messages::stringValueTooLong(asyncResp->res, password, limit);
479 return;
480 }
481 // Open pipe
482 std::shared_ptr<CredentialsPipe> secretPipe =
483 std::make_shared<CredentialsPipe>(
484 crow::connections::systemBus->get_io_context());
485 int fd = secretPipe->releaseFd();
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100486
Ed Tanous4bbf2a12025-02-11 07:51:38 -0800487 // Pass secret over pipe
488 secretPipe->asyncWrite(
489 std::move(userName), std::move(password),
490 [asyncResp,
491 secretPipe](const boost::system::error_code& ec, std::size_t) {
492 if (ec)
493 {
494 BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
495 messages::internalError(asyncResp->res);
496 }
497 });
498
499 sdbusplus::message::unix_fd unixFd(fd);
Ed Tanous11e8f602023-08-24 14:25:18 -0700500
501 sdbusplus::message::object_path path(
502 "/xyz/openbmc_project/VirtualMedia/Legacy");
503 path /= name;
Ed Tanous22db1722021-06-09 10:53:51 -0700504 crow::connections::systemBus->async_method_call(
Ed Tanous4bbf2a12025-02-11 07:51:38 -0800505 [asyncResp](const boost::system::error_code& ec, bool success) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400506 if (ec)
507 {
508 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
509 messages::internalError(asyncResp->res);
510 return;
511 }
512 if (!success)
513 {
514 BMCWEB_LOG_ERROR("Service responded with error");
515 messages::internalError(asyncResp->res);
516 }
517 },
Ed Tanous11e8f602023-08-24 14:25:18 -0700518 service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
519 imageUrl, rw, unixFd);
Ed Tanous22db1722021-06-09 10:53:51 -0700520}
521
522/**
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200523 * @brief Function validate parameters of insert media request.
524 *
525 */
526inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
527 const std::string& service,
528 const std::string& resName,
529 InsertMediaActionParams& actionParams)
530{
Ed Tanous62598e32023-07-17 17:06:25 -0700531 BMCWEB_LOG_DEBUG("Validation started");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200532 // required param imageUrl must not be empty
533 if (!actionParams.imageUrl)
534 {
Ed Tanous62598e32023-07-17 17:06:25 -0700535 BMCWEB_LOG_ERROR("Request action parameter Image is empty.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200536
537 messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
538
539 return;
540 }
541
542 // optional param inserted must be true
Ed Tanouse01d0c32023-06-30 13:21:32 -0700543 if (actionParams.inserted && !*actionParams.inserted)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200544 {
Ed Tanous62598e32023-07-17 17:06:25 -0700545 BMCWEB_LOG_ERROR(
546 "Request action optional parameter Inserted must be true.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200547
548 messages::actionParameterNotSupported(asyncResp->res, "Inserted",
549 "InsertMedia");
550
551 return;
552 }
553
554 // optional param transferMethod must be stream
Ed Tanouse01d0c32023-06-30 13:21:32 -0700555 if (actionParams.transferMethod &&
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200556 (*actionParams.transferMethod != "Stream"))
557 {
Ed Tanous62598e32023-07-17 17:06:25 -0700558 BMCWEB_LOG_ERROR("Request action optional parameter "
559 "TransferMethod must be Stream.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200560
561 messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
562 "InsertMedia");
563
564 return;
565 }
Ed Tanous6fd29552023-10-04 09:40:14 -0700566 boost::system::result<boost::urls::url_view> url =
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200567 boost::urls::parse_uri(*actionParams.imageUrl);
568 if (!url)
569 {
570 messages::actionParameterValueFormatError(
571 asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
572 return;
573 }
574 std::optional<TransferProtocol> uriTransferProtocolType =
575 getTransferProtocolFromUri(*url);
576
577 std::optional<TransferProtocol> paramTransferProtocolType =
578 getTransferProtocolFromParam(actionParams.transferProtocolType);
579
580 // ImageUrl does not contain valid protocol type
Ed Tanouse01d0c32023-06-30 13:21:32 -0700581 if (uriTransferProtocolType &&
582 *uriTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200583 {
Ed Tanous62598e32023-07-17 17:06:25 -0700584 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
585 "contain specified protocol type from list: "
586 "(smb, https).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200587
588 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
589
590 return;
591 }
592
593 // transferProtocolType should contain value from list
Ed Tanouse01d0c32023-06-30 13:21:32 -0700594 if (paramTransferProtocolType &&
595 *paramTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200596 {
Ed Tanous62598e32023-07-17 17:06:25 -0700597 BMCWEB_LOG_ERROR("Request action parameter TransferProtocolType "
598 "must be provided with value from list: "
599 "(CIFS, HTTPS).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200600
Ed Tanouse01d0c32023-06-30 13:21:32 -0700601 messages::propertyValueNotInList(
602 asyncResp->res, actionParams.transferProtocolType.value_or(""),
603 "TransferProtocolType");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200604 return;
605 }
606
607 // valid transfer protocol not provided either with URI nor param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700608 if (!uriTransferProtocolType && !paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200609 {
Ed Tanous62598e32023-07-17 17:06:25 -0700610 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
611 "contain specified protocol type or param "
612 "TransferProtocolType must be provided.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200613
614 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
615
616 return;
617 }
618
619 // valid transfer protocol provided both with URI and param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700620 if (paramTransferProtocolType && uriTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200621 {
622 // check if protocol is the same for URI and param
623 if (*paramTransferProtocolType != *uriTransferProtocolType)
624 {
Ed Tanous62598e32023-07-17 17:06:25 -0700625 BMCWEB_LOG_ERROR("Request action parameter "
626 "TransferProtocolType must contain the "
627 "same protocol type as protocol type "
628 "provided with param imageUrl.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200629
630 messages::actionParameterValueTypeError(
Ed Tanouse01d0c32023-06-30 13:21:32 -0700631 asyncResp->res, actionParams.transferProtocolType.value_or(""),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200632 "TransferProtocolType", "InsertMedia");
633
634 return;
635 }
636 }
637
638 // validation passed, add protocol to URI if needed
Boleslaw Ogonczyk Makowski7ead48e2023-09-01 15:57:10 +0200639 if (!uriTransferProtocolType && paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200640 {
641 actionParams.imageUrl = getUriWithTransferProtocol(
642 *actionParams.imageUrl, *paramTransferProtocolType);
643 }
644
Jayaprakash Mutyala452bd8d2023-04-18 12:28:38 +0000645 if (!actionParams.userName)
646 {
647 actionParams.userName = "";
648 }
649
650 if (!actionParams.password)
651 {
652 actionParams.password = "";
653 }
654
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200655 doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
Ed Tanouse01d0c32023-06-30 13:21:32 -0700656 !(actionParams.writeProtected.value_or(false)),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200657 std::move(*actionParams.userName),
658 std::move(*actionParams.password));
659}
660
661/**
Ed Tanous22db1722021-06-09 10:53:51 -0700662 * @brief Function transceives data with dbus directly.
663 *
664 * All BMC state properties will be retrieved before sending reset request.
665 */
Ed Tanous24e740a2023-02-24 12:08:58 -0800666inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
667 const std::string& service, const std::string& name,
668 bool legacy)
Ed Tanous22db1722021-06-09 10:53:51 -0700669{
Ed Tanous22db1722021-06-09 10:53:51 -0700670 // Legacy mount requires parameter with image
671 if (legacy)
672 {
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100673 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800674 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400675 if (ec)
676 {
677 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700678
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400679 messages::internalError(asyncResp->res);
680 return;
681 }
682 },
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100683 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
Ed Tanous22db1722021-06-09 10:53:51 -0700684 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200685 }
Ed Tanous22db1722021-06-09 10:53:51 -0700686 else // proxy
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200687 {
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200688 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800689 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400690 if (ec)
691 {
692 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700693
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400694 messages::internalError(asyncResp->res);
695 return;
696 }
697 },
Ed Tanous22db1722021-06-09 10:53:51 -0700698 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
699 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
700 }
701}
702
Ed Tanous96825be2022-06-03 09:43:38 -0700703inline void handleManagersVirtualMediaActionInsertPost(
704 crow::App& app, const crow::Request& req,
705 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
706 const std::string& name, const std::string& resName)
707{
708 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
709 {
710 return;
711 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200712
713 constexpr std::string_view action = "VirtualMedia.InsertMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700714 if (name != "bmc")
715 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200716 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700717
718 return;
719 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200720 InsertMediaActionParams actionParams;
Ed Tanous96825be2022-06-03 09:43:38 -0700721
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200722 // Read obligatory parameters (url of image)
Patrick Williams504af5a2025-02-03 14:29:03 -0500723 if (!json_util::readJsonAction( //
724 req, asyncResp->res, //
725 "Image", actionParams.imageUrl, //
726 "Inserted", actionParams.inserted, //
727 "Password", actionParams.password, //
728 "TransferMethod", actionParams.transferMethod, //
Myung Baeafc474a2024-10-09 00:53:29 -0700729 "TransferProtocolType", actionParams.transferProtocolType, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500730 "UserName", actionParams.userName, //
731 "WriteProtected", actionParams.writeProtected //
Myung Baeafc474a2024-10-09 00:53:29 -0700732 ))
Ed Tanous96825be2022-06-03 09:43:38 -0700733 {
734 return;
735 }
736
George Liu2b731192023-01-11 16:27:13 +0800737 dbus::utility::getDbusObject(
738 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200739 [asyncResp, action, actionParams,
George Liu2b731192023-01-11 16:27:13 +0800740 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700741 const dbus::utility::MapperGetObject& getObjectType) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400742 if (ec)
Ed Tanous96825be2022-06-03 09:43:38 -0700743 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400744 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200745 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700746
747 return;
748 }
Ed Tanous96825be2022-06-03 09:43:38 -0700749
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400750 std::string service = getObjectType.begin()->first;
751 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
752
753 sdbusplus::message::object_path path(
754 "/xyz/openbmc_project/VirtualMedia");
755 dbus::utility::getManagedObjects(
756 service, path,
757 [service, resName, action, actionParams, asyncResp](
758 const boost::system::error_code& ec2,
759 const dbus::utility::ManagedObjectType& subtree) mutable {
760 if (ec2)
761 {
762 // Not possible in proxy mode
763 BMCWEB_LOG_DEBUG("InsertMedia not "
764 "allowed in proxy mode");
765 messages::resourceNotFound(asyncResp->res, action,
766 resName);
767
768 return;
769 }
770 for (const auto& object : subtree)
771 {
772 VmMode mode =
773 parseObjectPathAndGetMode(object.first, resName);
774 if (mode == VmMode::Legacy)
775 {
776 validateParams(asyncResp, service, resName,
777 actionParams);
778
779 return;
780 }
781 }
782 BMCWEB_LOG_DEBUG("Parent item not found");
783 messages::resourceNotFound(asyncResp->res, "VirtualMedia",
784 resName);
785 });
George Liu2b731192023-01-11 16:27:13 +0800786 });
Ed Tanous96825be2022-06-03 09:43:38 -0700787}
788
789inline void handleManagersVirtualMediaActionEject(
790 crow::App& app, const crow::Request& req,
791 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
792 const std::string& managerName, const std::string& resName)
793{
794 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
795 {
796 return;
797 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200798
799 constexpr std::string_view action = "VirtualMedia.EjectMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700800 if (managerName != "bmc")
801 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200802 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700803
804 return;
805 }
806
George Liu2b731192023-01-11 16:27:13 +0800807 dbus::utility::getDbusObject(
808 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200809 [asyncResp, action,
George Liu2b731192023-01-11 16:27:13 +0800810 resName](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700811 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400812 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700813 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400814 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}",
815 ec2);
816 messages::internalError(asyncResp->res);
817
Ed Tanous96825be2022-06-03 09:43:38 -0700818 return;
819 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400820 std::string service = getObjectType.begin()->first;
821 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700822
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400823 sdbusplus::message::object_path path(
824 "/xyz/openbmc_project/VirtualMedia");
825 dbus::utility::getManagedObjects(
826 service, path,
827 [resName, service, action,
828 asyncResp](const boost::system::error_code& ec,
829 const dbus::utility::ManagedObjectType& subtree) {
830 if (ec)
831 {
832 BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
833 messages::resourceNotFound(asyncResp->res, action,
834 resName);
835 return;
836 }
837
838 for (const auto& object : subtree)
839 {
840 VmMode mode =
841 parseObjectPathAndGetMode(object.first, resName);
842 if (mode != VmMode::Invalid)
843 {
844 doEjectAction(asyncResp, service, resName,
845 mode == VmMode::Legacy);
846 return;
847 }
848 }
849 BMCWEB_LOG_DEBUG("Parent item not found");
850 messages::resourceNotFound(asyncResp->res, "VirtualMedia",
851 resName);
852 });
George Liu2b731192023-01-11 16:27:13 +0800853 });
Ed Tanous96825be2022-06-03 09:43:38 -0700854}
855
856inline void handleManagersVirtualMediaCollectionGet(
857 crow::App& app, const crow::Request& req,
858 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
859 const std::string& name)
860{
861 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
862 {
863 return;
864 }
865 if (name != "bmc")
866 {
867 messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
868
869 return;
870 }
871
872 asyncResp->res.jsonValue["@odata.type"] =
873 "#VirtualMediaCollection.VirtualMediaCollection";
874 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700875 asyncResp->res.jsonValue["@odata.id"] =
876 boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
Ed Tanous96825be2022-06-03 09:43:38 -0700877
George Liu2b731192023-01-11 16:27:13 +0800878 dbus::utility::getDbusObject(
879 "/xyz/openbmc_project/VirtualMedia", {},
880 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700881 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400882 if (ec)
883 {
884 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
885 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700886
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400887 return;
888 }
889 std::string service = getObjectType.begin()->first;
890 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700891
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400892 getVmResourceList(asyncResp, service, name);
893 });
Ed Tanous96825be2022-06-03 09:43:38 -0700894}
895
Patrick Williams504af5a2025-02-03 14:29:03 -0500896inline void handleVirtualMediaGet(
897 crow::App& app, const crow::Request& req,
898 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
899 const std::string& name, const std::string& resName)
Ed Tanous96825be2022-06-03 09:43:38 -0700900{
901 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
902 {
903 return;
904 }
905 if (name != "bmc")
906 {
907 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
908
909 return;
910 }
911
George Liu2b731192023-01-11 16:27:13 +0800912 dbus::utility::getDbusObject(
913 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700914 [asyncResp, name,
George Liu2b731192023-01-11 16:27:13 +0800915 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700916 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400917 if (ec)
918 {
919 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
920 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700921
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400922 return;
923 }
924 std::string service = getObjectType.begin()->first;
925 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700926
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400927 getVmData(asyncResp, service, name, resName);
928 });
Ed Tanous96825be2022-06-03 09:43:38 -0700929}
930
Ed Tanous22db1722021-06-09 10:53:51 -0700931inline void requestNBDVirtualMediaRoutes(App& app)
932{
George Liu0fda0f12021-11-16 10:06:17 +0800933 BMCWEB_ROUTE(
934 app,
935 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700936 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700937 .methods(boost::beast::http::verb::post)(std::bind_front(
938 handleManagersVirtualMediaActionInsertPost, std::ref(app)));
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200939
George Liu0fda0f12021-11-16 10:06:17 +0800940 BMCWEB_ROUTE(
941 app,
942 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700943 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700944 .methods(boost::beast::http::verb::post)(std::bind_front(
945 handleManagersVirtualMediaActionEject, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -0700946
Ed Tanous22db1722021-06-09 10:53:51 -0700947 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
Ed Tanoused398212021-06-09 17:05:54 -0700948 .privileges(redfish::privileges::getVirtualMediaCollection)
Ed Tanous96825be2022-06-03 09:43:38 -0700949 .methods(boost::beast::http::verb::get)(std::bind_front(
950 handleManagersVirtualMediaCollectionGet, std::ref(app)));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200951
Ed Tanous22db1722021-06-09 10:53:51 -0700952 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700953 .privileges(redfish::privileges::getVirtualMedia)
Ed Tanous22db1722021-06-09 10:53:51 -0700954 .methods(boost::beast::http::verb::get)(
Ed Tanous96825be2022-06-03 09:43:38 -0700955 std::bind_front(handleVirtualMediaGet, std::ref(app)));
Ed Tanous22db1722021-06-09 10:53:51 -0700956}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200957
958} // namespace redfish