diff options
Diffstat (limited to 'virtual-media/src/configuration.hpp')
-rw-r--r-- | virtual-media/src/configuration.hpp | 233 |
1 files changed, 233 insertions, 0 deletions
diff --git a/virtual-media/src/configuration.hpp b/virtual-media/src/configuration.hpp new file mode 100644 index 0000000..dd71837 --- /dev/null +++ b/virtual-media/src/configuration.hpp @@ -0,0 +1,233 @@ +#pragma once + +#include "logger.hpp" +#include "system.hpp" + +#include <algorithm> +#include <boost/container/flat_map.hpp> +#include <iostream> +#include <nlohmann/json.hpp> +#include <optional> +#include <string> +#include <vector> + +class Configuration +{ + public: + enum class Mode + { + // Proxy mode - works directly from browser and uses JavaScript/HTML5 + // to communicate over Secure WebSockets directly to HTTPS endpoint + // hosted by bmcweb on BMC + proxy = 0, + + // Legacy mode - is initiated from browser using Redfish defined + // VirtualMedia schemas, then BMC process connects to external + // CIFS/HTTPS image pointed during initialization. + legacy = 1, + }; + + struct MountPoint + { + NBDDevice nbdDevice; + std::string unixSocket; + std::string endPointId; + std::optional<int> timeout; + std::optional<int> blocksize; + Mode mode; + + static std::vector<std::string> toArgs(const MountPoint& mp) + { + std::vector<std::string> args = { + "-t", "30", "-u", mp.unixSocket, mp.nbdDevice.to_path(), "-n"}; + return args; + } + }; + + const MountPoint* getMountPoint(const std::string& name) const + { + const auto mp = mountPoints.find(name); + if (mp != mountPoints.end()) + { + return &(mp->second); + } + else + { + return nullptr; + } + } + + bool valid = false; + boost::container::flat_map<std::string, MountPoint> mountPoints; + + Configuration(const std::string& file) + { + valid = loadConfiguration(file); + } + + private: + bool loadConfiguration(const std::string& file) noexcept + { + std::ifstream configFile(file); + if (!configFile.is_open()) + { + LogMsg(Logger::Critical, "Could not open configuration file"); + return false; + } + try + { + auto data = nlohmann::json::parse(configFile, nullptr); + setupVariables(data); + } + catch (nlohmann::json::exception& e) + { + LogMsg(Logger::Critical, "Error parsing JSON file"); + return false; + } + catch (std::out_of_range& e) + { + LogMsg(Logger::Critical, "Error parsing JSON file"); + return false; + } + return true; + } + + bool setupVariables(const nlohmann::json& config) + { + for (const auto& item : config.items()) + { + if (item.key() == "MountPoints") + { + for (const auto& mountpoint : item.value().items()) + { + MountPoint mp; + const auto nbdDeviceIter = + mountpoint.value().find("NBDDevice"); + if (nbdDeviceIter != mountpoint.value().cend()) + { + const std::string* value = + nbdDeviceIter->get_ptr<const std::string*>(); + if (value) + { + mp.nbdDevice = NBDDevice(value->c_str()); + if (!mp.nbdDevice) + { + LogMsg(Logger::Error, + "NBDDevice unrecognized."); + continue; + } + } + else + { + LogMsg(Logger::Error, + "NBDDevice required, not set"); + continue; + } + }; + const auto unixSocketIter = + mountpoint.value().find("UnixSocket"); + if (unixSocketIter != mountpoint.value().cend()) + { + const std::string* value = + unixSocketIter->get_ptr<const std::string*>(); + if (value) + { + mp.unixSocket = *value; + } + else + { + LogMsg(Logger::Error, + "UnixSocket required, not set"); + continue; + } + } + const auto endPointIdIter = + mountpoint.value().find("EndpointId"); + if (endPointIdIter != mountpoint.value().cend()) + { + const std::string* value = + endPointIdIter->get_ptr<const std::string*>(); + if (value) + { + mp.endPointId = *value; + } + else + { + LogMsg(Logger::Info, + "EndpointId required, not set"); + continue; + } + } + const auto timeoutIter = mountpoint.value().find("Timeout"); + if (timeoutIter != mountpoint.value().cend()) + { + const uint64_t* value = + timeoutIter->get_ptr<const uint64_t*>(); + if (value) + { + mp.timeout = *value; + } + else + { + LogMsg(Logger::Info, + "Timeout not set, use default"); + } + } + const auto blocksizeIter = + mountpoint.value().find("BlockSize"); + if (blocksizeIter != mountpoint.value().cend()) + { + const uint64_t* value = + blocksizeIter->get_ptr<const uint64_t*>(); + if (value) + { + mp.blocksize = *value; + } + else + { + LogMsg(Logger::Info, + "BlockSize not set, use default"); + } + } + const auto modeIter = mountpoint.value().find("Mode"); + if (modeIter != mountpoint.value().cend()) + { + const uint64_t* value = + modeIter->get_ptr<const uint64_t*>(); + if (value) + { + if (*value == 0) + { + mp.mode = Configuration::Mode::proxy; + } + else if (*value == 1) + { + mp.mode = Configuration::Mode::legacy; + } + else + { + LogMsg(Logger::Error, + "Incorrect Mode, skip this mount point"); + continue; + } + } + else + { + LogMsg(Logger::Error, + "Mode not set, skip this mount point"); + continue; + } + } + else + { + LogMsg(Logger::Error, + "Mode does not exist, skip this mount point"); + continue; + } + mountPoints[mountpoint.key()] = std::move(mp); + } + } + } + return true; + } +}; |