blob: cd0d9726e99adbd4988b58837735aae600f450f3 [file] [log] [blame]
/*
Copyright (c) 2018 Intel Corporation
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
#pragma once
#include "account_service.hpp"
#include "app.hpp"
#include "async_resp.hpp"
#include "credential_pipe.hpp"
#include "dbus_utility.hpp"
#include "generated/enums/virtual_media.hpp"
#include "query.hpp"
#include "registries/privilege_registry.hpp"
#include "utils/json_utils.hpp"
#include <boost/url/format.hpp>
#include <boost/url/url_view.hpp>
#include <boost/url/url_view_base.hpp>
#include <array>
#include <ranges>
#include <string_view>
namespace redfish
{
enum class VmMode
{
Invalid,
Legacy,
Proxy
};
inline VmMode parseObjectPathAndGetMode(
const sdbusplus::message::object_path& itemPath, const std::string& resName)
{
std::string thisPath = itemPath.filename();
BMCWEB_LOG_DEBUG("Filename: {}, ThisPath: {}", itemPath.str, thisPath);
if (thisPath.empty())
{
return VmMode::Invalid;
}
if (thisPath != resName)
{
return VmMode::Invalid;
}
auto mode = itemPath.parent_path();
auto type = mode.parent_path();
if (mode.filename().empty() || type.filename().empty())
{
return VmMode::Invalid;
}
if (type.filename() != "VirtualMedia")
{
return VmMode::Invalid;
}
std::string modeStr = mode.filename();
if (modeStr == "Legacy")
{
return VmMode::Legacy;
}
if (modeStr == "Proxy")
{
return VmMode::Proxy;
}
return VmMode::Invalid;
}
using CheckItemHandler =
std::function<void(const std::string& service, const std::string& resName,
const std::shared_ptr<bmcweb::AsyncResp>&,
const std::pair<sdbusplus::message::object_path,
dbus::utility::DBusInterfacesMap>&)>;
inline void
findAndParseObject(const std::string& service, const std::string& resName,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
CheckItemHandler&& handler)
{
sdbusplus::message::object_path path("/xyz/openbmc_project/VirtualMedia");
dbus::utility::getManagedObjects(
service, path,
[service, resName, asyncResp, handler = std::move(handler)](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& subtree) {
if (ec)
{
BMCWEB_LOG_DEBUG("DBUS response error");
return;
}
for (const auto& item : subtree)
{
VmMode mode = parseObjectPathAndGetMode(item.first, resName);
if (mode != VmMode::Invalid)
{
handler(service, resName, asyncResp, item);
return;
}
}
BMCWEB_LOG_DEBUG("Parent item not found");
asyncResp->res.result(boost::beast::http::status::not_found);
});
}
/**
* @brief Function extracts transfer protocol name from URI.
*/
inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
{
boost::system::result<boost::urls::url_view> url =
boost::urls::parse_uri(imageUri);
if (!url)
{
return "None";
}
std::string_view scheme = url->scheme();
if (scheme == "smb")
{
return "CIFS";
}
if (scheme == "https")
{
return "HTTPS";
}
return "None";
}
/**
* @brief Read all known properties from VM object interfaces
*/
inline void
vmParseInterfaceObject(const dbus::utility::DBusInterfacesMap& interfaces,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
{
for (const auto& [interface, values] : interfaces)
{
if (interface == "xyz.openbmc_project.VirtualMedia.MountPoint")
{
for (const auto& [property, value] : values)
{
if (property == "EndpointId")
{
const std::string* endpointIdValue =
std::get_if<std::string>(&value);
if (endpointIdValue == nullptr)
{
continue;
}
if (!endpointIdValue->empty())
{
// Proxy mode
asyncResp->res
.jsonValue["Oem"]["OpenBMC"]["WebSocketEndpoint"] =
*endpointIdValue;
asyncResp->res.jsonValue["TransferProtocolType"] =
"OEM";
}
}
if (property == "ImageURL")
{
const std::string* imageUrlValue =
std::get_if<std::string>(&value);
if (imageUrlValue != nullptr && !imageUrlValue->empty())
{
std::filesystem::path filePath = *imageUrlValue;
if (!filePath.has_filename())
{
// this will handle https share, which not
// necessarily has to have filename given.
asyncResp->res.jsonValue["ImageName"] = "";
}
else
{
asyncResp->res.jsonValue["ImageName"] =
filePath.filename();
}
asyncResp->res.jsonValue["Image"] = *imageUrlValue;
asyncResp->res.jsonValue["TransferProtocolType"] =
getTransferProtocolTypeFromUri(*imageUrlValue);
asyncResp->res.jsonValue["ConnectedVia"] =
virtual_media::ConnectedVia::URI;
}
}
if (property == "WriteProtected")
{
const bool* writeProtectedValue = std::get_if<bool>(&value);
if (writeProtectedValue != nullptr)
{
asyncResp->res.jsonValue["WriteProtected"] =
*writeProtectedValue;
}
}
}
}
if (interface == "xyz.openbmc_project.VirtualMedia.Process")
{
for (const auto& [property, value] : values)
{
if (property == "Active")
{
const bool* activeValue = std::get_if<bool>(&value);
if (activeValue == nullptr)
{
BMCWEB_LOG_DEBUG("Value Active not found");
return;
}
asyncResp->res.jsonValue["Inserted"] = *activeValue;
if (*activeValue)
{
asyncResp->res.jsonValue["ConnectedVia"] =
virtual_media::ConnectedVia::Applet;
}
}
}
}
}
}
/**
* @brief Fill template for Virtual Media Item.
*/
inline nlohmann::json vmItemTemplate(const std::string& name,
const std::string& resName)
{
nlohmann::json item;
item["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/VirtualMedia/{}", name, resName);
item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
item["Name"] = "Virtual Removable Media";
item["Id"] = resName;
item["WriteProtected"] = true;
item["ConnectedVia"] = virtual_media::ConnectedVia::NotConnected;
item["MediaTypes"] = nlohmann::json::array_t({"CD", "USBStick"});
item["TransferMethod"] = virtual_media::TransferMethod::Stream;
item["Oem"]["OpenBMC"]["@odata.type"] =
"#OpenBMCVirtualMedia.v1_0_0.VirtualMedia";
item["Oem"]["OpenBMC"]["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/VirtualMedia/{}#/Oem/OpenBMC", name, resName);
return item;
}
/**
* @brief Fills collection data
*/
inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> asyncResp,
const std::string& service,
const std::string& name)
{
BMCWEB_LOG_DEBUG("Get available Virtual Media resources.");
sdbusplus::message::object_path objPath(
"/xyz/openbmc_project/VirtualMedia");
dbus::utility::getManagedObjects(
service, objPath,
[name, asyncResp{std::move(asyncResp)}](
const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& subtree) {
if (ec)
{
BMCWEB_LOG_DEBUG("DBUS response error");
return;
}
nlohmann::json& members = asyncResp->res.jsonValue["Members"];
members = nlohmann::json::array();
for (const auto& object : subtree)
{
nlohmann::json item;
std::string path = object.first.filename();
if (path.empty())
{
continue;
}
item["@odata.id"] = boost::urls::format(
"/redfish/v1/Managers/{}/VirtualMedia/{}", name, path);
members.emplace_back(std::move(item));
}
asyncResp->res.jsonValue["Members@odata.count"] = members.size();
});
}
inline void
afterGetVmData(const std::string& name, const std::string& /*service*/,
const std::string& resName,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::pair<sdbusplus::message::object_path,
dbus::utility::DBusInterfacesMap>& item)
{
VmMode mode = parseObjectPathAndGetMode(item.first, resName);
if (mode == VmMode::Invalid)
{
return;
}
asyncResp->res.jsonValue = vmItemTemplate(name, resName);
// Check if dbus path is Legacy type
if (mode == VmMode::Legacy)
{
asyncResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
["target"] = boost::urls::format(
"/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.InsertMedia",
name, resName);
}
vmParseInterfaceObject(item.second, asyncResp);
asyncResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
["target"] = boost::urls::format(
"/redfish/v1/Managers/{}/VirtualMedia/{}/Actions/VirtualMedia.EjectMedia",
name, resName);
}
/**
* @brief Fills data for specific resource
*/
inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& service, const std::string& name,
const std::string& resName)
{
BMCWEB_LOG_DEBUG("Get Virtual Media resource data.");
findAndParseObject(service, resName, asyncResp,
std::bind_front(afterGetVmData, name));
}
/**
* @brief Transfer protocols supported for InsertMedia action.
*
*/
enum class TransferProtocol
{
https,
smb,
invalid
};
/**
* @brief Function extracts transfer protocol type from URI.
*
*/
inline std::optional<TransferProtocol>
getTransferProtocolFromUri(const boost::urls::url_view_base& imageUri)
{
std::string_view scheme = imageUri.scheme();
if (scheme == "smb")
{
return TransferProtocol::smb;
}
if (scheme == "https")
{
return TransferProtocol::https;
}
if (!scheme.empty())
{
return TransferProtocol::invalid;
}
return {};
}
/**
* @brief Function convert transfer protocol from string param.
*
*/
inline std::optional<TransferProtocol> getTransferProtocolFromParam(
const std::optional<std::string>& transferProtocolType)
{
if (!transferProtocolType)
{
return {};
}
if (*transferProtocolType == "CIFS")
{
return TransferProtocol::smb;
}
if (*transferProtocolType == "HTTPS")
{
return TransferProtocol::https;
}
return TransferProtocol::invalid;
}
/**
* @brief Function extends URI with transfer protocol type.
*
*/
inline std::string getUriWithTransferProtocol(
const std::string& imageUri, const TransferProtocol& transferProtocol)
{
if (transferProtocol == TransferProtocol::smb)
{
return "smb://" + imageUri;
}
if (transferProtocol == TransferProtocol::https)
{
return "https://" + imageUri;
}
return imageUri;
}
struct InsertMediaActionParams
{
std::optional<std::string> imageUrl;
std::optional<std::string> userName;
std::optional<std::string> password;
std::optional<std::string> transferMethod;
std::optional<std::string> transferProtocolType;
std::optional<bool> writeProtected = true;
std::optional<bool> inserted;
};
/**
* @brief Function transceives data with dbus directly.
*
* All BMC state properties will be retrieved before sending reset request.
*/
inline void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& service, const std::string& name,
const std::string& imageUrl, bool rw,
std::string&& userName, std::string&& password)
{
int fd = -1;
std::shared_ptr<CredentialsPipe> secretPipe;
if (!userName.empty() || !password.empty())
{
// Payload must contain data + NULL delimiters
constexpr const size_t secretLimit = 1024;
if (userName.size() + password.size() + 2 > secretLimit)
{
BMCWEB_LOG_ERROR("Credentials too long to handle");
messages::unrecognizedRequestBody(asyncResp->res);
return;
}
// Open pipe
secretPipe = std::make_shared<CredentialsPipe>(
crow::connections::systemBus->get_io_context());
fd = secretPipe->releaseFd();
// Pass secret over pipe
secretPipe->asyncWrite(
std::move(userName), std::move(password),
[asyncResp,
secretPipe](const boost::system::error_code& ec, std::size_t) {
if (ec)
{
BMCWEB_LOG_ERROR("Failed to pass secret: {}", ec);
messages::internalError(asyncResp->res);
}
});
}
dbus::utility::DbusVariantType unixFd(
std::in_place_type<sdbusplus::message::unix_fd>, fd);
sdbusplus::message::object_path path(
"/xyz/openbmc_project/VirtualMedia/Legacy");
path /= name;
crow::connections::systemBus->async_method_call(
[asyncResp,
secretPipe](const boost::system::error_code& ec, bool success) {
if (ec)
{
BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
messages::internalError(asyncResp->res);
return;
}
if (!success)
{
BMCWEB_LOG_ERROR("Service responded with error");
messages::internalError(asyncResp->res);
}
},
service, path.str, "xyz.openbmc_project.VirtualMedia.Legacy", "Mount",
imageUrl, rw, unixFd);
}
/**
* @brief Function validate parameters of insert media request.
*
*/
inline void validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& service,
const std::string& resName,
InsertMediaActionParams& actionParams)
{
BMCWEB_LOG_DEBUG("Validation started");
// required param imageUrl must not be empty
if (!actionParams.imageUrl)
{
BMCWEB_LOG_ERROR("Request action parameter Image is empty.");
messages::propertyValueFormatError(asyncResp->res, "<empty>", "Image");
return;
}
// optional param inserted must be true
if (actionParams.inserted && !*actionParams.inserted)
{
BMCWEB_LOG_ERROR(
"Request action optional parameter Inserted must be true.");
messages::actionParameterNotSupported(asyncResp->res, "Inserted",
"InsertMedia");
return;
}
// optional param transferMethod must be stream
if (actionParams.transferMethod &&
(*actionParams.transferMethod != "Stream"))
{
BMCWEB_LOG_ERROR("Request action optional parameter "
"TransferMethod must be Stream.");
messages::actionParameterNotSupported(asyncResp->res, "TransferMethod",
"InsertMedia");
return;
}
boost::system::result<boost::urls::url_view> url =
boost::urls::parse_uri(*actionParams.imageUrl);
if (!url)
{
messages::actionParameterValueFormatError(
asyncResp->res, *actionParams.imageUrl, "Image", "InsertMedia");
return;
}
std::optional<TransferProtocol> uriTransferProtocolType =
getTransferProtocolFromUri(*url);
std::optional<TransferProtocol> paramTransferProtocolType =
getTransferProtocolFromParam(actionParams.transferProtocolType);
// ImageUrl does not contain valid protocol type
if (uriTransferProtocolType &&
*uriTransferProtocolType == TransferProtocol::invalid)
{
BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
"contain specified protocol type from list: "
"(smb, https).");
messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
return;
}
// transferProtocolType should contain value from list
if (paramTransferProtocolType &&
*paramTransferProtocolType == TransferProtocol::invalid)
{
BMCWEB_LOG_ERROR("Request action parameter TransferProtocolType "
"must be provided with value from list: "
"(CIFS, HTTPS).");
messages::propertyValueNotInList(
asyncResp->res, actionParams.transferProtocolType.value_or(""),
"TransferProtocolType");
return;
}
// valid transfer protocol not provided either with URI nor param
if (!uriTransferProtocolType && !paramTransferProtocolType)
{
BMCWEB_LOG_ERROR("Request action parameter ImageUrl must "
"contain specified protocol type or param "
"TransferProtocolType must be provided.");
messages::resourceAtUriInUnknownFormat(asyncResp->res, *url);
return;
}
// valid transfer protocol provided both with URI and param
if (paramTransferProtocolType && uriTransferProtocolType)
{
// check if protocol is the same for URI and param
if (*paramTransferProtocolType != *uriTransferProtocolType)
{
BMCWEB_LOG_ERROR("Request action parameter "
"TransferProtocolType must contain the "
"same protocol type as protocol type "
"provided with param imageUrl.");
messages::actionParameterValueTypeError(
asyncResp->res, actionParams.transferProtocolType.value_or(""),
"TransferProtocolType", "InsertMedia");
return;
}
}
// validation passed, add protocol to URI if needed
if (!uriTransferProtocolType && paramTransferProtocolType)
{
actionParams.imageUrl = getUriWithTransferProtocol(
*actionParams.imageUrl, *paramTransferProtocolType);
}
if (!actionParams.userName)
{
actionParams.userName = "";
}
if (!actionParams.password)
{
actionParams.password = "";
}
doMountVmLegacy(asyncResp, service, resName, *actionParams.imageUrl,
!(actionParams.writeProtected.value_or(false)),
std::move(*actionParams.userName),
std::move(*actionParams.password));
}
/**
* @brief Function transceives data with dbus directly.
*
* All BMC state properties will be retrieved before sending reset request.
*/
inline void doEjectAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& service, const std::string& name,
bool legacy)
{
// Legacy mount requires parameter with image
if (legacy)
{
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
if (ec)
{
BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
messages::internalError(asyncResp->res);
return;
}
},
service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
"xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
}
else // proxy
{
crow::connections::systemBus->async_method_call(
[asyncResp](const boost::system::error_code& ec) {
if (ec)
{
BMCWEB_LOG_ERROR("Bad D-Bus request error: {}", ec);
messages::internalError(asyncResp->res);
return;
}
},
service, "/xyz/openbmc_project/VirtualMedia/Proxy/" + name,
"xyz.openbmc_project.VirtualMedia.Proxy", "Unmount");
}
}
inline void handleManagersVirtualMediaActionInsertPost(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& name, const std::string& resName)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
constexpr std::string_view action = "VirtualMedia.InsertMedia";
if (name != "bmc")
{
messages::resourceNotFound(asyncResp->res, action, resName);
return;
}
InsertMediaActionParams actionParams;
// Read obligatory parameters (url of image)
if (!json_util::readJsonAction( //
req, asyncResp->res, //
"Image", actionParams.imageUrl, //
"Inserted", actionParams.inserted, //
"Password", actionParams.password, //
"TransferMethod", actionParams.transferMethod, //
"TransferProtocolType", actionParams.transferProtocolType, //
"UserName", actionParams.userName, //
"WriteProtected", actionParams.writeProtected //
))
{
return;
}
dbus::utility::getDbusObject(
"/xyz/openbmc_project/VirtualMedia", {},
[asyncResp, action, actionParams,
resName](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& getObjectType) mutable {
if (ec)
{
BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
messages::resourceNotFound(asyncResp->res, action, resName);
return;
}
std::string service = getObjectType.begin()->first;
BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
sdbusplus::message::object_path path(
"/xyz/openbmc_project/VirtualMedia");
dbus::utility::getManagedObjects(
service, path,
[service, resName, action, actionParams, asyncResp](
const boost::system::error_code& ec2,
const dbus::utility::ManagedObjectType& subtree) mutable {
if (ec2)
{
// Not possible in proxy mode
BMCWEB_LOG_DEBUG("InsertMedia not "
"allowed in proxy mode");
messages::resourceNotFound(asyncResp->res, action,
resName);
return;
}
for (const auto& object : subtree)
{
VmMode mode =
parseObjectPathAndGetMode(object.first, resName);
if (mode == VmMode::Legacy)
{
validateParams(asyncResp, service, resName,
actionParams);
return;
}
}
BMCWEB_LOG_DEBUG("Parent item not found");
messages::resourceNotFound(asyncResp->res, "VirtualMedia",
resName);
});
});
}
inline void handleManagersVirtualMediaActionEject(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& managerName, const std::string& resName)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
constexpr std::string_view action = "VirtualMedia.EjectMedia";
if (managerName != "bmc")
{
messages::resourceNotFound(asyncResp->res, action, resName);
return;
}
dbus::utility::getDbusObject(
"/xyz/openbmc_project/VirtualMedia", {},
[asyncResp, action,
resName](const boost::system::error_code& ec2,
const dbus::utility::MapperGetObject& getObjectType) {
if (ec2)
{
BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}",
ec2);
messages::internalError(asyncResp->res);
return;
}
std::string service = getObjectType.begin()->first;
BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
sdbusplus::message::object_path path(
"/xyz/openbmc_project/VirtualMedia");
dbus::utility::getManagedObjects(
service, path,
[resName, service, action,
asyncResp](const boost::system::error_code& ec,
const dbus::utility::ManagedObjectType& subtree) {
if (ec)
{
BMCWEB_LOG_ERROR("ObjectMapper : No Service found");
messages::resourceNotFound(asyncResp->res, action,
resName);
return;
}
for (const auto& object : subtree)
{
VmMode mode =
parseObjectPathAndGetMode(object.first, resName);
if (mode != VmMode::Invalid)
{
doEjectAction(asyncResp, service, resName,
mode == VmMode::Legacy);
return;
}
}
BMCWEB_LOG_DEBUG("Parent item not found");
messages::resourceNotFound(asyncResp->res, "VirtualMedia",
resName);
});
});
}
inline void handleManagersVirtualMediaCollectionGet(
crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& name)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
if (name != "bmc")
{
messages::resourceNotFound(asyncResp->res, "VirtualMedia", name);
return;
}
asyncResp->res.jsonValue["@odata.type"] =
"#VirtualMediaCollection.VirtualMediaCollection";
asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
asyncResp->res.jsonValue["@odata.id"] =
boost::urls::format("/redfish/v1/Managers/{}/VirtualMedia", name);
dbus::utility::getDbusObject(
"/xyz/openbmc_project/VirtualMedia", {},
[asyncResp, name](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& getObjectType) {
if (ec)
{
BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
messages::internalError(asyncResp->res);
return;
}
std::string service = getObjectType.begin()->first;
BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
getVmResourceList(asyncResp, service, name);
});
}
inline void
handleVirtualMediaGet(crow::App& app, const crow::Request& req,
const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
const std::string& name, const std::string& resName)
{
if (!redfish::setUpRedfishRoute(app, req, asyncResp))
{
return;
}
if (name != "bmc")
{
messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
return;
}
dbus::utility::getDbusObject(
"/xyz/openbmc_project/VirtualMedia", {},
[asyncResp, name,
resName](const boost::system::error_code& ec,
const dbus::utility::MapperGetObject& getObjectType) {
if (ec)
{
BMCWEB_LOG_ERROR("ObjectMapper::GetObject call failed: {}", ec);
messages::internalError(asyncResp->res);
return;
}
std::string service = getObjectType.begin()->first;
BMCWEB_LOG_DEBUG("GetObjectType: {}", service);
getVmData(asyncResp, service, name, resName);
});
}
inline void requestNBDVirtualMediaRoutes(App& app)
{
BMCWEB_ROUTE(
app,
"/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.InsertMedia")
.privileges(redfish::privileges::postVirtualMedia)
.methods(boost::beast::http::verb::post)(std::bind_front(
handleManagersVirtualMediaActionInsertPost, std::ref(app)));
BMCWEB_ROUTE(
app,
"/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/VirtualMedia.EjectMedia")
.privileges(redfish::privileges::postVirtualMedia)
.methods(boost::beast::http::verb::post)(std::bind_front(
handleManagersVirtualMediaActionEject, std::ref(app)));
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
.privileges(redfish::privileges::getVirtualMediaCollection)
.methods(boost::beast::http::verb::get)(std::bind_front(
handleManagersVirtualMediaCollectionGet, std::ref(app)));
BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
.privileges(redfish::privileges::getVirtualMedia)
.methods(boost::beast::http::verb::get)(
std::bind_front(handleVirtualMediaGet, std::ref(app)));
}
} // namespace redfish