blob: d854ee53b67350412402101b75f4e87048fe9d0e [file] [log] [blame]
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +02001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "account_service.hpp"
19#include "app.hpp"
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020020#include "async_resp.hpp"
Ed Tanous11e8f602023-08-24 14:25:18 -070021#include "credential_pipe.hpp"
George Liu2b731192023-01-11 16:27:13 +080022#include "dbus_utility.hpp"
Ed Tanous739b87e2023-02-24 13:13:33 -080023#include "generated/enums/virtual_media.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080024#include "query.hpp"
25#include "registries/privilege_registry.hpp"
26#include "utils/json_utils.hpp"
27
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +010028#include <boost/process/async_pipe.hpp>
Ed Tanousef4c65b2023-04-24 15:28:50 -070029#include <boost/url/format.hpp>
Anna Platash9e319cf2020-11-17 10:18:31 +010030#include <boost/url/url_view.hpp>
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020031
George Liu2b731192023-01-11 16:27:13 +080032#include <array>
Ed Tanous3544d2a2023-08-06 18:12:20 -070033#include <ranges>
George Liu2b731192023-01-11 16:27:13 +080034#include <string_view>
35
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020036namespace redfish
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020037{
Ed Tanous365a73f2023-02-24 12:16:49 -080038
39enum class VmMode
40{
41 Invalid,
42 Legacy,
43 Proxy
44};
45
46inline VmMode
47 parseObjectPathAndGetMode(const sdbusplus::message::object_path& itemPath,
48 const std::string& resName)
49{
50 std::string thisPath = itemPath.filename();
Ed Tanous62598e32023-07-17 17:06:25 -070051 BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
Ed Tanous365a73f2023-02-24 12:16:49 -080052
53 if (thisPath.empty())
54 {
55 return VmMode::Invalid;
56 }
57
58 if (thisPath != resName)
59 {
60 return VmMode::Invalid;
61 }
62
63 auto mode = itemPath.parent_path();
64 auto type = mode.parent_path();
65
66 if (mode.filename().empty() || type.filename().empty())
67 {
68 return VmMode::Invalid;
69 }
70
71 if (type.filename() != "VirtualMedia")
72 {
73 return VmMode::Invalid;
74 }
75 std::string modeStr = mode.filename();
76 if (modeStr == "Legacy")
77 {
78 return VmMode::Legacy;
79 }
80 if (modeStr == "Proxy")
81 {
82 return VmMode::Proxy;
83 }
84 return VmMode::Invalid;
85}
86
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020087using CheckItemHandler =
88 std::function<void(const std::string& service, const std::string& resName,
89 const std::shared_ptr<bmcweb::AsyncResp>&,
George Liu70cbdf52023-03-04 12:07:25 +080090 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +000091 dbus::utility::DBusInterfacesMap>&)>;
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020092
Ed Tanousac106bf2023-06-07 09:24:59 -070093inline void
94 findAndParseObject(const std::string& service, const std::string& resName,
95 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
96 CheckItemHandler&& handler)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020097{
George Liu5eb468d2023-06-20 17:03:24 +080098 sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
99 dbus::utility::getManagedObjects(
100 service, path,
Ed Tanousac106bf2023-06-07 09:24:59 -0700101 [service, resName, asyncResp,
Lakshmi Yadlapati746c5b82023-03-06 16:07:28 -0600102 handler](const boost::system::error_code& ec,
George Liu70cbdf52023-03-04 12:07:25 +0800103 const dbus::utility::ManagedObjectType& subtree) {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200104 if (ec)
105 {
Ed Tanous62598e32023-07-17 17:06:25 -0700106 BMCWEB_LOG_DEBUG("DBUS response error");
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200107
108 return;
109 }
110
George Liu70cbdf52023-03-04 12:07:25 +0800111 for (const auto& item : subtree)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200112 {
113 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
114 if (mode != VmMode::Invalid)
115 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700116 handler(service, resName, asyncResp, item);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200117 return;
118 }
119 }
120
Ed Tanous62598e32023-07-17 17:06:25 -0700121 BMCWEB_LOG_DEBUG("Parent item not found");
Ed Tanousac106bf2023-06-07 09:24:59 -0700122 asyncResp->res.result(boost::beast::http::status::not_found);
George Liu5eb468d2023-06-20 17:03:24 +0800123 });
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200124}
125
Anna Platash9e319cf2020-11-17 10:18:31 +0100126/**
127 * @brief Function extracts transfer protocol name from URI.
128 */
Ed Tanous67df0732021-10-26 11:23:56 -0700129inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
130{
131 boost::urls::result<boost::urls::url_view> url =
Ed Tanous079360a2022-06-29 10:05:19 -0700132 boost::urls::parse_uri(imageUri);
Ed Tanous67df0732021-10-26 11:23:56 -0700133 if (!url)
134 {
135 return "None";
136 }
Ed Tanous079360a2022-06-29 10:05:19 -0700137 std::string_view scheme = url->scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700138 if (scheme == "smb")
139 {
140 return "CIFS";
141 }
142 if (scheme == "https")
143 {
144 return "HTTPS";
145 }
146
147 return "None";
148}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200149
150/**
151 * @brief Read all known properties from VM object interfaces
152 */
Ed Tanous22db1722021-06-09 10:53:51 -0700153inline void
Michael Shen80f79a42023-08-24 13:41:53 +0000154 vmParseInterfaceObject(const dbus::utility::DBusInterfacesMap& interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700155 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200156{
Ed Tanous8a592812022-06-04 09:06:59 -0700157 for (const auto& [interface, values] : interfaces)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200158 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800159 if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200160 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800161 for (const auto& [property, value] : values)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200162 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800163 if (property == "EndpointId")
164 {
165 const std::string* endpointIdValue =
166 std::get_if<std::string>(&value);
167 if (endpointIdValue == nullptr)
168 {
169 continue;
170 }
171 if (!endpointIdValue->empty())
172 {
173 // Proxy mode
Ed Tanousac106bf2023-06-07 09:24:59 -0700174 asyncResp->res
Ed Tanous711ac7a2021-12-20 09:34:41 -0800175 .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
176 *endpointIdValue;
Ed Tanousac106bf2023-06-07 09:24:59 -0700177 asyncResp->res.jsonValue["TransferProtocolType"] =
178 "OEM";
Ed Tanous711ac7a2021-12-20 09:34:41 -0800179 }
180 }
181 if (property == "ImageURL")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200182 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100183 const std::string* imageUrlValue =
Ed Tanous711ac7a2021-12-20 09:34:41 -0800184 std::get_if<std::string>(&value);
Ed Tanous26f69762022-01-25 09:49:11 -0800185 if (imageUrlValue != nullptr && !imageUrlValue->empty())
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100186 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100187 std::filesystem::path filePath = *imageUrlValue;
188 if (!filePath.has_filename())
189 {
190 // this will handle https share, which not
191 // necessarily has to have filename given.
Ed Tanousac106bf2023-06-07 09:24:59 -0700192 asyncResp->res.jsonValue["ImageName"] = "";
Anna Platash9e319cf2020-11-17 10:18:31 +0100193 }
194 else
195 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700196 asyncResp->res.jsonValue["ImageName"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100197 filePath.filename();
198 }
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100199
Ed Tanousac106bf2023-06-07 09:24:59 -0700200 asyncResp->res.jsonValue["Image"] = *imageUrlValue;
201 asyncResp->res.jsonValue["TransferProtocolType"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100202 getTransferProtocolTypeFromUri(*imageUrlValue);
203
Ed Tanousac106bf2023-06-07 09:24:59 -0700204 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800205 virtual_media::ConnectedVia::URI;
Anna Platash9e319cf2020-11-17 10:18:31 +0100206 }
207 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800208 if (property == "WriteProtected")
Anna Platash9e319cf2020-11-17 10:18:31 +0100209 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800210 const bool* writeProtectedValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800211 if (writeProtectedValue != nullptr)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200212 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700213 asyncResp->res.jsonValue["WriteProtected"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100214 *writeProtectedValue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200215 }
216 }
217 }
218 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800219 if (interface == "xyz.openbmc_project.VirtualMedia.Process")
220 {
221 for (const auto& [property, value] : values)
222 {
223 if (property == "Active")
224 {
225 const bool* activeValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800226 if (activeValue == nullptr)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800227 {
Ed Tanous62598e32023-07-17 17:06:25 -0700228 BMCWEB_LOG_DEBUG("Value Active not found");
Ed Tanous711ac7a2021-12-20 09:34:41 -0800229 return;
230 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700231 asyncResp->res.jsonValue["Inserted"] = *activeValue;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800232
Ed Tanouse05aec52022-01-25 10:28:56 -0800233 if (*activeValue)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800234 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700235 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800236 virtual_media::ConnectedVia::Applet;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800237 }
238 }
239 }
240 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200241 }
242}
243
244/**
245 * @brief Fill template for Virtual Media Item.
246 */
Ed Tanous22db1722021-06-09 10:53:51 -0700247inline nlohmann::json vmItemTemplate(const std::string& name,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500248 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200249{
250 nlohmann::json item;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700251 item["@odata.id"] = boost::urls::format(
252 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
Ed Tanous22db1722021-06-09 10:53:51 -0700253
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100254 item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200255 item["Name"] = "Virtual Removable Media";
256 item["Id"] = resName;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200257 item["WriteProtected"] = true;
Ed Tanous739b87e2023-02-24 13:13:33 -0800258 item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
Ed Tanous613dabe2022-07-09 11:17:36 -0700259 item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200260 item["TransferMethod"] = "Stream";
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100261 item["Oem"]["OpenBMC"]["@odata.type"] =
262 "#OemVirtualMedia.v1_0_0.VirtualMedia";
V-Sanjana15b89722023-05-11 16:27:03 +0530263 item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
264 "/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200265
266 return item;
267}
268
269/**
270 * @brief Fills collection data
271 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700272inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500273 const std::string& service,
274 const std::string& name)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200275{
Ed Tanous62598e32023-07-17 17:06:25 -0700276 BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
George Liu5eb468d2023-06-20 17:03:24 +0800277 sdbusplus::message::object_path objPath(
278 "/xyz/openbmc_project/VirtualMedia");
279 dbus::utility::getManagedObjects(
280 service, objPath,
Ed Tanousac106bf2023-06-07 09:24:59 -0700281 [name, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800282 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700283 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700284 if (ec)
285 {
Ed Tanous62598e32023-07-17 17:06:25 -0700286 BMCWEB_LOG_DEBUG("DBUS response error");
Ed Tanous002d39b2022-05-31 08:59:27 -0700287 return;
288 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700289 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
Ed Tanous002d39b2022-05-31 08:59:27 -0700290 members = nlohmann::json::array();
291
292 for (const auto& object : subtree)
293 {
294 nlohmann::json item;
295 std::string path = object.first.filename();
296 if (path.empty())
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200297 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700298 continue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200299 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200300
Ed Tanousef4c65b2023-04-24 15:28:50 -0700301 item["@odata.id"] = boost::urls::format(
302 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700303 members.emplace_back(std::move(item));
304 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700305 asyncResp->res.jsonValue["Members@odata.count"] = members.size();
George Liu5eb468d2023-06-20 17:03:24 +0800306 });
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200307}
308
George Liu70cbdf52023-03-04 12:07:25 +0800309inline void
310 afterGetVmData(const std::string& name, const std::string& /*service*/,
311 const std::string& resName,
312 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
313 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +0000314 dbus::utility::DBusInterfacesMap>& item)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200315{
316 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
317 if (mode == VmMode::Invalid)
318 {
319 return;
320 }
321
322 asyncResp->res.jsonValue = vmItemTemplate(name, resName);
323
324 // Check if dbus path is Legacy type
325 if (mode == VmMode::Legacy)
326 {
Ed Tanousef4c65b2023-04-24 15:28:50 -0700327 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
328 ["target"] = boost::urls::format(
329 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
330 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200331 }
332
333 vmParseInterfaceObject(item.second, asyncResp);
334
Ed Tanousef4c65b2023-04-24 15:28:50 -0700335 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
336 ["target"] = boost::urls::format(
337 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
338 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200339}
340
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200341/**
342 * @brief Fills data for specific resource
343 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700344inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500345 const std::string& service, const std::string& name,
346 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200347{
Ed Tanous62598e32023-07-17 17:06:25 -0700348 BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200349
Ed Tanousac106bf2023-06-07 09:24:59 -0700350 findAndParseObject(service, resName, asyncResp,
George Liu70cbdf52023-03-04 12:07:25 +0800351 std::bind_front(afterGetVmData, name));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200352}
353
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200354/**
Ed Tanous22db1722021-06-09 10:53:51 -0700355 * @brief Transfer protocols supported for InsertMedia action.
356 *
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200357 */
Ed Tanous22db1722021-06-09 10:53:51 -0700358enum class TransferProtocol
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200359{
Ed Tanous22db1722021-06-09 10:53:51 -0700360 https,
361 smb,
362 invalid
363};
364
365/**
366 * @brief Function extracts transfer protocol type from URI.
367 *
368 */
Ed Tanous67df0732021-10-26 11:23:56 -0700369inline std::optional<TransferProtocol>
Ed Tanousd9f466b2023-03-06 15:04:25 -0800370 getTransferProtocolFromUri(boost::urls::url_view imageUri)
Ed Tanous67df0732021-10-26 11:23:56 -0700371{
Ed Tanous079360a2022-06-29 10:05:19 -0700372 std::string_view scheme = imageUri.scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700373 if (scheme == "smb")
374 {
375 return TransferProtocol::smb;
376 }
377 if (scheme == "https")
378 {
379 return TransferProtocol::https;
380 }
381 if (!scheme.empty())
382 {
383 return TransferProtocol::invalid;
384 }
385
386 return {};
387}
Ed Tanous22db1722021-06-09 10:53:51 -0700388
389/**
390 * @brief Function convert transfer protocol from string param.
391 *
392 */
393inline std::optional<TransferProtocol> getTransferProtocolFromParam(
394 const std::optional<std::string>& transferProtocolType)
395{
Ed Tanouse01d0c32023-06-30 13:21:32 -0700396 if (!transferProtocolType)
Agata Olenderc6f4e012020-03-11 15:19:07 +0100397 {
Ed Tanous22db1722021-06-09 10:53:51 -0700398 return {};
Agata Olenderc6f4e012020-03-11 15:19:07 +0100399 }
400
Ed Tanous22db1722021-06-09 10:53:51 -0700401 if (*transferProtocolType == "CIFS")
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200402 {
Ed Tanous22db1722021-06-09 10:53:51 -0700403 return TransferProtocol::smb;
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200404 }
405
Ed Tanous22db1722021-06-09 10:53:51 -0700406 if (*transferProtocolType == "HTTPS")
407 {
408 return TransferProtocol::https;
409 }
410
411 return TransferProtocol::invalid;
412}
413
414/**
415 * @brief Function extends URI with transfer protocol type.
416 *
417 */
418inline std::string
419 getUriWithTransferProtocol(const std::string& imageUri,
420 const TransferProtocol& transferProtocol)
421{
422 if (transferProtocol == TransferProtocol::smb)
423 {
424 return "smb://" + imageUri;
425 }
426
427 if (transferProtocol == TransferProtocol::https)
428 {
429 return "https://" + imageUri;
430 }
431
432 return imageUri;
433}
434
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200435struct InsertMediaActionParams
436{
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200437 std::optional<std::string> imageUrl;
Przemyslaw Czarnowski1f2a40c2022-06-24 13:47:08 +0200438 std::optional<std::string> userName;
439 std::optional<std::string> password;
440 std::optional<std::string> transferMethod;
441 std::optional<std::string> transferProtocolType;
442 std::optional<bool> writeProtected = true;
443 std::optional<bool> inserted;
444};
445
Ed Tanous22db1722021-06-09 10:53:51 -0700446/**
447 * @brief Function transceives data with dbus directly.
448 *
449 * All BMC state properties will be retrieved before sending reset request.
450 */
451inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
452 const std::string& service, const std::string& name,
Ed Tanous11e8f602023-08-24 14:25:18 -0700453 const std::string& imageUrl, bool rw,
Ed Tanous22db1722021-06-09 10:53:51 -0700454 std::string&& userName, std::string&& password)
455{
Ed Tanous11e8f602023-08-24 14:25:18 -0700456 int fd = -1;
457 std::shared_ptr<CredentialsPipe> secretPipe;
Ed Tanous22db1722021-06-09 10:53:51 -0700458 if (!userName.empty() || !password.empty())
459 {
Ed Tanous22db1722021-06-09 10:53:51 -0700460 // Payload must contain data + NULL delimiters
Ed Tanous11e8f602023-08-24 14:25:18 -0700461 constexpr const size_t secretLimit = 1024;
462 if (userName.size() + password.size() + 2 > secretLimit)
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100463 {
Ed Tanous62598e32023-07-17 17:06:25 -0700464 BMCWEB_LOG_ERROR("Credentials too long to handle");
Ed Tanous22db1722021-06-09 10:53:51 -0700465 messages::unrecognizedRequestBody(asyncResp->res);
466 return;
467 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100468
Ed Tanous22db1722021-06-09 10:53:51 -0700469 // Open pipe
Ed Tanous11e8f602023-08-24 14:25:18 -0700470 secretPipe = std::make_shared<CredentialsPipe>(
471 crow::connections::systemBus->get_io_context());
472 fd = secretPipe->fd();
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100473
Ed Tanous22db1722021-06-09 10:53:51 -0700474 // Pass secret over pipe
475 secretPipe->asyncWrite(
Ed Tanous11e8f602023-08-24 14:25:18 -0700476 std::move(userName), std::move(password),
477 [asyncResp, secretPipe](const boost::system::error_code& ec,
478 std::size_t) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700479 if (ec)
480 {
Ed Tanous62598e32023-07-17 17:06:25 -0700481 BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700482 messages::internalError(asyncResp->res);
483 }
Ed Tanous11e8f602023-08-24 14:25:18 -0700484 });
Ed Tanous22db1722021-06-09 10:53:51 -0700485 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100486
Ed Tanous11e8f602023-08-24 14:25:18 -0700487 dbus::utility::DbusVariantType unixFd(
488 std::in_place_type<sdbusplus::message::unix_fd>, fd);
489
490 sdbusplus::message::object_path path(
491 "/xyz/openbmc_project/VirtualMedia/Legacy");
492 path /= name;
Ed Tanous22db1722021-06-09 10:53:51 -0700493 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800494 [asyncResp, secretPipe](const boost::system::error_code& ec,
Ed Tanous22db1722021-06-09 10:53:51 -0700495 bool success) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700496 if (ec)
497 {
Ed Tanous62598e32023-07-17 17:06:25 -0700498 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700499 messages::internalError(asyncResp->res);
Ed Tanous11e8f602023-08-24 14:25:18 -0700500 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700501 }
Ed Tanous11e8f602023-08-24 14:25:18 -0700502 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700503 {
Ed Tanous62598e32023-07-17 17:06:25 -0700504 BMCWEB_LOG_ERROR("Service responded with error");
Ed Tanous11e8f602023-08-24 14:25:18 -0700505 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700506 }
Ed Tanous22db1722021-06-09 10:53:51 -0700507 },
Ed Tanous11e8f602023-08-24 14:25:18 -0700508 service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
509 imageUrl, rw, unixFd);
Ed Tanous22db1722021-06-09 10:53:51 -0700510}
511
512/**
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200513 * @brief Function validate parameters of insert media request.
514 *
515 */
516inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
517 const std::string& service,
518 const std::string& resName,
519 InsertMediaActionParams& actionParams)
520{
Ed Tanous62598e32023-07-17 17:06:25 -0700521 BMCWEB_LOG_DEBUG("Validation started");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200522 // required param imageUrl must not be empty
523 if (!actionParams.imageUrl)
524 {
Ed Tanous62598e32023-07-17 17:06:25 -0700525 BMCWEB_LOG_ERROR("Request action parameter Image is empty.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200526
527 messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
528
529 return;
530 }
531
532 // optional param inserted must be true
Ed Tanouse01d0c32023-06-30 13:21:32 -0700533 if (actionParams.inserted && !*actionParams.inserted)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200534 {
Ed Tanous62598e32023-07-17 17:06:25 -0700535 BMCWEB_LOG_ERROR(
536 "Request action optional parameter Inserted must be true.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200537
538 messages::actionParameterNotSupported(asyncResp->res, "Inserted",
539 "InsertMedia");
540
541 return;
542 }
543
544 // optional param transferMethod must be stream
Ed Tanouse01d0c32023-06-30 13:21:32 -0700545 if (actionParams.transferMethod &&
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200546 (*actionParams.transferMethod != "Stream"))
547 {
Ed Tanous62598e32023-07-17 17:06:25 -0700548 BMCWEB_LOG_ERROR("Request action optional parameter "
549 "TransferMethod must be Stream.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200550
551 messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
552 "InsertMedia");
553
554 return;
555 }
556 boost::urls::result<boost::urls::url_view> url =
557 boost::urls::parse_uri(*actionParams.imageUrl);
558 if (!url)
559 {
560 messages::actionParameterValueFormatError(
561 asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
562 return;
563 }
564 std::optional<TransferProtocol> uriTransferProtocolType =
565 getTransferProtocolFromUri(*url);
566
567 std::optional<TransferProtocol> paramTransferProtocolType =
568 getTransferProtocolFromParam(actionParams.transferProtocolType);
569
570 // ImageUrl does not contain valid protocol type
Ed Tanouse01d0c32023-06-30 13:21:32 -0700571 if (uriTransferProtocolType &&
572 *uriTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200573 {
Ed Tanous62598e32023-07-17 17:06:25 -0700574 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
575 "contain specified protocol type from list: "
576 "(smb, https).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200577
578 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
579
580 return;
581 }
582
583 // transferProtocolType should contain value from list
Ed Tanouse01d0c32023-06-30 13:21:32 -0700584 if (paramTransferProtocolType &&
585 *paramTransferProtocolType == TransferProtocol::invalid)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200586 {
Ed Tanous62598e32023-07-17 17:06:25 -0700587 BMCWEB_LOG_ERROR("Request action parameter TransferProtocolType "
588 "must be provided with value from list: "
589 "(CIFS, HTTPS).");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200590
Ed Tanouse01d0c32023-06-30 13:21:32 -0700591 messages::propertyValueNotInList(
592 asyncResp->res, actionParams.transferProtocolType.value_or(""),
593 "TransferProtocolType");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200594 return;
595 }
596
597 // valid transfer protocol not provided either with URI nor param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700598 if (!uriTransferProtocolType && !paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200599 {
Ed Tanous62598e32023-07-17 17:06:25 -0700600 BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
601 "contain specified protocol type or param "
602 "TransferProtocolType must be provided.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200603
604 messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
605
606 return;
607 }
608
609 // valid transfer protocol provided both with URI and param
Ed Tanouse01d0c32023-06-30 13:21:32 -0700610 if (paramTransferProtocolType && uriTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200611 {
612 // check if protocol is the same for URI and param
613 if (*paramTransferProtocolType != *uriTransferProtocolType)
614 {
Ed Tanous62598e32023-07-17 17:06:25 -0700615 BMCWEB_LOG_ERROR("Request action parameter "
616 "TransferProtocolType must contain the "
617 "same protocol type as protocol type "
618 "provided with param imageUrl.");
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200619
620 messages::actionParameterValueTypeError(
Ed Tanouse01d0c32023-06-30 13:21:32 -0700621 asyncResp->res, actionParams.transferProtocolType.value_or(""),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200622 "TransferProtocolType", "InsertMedia");
623
624 return;
625 }
626 }
627
628 // validation passed, add protocol to URI if needed
Boleslaw Ogonczyk Makowski7ead48e2023-09-01 15:57:10 +0200629 if (!uriTransferProtocolType && paramTransferProtocolType)
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200630 {
631 actionParams.imageUrl = getUriWithTransferProtocol(
632 *actionParams.imageUrl, *paramTransferProtocolType);
633 }
634
Jayaprakash Mutyala452bd8d2023-04-18 12:28:38 +0000635 if (!actionParams.userName)
636 {
637 actionParams.userName = "";
638 }
639
640 if (!actionParams.password)
641 {
642 actionParams.password = "";
643 }
644
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200645 doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
Ed Tanouse01d0c32023-06-30 13:21:32 -0700646 !(actionParams.writeProtected.value_or(false)),
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200647 std::move(*actionParams.userName),
648 std::move(*actionParams.password));
649}
650
651/**
Ed Tanous22db1722021-06-09 10:53:51 -0700652 * @brief Function transceives data with dbus directly.
653 *
654 * All BMC state properties will be retrieved before sending reset request.
655 */
Ed Tanous24e740a2023-02-24 12:08:58 -0800656inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
657 const std::string& service, const std::string& name,
658 bool legacy)
Ed Tanous22db1722021-06-09 10:53:51 -0700659{
Ed Tanous22db1722021-06-09 10:53:51 -0700660 // Legacy mount requires parameter with image
661 if (legacy)
662 {
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100663 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800664 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700665 if (ec)
666 {
Ed Tanous62598e32023-07-17 17:06:25 -0700667 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700668
Ed Tanous002d39b2022-05-31 08:59:27 -0700669 messages::internalError(asyncResp->res);
670 return;
671 }
Adrian Ambrożewiczd6da5be2020-01-13 18:31:01 +0100672 },
673 service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
Ed Tanous22db1722021-06-09 10:53:51 -0700674 "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200675 }
Ed Tanous22db1722021-06-09 10:53:51 -0700676 else // proxy
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200677 {
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200678 crow::connections::systemBus->async_method_call(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800679 [asyncResp](const boost::system::error_code& ec) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700680 if (ec)
681 {
Ed Tanous62598e32023-07-17 17:06:25 -0700682 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700683
Ed Tanous002d39b2022-05-31 08:59:27 -0700684 messages::internalError(asyncResp->res);
685 return;
686 }
Ed Tanous22db1722021-06-09 10:53:51 -0700687 },
688 service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
689 "xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
690 }
691}
692
Ed Tanous96825be2022-06-03 09:43:38 -0700693inline void handleManagersVirtualMediaActionInsertPost(
694 crow::App& app, const crow::Request& req,
695 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
696 const std::string& name, const std::string& resName)
697{
698 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
699 {
700 return;
701 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200702
703 constexpr std::string_view action = "VirtualMedia.InsertMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700704 if (name != "bmc")
705 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200706 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700707
708 return;
709 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200710 InsertMediaActionParams actionParams;
Ed Tanous96825be2022-06-03 09:43:38 -0700711
Przemyslaw Czarnowski120fa862022-06-24 15:10:48 +0200712 // Read obligatory parameters (url of image)
Ed Tanous96825be2022-06-03 09:43:38 -0700713 if (!json_util::readJsonAction(
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200714 req, asyncResp->res, "Image", actionParams.imageUrl,
715 "WriteProtected", actionParams.writeProtected, "UserName",
716 actionParams.userName, "Password", actionParams.password,
717 "Inserted", actionParams.inserted, "TransferMethod",
718 actionParams.transferMethod, "TransferProtocolType",
719 actionParams.transferProtocolType))
Ed Tanous96825be2022-06-03 09:43:38 -0700720 {
721 return;
722 }
723
George Liu2b731192023-01-11 16:27:13 +0800724 dbus::utility::getDbusObject(
725 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200726 [asyncResp, action, actionParams,
George Liu2b731192023-01-11 16:27:13 +0800727 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700728 const dbus::utility::MapperGetObject& getObjectType) mutable {
729 if (ec)
730 {
Ed Tanous62598e32023-07-17 17:06:25 -0700731 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200732 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700733
734 return;
735 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200736
Ed Tanous96825be2022-06-03 09:43:38 -0700737 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700738 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700739
George Liu5eb468d2023-06-20 17:03:24 +0800740 sdbusplus::message::object_path path(
741 "/xyz/openbmc_project/VirtualMedia");
742 dbus::utility::getManagedObjects(
743 service, path,
744 [service, resName, action, actionParams, asyncResp](
745 const boost::system::error_code& ec2,
746 const dbus::utility::ManagedObjectType& subtree) mutable {
Ed Tanous8a592812022-06-04 09:06:59 -0700747 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700748 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200749 // Not possible in proxy mode
Ed Tanous62598e32023-07-17 17:06:25 -0700750 BMCWEB_LOG_DEBUG("InsertMedia not "
751 "allowed in proxy mode");
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200752 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700753
754 return;
755 }
Ed Tanous96825be2022-06-03 09:43:38 -0700756 for (const auto& object : subtree)
757 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800758 VmMode mode = parseObjectPathAndGetMode(object.first, resName);
Boleslaw Ogonczyk Makowski5880f0c2023-04-14 15:32:40 +0200759 if (mode == VmMode::Legacy)
Ed Tanous96825be2022-06-03 09:43:38 -0700760 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200761 validateParams(asyncResp, service, resName, actionParams);
Ed Tanous96825be2022-06-03 09:43:38 -0700762
763 return;
764 }
765 }
Ed Tanous62598e32023-07-17 17:06:25 -0700766 BMCWEB_LOG_DEBUG("Parent item not found");
Ed Tanous96825be2022-06-03 09:43:38 -0700767 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
George Liu5eb468d2023-06-20 17:03:24 +0800768 });
George Liu2b731192023-01-11 16:27:13 +0800769 });
Ed Tanous96825be2022-06-03 09:43:38 -0700770}
771
772inline void handleManagersVirtualMediaActionEject(
773 crow::App& app, const crow::Request& req,
774 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
775 const std::string& managerName, const std::string& resName)
776{
777 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
778 {
779 return;
780 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200781
782 constexpr std::string_view action = "VirtualMedia.EjectMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700783 if (managerName != "bmc")
784 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200785 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700786
787 return;
788 }
789
George Liu2b731192023-01-11 16:27:13 +0800790 dbus::utility::getDbusObject(
791 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200792 [asyncResp, action,
George Liu2b731192023-01-11 16:27:13 +0800793 resName](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700794 const dbus::utility::MapperGetObject& getObjectType) {
Ed Tanous8a592812022-06-04 09:06:59 -0700795 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700796 {
Ed Tanous62598e32023-07-17 17:06:25 -0700797 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec2);
Ed Tanous96825be2022-06-03 09:43:38 -0700798 messages::internalError(asyncResp->res);
799
800 return;
801 }
802 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700803 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700804
George Liu5eb468d2023-06-20 17:03:24 +0800805 sdbusplus::message::object_path path(
806 "/xyz/openbmc_project/VirtualMedia");
807 dbus::utility::getManagedObjects(
808 service, path,
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200809 [resName, service, action,
810 asyncResp](const boost::system::error_code& ec,
811 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous96825be2022-06-03 09:43:38 -0700812 if (ec)
813 {
Ed Tanous62598e32023-07-17 17:06:25 -0700814 BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200815 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700816 return;
817 }
818
819 for (const auto& object : subtree)
820 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800821 VmMode mode = parseObjectPathAndGetMode(object.first, resName);
822 if (mode != VmMode::Invalid)
Ed Tanous96825be2022-06-03 09:43:38 -0700823 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800824 doEjectAction(asyncResp, service, resName,
825 mode == VmMode::Legacy);
Boleslaw Ogonczyk Makowski5880f0c2023-04-14 15:32:40 +0200826 return;
Ed Tanous96825be2022-06-03 09:43:38 -0700827 }
828 }
Ed Tanous62598e32023-07-17 17:06:25 -0700829 BMCWEB_LOG_DEBUG("Parent item not found");
Ed Tanous96825be2022-06-03 09:43:38 -0700830 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
George Liu5eb468d2023-06-20 17:03:24 +0800831 });
George Liu2b731192023-01-11 16:27:13 +0800832 });
Ed Tanous96825be2022-06-03 09:43:38 -0700833}
834
835inline void handleManagersVirtualMediaCollectionGet(
836 crow::App& app, const crow::Request& req,
837 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
838 const std::string& name)
839{
840 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
841 {
842 return;
843 }
844 if (name != "bmc")
845 {
846 messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
847
848 return;
849 }
850
851 asyncResp->res.jsonValue["@odata.type"] =
852 "#VirtualMediaCollection.VirtualMediaCollection";
853 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700854 asyncResp->res.jsonValue["@odata.id"] =
855 boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
Ed Tanous96825be2022-06-03 09:43:38 -0700856
George Liu2b731192023-01-11 16:27:13 +0800857 dbus::utility::getDbusObject(
858 "/xyz/openbmc_project/VirtualMedia", {},
859 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700860 const dbus::utility::MapperGetObject& getObjectType) {
861 if (ec)
862 {
Ed Tanous62598e32023-07-17 17:06:25 -0700863 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Ed Tanous96825be2022-06-03 09:43:38 -0700864 messages::internalError(asyncResp->res);
865
866 return;
867 }
868 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700869 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700870
871 getVmResourceList(asyncResp, service, name);
George Liu2b731192023-01-11 16:27:13 +0800872 });
Ed Tanous96825be2022-06-03 09:43:38 -0700873}
874
875inline void
876 handleVirtualMediaGet(crow::App& app, const crow::Request& req,
877 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
878 const std::string& name, const std::string& resName)
879{
880 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
881 {
882 return;
883 }
884 if (name != "bmc")
885 {
886 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
887
888 return;
889 }
890
George Liu2b731192023-01-11 16:27:13 +0800891 dbus::utility::getDbusObject(
892 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700893 [asyncResp, name,
George Liu2b731192023-01-11 16:27:13 +0800894 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700895 const dbus::utility::MapperGetObject& getObjectType) {
896 if (ec)
897 {
Ed Tanous62598e32023-07-17 17:06:25 -0700898 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Ed Tanous96825be2022-06-03 09:43:38 -0700899 messages::internalError(asyncResp->res);
900
901 return;
902 }
903 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700904 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700905
906 getVmData(asyncResp, service, name, resName);
George Liu2b731192023-01-11 16:27:13 +0800907 });
Ed Tanous96825be2022-06-03 09:43:38 -0700908}
909
Ed Tanous22db1722021-06-09 10:53:51 -0700910inline void requestNBDVirtualMediaRoutes(App& app)
911{
George Liu0fda0f12021-11-16 10:06:17 +0800912 BMCWEB_ROUTE(
913 app,
914 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700915 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700916 .methods(boost::beast::http::verb::post)(std::bind_front(
917 handleManagersVirtualMediaActionInsertPost, std::ref(app)));
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200918
George Liu0fda0f12021-11-16 10:06:17 +0800919 BMCWEB_ROUTE(
920 app,
921 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700922 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700923 .methods(boost::beast::http::verb::post)(std::bind_front(
924 handleManagersVirtualMediaActionEject, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -0700925
Ed Tanous22db1722021-06-09 10:53:51 -0700926 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
Ed Tanoused398212021-06-09 17:05:54 -0700927 .privileges(redfish::privileges::getVirtualMediaCollection)
Ed Tanous96825be2022-06-03 09:43:38 -0700928 .methods(boost::beast::http::verb::get)(std::bind_front(
929 handleManagersVirtualMediaCollectionGet, std::ref(app)));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200930
Ed Tanous22db1722021-06-09 10:53:51 -0700931 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700932 .privileges(redfish::privileges::getVirtualMedia)
Ed Tanous22db1722021-06-09 10:53:51 -0700933 .methods(boost::beast::http::verb::get)(
Ed Tanous96825be2022-06-03 09:43:38 -0700934 std::bind_front(handleVirtualMediaGet, std::ref(app)));
Ed Tanous22db1722021-06-09 10:53:51 -0700935}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200936
937} // namespace redfish