blob: 529b9dc5d9fc32da8299ee51e2f103ba7b9fbaa7 [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>
Ed Tanous4a7fbef2024-04-06 16:03:49 -070031#include <boost/url/url_view_base.hpp>
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020032
George Liu2b731192023-01-11 16:27:13 +080033#include <array>
Ed Tanous3544d2a2023-08-06 18:12:20 -070034#include <ranges>
George Liu2b731192023-01-11 16:27:13 +080035#include <string_view>
36
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020037namespace redfish
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +020038{
Ed Tanous365a73f2023-02-24 12:16:49 -080039
40enum class VmMode
41{
42 Invalid,
43 Legacy,
44 Proxy
45};
46
47inline VmMode
48 parseObjectPathAndGetMode(const sdbusplus::message::object_path& itemPath,
49 const std::string& resName)
50{
51 std::string thisPath = itemPath.filename();
Ed Tanous62598e32023-07-17 17:06:25 -070052 BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
Ed Tanous365a73f2023-02-24 12:16:49 -080053
54 if (thisPath.empty())
55 {
56 return VmMode::Invalid;
57 }
58
59 if (thisPath != resName)
60 {
61 return VmMode::Invalid;
62 }
63
64 auto mode = itemPath.parent_path();
65 auto type = mode.parent_path();
66
67 if (mode.filename().empty() || type.filename().empty())
68 {
69 return VmMode::Invalid;
70 }
71
72 if (type.filename() != "VirtualMedia")
73 {
74 return VmMode::Invalid;
75 }
76 std::string modeStr = mode.filename();
77 if (modeStr == "Legacy")
78 {
79 return VmMode::Legacy;
80 }
81 if (modeStr == "Proxy")
82 {
83 return VmMode::Proxy;
84 }
85 return VmMode::Invalid;
86}
87
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020088using CheckItemHandler =
89 std::function<void(const std::string& service, const std::string& resName,
90 const std::shared_ptr<bmcweb::AsyncResp>&,
George Liu70cbdf52023-03-04 12:07:25 +080091 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +000092 dbus::utility::DBusInterfacesMap>&)>;
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020093
Ed Tanousac106bf2023-06-07 09:24:59 -070094inline void
95 findAndParseObject(const std::string& service, const std::string& resName,
96 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
97 CheckItemHandler&& handler)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +020098{
George Liu5eb468d2023-06-20 17:03:24 +080099 sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
100 dbus::utility::getManagedObjects(
101 service, path,
Ed Tanous8cb2c022024-03-27 16:31:46 -0700102 [service, resName, asyncResp, handler = std::move(handler)](
103 const boost::system::error_code& ec,
104 const dbus::utility::ManagedObjectType& subtree) {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200105 if (ec)
106 {
Ed Tanous62598e32023-07-17 17:06:25 -0700107 BMCWEB_LOG_DEBUG("DBUS response error");
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200108
109 return;
110 }
111
George Liu70cbdf52023-03-04 12:07:25 +0800112 for (const auto& item : subtree)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200113 {
114 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
115 if (mode != VmMode::Invalid)
116 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700117 handler(service, resName, asyncResp, item);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200118 return;
119 }
120 }
121
Ed Tanous62598e32023-07-17 17:06:25 -0700122 BMCWEB_LOG_DEBUG("Parent item not found");
Ed Tanousac106bf2023-06-07 09:24:59 -0700123 asyncResp->res.result(boost::beast::http::status::not_found);
Patrick Williams5a39f772023-10-20 11:20:21 -0500124 });
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200125}
126
Anna Platash9e319cf2020-11-17 10:18:31 +0100127/**
128 * @brief Function extracts transfer protocol name from URI.
129 */
Ed Tanous67df0732021-10-26 11:23:56 -0700130inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
131{
Ed Tanous6fd29552023-10-04 09:40:14 -0700132 boost::system::result<boost::urls::url_view> url =
Ed Tanous079360a2022-06-29 10:05:19 -0700133 boost::urls::parse_uri(imageUri);
Ed Tanous67df0732021-10-26 11:23:56 -0700134 if (!url)
135 {
136 return "None";
137 }
Ed Tanous079360a2022-06-29 10:05:19 -0700138 std::string_view scheme = url->scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700139 if (scheme == "smb")
140 {
141 return "CIFS";
142 }
143 if (scheme == "https")
144 {
145 return "HTTPS";
146 }
147
148 return "None";
149}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200150
151/**
152 * @brief Read all known properties from VM object interfaces
153 */
Ed Tanous22db1722021-06-09 10:53:51 -0700154inline void
Michael Shen80f79a42023-08-24 13:41:53 +0000155 vmParseInterfaceObject(const dbus::utility::DBusInterfacesMap& interfaces,
Ed Tanousac106bf2023-06-07 09:24:59 -0700156 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200157{
Ed Tanous8a592812022-06-04 09:06:59 -0700158 for (const auto& [interface, values] : interfaces)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200159 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800160 if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200161 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800162 for (const auto& [property, value] : values)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200163 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800164 if (property == "EndpointId")
165 {
166 const std::string* endpointIdValue =
167 std::get_if<std::string>(&value);
168 if (endpointIdValue == nullptr)
169 {
170 continue;
171 }
172 if (!endpointIdValue->empty())
173 {
174 // Proxy mode
Ed Tanousac106bf2023-06-07 09:24:59 -0700175 asyncResp->res
Ed Tanous711ac7a2021-12-20 09:34:41 -0800176 .jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
177 *endpointIdValue;
Ed Tanousac106bf2023-06-07 09:24:59 -0700178 asyncResp->res.jsonValue["TransferProtocolType"] =
179 "OEM";
Ed Tanous711ac7a2021-12-20 09:34:41 -0800180 }
181 }
182 if (property == "ImageURL")
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200183 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100184 const std::string* imageUrlValue =
Ed Tanous711ac7a2021-12-20 09:34:41 -0800185 std::get_if<std::string>(&value);
Ed Tanous26f69762022-01-25 09:49:11 -0800186 if (imageUrlValue != nullptr && !imageUrlValue->empty())
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100187 {
Anna Platash9e319cf2020-11-17 10:18:31 +0100188 std::filesystem::path filePath = *imageUrlValue;
189 if (!filePath.has_filename())
190 {
191 // this will handle https share, which not
192 // necessarily has to have filename given.
Ed Tanousac106bf2023-06-07 09:24:59 -0700193 asyncResp->res.jsonValue["ImageName"] = "";
Anna Platash9e319cf2020-11-17 10:18:31 +0100194 }
195 else
196 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700197 asyncResp->res.jsonValue["ImageName"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100198 filePath.filename();
199 }
Przemyslaw Czarnowskida4784d2020-11-06 09:58:25 +0100200
Ed Tanousac106bf2023-06-07 09:24:59 -0700201 asyncResp->res.jsonValue["Image"] = *imageUrlValue;
202 asyncResp->res.jsonValue["TransferProtocolType"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100203 getTransferProtocolTypeFromUri(*imageUrlValue);
204
Ed Tanousac106bf2023-06-07 09:24:59 -0700205 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800206 virtual_media::ConnectedVia::URI;
Anna Platash9e319cf2020-11-17 10:18:31 +0100207 }
208 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800209 if (property == "WriteProtected")
Anna Platash9e319cf2020-11-17 10:18:31 +0100210 {
Ed Tanous711ac7a2021-12-20 09:34:41 -0800211 const bool* writeProtectedValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800212 if (writeProtectedValue != nullptr)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200213 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700214 asyncResp->res.jsonValue["WriteProtected"] =
Anna Platash9e319cf2020-11-17 10:18:31 +0100215 *writeProtectedValue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200216 }
217 }
218 }
219 }
Ed Tanous711ac7a2021-12-20 09:34:41 -0800220 if (interface == "xyz.openbmc_project.VirtualMedia.Process")
221 {
222 for (const auto& [property, value] : values)
223 {
224 if (property == "Active")
225 {
226 const bool* activeValue = std::get_if<bool>(&value);
Ed Tanouse662eae2022-01-25 10:39:19 -0800227 if (activeValue == nullptr)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800228 {
Ed Tanous62598e32023-07-17 17:06:25 -0700229 BMCWEB_LOG_DEBUG("Value Active not found");
Ed Tanous711ac7a2021-12-20 09:34:41 -0800230 return;
231 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700232 asyncResp->res.jsonValue["Inserted"] = *activeValue;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800233
Ed Tanouse05aec52022-01-25 10:28:56 -0800234 if (*activeValue)
Ed Tanous711ac7a2021-12-20 09:34:41 -0800235 {
Ed Tanousac106bf2023-06-07 09:24:59 -0700236 asyncResp->res.jsonValue["ConnectedVia"] =
Ed Tanous739b87e2023-02-24 13:13:33 -0800237 virtual_media::ConnectedVia::Applet;
Ed Tanous711ac7a2021-12-20 09:34:41 -0800238 }
239 }
240 }
241 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200242 }
243}
244
245/**
246 * @brief Fill template for Virtual Media Item.
247 */
Ed Tanous22db1722021-06-09 10:53:51 -0700248inline nlohmann::json vmItemTemplate(const std::string& name,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500249 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200250{
251 nlohmann::json item;
Ed Tanousef4c65b2023-04-24 15:28:50 -0700252 item["@odata.id"] = boost::urls::format(
253 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
Ed Tanous22db1722021-06-09 10:53:51 -0700254
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100255 item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200256 item["Name"] = "Virtual Removable Media";
257 item["Id"] = resName;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200258 item["WriteProtected"] = true;
Ed Tanous739b87e2023-02-24 13:13:33 -0800259 item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
Ed Tanous613dabe2022-07-09 11:17:36 -0700260 item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200261 item["TransferMethod"] = "Stream";
Przemyslaw Czarnowskid04ba322020-01-21 12:41:56 +0100262 item["Oem"]["OpenBMC"]["@odata.type"] =
263 "#OemVirtualMedia.v1_0_0.VirtualMedia";
V-Sanjana15b89722023-05-11 16:27:03 +0530264 item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
265 "/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200266
267 return item;
268}
269
270/**
271 * @brief Fills collection data
272 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700273inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500274 const std::string& service,
275 const std::string& name)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200276{
Ed Tanous62598e32023-07-17 17:06:25 -0700277 BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
George Liu5eb468d2023-06-20 17:03:24 +0800278 sdbusplus::message::object_path objPath(
279 "/xyz/openbmc_project/VirtualMedia");
280 dbus::utility::getManagedObjects(
281 service, objPath,
Ed Tanousac106bf2023-06-07 09:24:59 -0700282 [name, asyncResp{std::move(asyncResp)}](
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800283 const boost::system::error_code& ec,
Ed Tanous02cad962022-06-30 16:50:15 -0700284 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700285 if (ec)
286 {
Ed Tanous62598e32023-07-17 17:06:25 -0700287 BMCWEB_LOG_DEBUG("DBUS response error");
Ed Tanous002d39b2022-05-31 08:59:27 -0700288 return;
289 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700290 nlohmann::json& members = asyncResp->res.jsonValue["Members"];
Ed Tanous002d39b2022-05-31 08:59:27 -0700291 members = nlohmann::json::array();
292
293 for (const auto& object : subtree)
294 {
295 nlohmann::json item;
296 std::string path = object.first.filename();
297 if (path.empty())
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200298 {
Ed Tanous002d39b2022-05-31 08:59:27 -0700299 continue;
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200300 }
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200301
Ed Tanousef4c65b2023-04-24 15:28:50 -0700302 item["@odata.id"] = boost::urls::format(
303 "/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
Ed Tanous002d39b2022-05-31 08:59:27 -0700304 members.emplace_back(std::move(item));
305 }
Ed Tanousac106bf2023-06-07 09:24:59 -0700306 asyncResp->res.jsonValue["Members@odata.count"] = members.size();
Patrick Williams5a39f772023-10-20 11:20:21 -0500307 });
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200308}
309
George Liu70cbdf52023-03-04 12:07:25 +0800310inline void
311 afterGetVmData(const std::string& name, const std::string& /*service*/,
312 const std::string& resName,
313 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
314 const std::pair<sdbusplus::message::object_path,
Michael Shen80f79a42023-08-24 13:41:53 +0000315 dbus::utility::DBusInterfacesMap>& item)
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200316{
317 VmMode mode = parseObjectPathAndGetMode(item.first, resName);
318 if (mode == VmMode::Invalid)
319 {
320 return;
321 }
322
323 asyncResp->res.jsonValue = vmItemTemplate(name, resName);
324
325 // Check if dbus path is Legacy type
326 if (mode == VmMode::Legacy)
327 {
Ed Tanousef4c65b2023-04-24 15:28:50 -0700328 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
329 ["target"] = boost::urls::format(
330 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
331 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200332 }
333
334 vmParseInterfaceObject(item.second, asyncResp);
335
Ed Tanousef4c65b2023-04-24 15:28:50 -0700336 asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
337 ["target"] = boost::urls::format(
338 "/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
339 name, resName);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200340}
341
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200342/**
343 * @brief Fills data for specific resource
344 */
Ed Tanousac106bf2023-06-07 09:24:59 -0700345inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Gunnar Mills1214b7e2020-06-04 10:11:30 -0500346 const std::string& service, const std::string& name,
347 const std::string& resName)
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200348{
Ed Tanous62598e32023-07-17 17:06:25 -0700349 BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200350
Ed Tanousac106bf2023-06-07 09:24:59 -0700351 findAndParseObject(service, resName, asyncResp,
George Liu70cbdf52023-03-04 12:07:25 +0800352 std::bind_front(afterGetVmData, name));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200353}
354
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200355/**
Ed Tanous22db1722021-06-09 10:53:51 -0700356 * @brief Transfer protocols supported for InsertMedia action.
357 *
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200358 */
Ed Tanous22db1722021-06-09 10:53:51 -0700359enum class TransferProtocol
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200360{
Ed Tanous22db1722021-06-09 10:53:51 -0700361 https,
362 smb,
363 invalid
364};
365
366/**
367 * @brief Function extracts transfer protocol type from URI.
368 *
369 */
Ed Tanous67df0732021-10-26 11:23:56 -0700370inline std::optional<TransferProtocol>
Ed Tanous4a7fbef2024-04-06 16:03:49 -0700371 getTransferProtocolFromUri(const boost::urls::url_view_base& imageUri)
Ed Tanous67df0732021-10-26 11:23:56 -0700372{
Ed Tanous079360a2022-06-29 10:05:19 -0700373 std::string_view scheme = imageUri.scheme();
Ed Tanous67df0732021-10-26 11:23:56 -0700374 if (scheme == "smb")
375 {
376 return TransferProtocol::smb;
377 }
378 if (scheme == "https")
379 {
380 return TransferProtocol::https;
381 }
382 if (!scheme.empty())
383 {
384 return TransferProtocol::invalid;
385 }
386
387 return {};
388}
Ed Tanous22db1722021-06-09 10:53:51 -0700389
390/**
391 * @brief Function convert transfer protocol from string param.
392 *
393 */
394inline std::optional<TransferProtocol> getTransferProtocolFromParam(
395 const std::optional<std::string>& transferProtocolType)
396{
Ed Tanouse01d0c32023-06-30 13:21:32 -0700397 if (!transferProtocolType)
Agata Olenderc6f4e012020-03-11 15:19:07 +0100398 {
Ed Tanous22db1722021-06-09 10:53:51 -0700399 return {};
Agata Olenderc6f4e012020-03-11 15:19:07 +0100400 }
401
Ed Tanous22db1722021-06-09 10:53:51 -0700402 if (*transferProtocolType == "CIFS")
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200403 {
Ed Tanous22db1722021-06-09 10:53:51 -0700404 return TransferProtocol::smb;
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200405 }
406
Ed Tanous22db1722021-06-09 10:53:51 -0700407 if (*transferProtocolType == "HTTPS")
408 {
409 return TransferProtocol::https;
410 }
411
412 return TransferProtocol::invalid;
413}
414
415/**
416 * @brief Function extends URI with transfer protocol type.
417 *
418 */
419inline std::string
420 getUriWithTransferProtocol(const std::string& imageUri,
421 const TransferProtocol& transferProtocol)
422{
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());
473 fd = secretPipe->fd();
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),
478 [asyncResp, secretPipe](const boost::system::error_code& ec,
479 std::size_t) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700480 if (ec)
481 {
Ed Tanous62598e32023-07-17 17:06:25 -0700482 BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700483 messages::internalError(asyncResp->res);
484 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500485 });
Ed Tanous22db1722021-06-09 10:53:51 -0700486 }
Adrian Ambrożewicz988fb7b2020-01-13 18:52:46 +0100487
Ed Tanous11e8f602023-08-24 14:25:18 -0700488 dbus::utility::DbusVariantType unixFd(
489 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(
Ed Tanous5e7e2dc2023-02-16 10:37:01 -0800495 [asyncResp, secretPipe](const boost::system::error_code& ec,
Ed Tanous22db1722021-06-09 10:53:51 -0700496 bool success) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700497 if (ec)
498 {
Ed Tanous62598e32023-07-17 17:06:25 -0700499 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous002d39b2022-05-31 08:59:27 -0700500 messages::internalError(asyncResp->res);
Ed Tanous11e8f602023-08-24 14:25:18 -0700501 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700502 }
Ed Tanous11e8f602023-08-24 14:25:18 -0700503 if (!success)
Ed Tanous002d39b2022-05-31 08:59:27 -0700504 {
Ed Tanous62598e32023-07-17 17:06:25 -0700505 BMCWEB_LOG_ERROR("Service responded with error");
Ed Tanous11e8f602023-08-24 14:25:18 -0700506 messages::internalError(asyncResp->res);
Ed Tanous002d39b2022-05-31 08:59:27 -0700507 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500508 },
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) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700666 if (ec)
667 {
Ed Tanous62598e32023-07-17 17:06:25 -0700668 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700669
Ed Tanous002d39b2022-05-31 08:59:27 -0700670 messages::internalError(asyncResp->res);
671 return;
672 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500673 },
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) {
Ed Tanous002d39b2022-05-31 08:59:27 -0700681 if (ec)
682 {
Ed Tanous62598e32023-07-17 17:06:25 -0700683 BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
Ed Tanous22db1722021-06-09 10:53:51 -0700684
Ed Tanous002d39b2022-05-31 08:59:27 -0700685 messages::internalError(asyncResp->res);
686 return;
687 }
Patrick Williams5a39f772023-10-20 11:20:21 -0500688 },
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)
Ed Tanous96825be2022-06-03 09:43:38 -0700714 if (!json_util::readJsonAction(
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200715 req, asyncResp->res, "Image", actionParams.imageUrl,
716 "WriteProtected", actionParams.writeProtected, "UserName",
717 actionParams.userName, "Password", actionParams.password,
718 "Inserted", actionParams.inserted, "TransferMethod",
719 actionParams.transferMethod, "TransferProtocolType",
720 actionParams.transferProtocolType))
Ed Tanous96825be2022-06-03 09:43:38 -0700721 {
722 return;
723 }
724
George Liu2b731192023-01-11 16:27:13 +0800725 dbus::utility::getDbusObject(
726 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200727 [asyncResp, action, actionParams,
George Liu2b731192023-01-11 16:27:13 +0800728 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700729 const dbus::utility::MapperGetObject& getObjectType) mutable {
730 if (ec)
731 {
Ed Tanous62598e32023-07-17 17:06:25 -0700732 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200733 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700734
735 return;
736 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200737
Ed Tanous96825be2022-06-03 09:43:38 -0700738 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700739 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700740
George Liu5eb468d2023-06-20 17:03:24 +0800741 sdbusplus::message::object_path path(
742 "/xyz/openbmc_project/VirtualMedia");
743 dbus::utility::getManagedObjects(
744 service, path,
745 [service, resName, action, actionParams, asyncResp](
746 const boost::system::error_code& ec2,
747 const dbus::utility::ManagedObjectType& subtree) mutable {
Ed Tanous8a592812022-06-04 09:06:59 -0700748 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700749 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200750 // Not possible in proxy mode
Ed Tanous62598e32023-07-17 17:06:25 -0700751 BMCWEB_LOG_DEBUG("InsertMedia not "
752 "allowed in proxy mode");
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200753 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700754
755 return;
756 }
Ed Tanous96825be2022-06-03 09:43:38 -0700757 for (const auto& object : subtree)
758 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800759 VmMode mode = parseObjectPathAndGetMode(object.first, resName);
Boleslaw Ogonczyk Makowski5880f0c2023-04-14 15:32:40 +0200760 if (mode == VmMode::Legacy)
Ed Tanous96825be2022-06-03 09:43:38 -0700761 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200762 validateParams(asyncResp, service, resName, actionParams);
Ed Tanous96825be2022-06-03 09:43:38 -0700763
764 return;
765 }
766 }
Ed Tanous62598e32023-07-17 17:06:25 -0700767 BMCWEB_LOG_DEBUG("Parent item not found");
Ed Tanous96825be2022-06-03 09:43:38 -0700768 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
George Liu2b731192023-01-11 16:27:13 +0800769 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500770 });
Ed Tanous96825be2022-06-03 09:43:38 -0700771}
772
773inline void handleManagersVirtualMediaActionEject(
774 crow::App& app, const crow::Request& req,
775 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
776 const std::string& managerName, const std::string& resName)
777{
778 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
779 {
780 return;
781 }
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200782
783 constexpr std::string_view action = "VirtualMedia.EjectMedia";
Ed Tanous96825be2022-06-03 09:43:38 -0700784 if (managerName != "bmc")
785 {
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200786 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700787
788 return;
789 }
790
George Liu2b731192023-01-11 16:27:13 +0800791 dbus::utility::getDbusObject(
792 "/xyz/openbmc_project/VirtualMedia", {},
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200793 [asyncResp, action,
George Liu2b731192023-01-11 16:27:13 +0800794 resName](const boost::system::error_code& ec2,
Ed Tanous96825be2022-06-03 09:43:38 -0700795 const dbus::utility::MapperGetObject& getObjectType) {
Ed Tanous8a592812022-06-04 09:06:59 -0700796 if (ec2)
Ed Tanous96825be2022-06-03 09:43:38 -0700797 {
Ed Tanous62598e32023-07-17 17:06:25 -0700798 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec2);
Ed Tanous96825be2022-06-03 09:43:38 -0700799 messages::internalError(asyncResp->res);
800
801 return;
802 }
803 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700804 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700805
George Liu5eb468d2023-06-20 17:03:24 +0800806 sdbusplus::message::object_path path(
807 "/xyz/openbmc_project/VirtualMedia");
808 dbus::utility::getManagedObjects(
809 service, path,
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200810 [resName, service, action,
811 asyncResp](const boost::system::error_code& ec,
812 const dbus::utility::ManagedObjectType& subtree) {
Ed Tanous96825be2022-06-03 09:43:38 -0700813 if (ec)
814 {
Ed Tanous62598e32023-07-17 17:06:25 -0700815 BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
Przemyslaw Czarnowski79fdf632022-06-28 18:11:59 +0200816 messages::resourceNotFound(asyncResp->res, action, resName);
Ed Tanous96825be2022-06-03 09:43:38 -0700817 return;
818 }
819
820 for (const auto& object : subtree)
821 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800822 VmMode mode = parseObjectPathAndGetMode(object.first, resName);
823 if (mode != VmMode::Invalid)
Ed Tanous96825be2022-06-03 09:43:38 -0700824 {
Ed Tanous365a73f2023-02-24 12:16:49 -0800825 doEjectAction(asyncResp, service, resName,
826 mode == VmMode::Legacy);
Boleslaw Ogonczyk Makowski5880f0c2023-04-14 15:32:40 +0200827 return;
Ed Tanous96825be2022-06-03 09:43:38 -0700828 }
829 }
Ed Tanous62598e32023-07-17 17:06:25 -0700830 BMCWEB_LOG_DEBUG("Parent item not found");
Ed Tanous96825be2022-06-03 09:43:38 -0700831 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
George Liu2b731192023-01-11 16:27:13 +0800832 });
Patrick Williams5a39f772023-10-20 11:20:21 -0500833 });
Ed Tanous96825be2022-06-03 09:43:38 -0700834}
835
836inline void handleManagersVirtualMediaCollectionGet(
837 crow::App& app, const crow::Request& req,
838 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
839 const std::string& name)
840{
841 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
842 {
843 return;
844 }
845 if (name != "bmc")
846 {
847 messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
848
849 return;
850 }
851
852 asyncResp->res.jsonValue["@odata.type"] =
853 "#VirtualMediaCollection.VirtualMediaCollection";
854 asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
Ed Tanousef4c65b2023-04-24 15:28:50 -0700855 asyncResp->res.jsonValue["@odata.id"] =
856 boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
Ed Tanous96825be2022-06-03 09:43:38 -0700857
George Liu2b731192023-01-11 16:27:13 +0800858 dbus::utility::getDbusObject(
859 "/xyz/openbmc_project/VirtualMedia", {},
860 [asyncResp, name](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700861 const dbus::utility::MapperGetObject& getObjectType) {
862 if (ec)
863 {
Ed Tanous62598e32023-07-17 17:06:25 -0700864 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Ed Tanous96825be2022-06-03 09:43:38 -0700865 messages::internalError(asyncResp->res);
866
867 return;
868 }
869 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700870 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700871
872 getVmResourceList(asyncResp, service, name);
Patrick Williams5a39f772023-10-20 11:20:21 -0500873 });
Ed Tanous96825be2022-06-03 09:43:38 -0700874}
875
876inline void
877 handleVirtualMediaGet(crow::App& app, const crow::Request& req,
878 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
879 const std::string& name, const std::string& resName)
880{
881 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
882 {
883 return;
884 }
885 if (name != "bmc")
886 {
887 messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
888
889 return;
890 }
891
George Liu2b731192023-01-11 16:27:13 +0800892 dbus::utility::getDbusObject(
893 "/xyz/openbmc_project/VirtualMedia", {},
Ed Tanous96825be2022-06-03 09:43:38 -0700894 [asyncResp, name,
George Liu2b731192023-01-11 16:27:13 +0800895 resName](const boost::system::error_code& ec,
Ed Tanous96825be2022-06-03 09:43:38 -0700896 const dbus::utility::MapperGetObject& getObjectType) {
897 if (ec)
898 {
Ed Tanous62598e32023-07-17 17:06:25 -0700899 BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
Ed Tanous96825be2022-06-03 09:43:38 -0700900 messages::internalError(asyncResp->res);
901
902 return;
903 }
904 std::string service = getObjectType.begin()->first;
Ed Tanous62598e32023-07-17 17:06:25 -0700905 BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
Ed Tanous96825be2022-06-03 09:43:38 -0700906
907 getVmData(asyncResp, service, name, resName);
Patrick Williams5a39f772023-10-20 11:20:21 -0500908 });
Ed Tanous96825be2022-06-03 09:43:38 -0700909}
910
Ed Tanous22db1722021-06-09 10:53:51 -0700911inline void requestNBDVirtualMediaRoutes(App& app)
912{
George Liu0fda0f12021-11-16 10:06:17 +0800913 BMCWEB_ROUTE(
914 app,
915 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700916 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700917 .methods(boost::beast::http::verb::post)(std::bind_front(
918 handleManagersVirtualMediaActionInsertPost, std::ref(app)));
Przemyslaw Czarnowskie13c2762019-09-02 17:32:43 +0200919
George Liu0fda0f12021-11-16 10:06:17 +0800920 BMCWEB_ROUTE(
921 app,
922 "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
Ed Tanoused398212021-06-09 17:05:54 -0700923 .privileges(redfish::privileges::postVirtualMedia)
Ed Tanous96825be2022-06-03 09:43:38 -0700924 .methods(boost::beast::http::verb::post)(std::bind_front(
925 handleManagersVirtualMediaActionEject, std::ref(app)));
Ed Tanous002d39b2022-05-31 08:59:27 -0700926
Ed Tanous22db1722021-06-09 10:53:51 -0700927 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
Ed Tanoused398212021-06-09 17:05:54 -0700928 .privileges(redfish::privileges::getVirtualMediaCollection)
Ed Tanous96825be2022-06-03 09:43:38 -0700929 .methods(boost::beast::http::verb::get)(std::bind_front(
930 handleManagersVirtualMediaCollectionGet, std::ref(app)));
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200931
Ed Tanous22db1722021-06-09 10:53:51 -0700932 BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700933 .privileges(redfish::privileges::getVirtualMedia)
Ed Tanous22db1722021-06-09 10:53:51 -0700934 .methods(boost::beast::http::verb::get)(
Ed Tanous96825be2022-06-03 09:43:38 -0700935 std::bind_front(handleVirtualMediaGet, std::ref(app)));
Ed Tanous22db1722021-06-09 10:53:51 -0700936}
Przemyslaw Czarnowski107077d2019-07-11 10:16:43 +0200937
938} // namespace redfish