Remove Node class from NBD proxy
This was broken as part of the recent Node removal. Although this code
is currently dead, it would be good if at least was able to be built, so
if someone was inclined to upstream the backend for it, they could
without too much trouble.
Because of this move in code, clang-tidy can now see this code and found
a number of failures, so this is combined with a couple of relatively
trivial clang-tidy changes that are low impact and mechanical in nature.
Tested:
Commented in the option in meson_options.txt, and built. Code builds.
Signed-off-by: Ed Tanous <edtanous@google.com>
Change-Id: I5ff52b773fc4fc9d44a916c4e6bf6e60295c3aaa
diff --git a/redfish-core/include/redfish.hpp b/redfish-core/include/redfish.hpp
index 47d4848..e4d732c 100644
--- a/redfish-core/include/redfish.hpp
+++ b/redfish-core/include/redfish.hpp
@@ -21,6 +21,7 @@
#include "../lib/chassis.hpp"
#include "../lib/ethernet.hpp"
#include "../lib/event_service.hpp"
+#include "../lib/hypervisor_system.hpp"
#include "../lib/log_services.hpp"
#include "../lib/managers.hpp"
#include "../lib/memory.hpp"
@@ -41,10 +42,7 @@
#include "../lib/telemetry_service.hpp"
#include "../lib/thermal.hpp"
#include "../lib/update_service.hpp"
-#ifdef BMCWEB_ENABLE_VM_NBDPROXY
#include "../lib/virtual_media.hpp"
-#endif // BMCWEB_ENABLE_VM_NBDPROXY
-#include "../lib/hypervisor_system.hpp"
namespace redfish
{
@@ -148,13 +146,11 @@
requestRoutesSystemResetActionInfo(app);
requestRoutesBiosService(app);
requestRoutesBiosReset(app);
+
#ifdef BMCWEB_ENABLE_VM_NBDPROXY
- nodes.emplace_back(std::make_unique<VirtualMedia>(app));
- nodes.emplace_back(std::make_unique<VirtualMediaCollection>(app));
- nodes.emplace_back(
- std::make_unique<VirtualMediaActionInsertMedia>(app));
- nodes.emplace_back(std::make_unique<VirtualMediaActionEjectMedia>(app));
+ requestNBDVirtualMediaRoutes(app);
#endif // BMCWEB_ENABLE_VM_NBDPROXY
+
#ifdef BMCWEB_ENABLE_REDFISH_DBUS_LOG_ENTRIES
requestRoutesDBusLogServiceActionsClear(app);
requestRoutesDBusEventLogEntryCollection(app);
diff --git a/redfish-core/lib/virtual_media.hpp b/redfish-core/lib/virtual_media.hpp
index cdb6a51..e0b6726 100644
--- a/redfish-core/lib/virtual_media.hpp
+++ b/redfish-core/lib/virtual_media.hpp
@@ -25,12 +25,11 @@
#include <boost/url/url_view.hpp>
namespace redfish
-
{
/**
* @brief Function extracts transfer protocol name from URI.
*/
-static std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
+inline std::string getTransferProtocolTypeFromUri(const std::string& imageUri)
{
try
{
@@ -39,7 +38,7 @@
{
return "CIFS";
}
- else if (scheme == "https")
+ if (scheme == "https")
{
return "HTTPS";
}
@@ -54,7 +53,7 @@
/**
* @brief Read all known properties from VM object interfaces
*/
-static void
+inline void
vmParseInterfaceObject(const DbusInterfaceType& interface,
const std::shared_ptr<bmcweb::AsyncResp>& aResp)
{
@@ -164,12 +163,17 @@
/**
* @brief Fill template for Virtual Media Item.
*/
-static nlohmann::json vmItemTemplate(const std::string& name,
+inline nlohmann::json vmItemTemplate(const std::string& name,
const std::string& resName)
{
nlohmann::json item;
- item["@odata.id"] =
- "/redfish/v1/Managers/" + name + "/VirtualMedia/" + resName;
+
+ std::string id = "/redfish/v1/Managers/";
+ id += name;
+ id += "/VirtualMedia/";
+ id += resName;
+ item["@odata.id"] = std::move(id);
+
item["@odata.type"] = "#VirtualMedia.v1_3_0.VirtualMedia";
item["Name"] = "Virtual Removable Media";
item["Id"] = resName;
@@ -185,7 +189,7 @@
/**
* @brief Fills collection data
*/
-static void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> aResp,
+inline void getVmResourceList(std::shared_ptr<bmcweb::AsyncResp> aResp,
const std::string& service,
const std::string& name)
{
@@ -210,9 +214,12 @@
continue;
}
- item["@odata.id"] =
- "/redfish/v1/Managers/" + name + "/VirtualMedia/" + path;
+ std::string id = "/redfish/v1/Managers/";
+ id += name;
+ id += "/VirtualMedia/";
+ id += path;
+ item["@odata.id"] = std::move(id);
members.emplace_back(std::move(item));
}
aResp->res.jsonValue["Members@odata.count"] = members.size();
@@ -224,7 +231,7 @@
/**
* @brief Fills data for specific resource
*/
-static void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
+inline void getVmData(const std::shared_ptr<bmcweb::AsyncResp>& aResp,
const std::string& service, const std::string& name,
const std::string& resName)
{
@@ -268,22 +275,25 @@
}
aResp->res.jsonValue = vmItemTemplate(name, resName);
+ std::string actionsId = "/redfish/v1/Managers/";
+ actionsId += name;
+ actionsId += "/VirtualMedia/";
+ actionsId += resName;
+ actionsId += "/Actions";
// Check if dbus path is Legacy type
if (mode.filename() == "Legacy")
{
aResp->res.jsonValue["Actions"]["#VirtualMedia.InsertMedia"]
["target"] =
- "/redfish/v1/Managers/" + name + "/VirtualMedia/" +
- resName + "/Actions/VirtualMedia.InsertMedia";
+ actionsId + "/VirtualMedia.InsertMedia";
}
vmParseInterfaceObject(item.second, aResp);
aResp->res.jsonValue["Actions"]["#VirtualMedia.EjectMedia"]
["target"] =
- "/redfish/v1/Managers/" + name + "/VirtualMedia/" +
- resName + "/Actions/VirtualMedia.EjectMedia";
+ actionsId + "/VirtualMedia.EjectMedia";
return;
}
@@ -296,899 +306,791 @@
}
/**
- @brief InsertMedia action class
+ * @brief Transfer protocols supported for InsertMedia action.
+ *
*/
-class VirtualMediaActionInsertMedia : public Node
+enum class TransferProtocol
{
- public:
- VirtualMediaActionInsertMedia(App& app) :
- Node(app,
- "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
- "VirtualMedia.InsertMedia",
- std::string(), std::string())
+ https,
+ smb,
+ invalid
+};
+
+/**
+ * @brief Function extracts transfer protocol type from URI.
+ *
+ */
+inline std::optional<TransferProtocol>
+ getTransferProtocolFromUri(const std::string& imageUri)
+{
+ try
{
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
- {boost::beast::http::verb::put, {{"ConfigureManager"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
- {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
- }
-
- private:
- /**
- * @brief Transfer protocols supported for InsertMedia action.
- *
- */
- enum class TransferProtocol
- {
- https,
- smb,
- invalid
- };
-
- /**
- * @brief Function extracts transfer protocol type from URI.
- *
- */
- std::optional<TransferProtocol>
- getTransferProtocolFromUri(const std::string& imageUri)
- {
- try
- {
- std::string_view scheme = boost::urls::url_view(imageUri).scheme();
- if (scheme == "smb")
- {
- return TransferProtocol::smb;
- }
- if (scheme == "https")
- {
- return TransferProtocol::https;
- }
- else if (!scheme.empty())
- {
- return TransferProtocol::invalid;
- }
- }
- catch (std::exception& p)
- {
- BMCWEB_LOG_ERROR << p.what();
- }
-
- return {};
- }
-
- /**
- * @brief Function convert transfer protocol from string param.
- *
- */
- std::optional<TransferProtocol> getTransferProtocolFromParam(
- const std::optional<std::string>& transferProtocolType)
- {
- if (transferProtocolType == std::nullopt)
- {
- return {};
- }
-
- if (*transferProtocolType == "CIFS")
+ std::string_view scheme = boost::urls::url_view(imageUri).scheme();
+ if (scheme == "smb")
{
return TransferProtocol::smb;
}
-
- if (*transferProtocolType == "HTTPS")
+ if (scheme == "https")
{
return TransferProtocol::https;
}
-
- return TransferProtocol::invalid;
+ if (!scheme.empty())
+ {
+ return TransferProtocol::invalid;
+ }
}
-
- /**
- * @brief Function extends URI with transfer protocol type.
- *
- */
- std::string
- getUriWithTransferProtocol(const std::string& imageUri,
- const TransferProtocol& transferProtocol)
+ catch (std::exception& p)
{
- if (transferProtocol == TransferProtocol::smb)
- {
- return "smb://" + imageUri;
- }
-
- if (transferProtocol == TransferProtocol::https)
- {
- return "https://" + imageUri;
- }
-
- return imageUri;
+ BMCWEB_LOG_ERROR << p.what();
}
- /**
- * @brief Function validate parameters of insert media request.
- *
- */
- bool validateParams(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- std::string& imageUrl,
- const std::optional<bool>& inserted,
- const std::optional<std::string>& transferMethod,
- const std::optional<std::string>& transferProtocolType)
+ return {};
+}
+
+/**
+ * @brief Function convert transfer protocol from string param.
+ *
+ */
+inline std::optional<TransferProtocol> getTransferProtocolFromParam(
+ const std::optional<std::string>& transferProtocolType)
+{
+ if (transferProtocolType == std::nullopt)
{
- BMCWEB_LOG_DEBUG << "Validation started";
- // required param imageUrl must not be empty
- if (imageUrl.empty())
- {
- BMCWEB_LOG_ERROR << "Request action parameter Image is empty.";
-
- messages::propertyValueFormatError(asyncResp->res, "<empty>",
- "Image");
-
- return false;
- }
-
- // optional param inserted must be true
- if ((inserted != std::nullopt) && (*inserted != true))
- {
- BMCWEB_LOG_ERROR
- << "Request action optional parameter Inserted must be true.";
-
- messages::actionParameterNotSupported(asyncResp->res, "Inserted",
- "InsertMedia");
-
- return false;
- }
-
- // optional param transferMethod must be stream
- if ((transferMethod != std::nullopt) && (*transferMethod != "Stream"))
- {
- BMCWEB_LOG_ERROR << "Request action optional parameter "
- "TransferMethod must be Stream.";
-
- messages::actionParameterNotSupported(
- asyncResp->res, "TransferMethod", "InsertMedia");
-
- return false;
- }
-
- std::optional<TransferProtocol> uriTransferProtocolType =
- getTransferProtocolFromUri(imageUrl);
-
- std::optional<TransferProtocol> paramTransferProtocolType =
- getTransferProtocolFromParam(transferProtocolType);
-
- // ImageUrl does not contain valid protocol type
- if (*uriTransferProtocolType == TransferProtocol::invalid)
- {
- BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must "
- "contain specified protocol type from list: "
- "(smb, https).";
-
- messages::resourceAtUriInUnknownFormat(asyncResp->res, imageUrl);
-
- return false;
- }
-
- // transferProtocolType should contain value from list
- if (*paramTransferProtocolType == TransferProtocol::invalid)
- {
- BMCWEB_LOG_ERROR << "Request action parameter TransferProtocolType "
- "must be provided with value from list: "
- "(CIFS, HTTPS).";
-
- messages::propertyValueNotInList(
- asyncResp->res, *transferProtocolType, "TransferProtocolType");
- return false;
- }
-
- // valid transfer protocol not provided either with URI nor param
- if ((uriTransferProtocolType == std::nullopt) &&
- (paramTransferProtocolType == std::nullopt))
- {
- BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must "
- "contain specified protocol type or param "
- "TransferProtocolType must be provided.";
-
- messages::resourceAtUriInUnknownFormat(asyncResp->res, imageUrl);
-
- return false;
- }
-
- // valid transfer protocol provided both with URI and param
- if ((paramTransferProtocolType != std::nullopt) &&
- (uriTransferProtocolType != std::nullopt))
- {
- // 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, *transferProtocolType,
- "TransferProtocolType", "InsertMedia");
-
- return false;
- }
- }
-
- // validation passed
- // add protocol to URI if needed
- if (uriTransferProtocolType == std::nullopt)
- {
- imageUrl = getUriWithTransferProtocol(imageUrl,
- *paramTransferProtocolType);
- }
-
- return true;
+ return {};
}
- /**
- * @brief Function handles POST method request.
- *
- * Analyzes POST body message before sends Reset request data to dbus.
- */
- void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
+ if (*transferProtocolType == "CIFS")
{
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- // take resource name from URL
- const std::string& resName = params[1];
-
- if (params[0] != "bmc")
- {
- messages::resourceNotFound(asyncResp->res, "VirtualMedia.Insert",
- resName);
-
- return;
- }
-
- crow::connections::systemBus->async_method_call(
- [this, asyncResp, req,
- resName](const boost::system::error_code ec,
- const GetObjectType& 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;
-
- crow::connections::systemBus->async_method_call(
- [this, service, resName, req,
- asyncResp](const boost::system::error_code ec,
- ManagedObjectType& subtree) {
- if (ec)
- {
- BMCWEB_LOG_DEBUG << "DBUS response error";
-
- return;
- }
-
- for (const auto& object : subtree)
- {
- const std::string& path =
- static_cast<const std::string&>(object.first);
-
- std::size_t lastIndex = path.rfind('/');
- if (lastIndex == std::string::npos)
- {
- continue;
- }
-
- lastIndex += 1;
-
- if (path.substr(lastIndex) == resName)
- {
- lastIndex = path.rfind("Proxy");
- if (lastIndex != std::string::npos)
- {
- // Not possible in proxy mode
- BMCWEB_LOG_DEBUG << "InsertMedia not "
- "allowed in proxy mode";
- messages::resourceNotFound(
- asyncResp->res,
- "VirtualMedia.InsertMedia", resName);
-
- return;
- }
-
- lastIndex = path.rfind("Legacy");
- if (lastIndex == std::string::npos)
- {
- continue;
- }
-
- // Legacy mode
- 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;
-
- // Read obligatory parameters (url of image)
- if (!json_util::readJson(
- req, asyncResp->res, "Image", imageUrl,
- "WriteProtected", writeProtected,
- "UserName", userName, "Password",
- password, "Inserted", inserted,
- "TransferMethod", transferMethod,
- "TransferProtocolType",
- transferProtocolType))
- {
- BMCWEB_LOG_DEBUG << "Image is not provided";
- return;
- }
-
- bool paramsValid = validateParams(
- asyncResp->res, imageUrl, inserted,
- transferMethod, transferProtocolType);
-
- if (paramsValid == false)
- {
- return;
- }
-
- // manager is irrelevant for VirtualMedia dbus
- // calls
- doMountVmLegacy(asyncResp, service, resName,
- imageUrl, !(*writeProtected),
- std::move(*userName),
- std::move(*password));
-
- return;
- }
- }
- BMCWEB_LOG_DEBUG << "Parent item not found";
- messages::resourceNotFound(asyncResp->res,
- "VirtualMedia", resName);
- },
- service, "/xyz/openbmc_project/VirtualMedia",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetObject",
- "/xyz/openbmc_project/VirtualMedia", std::array<const char*, 0>());
+ 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;
+}
+
+/**
+ * @brief Function validate parameters of insert media request.
+ *
+ */
+inline bool
+ validateParams(crow::Response& res, std::string& imageUrl,
+ const std::optional<bool>& inserted,
+ const std::optional<std::string>& transferMethod,
+ const std::optional<std::string>& transferProtocolType)
+{
+ BMCWEB_LOG_DEBUG << "Validation started";
+ // required param imageUrl must not be empty
+ if (imageUrl.empty())
+ {
+ BMCWEB_LOG_ERROR << "Request action parameter Image is empty.";
+
+ messages::propertyValueFormatError(res, "<empty>", "Image");
+
+ return false;
+ }
+
+ // optional param inserted must be true
+ if ((inserted != std::nullopt) && (*inserted != true))
+ {
+ BMCWEB_LOG_ERROR
+ << "Request action optional parameter Inserted must be true.";
+
+ messages::actionParameterNotSupported(res, "Inserted", "InsertMedia");
+
+ return false;
+ }
+
+ // optional param transferMethod must be stream
+ if ((transferMethod != std::nullopt) && (*transferMethod != "Stream"))
+ {
+ BMCWEB_LOG_ERROR << "Request action optional parameter "
+ "TransferMethod must be Stream.";
+
+ messages::actionParameterNotSupported(res, "TransferMethod",
+ "InsertMedia");
+
+ return false;
+ }
+
+ std::optional<TransferProtocol> uriTransferProtocolType =
+ getTransferProtocolFromUri(imageUrl);
+
+ std::optional<TransferProtocol> paramTransferProtocolType =
+ getTransferProtocolFromParam(transferProtocolType);
+
+ // ImageUrl does not contain valid protocol type
+ if (*uriTransferProtocolType == TransferProtocol::invalid)
+ {
+ BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must "
+ "contain specified protocol type from list: "
+ "(smb, https).";
+
+ messages::resourceAtUriInUnknownFormat(res, imageUrl);
+
+ return false;
+ }
+
+ // transferProtocolType should contain value from list
+ if (*paramTransferProtocolType == TransferProtocol::invalid)
+ {
+ BMCWEB_LOG_ERROR << "Request action parameter TransferProtocolType "
+ "must be provided with value from list: "
+ "(CIFS, HTTPS).";
+
+ messages::propertyValueNotInList(res, *transferProtocolType,
+ "TransferProtocolType");
+ return false;
+ }
+
+ // valid transfer protocol not provided either with URI nor param
+ if ((uriTransferProtocolType == std::nullopt) &&
+ (paramTransferProtocolType == std::nullopt))
+ {
+ BMCWEB_LOG_ERROR << "Request action parameter ImageUrl must "
+ "contain specified protocol type or param "
+ "TransferProtocolType must be provided.";
+
+ messages::resourceAtUriInUnknownFormat(res, imageUrl);
+
+ return false;
+ }
+
+ // valid transfer protocol provided both with URI and param
+ if ((paramTransferProtocolType != std::nullopt) &&
+ (uriTransferProtocolType != std::nullopt))
+ {
+ // 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(res, *transferProtocolType,
+ "TransferProtocolType",
+ "InsertMedia");
+
+ return false;
+ }
+ }
+
+ // validation passed
+ // add protocol to URI if needed
+ if (uriTransferProtocolType == std::nullopt)
+ {
+ imageUrl =
+ getUriWithTransferProtocol(imageUrl, *paramTransferProtocolType);
+ }
+
+ return true;
+}
+
+template <typename T>
+static void secureCleanup(T& value)
+{
+ auto raw = const_cast<typename T::value_type*>(value.data());
+ explicit_bzero(raw, value.size() * sizeof(*raw));
+}
+
+class Credentials
+{
+ public:
+ Credentials(std::string&& user, std::string&& password) :
+ userBuf(std::move(user)), passBuf(std::move(password))
+ {}
+
+ ~Credentials()
+ {
+ secureCleanup(userBuf);
+ secureCleanup(passBuf);
+ }
+
+ const std::string& user()
+ {
+ return userBuf;
+ }
+
+ const std::string& password()
+ {
+ return passBuf;
+ }
+
+ Credentials() = delete;
+ Credentials(const Credentials&) = delete;
+ Credentials& operator=(const Credentials&) = delete;
+
+ private:
+ std::string userBuf;
+ std::string passBuf;
+};
+
+class CredentialsProvider
+{
+ public:
template <typename T>
- static void secureCleanup(T& value)
+ struct Deleter
{
- auto raw = const_cast<typename T::value_type*>(value.data());
- explicit_bzero(raw, value.size() * sizeof(*raw));
+ void operator()(T* buff) const
+ {
+ if (buff)
+ {
+ secureCleanup(*buff);
+ delete buff;
+ }
+ }
+ };
+
+ using Buffer = std::vector<char>;
+ using SecureBuffer = std::unique_ptr<Buffer, Deleter<Buffer>>;
+ // Using explicit definition instead of std::function to avoid implicit
+ // conversions eg. stack copy instead of reference
+ using FormatterFunc = void(const std::string& username,
+ const std::string& password, Buffer& dest);
+
+ CredentialsProvider(std::string&& user, std::string&& password) :
+ credentials(std::move(user), std::move(password))
+ {}
+
+ const std::string& user()
+ {
+ return credentials.user();
}
- class Credentials
+ const std::string& password()
{
- public:
- Credentials(std::string&& user, std::string&& password) :
- userBuf(std::move(user)), passBuf(std::move(password))
- {}
+ return credentials.password();
+ }
- ~Credentials()
- {
- secureCleanup(userBuf);
- secureCleanup(passBuf);
- }
-
- const std::string& user()
- {
- return userBuf;
- }
-
- const std::string& password()
- {
- return passBuf;
- }
-
- private:
- Credentials() = delete;
- Credentials(const Credentials&) = delete;
- Credentials& operator=(const Credentials&) = delete;
-
- std::string userBuf;
- std::string passBuf;
- };
-
- class CredentialsProvider
+ SecureBuffer pack(FormatterFunc formatter)
{
- public:
- template <typename T>
- struct Deleter
+ SecureBuffer packed{new Buffer{}};
+ if (formatter)
{
- void operator()(T* buff) const
- {
- if (buff)
- {
- secureCleanup(*buff);
- delete buff;
- }
- }
- };
-
- using Buffer = std::vector<char>;
- using SecureBuffer = std::unique_ptr<Buffer, Deleter<Buffer>>;
- // Using explicit definition instead of std::function to avoid implicit
- // conversions eg. stack copy instead of reference
- using FormatterFunc = void(const std::string& username,
- const std::string& password, Buffer& dest);
-
- CredentialsProvider(std::string&& user, std::string&& password) :
- credentials(std::move(user), std::move(password))
- {}
-
- const std::string& user()
- {
- return credentials.user();
+ formatter(credentials.user(), credentials.password(), *packed);
}
- const std::string& password()
- {
- return credentials.password();
- }
+ return packed;
+ }
- SecureBuffer pack(FormatterFunc formatter)
- {
- SecureBuffer packed{new Buffer{}};
- if (formatter)
- {
- formatter(credentials.user(), credentials.password(), *packed);
- }
+ private:
+ Credentials credentials;
+};
- return packed;
- }
+// Wrapper for boost::async_pipe ensuring proper pipe cleanup
+template <typename Buffer>
+class Pipe
+{
+ public:
+ using unix_fd = sdbusplus::message::unix_fd;
- private:
- Credentials credentials;
- };
+ Pipe(boost::asio::io_context& io, Buffer&& buffer) :
+ impl(io), buffer{std::move(buffer)}
+ {}
- // Wrapper for boost::async_pipe ensuring proper pipe cleanup
- template <typename Buffer>
- class Pipe
+ ~Pipe()
{
- public:
- using unix_fd = sdbusplus::message::unix_fd;
+ // Named pipe needs to be explicitly removed
+ impl.close();
+ }
- Pipe(boost::asio::io_context& io, Buffer&& buffer) :
- impl(io), buffer{std::move(buffer)}
- {}
-
- ~Pipe()
- {
- // Named pipe needs to be explicitly removed
- impl.close();
- }
-
- unix_fd fd()
- {
- return unix_fd{impl.native_source()};
- }
-
- template <typename WriteHandler>
- void asyncWrite(WriteHandler&& handler)
- {
- impl.async_write_some(data(), std::forward<WriteHandler>(handler));
- }
-
- private:
- // Specialization for pointer types
- template <typename B = Buffer>
- typename std::enable_if<boost::has_dereference<B>::value,
- boost::asio::const_buffer>::type
- data()
- {
- return boost::asio::buffer(*buffer);
- }
-
- template <typename B = Buffer>
- typename std::enable_if<!boost::has_dereference<B>::value,
- boost::asio::const_buffer>::type
- data()
- {
- return boost::asio::buffer(buffer);
- }
-
- const std::string name;
- boost::process::async_pipe impl;
- Buffer buffer;
- };
-
- /**
- * @brief Function transceives data with dbus directly.
- *
- * All BMC state properties will be retrieved before sending reset request.
- */
- void doMountVmLegacy(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& service, const std::string& name,
- const std::string& imageUrl, const bool rw,
- std::string&& userName, std::string&& password)
+ unix_fd fd()
{
- using SecurePipe = Pipe<CredentialsProvider::SecureBuffer>;
- constexpr const size_t secretLimit = 1024;
+ return unix_fd{impl.native_source()};
+ }
- std::shared_ptr<SecurePipe> secretPipe;
- std::variant<int, SecurePipe::unix_fd> unixFd = -1;
+ template <typename WriteHandler>
+ void asyncWrite(WriteHandler&& handler)
+ {
+ impl.async_write_some(data(), std::forward<WriteHandler>(handler));
+ }
- if (!userName.empty() || !password.empty())
+ private:
+ // Specialization for pointer types
+ template <typename B = Buffer>
+ typename std::enable_if<boost::has_dereference<B>::value,
+ boost::asio::const_buffer>::type
+ data()
+ {
+ return boost::asio::buffer(*buffer);
+ }
+
+ template <typename B = Buffer>
+ typename std::enable_if<!boost::has_dereference<B>::value,
+ boost::asio::const_buffer>::type
+ data()
+ {
+ return boost::asio::buffer(buffer);
+ }
+
+ const std::string name;
+ boost::process::async_pipe impl;
+ Buffer buffer;
+};
+
+/**
+ * @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, const bool rw,
+ std::string&& userName, std::string&& password)
+{
+ using SecurePipe = Pipe<CredentialsProvider::SecureBuffer>;
+ constexpr const size_t secretLimit = 1024;
+
+ std::shared_ptr<SecurePipe> secretPipe;
+ std::variant<int, SecurePipe::unix_fd> unixFd = -1;
+
+ if (!userName.empty() || !password.empty())
+ {
+ // Encapsulate in safe buffer
+ CredentialsProvider credentials(std::move(userName),
+ std::move(password));
+
+ // Payload must contain data + NULL delimiters
+ if (credentials.user().size() + credentials.password().size() + 2 >
+ secretLimit)
{
- // Encapsulate in safe buffer
- CredentialsProvider credentials(std::move(userName),
- std::move(password));
+ BMCWEB_LOG_ERROR << "Credentials too long to handle";
+ messages::unrecognizedRequestBody(asyncResp->res);
+ return;
+ }
- // Payload must contain data + NULL delimiters
- if (credentials.user().size() + credentials.password().size() + 2 >
- secretLimit)
- {
- BMCWEB_LOG_ERROR << "Credentials too long to handle";
- messages::unrecognizedRequestBody(asyncResp->res);
- return;
- }
-
- // Pack secret
- auto secret = credentials.pack([](const auto& user,
- const auto& pass, auto& buff) {
+ // Pack secret
+ auto secret = credentials.pack(
+ [](const auto& user, const auto& pass, auto& buff) {
std::copy(user.begin(), user.end(), std::back_inserter(buff));
buff.push_back('\0');
std::copy(pass.begin(), pass.end(), std::back_inserter(buff));
buff.push_back('\0');
});
- // Open pipe
- secretPipe = std::make_shared<SecurePipe>(
- crow::connections::systemBus->get_io_context(),
- std::move(secret));
- unixFd = secretPipe->fd();
+ // Open pipe
+ secretPipe = std::make_shared<SecurePipe>(
+ crow::connections::systemBus->get_io_context(), std::move(secret));
+ unixFd = secretPipe->fd();
- // Pass secret over pipe
- secretPipe->asyncWrite(
- [asyncResp](const boost::system::error_code& ec, std::size_t) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "Failed to pass secret: " << ec;
- messages::internalError(asyncResp->res);
- }
- });
- }
+ // Pass secret over pipe
+ secretPipe->asyncWrite(
+ [asyncResp](const boost::system::error_code& ec, std::size_t) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "Failed to pass secret: " << ec;
+ messages::internalError(asyncResp->res);
+ }
+ });
+ }
+ 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);
+ }
+ else if (!success)
+ {
+ BMCWEB_LOG_ERROR << "Service responded with error";
+ messages::generalError(asyncResp->res);
+ }
+ },
+ service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
+ "xyz.openbmc_project.VirtualMedia.Legacy", "Mount", imageUrl, rw,
+ unixFd);
+}
+
+/**
+ * @brief Function transceives data with dbus directly.
+ *
+ * All BMC state properties will be retrieved before sending reset request.
+ */
+inline void doVmAction(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, secretPipe](const boost::system::error_code ec,
- bool success) {
+ [asyncResp](const boost::system::error_code ec) {
if (ec)
{
BMCWEB_LOG_ERROR << "Bad D-Bus request error: " << ec;
+
messages::internalError(asyncResp->res);
- }
- else if (!success)
- {
- BMCWEB_LOG_ERROR << "Service responded with error";
- messages::generalError(asyncResp->res);
+ return;
}
},
service, "/xyz/openbmc_project/VirtualMedia/Legacy/" + name,
- "xyz.openbmc_project.VirtualMedia.Legacy", "Mount", imageUrl, rw,
- unixFd);
+ "xyz.openbmc_project.VirtualMedia.Legacy", "Unmount");
}
-};
-
-/**
- @brief EjectMedia action class
- */
-class VirtualMediaActionEjectMedia : public Node
-{
- public:
- VirtualMediaActionEjectMedia(App& app) :
- Node(app,
- "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
- "VirtualMedia.EjectMedia",
- std::string(), std::string())
+ else // proxy
{
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
- {boost::beast::http::verb::put, {{"ConfigureManager"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
- {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
- }
-
- private:
- /**
- * @brief Function handles POST method request.
- *
- * Analyzes POST body message before sends Reset request data to dbus.
- */
- void doPost(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request& req,
- const std::vector<std::string>& params) override
- {
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- // take resource name from URL
- const std::string& resName = params[1];
-
- if (params[0] != "bmc")
- {
- messages::resourceNotFound(asyncResp->res, "VirtualMedia.Eject",
- resName);
-
- return;
- }
-
crow::connections::systemBus->async_method_call(
- [this, asyncResp{std::move(asyncResp)}, req,
- resName](const boost::system::error_code ec,
- const GetObjectType& getObjectType) {
+ [asyncResp](const boost::system::error_code ec) {
if (ec)
{
- BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
- << 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 requestNBDVirtualMediaRoutes(App& app)
+{
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
+ "VirtualMedia.InsertMedia")
+ .privileges({"ConfigureManager"})
+ .methods(boost::beast::http::verb::post)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& name, const std::string& resName) {
+ if (name != "bmc")
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "VirtualMedia.Insert", resName);
return;
}
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
crow::connections::systemBus->async_method_call(
- [this, resName, service, req,
- asyncResp{asyncResp}](const boost::system::error_code ec,
- ManagedObjectType& subtree) {
+ [asyncResp, req,
+ resName](const boost::system::error_code ec,
+ const GetObjectType& getObjectType) {
if (ec)
{
- BMCWEB_LOG_DEBUG << "DBUS response error";
+ BMCWEB_LOG_ERROR
+ << "ObjectMapper::GetObject call failed: "
+ << ec;
+ messages::internalError(asyncResp->res);
return;
}
+ std::string service = getObjectType.begin()->first;
+ BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
- for (const auto& object : subtree)
- {
- const std::string& path =
- static_cast<const std::string&>(object.first);
-
- std::size_t lastIndex = path.rfind('/');
- if (lastIndex == std::string::npos)
- {
- continue;
- }
-
- lastIndex += 1;
-
- if (path.substr(lastIndex) == resName)
- {
- lastIndex = path.rfind("Proxy");
- if (lastIndex != std::string::npos)
+ crow::connections::systemBus->async_method_call(
+ [service, resName, req,
+ asyncResp](const boost::system::error_code ec,
+ ManagedObjectType& subtree) {
+ if (ec)
{
- // Proxy mode
- doVmAction(asyncResp, service, resName,
- false);
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+
+ return;
}
- lastIndex = path.rfind("Legacy");
- if (lastIndex != std::string::npos)
+ for (const auto& object : subtree)
{
- // Legacy mode
- doVmAction(asyncResp, service, resName,
- true);
- }
+ const std::string& path =
+ static_cast<const std::string&>(
+ object.first);
- return;
- }
- }
- BMCWEB_LOG_DEBUG << "Parent item not found";
- messages::resourceNotFound(asyncResp->res,
- "VirtualMedia", resName);
+ std::size_t lastIndex = path.rfind('/');
+ if (lastIndex == std::string::npos)
+ {
+ continue;
+ }
+
+ lastIndex += 1;
+
+ if (path.substr(lastIndex) == resName)
+ {
+ lastIndex = path.rfind("Proxy");
+ if (lastIndex != std::string::npos)
+ {
+ // Not possible in proxy mode
+ BMCWEB_LOG_DEBUG
+ << "InsertMedia not "
+ "allowed in proxy mode";
+ messages::resourceNotFound(
+ asyncResp->res,
+ "VirtualMedia.InsertMedia",
+ resName);
+
+ return;
+ }
+
+ lastIndex = path.rfind("Legacy");
+ if (lastIndex == std::string::npos)
+ {
+ continue;
+ }
+
+ // Legacy mode
+ 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;
+
+ // Read obligatory parameters (url of
+ // image)
+ if (!json_util::readJson(
+ req, asyncResp->res, "Image",
+ imageUrl, "WriteProtected",
+ writeProtected, "UserName",
+ userName, "Password", password,
+ "Inserted", inserted,
+ "TransferMethod",
+ transferMethod,
+ "TransferProtocolType",
+ transferProtocolType))
+ {
+ BMCWEB_LOG_DEBUG
+ << "Image is not provided";
+ return;
+ }
+
+ bool paramsValid = validateParams(
+ asyncResp->res, imageUrl, inserted,
+ transferMethod,
+ transferProtocolType);
+
+ if (paramsValid == false)
+ {
+ return;
+ }
+
+ // manager is irrelevant for
+ // VirtualMedia dbus calls
+ doMountVmLegacy(asyncResp, service,
+ resName, imageUrl,
+ !(*writeProtected),
+ std::move(*userName),
+ std::move(*password));
+
+ return;
+ }
+ }
+ BMCWEB_LOG_DEBUG << "Parent item not found";
+ messages::resourceNotFound(
+ asyncResp->res, "VirtualMedia", resName);
+ },
+ service, "/xyz/openbmc_project/VirtualMedia",
+ "org.freedesktop.DBus.ObjectManager",
+ "GetManagedObjects");
},
- service, "/xyz/openbmc_project/VirtualMedia",
- "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetObject",
- "/xyz/openbmc_project/VirtualMedia", std::array<const char*, 0>());
- }
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject",
+ "/xyz/openbmc_project/VirtualMedia",
+ std::array<const char*, 0>());
+ });
- /**
- * @brief Function transceives data with dbus directly.
- *
- * All BMC state properties will be retrieved before sending reset request.
- */
- void doVmAction(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const std::string& service, const std::string& name,
- bool legacy)
- {
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/Actions/"
+ "VirtualMedia.EjectMedia")
+ .privileges({"ConfigureManager"})
+ .methods(boost::beast::http::verb::post)(
+ [](const crow::Request& req,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& name, const std::string& resName) {
+ if (name != "bmc")
+ {
+ messages::resourceNotFound(asyncResp->res,
+ "VirtualMedia.Eject", resName);
- // 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;
+ return;
+ }
- 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");
- }
- }
-};
-
-class VirtualMediaCollection : public Node
-{
- public:
- /*
- * Default Constructor
- */
- VirtualMediaCollection(App& app) :
- Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/", std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
- {boost::beast::http::verb::put, {{"ConfigureManager"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
- {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
- }
-
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
- {
-
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 1)
- {
- messages::internalError(asyncResp->res);
-
- return;
- }
-
- const std::string& name = params[0];
-
- 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"] =
- "/redfish/v1/Managers/" + name + "/VirtualMedia";
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, name](const boost::system::error_code ec,
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, req,
+ resName](const boost::system::error_code ec,
const GetObjectType& getObjectType) {
- if (ec)
+ 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;
+
+ crow::connections::systemBus->async_method_call(
+ [resName, service, req, asyncResp{asyncResp}](
+ const boost::system::error_code ec,
+ ManagedObjectType& subtree) {
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG << "DBUS response error";
+
+ return;
+ }
+
+ for (const auto& object : subtree)
+ {
+ const std::string& path =
+ static_cast<const std::string&>(
+ object.first);
+
+ std::size_t lastIndex = path.rfind('/');
+ if (lastIndex == std::string::npos)
+ {
+ continue;
+ }
+
+ lastIndex += 1;
+
+ if (path.substr(lastIndex) == resName)
+ {
+ lastIndex = path.rfind("Proxy");
+ if (lastIndex != std::string::npos)
+ {
+ // Proxy mode
+ doVmAction(asyncResp, service,
+ resName, false);
+ }
+
+ lastIndex = path.rfind("Legacy");
+ if (lastIndex != std::string::npos)
+ {
+ // Legacy mode
+ doVmAction(asyncResp, service,
+ resName, true);
+ }
+
+ return;
+ }
+ }
+ BMCWEB_LOG_DEBUG << "Parent item not found";
+ messages::resourceNotFound(
+ asyncResp->res, "VirtualMedia", resName);
+ },
+ service, "/xyz/openbmc_project/VirtualMedia",
+ "org.freedesktop.DBus.ObjectManager",
+ "GetManagedObjects");
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject",
+ "/xyz/openbmc_project/VirtualMedia",
+ std::array<const char*, 0>());
+ });
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request& /* req */,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& name) {
+ if (name != "bmc")
{
- BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
- << ec;
- messages::internalError(asyncResp->res);
+ messages::resourceNotFound(asyncResp->res, "VirtualMedia",
+ name);
return;
}
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
- getVmResourceList(asyncResp, service, name);
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetObject",
- "/xyz/openbmc_project/VirtualMedia", std::array<const char*, 0>());
- }
-};
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#VirtualMediaCollection.VirtualMediaCollection";
+ asyncResp->res.jsonValue["Name"] = "Virtual Media Services";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Managers/" + name + "/VirtualMedia";
-class VirtualMedia : public Node
-{
- public:
- /*
- * Default Constructor
- */
- VirtualMedia(App& app) :
- Node(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/",
- std::string(), std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
- {boost::beast::http::verb::put, {{"ConfigureManager"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
- {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
- }
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, name](const boost::system::error_code ec,
+ const GetObjectType& getObjectType) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR
+ << "ObjectMapper::GetObject call failed: "
+ << ec;
+ messages::internalError(asyncResp->res);
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
- const crow::Request&,
- const std::vector<std::string>& params) override
- {
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 2)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- const std::string& name = params[0];
- const std::string& resName = params[1];
+ return;
+ }
+ std::string service = getObjectType.begin()->first;
+ BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
- if (name != "bmc")
- {
- messages::resourceNotFound(asyncResp->res, "VirtualMedia", resName);
+ getVmResourceList(asyncResp, service, name);
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject",
+ "/xyz/openbmc_project/VirtualMedia",
+ std::array<const char*, 0>());
+ });
- return;
- }
-
- crow::connections::systemBus->async_method_call(
- [asyncResp, name, resName](const boost::system::error_code ec,
- const GetObjectType& getObjectType) {
- if (ec)
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/<str>/VirtualMedia/<str>/")
+ .privileges({"Login"})
+ .methods(boost::beast::http::verb::get)(
+ [](const crow::Request& /* req */,
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
+ const std::string& name, const std::string& resName) {
+ if (name != "bmc")
{
- BMCWEB_LOG_ERROR << "ObjectMapper::GetObject call failed: "
- << ec;
- messages::internalError(asyncResp->res);
+ messages::resourceNotFound(asyncResp->res, "VirtualMedia",
+ resName);
return;
}
- std::string service = getObjectType.begin()->first;
- BMCWEB_LOG_DEBUG << "GetObjectType: " << service;
- getVmData(asyncResp, service, name, resName);
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetObject",
- "/xyz/openbmc_project/VirtualMedia", std::array<const char*, 0>());
- }
-};
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, name,
+ resName](const boost::system::error_code ec,
+ const GetObjectType& 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);
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetObject",
+ "/xyz/openbmc_project/VirtualMedia",
+ std::array<const char*, 0>());
+ });
+}
} // namespace redfish