blob: fca6bbac930d662c43d5844c535854af9aa0cd74 [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>
29#include <filesystem>
30#include <functional>
31#include <memory>
32#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070033#include <ranges>
Ed Tanousd7857202025-01-28 15:32:26 -080034#include <string>
George Liu2b731192023-01-11 16:27:13 +080035#include <string_view>
Ed Tanousd7857202025-01-28 15:32:26 -080036#include <utility>
37#include <variant>
George Liu2b731192023-01-11 16:27:13 +080038
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020039namespace redfish
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020040{
Ed Tanous365a73f2023-02-24 12:16:49 -080041
42enum class VmMode
43{
44 Invalid,
45 Legacy,
46 Proxy
47};
48
Patrick Williamsbd79bce2024-08-16 15:22:20 -040049inline VmMode parseObjectPathAndGetMode(
50 const sdbusplus::message::object_path& itemPath, const std::string& resName)
Ed Tanous365a73f2023-02-24 12:16:49 -080051{
52 std::string thisPath = itemPath.filename();
Ed Tanous62598e32023-07-17 17:06:25 -070053 BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
Ed Tanous365a73f2023-02-24 12:16:49 -080054
55 if (thisPath.empty())
56 {
57 return VmMode::Invalid;
58 }
59
60 if (thisPath != resName)
61 {
62 return VmMode::Invalid;
63 }
64
65 auto mode = itemPath.parent_path();
66 auto type = mode.parent_path();
67
68 if (mode.filename().empty() || type.filename().empty())
69 {
70 return VmMode::Invalid;
71 }
72
73 if (type.filename() != "VirtualMedia")
74 {
75 return VmMode::Invalid;
76 }
77 std::string modeStr = mode.filename();
78 if (modeStr == "Legacy")
79 {
80 return VmMode::Legacy;
81 }
82 if (modeStr == "Proxy")
83 {
84 return VmMode::Proxy;
85 }
86 return VmMode::Invalid;
87}
88
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020089using CheckItemHandler =
90 std::function<void(const std::string& service, const std::string& resName,
91 const std::shared_ptr<bmcweb::AsyncResp>&,
George Liu70cbdf52023-03-04 12:07:25 +080092 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +000093 dbus::utility::DBusInterfacesMap>&)>;
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020094
Patrick Williams504af5a2025-02-03 14:29:03 -050095inline void findAndParseObject(
96 const std::string& service, const std::string& resName,
97 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
98 CheckItemHandler&& handler)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020099{
George Liu5eb468d2023-06-20 17:03:24 +0800100 sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
101 dbus::utility::getManagedObjects(
102 service, path,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700103 [service, resName, asyncResp, handler = std::move(handler)](
104 const boost::system::error_code& ec,
105 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400106 if (ec)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200107 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400108 BMCWEB_LOG_DEBUG("DBUS response error");
109
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200110 return;
111 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200112
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400113 for (const auto& item : subtree)
114 {
115 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
116 if (mode != VmMode::Invalid)
117 {
118 handler(service, resName, asyncResp, item);
119 return;
120 }
121 }
122
123 BMCWEB_LOG_DEBUG("Parent item not found");
124 asyncResp->res.result(boost::beast::http::status::not_found);
125 });
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200126}
127
Anna Platash9e319cf2020-11-17 10:18:31 +0100128/**
129 * @brief Function extracts transfer protocol name from URI.
130 */
Ed Tanous67df0732021-10-26 11:23:56 -0700131inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
132{
Ed Tanous6fd29552023-10-04 09:40:14 -0700133 boost::system::result<boost::urls::url_view> url =
Ed Tanous079360a2022-06-29 10:05:19 -0700134 boost::urls::parse_uri(imageUri);
Ed Tanous67df0732021-10-26 11:23:56 -0700135 if (!url)
136 {
137 return "None";
138 }
Ed Tanous079360a2022-06-29 10:05:19 -0700139 std::string_view scheme = url->scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700140 if (scheme == "smb")
141 {
142 return "CIFS";
143 }
144 if (scheme == "https")
145 {
146 return "HTTPS";
147 }
148
149 return "None";
150}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200151
152/**
153 * @brief Read all known properties from VM object interfaces
154 */
Patrick Williams504af5a2025-02-03 14:29:03 -0500155inline void vmParseInterfaceObject(
156 const dbus::utility::DBusInterfacesMap& interfaces,
157 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200158{
Ed Tanous8a592812022-06-04 09:06:59 -0700159 for (const auto& [interface, values] : interfaces)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200160 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800161 if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200162 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800163 for (const auto& [property, value] : values)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200164 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800165 if (property == "EndpointId")
166 {
167 const std::string* endpointIdValue =
168 std::get_if<std::string>(&value);
169 if (endpointIdValue == nullptr)
170 {
171 continue;
172 }
173 if (!endpointIdValue->empty())
174 {
175 // Proxy mode
Ed Tanousac106bf2023-06-07 09:24:59 -0700176 asyncResp->res
Ed Tanous711ac7a2021-12-20 09:34:41 -0800177 .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
178 *endpointIdValue;
Ed Tanousac106bf2023-06-07 09:24:59 -0700179 asyncResp->res.jsonValue["TransferProtocolType"] =
180 "OEM";
Ed Tanous711ac7a2021-12-20 09:34:41 -0800181 }
182 }
183 if (property == "ImageURL")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200184 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100185 const std::string* imageUrlValue =
Ed Tanous711ac7a2021-12-20 09:34:41 -0800186 std::get_if<std::string>(&value);
Ed Tanous26f69762022-01-25 09:49:11 -0800187 if (imageUrlValue != nullptr && !imageUrlValue->empty())
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100188 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100189 std::filesystem::path filePath = *imageUrlValue;
190 if (!filePath.has_filename())
191 {
192 // this will handle https share, which not
193 // necessarily has to have filename given.
Ed Tanousac106bf2023-06-07 09:24:59 -0700194 asyncResp->res.jsonValue["ImageName"] = "";
Anna Platash9e319cf2020-11-17 10:18:31 +0100195 }
196 else
197 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700198 asyncResp->res.jsonValue["ImageName"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100199 filePath.filename();
200 }
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100201
Ed Tanousac106bf2023-06-07 09:24:59 -0700202 asyncResp->res.jsonValue["Image"] = *imageUrlValue;
203 asyncResp->res.jsonValue["TransferProtocolType"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100204 getTransferProtocolTypeFromUri(*imageUrlValue);
205
Ed Tanousac106bf2023-06-07 09:24:59 -0700206 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800207 virtual_media::ConnectedVia::URI;
Anna Platash9e319cf2020-11-17 10:18:31 +0100208 }
209 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800210 if (property == "WriteProtected")
Anna Platash9e319cf2020-11-17 10:18:31 +0100211 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800212 const bool* writeProtectedValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800213 if (writeProtectedValue != nullptr)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200214 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700215 asyncResp->res.jsonValue["WriteProtected"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100216 *writeProtectedValue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200217 }
218 }
219 }
220 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800221 if (interface == "xyz.openbmc_project.VirtualMedia.Process")
222 {
223 for (const auto& [property, value] : values)
224 {
225 if (property == "Active")
226 {
227 const bool* activeValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800228 if (activeValue == nullptr)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800229 {
Ed Tanous62598e32023-07-17 17:06:25 -0700230 BMCWEB_LOG_DEBUG("Value Active not found");
Ed Tanous711ac7a2021-12-20 09:34:41 -0800231 return;
232 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700233 asyncResp->res.jsonValue["Inserted"] = *activeValue;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800234
Ed Tanouse05aec52022-01-25 10:28:56 -0800235 if (*activeValue)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800236 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700237 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800238 virtual_media::ConnectedVia::Applet;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800239 }
240 }
241 }
242 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200243 }
244}
245
246/**
247 * @brief Fill template for Virtual Media Item.
248 */
Ed Tanous22db1722021-06-09 10:53:51 -0700249inline nlohmann::json vmItemTemplate(const std::string& name,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500250 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200251{
252 nlohmann::json item;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700253 item["@odata.id"] = boost::urls::format(
254 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
Ed Tanous22db1722021-06-09 10:53:51 -0700255
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100256 item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200257 item["Name"] = "Virtual Removable Media";
258 item["Id"] = resName;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200259 item["WriteProtected"] = true;
Ed Tanous739b87e2023-02-24 13:13:33 -0800260 item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
Ed Tanous613dabe2022-07-09 11:17:36 -0700261 item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
Ed Tanous539d8c62024-06-19 14:38:27 -0700262 item["TransferMethod"] = virtual_media::TransferMethod::Stream;
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100263 item["Oem"]["OpenBMC"]["@odata.type"] =
Ed Tanousf958ed92024-07-12 11:16:59 -0700264 "#OpenBMCVirtualMedia.v1_0_0.VirtualMedia";
V-Sanjana15b89722023-05-11 16:27:03 +0530265 item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
266 "/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200267
268 return item;
269}
270
271/**
272 * @brief Fills collection data
273 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700274inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500275 const std::string& service,
276 const std::string& name)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200277{
Ed Tanous62598e32023-07-17 17:06:25 -0700278 BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
George Liu5eb468d2023-06-20 17:03:24 +0800279 sdbusplus::message::object_path objPath(
280 "/xyz/openbmc_project/VirtualMedia");
281 dbus::utility::getManagedObjects(
282 service, objPath,
Ed Tanousac106bf2023-06-07 09:24:59 -0700283 [name, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800284 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700285 const dbus::utility::ManagedObjectType& subtree) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400286 if (ec)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200287 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400288 BMCWEB_LOG_DEBUG("DBUS response error");
289 return;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200290 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400291 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
292 members = nlohmann::json::array();
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200293
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400294 for (const auto& object : subtree)
295 {
296 nlohmann::json item;
297 std::string path = object.first.filename();
298 if (path.empty())
299 {
300 continue;
301 }
302
303 item["@odata.id"] = boost::urls::format(
304 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
305 members.emplace_back(std::move(item));
306 }
307 asyncResp->res.jsonValue["Members@odata.count"] = members.size();
308 });
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200309}
310
Patrick Williams504af5a2025-02-03 14:29:03 -0500311inline void afterGetVmData(
312 const std::string& name, const std::string& /*service*/,
313 const std::string& resName,
314 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
315 const std::pair<sdbusplus::message::object_path,
316 dbus::utility::DBusInterfacesMap>& item)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200317{
318 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
319 if (mode == VmMode::Invalid)
320 {
321 return;
322 }
323
324 asyncResp->res.jsonValue = vmItemTemplate(name, resName);
325
326 // Check if dbus path is Legacy type
327 if (mode == VmMode::Legacy)
328 {
Ed Tanousef4c65b2023-04-24 15:28:50 -0700329 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
330 ["target"] = boost::urls::format(
331 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
332 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200333 }
334
335 vmParseInterfaceObject(item.second, asyncResp);
336
Ed Tanousef4c65b2023-04-24 15:28:50 -0700337 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
338 ["target"] = boost::urls::format(
339 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
340 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200341}
342
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200343/**
344 * @brief Fills data for specific resource
345 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700346inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500347 const std::string& service, const std::string& name,
348 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200349{
Ed Tanous62598e32023-07-17 17:06:25 -0700350 BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200351
Ed Tanousac106bf2023-06-07 09:24:59 -0700352 findAndParseObject(service, resName, asyncResp,
George Liu70cbdf52023-03-04 12:07:25 +0800353 std::bind_front(afterGetVmData, name));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200354}
355
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200356/**
Ed Tanous22db1722021-06-09 10:53:51 -0700357 * @brief Transfer protocols supported for InsertMedia action.
358 *
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200359 */
Ed Tanous22db1722021-06-09 10:53:51 -0700360enum class TransferProtocol
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200361{
Ed Tanous22db1722021-06-09 10:53:51 -0700362 https,
363 smb,
364 invalid
365};
366
367/**
368 * @brief Function extracts transfer protocol type from URI.
369 *
370 */
Patrick Williams504af5a2025-02-03 14:29:03 -0500371inline std::optional<TransferProtocol> getTransferProtocolFromUri(
372 const boost::urls::url_view_base& imageUri)
Ed Tanous67df0732021-10-26 11:23:56 -0700373{
Ed Tanous079360a2022-06-29 10:05:19 -0700374 std::string_view scheme = imageUri.scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700375 if (scheme == "smb")
376 {
377 return TransferProtocol::smb;
378 }
379 if (scheme == "https")
380 {
381 return TransferProtocol::https;
382 }
383 if (!scheme.empty())
384 {
385 return TransferProtocol::invalid;
386 }
387
388 return {};
389}
Ed Tanous22db1722021-06-09 10:53:51 -0700390
391/**
392 * @brief Function convert transfer protocol from string param.
393 *
394 */
395inline std::optional<TransferProtocol> getTransferProtocolFromParam(
396 const std::optional<std::string>& transferProtocolType)
397{
Ed Tanouse01d0c32023-06-30 13:21:32 -0700398 if (!transferProtocolType)
Agata Olenderc6f4e012020-03-11 15:19:07 +0100399 {
Ed Tanous22db1722021-06-09 10:53:51 -0700400 return {};
Agata Olenderc6f4e012020-03-11 15:19:07 +0100401 }
402
Ed Tanous22db1722021-06-09 10:53:51 -0700403 if (*transferProtocolType == "CIFS")
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200404 {
Ed Tanous22db1722021-06-09 10:53:51 -0700405 return TransferProtocol::smb;
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200406 }
407
Ed Tanous22db1722021-06-09 10:53:51 -0700408 if (*transferProtocolType == "HTTPS")
409 {
410 return TransferProtocol::https;
411 }
412
413 return TransferProtocol::invalid;
414}
415
416/**
417 * @brief Function extends URI with transfer protocol type.
418 *
419 */
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400420inline std::string getUriWithTransferProtocol(
421 const std::string& imageUri, const TransferProtocol& transferProtocol)
Ed Tanous22db1722021-06-09 10:53:51 -0700422{
423 if (transferProtocol == TransferProtocol::smb)
424 {
425 return "smb://" + imageUri;
426 }
427
428 if (transferProtocol == TransferProtocol::https)
429 {
430 return "https://" + imageUri;
431 }
432
433 return imageUri;
434}
435
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200436struct InsertMediaActionParams
437{
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200438 std::optional<std::string> imageUrl;
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200439 std::optional<std::string> userName;
440 std::optional<std::string> password;
441 std::optional<std::string> transferMethod;
442 std::optional<std::string> transferProtocolType;
443 std::optional<bool> writeProtected = true;
444 std::optional<bool> inserted;
445};
446
Ed Tanous22db1722021-06-09 10:53:51 -0700447/**
448 * @brief Function transceives data with dbus directly.
449 *
450 * All BMC state properties will be retrieved before sending reset request.
451 */
452inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
453 const std::string& service, const std::string& name,
Ed Tanous11e8f602023-08-24 14:25:18 -0700454 const std::string& imageUrl, bool rw,
Ed Tanous22db1722021-06-09 10:53:51 -0700455 std::string&& userName, std::string&& password)
456{
Ed Tanous11e8f602023-08-24 14:25:18 -0700457 int fd = -1;
458 std::shared_ptr<CredentialsPipe> secretPipe;
Ed Tanous22db1722021-06-09 10:53:51 -0700459 if (!userName.empty() || !password.empty())
460 {
Ed Tanous22db1722021-06-09 10:53:51 -0700461 // Payload must contain data + NULL delimiters
Ed Tanous11e8f602023-08-24 14:25:18 -0700462 constexpr const size_t secretLimit = 1024;
463 if (userName.size() + password.size() + 2 > secretLimit)
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100464 {
Ed Tanous62598e32023-07-17 17:06:25 -0700465 BMCWEB_LOG_ERROR("Credentials too long to handle");
Ed Tanous22db1722021-06-09 10:53:51 -0700466 messages::unrecognizedRequestBody(asyncResp->res);
467 return;
468 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100469
Ed Tanous22db1722021-06-09 10:53:51 -0700470 // Open pipe
Ed Tanous11e8f602023-08-24 14:25:18 -0700471 secretPipe = std::make_shared<CredentialsPipe>(
472 crow::connections::systemBus->get_io_context());
Ed Tanous3bfa3b22024-01-31 12:18:03 -0800473 fd = secretPipe->releaseFd();
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100474
Ed Tanous22db1722021-06-09 10:53:51 -0700475 // Pass secret over pipe
476 secretPipe->asyncWrite(
Ed Tanous11e8f602023-08-24 14:25:18 -0700477 std::move(userName), std::move(password),
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400478 [asyncResp,
479 secretPipe](const boost::system::error_code& ec, std::size_t) {
480 if (ec)
481 {
482 BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
483 messages::internalError(asyncResp->res);
484 }
485 });
Ed Tanous22db1722021-06-09 10:53:51 -0700486 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100487
Ed Tanouse3648032024-10-16 18:06:39 -0700488 std::variant<sdbusplus::message::unix_fd> unixFd(
Ed Tanous11e8f602023-08-24 14:25:18 -0700489 std::in_place_type<sdbusplus::message::unix_fd>, fd);
490
491 sdbusplus::message::object_path path(
492 "/xyz/openbmc_project/VirtualMedia/Legacy");
493 path /= name;
Ed Tanous22db1722021-06-09 10:53:51 -0700494 crow::connections::systemBus->async_method_call(
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400495 [asyncResp,
496 secretPipe](const boost::system::error_code& ec, bool success) {
497 if (ec)
498 {
499 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
500 messages::internalError(asyncResp->res);
501 return;
502 }
503 if (!success)
504 {
505 BMCWEB_LOG_ERROR("Service responded with error");
506 messages::internalError(asyncResp->res);
507 }
508 },
Ed Tanous11e8f602023-08-24 14:25:18 -0700509 service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
510 imageUrl, rw, unixFd);
Ed Tanous22db1722021-06-09 10:53:51 -0700511}
512
513/**
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200514 * @brief Function validate parameters of insert media request.
515 *
516 */
517inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
518 const std::string& service,
519 const std::string& resName,
520 InsertMediaActionParams& actionParams)
521{
Ed Tanous62598e32023-07-17 17:06:25 -0700522 BMCWEB_LOG_DEBUG("Validation started");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200523 // required param imageUrl must not be empty
524 if (!actionParams.imageUrl)
525 {
Ed Tanous62598e32023-07-17 17:06:25 -0700526 BMCWEB_LOG_ERROR("Request action parameter Image is empty.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200527
528 messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
529
530 return;
531 }
532
533 // optional param inserted must be true
Ed Tanouse01d0c32023-06-30 13:21:32 -0700534 if (actionParams.inserted && !*actionParams.inserted)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200535 {
Ed Tanous62598e32023-07-17 17:06:25 -0700536 BMCWEB_LOG_ERROR(
537 "Request action optional parameter Inserted must be true.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200538
539 messages::actionParameterNotSupported(asyncResp->res, "Inserted",
540 "InsertMedia");
541
542 return;
543 }
544
545 // optional param transferMethod must be stream
Ed Tanouse01d0c32023-06-30 13:21:32 -0700546 if (actionParams.transferMethod &&
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200547 (*actionParams.transferMethod != "Stream"))
548 {
Ed Tanous62598e32023-07-17 17:06:25 -0700549 BMCWEB_LOG_ERROR("Request action optional parameter "
550 "TransferMethod must be Stream.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200551
552 messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
553 "InsertMedia");
554
555 return;
556 }
Ed Tanous6fd29552023-10-04 09:40:14 -0700557 boost::system::result<boost::urls::url_view> url =
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200558 boost::urls::parse_uri(*actionParams.imageUrl);
559 if (!url)
560 {
561 messages::actionParameterValueFormatError(
562 asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
563 return;
564 }
565 std::optional<TransferProtocol> uriTransferProtocolType =
566 getTransferProtocolFromUri(*url);
567
568 std::optional<TransferProtocol> paramTransferProtocolType =
569 getTransferProtocolFromParam(actionParams.transferProtocolType);
570
571 // ImageUrl does not contain valid protocol type
Ed Tanouse01d0c32023-06-30 13:21:32 -0700572 if (uriTransferProtocolType &&
573 *uriTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200574 {
Ed Tanous62598e32023-07-17 17:06:25 -0700575 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
576 "contain specified protocol type from list: "
577 "(smb, https).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200578
579 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
580
581 return;
582 }
583
584 // transferProtocolType should contain value from list
Ed Tanouse01d0c32023-06-30 13:21:32 -0700585 if (paramTransferProtocolType &&
586 *paramTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200587 {
Ed Tanous62598e32023-07-17 17:06:25 -0700588 BMCWEB_LOG_ERROR("Request action parameter TransferProtocolType "
589 "must be provided with value from list: "
590 "(CIFS, HTTPS).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200591
Ed Tanouse01d0c32023-06-30 13:21:32 -0700592 messages::propertyValueNotInList(
593 asyncResp->res, actionParams.transferProtocolType.value_or(""),
594 "TransferProtocolType");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200595 return;
596 }
597
598 // valid transfer protocol not provided either with URI nor param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700599 if (!uriTransferProtocolType && !paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200600 {
Ed Tanous62598e32023-07-17 17:06:25 -0700601 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
602 "contain specified protocol type or param "
603 "TransferProtocolType must be provided.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200604
605 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
606
607 return;
608 }
609
610 // valid transfer protocol provided both with URI and param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700611 if (paramTransferProtocolType && uriTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200612 {
613 // check if protocol is the same for URI and param
614 if (*paramTransferProtocolType != *uriTransferProtocolType)
615 {
Ed Tanous62598e32023-07-17 17:06:25 -0700616 BMCWEB_LOG_ERROR("Request action parameter "
617 "TransferProtocolType must contain the "
618 "same protocol type as protocol type "
619 "provided with param imageUrl.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200620
621 messages::actionParameterValueTypeError(
Ed Tanouse01d0c32023-06-30 13:21:32 -0700622 asyncResp->res, actionParams.transferProtocolType.value_or(""),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200623 "TransferProtocolType", "InsertMedia");
624
625 return;
626 }
627 }
628
629 // validation passed, add protocol to URI if needed
Boleslaw Ogonczyk Makowski7ead48e2023-09-01 15:57:10 +0200630 if (!uriTransferProtocolType && paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200631 {
632 actionParams.imageUrl = getUriWithTransferProtocol(
633 *actionParams.imageUrl, *paramTransferProtocolType);
634 }
635
Jayaprakash Mutyala452bd8d2023-04-18 12:28:38 +0000636 if (!actionParams.userName)
637 {
638 actionParams.userName = "";
639 }
640
641 if (!actionParams.password)
642 {
643 actionParams.password = "";
644 }
645
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200646 doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
Ed Tanouse01d0c32023-06-30 13:21:32 -0700647 !(actionParams.writeProtected.value_or(false)),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200648 std::move(*actionParams.userName),
649 std::move(*actionParams.password));
650}
651
652/**
Ed Tanous22db1722021-06-09 10:53:51 -0700653 * @brief Function transceives data with dbus directly.
654 *
655 * All BMC state properties will be retrieved before sending reset request.
656 */
Ed Tanous24e740a2023-02-24 12:08:58 -0800657inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
658 const std::string& service, const std::string& name,
659 bool legacy)
Ed Tanous22db1722021-06-09 10:53:51 -0700660{
Ed Tanous22db1722021-06-09 10:53:51 -0700661 // Legacy mount requires parameter with image
662 if (legacy)
663 {
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100664 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 },
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100674 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
Ed Tanous22db1722021-06-09 10:53:51 -0700675 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200676 }
Ed Tanous22db1722021-06-09 10:53:51 -0700677 else // proxy
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200678 {
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200679 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800680 [asyncResp](const boost::system::error_code& ec) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400681 if (ec)
682 {
683 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700684
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400685 messages::internalError(asyncResp->res);
686 return;
687 }
688 },
Ed Tanous22db1722021-06-09 10:53:51 -0700689 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
690 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
691 }
692}
693
Ed Tanous96825be2022-06-03 09:43:38 -0700694inline void handleManagersVirtualMediaActionInsertPost(
695 crow::App& app, const crow::Request& req,
696 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
697 const std::string& name, const std::string& resName)
698{
699 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
700 {
701 return;
702 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200703
704 constexpr std::string_view action = "VirtualMedia.InsertMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700705 if (name != "bmc")
706 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200707 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700708
709 return;
710 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200711 InsertMediaActionParams actionParams;
Ed Tanous96825be2022-06-03 09:43:38 -0700712
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200713 // Read obligatory parameters (url of image)
Patrick Williams504af5a2025-02-03 14:29:03 -0500714 if (!json_util::readJsonAction( //
715 req, asyncResp->res, //
716 "Image", actionParams.imageUrl, //
717 "Inserted", actionParams.inserted, //
718 "Password", actionParams.password, //
719 "TransferMethod", actionParams.transferMethod, //
Myung Baeafc474a2024-10-09 00:53:29 -0700720 "TransferProtocolType", actionParams.transferProtocolType, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500721 "UserName", actionParams.userName, //
722 "WriteProtected", actionParams.writeProtected //
Myung Baeafc474a2024-10-09 00:53:29 -0700723 ))
Ed Tanous96825be2022-06-03 09:43:38 -0700724 {
725 return;
726 }
727
George Liu2b731192023-01-11 16:27:13 +0800728 dbus::utility::getDbusObject(
729 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200730 [asyncResp, action, actionParams,
George Liu2b731192023-01-11 16:27:13 +0800731 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700732 const dbus::utility::MapperGetObject& getObjectType) mutable {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400733 if (ec)
Ed Tanous96825be2022-06-03 09:43:38 -0700734 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400735 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200736 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700737
738 return;
739 }
Ed Tanous96825be2022-06-03 09:43:38 -0700740
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400741 std::string service = getObjectType.begin()->first;
742 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
743
744 sdbusplus::message::object_path path(
745 "/xyz/openbmc_project/VirtualMedia");
746 dbus::utility::getManagedObjects(
747 service, path,
748 [service, resName, action, actionParams, asyncResp](
749 const boost::system::error_code& ec2,
750 const dbus::utility::ManagedObjectType& subtree) mutable {
751 if (ec2)
752 {
753 // Not possible in proxy mode
754 BMCWEB_LOG_DEBUG("InsertMedia not "
755 "allowed in proxy mode");
756 messages::resourceNotFound(asyncResp->res, action,
757 resName);
758
759 return;
760 }
761 for (const auto& object : subtree)
762 {
763 VmMode mode =
764 parseObjectPathAndGetMode(object.first, resName);
765 if (mode == VmMode::Legacy)
766 {
767 validateParams(asyncResp, service, resName,
768 actionParams);
769
770 return;
771 }
772 }
773 BMCWEB_LOG_DEBUG("Parent item not found");
774 messages::resourceNotFound(asyncResp->res, "VirtualMedia",
775 resName);
776 });
George Liu2b731192023-01-11 16:27:13 +0800777 });
Ed Tanous96825be2022-06-03 09:43:38 -0700778}
779
780inline void handleManagersVirtualMediaActionEject(
781 crow::App& app, const crow::Request& req,
782 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
783 const std::string& managerName, const std::string& resName)
784{
785 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
786 {
787 return;
788 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200789
790 constexpr std::string_view action = "VirtualMedia.EjectMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700791 if (managerName != "bmc")
792 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200793 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700794
795 return;
796 }
797
George Liu2b731192023-01-11 16:27:13 +0800798 dbus::utility::getDbusObject(
799 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200800 [asyncResp, action,
George Liu2b731192023-01-11 16:27:13 +0800801 resName](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700802 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400803 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700804 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400805 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}",
806 ec2);
807 messages::internalError(asyncResp->res);
808
Ed Tanous96825be2022-06-03 09:43:38 -0700809 return;
810 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400811 std::string service = getObjectType.begin()->first;
812 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700813
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400814 sdbusplus::message::object_path path(
815 "/xyz/openbmc_project/VirtualMedia");
816 dbus::utility::getManagedObjects(
817 service, path,
818 [resName, service, action,
819 asyncResp](const boost::system::error_code& ec,
820 const dbus::utility::ManagedObjectType& subtree) {
821 if (ec)
822 {
823 BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
824 messages::resourceNotFound(asyncResp->res, action,
825 resName);
826 return;
827 }
828
829 for (const auto& object : subtree)
830 {
831 VmMode mode =
832 parseObjectPathAndGetMode(object.first, resName);
833 if (mode != VmMode::Invalid)
834 {
835 doEjectAction(asyncResp, service, resName,
836 mode == VmMode::Legacy);
837 return;
838 }
839 }
840 BMCWEB_LOG_DEBUG("Parent item not found");
841 messages::resourceNotFound(asyncResp->res, "VirtualMedia",
842 resName);
843 });
George Liu2b731192023-01-11 16:27:13 +0800844 });
Ed Tanous96825be2022-06-03 09:43:38 -0700845}
846
847inline void handleManagersVirtualMediaCollectionGet(
848 crow::App& app, const crow::Request& req,
849 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
850 const std::string& name)
851{
852 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
853 {
854 return;
855 }
856 if (name != "bmc")
857 {
858 messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
859
860 return;
861 }
862
863 asyncResp->res.jsonValue["@odata.type"] =
864 "#VirtualMediaCollection.VirtualMediaCollection";
865 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700866 asyncResp->res.jsonValue["@odata.id"] =
867 boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
Ed Tanous96825be2022-06-03 09:43:38 -0700868
George Liu2b731192023-01-11 16:27:13 +0800869 dbus::utility::getDbusObject(
870 "/xyz/openbmc_project/VirtualMedia", {},
871 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700872 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400873 if (ec)
874 {
875 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
876 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700877
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400878 return;
879 }
880 std::string service = getObjectType.begin()->first;
881 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700882
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400883 getVmResourceList(asyncResp, service, name);
884 });
Ed Tanous96825be2022-06-03 09:43:38 -0700885}
886
Patrick Williams504af5a2025-02-03 14:29:03 -0500887inline void handleVirtualMediaGet(
888 crow::App& app, const crow::Request& req,
889 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
890 const std::string& name, const std::string& resName)
Ed Tanous96825be2022-06-03 09:43:38 -0700891{
892 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
893 {
894 return;
895 }
896 if (name != "bmc")
897 {
898 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
899
900 return;
901 }
902
George Liu2b731192023-01-11 16:27:13 +0800903 dbus::utility::getDbusObject(
904 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700905 [asyncResp, name,
George Liu2b731192023-01-11 16:27:13 +0800906 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700907 const dbus::utility::MapperGetObject& getObjectType) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400908 if (ec)
909 {
910 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
911 messages::internalError(asyncResp->res);
Ed Tanous96825be2022-06-03 09:43:38 -0700912
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400913 return;
914 }
915 std::string service = getObjectType.begin()->first;
916 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700917
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400918 getVmData(asyncResp, service, name, resName);
919 });
Ed Tanous96825be2022-06-03 09:43:38 -0700920}
921
Ed Tanous22db1722021-06-09 10:53:51 -0700922inline void requestNBDVirtualMediaRoutes(App& app)
923{
George Liu0fda0f12021-11-16 10:06:17 +0800924 BMCWEB_ROUTE(
925 app,
926 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700927 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700928 .methods(boost::beast::http::verb::post)(std::bind_front(
929 handleManagersVirtualMediaActionInsertPost, std::ref(app)));
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200930
George Liu0fda0f12021-11-16 10:06:17 +0800931 BMCWEB_ROUTE(
932 app,
933 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700934 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700935 .methods(boost::beast::http::verb::post)(std::bind_front(
936 handleManagersVirtualMediaActionEject, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -0700937
Ed Tanous22db1722021-06-09 10:53:51 -0700938 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
Ed Tanoused398212021-06-09 17:05:54 -0700939 .privileges(redfish::privileges::getVirtualMediaCollection)
Ed Tanous96825be2022-06-03 09:43:38 -0700940 .methods(boost::beast::http::verb::get)(std::bind_front(
941 handleManagersVirtualMediaCollectionGet, std::ref(app)));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200942
Ed Tanous22db1722021-06-09 10:53:51 -0700943 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700944 .privileges(redfish::privileges::getVirtualMedia)
Ed Tanous22db1722021-06-09 10:53:51 -0700945 .methods(boost::beast::http::verb::get)(
Ed Tanous96825be2022-06-03 09:43:38 -0700946 std::bind_front(handleVirtualMediaGet, std::ref(app)));
Ed Tanous22db1722021-06-09 10:53:51 -0700947}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200948
949} // namespace redfish