518 lines
22 KiB
Diff
Executable File
518 lines
22 KiB
Diff
Executable File
From b814ff4bd75cc7ac9eac4b2b0214d1947d8d05b7 Mon Sep 17 00:00:00 2001
|
|
From: roly <Rolyli.Li@luxshare-ict.com>
|
|
Date: Fri, 17 Jan 2025 10:25:19 +0800
|
|
Subject: [PATCH] Add redfish oem rsyslog api
|
|
|
|
---
|
|
include/luxshare/dump.hpp | 461 ++++++++++++++++++++++++++++++++++
|
|
redfish-core/lib/managers.hpp | 4 +
|
|
src/webserver_main.cpp | 2 +
|
|
3 files changed, 467 insertions(+)
|
|
create mode 100755 include/luxshare/dump.hpp
|
|
|
|
diff --git a/include/luxshare/dump.hpp b/include/luxshare/dump.hpp
|
|
new file mode 100755
|
|
index 00000000..060e948f
|
|
--- /dev/null
|
|
+++ b/include/luxshare/dump.hpp
|
|
@@ -0,0 +1,461 @@
|
|
+#pragma once
|
|
+#include <app.hpp>
|
|
+#include <async_resp.hpp>
|
|
+#include <boost/asio/ip/address.hpp>
|
|
+#include <error_messages.hpp>
|
|
+#include <registries/privilege_registry.hpp>
|
|
+#include <xyz/openbmc_project/Common/Progress/server.hpp>
|
|
+
|
|
+#include <filesystem>
|
|
+#include <fstream>
|
|
+
|
|
+namespace crow
|
|
+{
|
|
+namespace luxshare_dump_api
|
|
+{
|
|
+
|
|
+namespace fs = std::filesystem;
|
|
+
|
|
+static const std::map<std::string, std::string> rsyslogIndexTranslation = {
|
|
+ {"index0", "Index0"},
|
|
+ {"index1", "Index1"},
|
|
+ {"index2", "Index2"},
|
|
+ {"index3", "Index3"}};
|
|
+
|
|
+
|
|
+inline std::string getRsyslogSettingsHelper(
|
|
+ const boost::asio::yield_context& yield,
|
|
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
|
|
+ const std::string& dbusObj, const std::string& propertyName)
|
|
+{
|
|
+ boost::system::error_code ec;
|
|
+ auto response = crow::connections::systemBus
|
|
+ ->yield_method_call<std::variant<std::string>>(
|
|
+ yield, ec, "xyz.openbmc_project.Settings", dbusObj,
|
|
+ "org.freedesktop.DBus.Properties", "Get",
|
|
+ "xyz.openbmc_project.Logging.Rsyslog",
|
|
+ propertyName);
|
|
+ if (ec)
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("Error getting {} property from {} : {}", propertyName,
|
|
+ dbusObj, ec.message());
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"]["Status"] = 1;
|
|
+ return std::string{};
|
|
+ }
|
|
+ const std::string* propertyValue = std::get_if<std::string>(&response);
|
|
+ if (propertyValue == nullptr)
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("D-Bus response gets null property value");
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"]["Status"] = 1;
|
|
+ return std::string{};
|
|
+ }
|
|
+ return *propertyValue;
|
|
+}
|
|
+
|
|
+template <typename PropertyType>
|
|
+inline void setRsyslogSettingsHelper(
|
|
+ const boost::asio::yield_context& yield,
|
|
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
|
|
+ const std::string& dbusObj, const std::string& propertyName,
|
|
+ const PropertyType& propertyValue)
|
|
+{
|
|
+ boost::system::error_code ec;
|
|
+ crow::connections::systemBus->yield_method_call<void>(
|
|
+ yield, ec, "xyz.openbmc_project.Settings", dbusObj,
|
|
+ "org.freedesktop.DBus.Properties", "Set",
|
|
+ "xyz.openbmc_project.Logging.Rsyslog", propertyName,
|
|
+ std::variant<PropertyType>(propertyValue));
|
|
+ if (ec)
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("Error setting {} property from {}: {}", propertyName,
|
|
+ dbusObj, ec.message());
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ return;
|
|
+ }
|
|
+}
|
|
+
|
|
+inline bool checkAddressTypeAndAddress(const std::string& dbusAddressType,
|
|
+ const std::string& dbusAddress)
|
|
+{
|
|
+ boost::system::error_code ec;
|
|
+ boost::asio::ip::address tmpAddress =
|
|
+ boost::asio::ip::make_address(dbusAddress, ec);
|
|
+ if (dbusAddressType == "xyz.openbmc_project.Logging.Rsyslog.Type.IPv4")
|
|
+ {
|
|
+ // check multicast address, broadcast address, and 0.x.x.x address.
|
|
+ if (!ec && tmpAddress.is_v4() && !tmpAddress.is_multicast() &&
|
|
+ (dbusAddress != "255.255.255.255") &&
|
|
+ !dbusAddress.starts_with("0."))
|
|
+ {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+ else if (dbusAddressType == "xyz.openbmc_project.Logging.Rsyslog.Type.IPv6")
|
|
+ {
|
|
+ // check multicast address
|
|
+ if (!ec && tmpAddress.is_v6() && !tmpAddress.is_multicast())
|
|
+ {
|
|
+ return true;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ BMCWEB_LOG_DEBUG(
|
|
+ "address does not match addressType, or address is invalid");
|
|
+ return false;
|
|
+}
|
|
+
|
|
+inline void requestRoutesOemLuxshareRsyslogSettings(App& app)
|
|
+{
|
|
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Oem/Luxshare/RsyslogSettings/")
|
|
+ .privileges(redfish::privileges::getLogService)
|
|
+ .methods(boost::beast::http::verb::get)(
|
|
+ [&app](const crow::Request& req,
|
|
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
|
|
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ crow::connections::systemBus->async_method_call(
|
|
+ [asyncResp](const boost::system::error_code ec,
|
|
+ const std::vector<std::string>& subTreePaths) {
|
|
+ if (ec)
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("Error calling GetSubTreePaths method: {}",
|
|
+ ec.message());
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ return;
|
|
+ }
|
|
+ for (const auto& path : subTreePaths)
|
|
+ {
|
|
+ sdbusplus::asio::getAllProperties(
|
|
+ *crow::connections::systemBus,
|
|
+ "xyz.openbmc_project.Settings", path,
|
|
+ "xyz.openbmc_project.Logging.Rsyslog",
|
|
+ [asyncResp, path](const boost::system::error_code& ec1,
|
|
+ const dbus::utility::DBusPropertiesMap&
|
|
+ propertiesList) {
|
|
+ if (ec1)
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR(
|
|
+ "Error getting Rsyslog properties from {}: {}",
|
|
+ path, ec1.message());
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ return;
|
|
+ }
|
|
+ const std::string* addressType = nullptr;
|
|
+ const std::string* address = nullptr;
|
|
+ const std::string* protocolType = nullptr;
|
|
+ const uint16_t* ports = nullptr;
|
|
+ const bool* status = nullptr;
|
|
+
|
|
+ bool success = sdbusplus::unpackPropertiesNoThrow(
|
|
+ redfish::dbus_utils::UnpackErrorPrinter(),
|
|
+ propertiesList, "AddressType", addressType, "Address",
|
|
+ address, "ProtocolType", protocolType, "Port", ports,
|
|
+ "Status", status);
|
|
+ if (!success)
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("Unpack error!");
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ nlohmann::json::object_t obj;
|
|
+ if (addressType != nullptr)
|
|
+ {
|
|
+ obj["AddressType"] =
|
|
+ (*addressType) ==
|
|
+ "xyz.openbmc_project.Logging.Rsyslog.Type.IPv6"
|
|
+ ? "IPv6"
|
|
+ : "IPv4";
|
|
+ }
|
|
+ if (address != nullptr)
|
|
+ {
|
|
+ obj["Address"] = *address;
|
|
+ }
|
|
+ if (protocolType != nullptr)
|
|
+ {
|
|
+ obj["ProtocolType"] =
|
|
+ (*protocolType) ==
|
|
+ "xyz.openbmc_project.Logging.Rsyslog.Protocol.UDP"
|
|
+ ? "UDP"
|
|
+ : "TCP";
|
|
+ }
|
|
+ if (ports != nullptr)
|
|
+ {
|
|
+ obj["Port"] = *ports;
|
|
+ }
|
|
+ if (status != nullptr)
|
|
+ {
|
|
+ obj["Status"] = (*status) ? "Enabled" : "Disabled";
|
|
+ }
|
|
+ sdbusplus::message::object_path objectPath(path);
|
|
+ std::string rsyslogIndex =
|
|
+ rsyslogIndexTranslation.at(objectPath.filename());
|
|
+ if (path.starts_with(
|
|
+ "/xyz/openbmc_project/logging/rsyslog/audit_log/"))
|
|
+ {
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"]["AuditLog"]
|
|
+ [rsyslogIndex] = obj;
|
|
+ }
|
|
+ else if (
|
|
+ path.starts_with(
|
|
+ "/xyz/openbmc_project/logging/rsyslog/sel_log/"))
|
|
+ {
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"]["SEL"]
|
|
+ [rsyslogIndex] = obj;
|
|
+ }
|
|
+ else if (
|
|
+ path.starts_with(
|
|
+ "/xyz/openbmc_project/logging/rsyslog/sol_log/"))
|
|
+ {
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"]["SOL"]
|
|
+ [rsyslogIndex] = obj;
|
|
+ }
|
|
+ else if (
|
|
+ path.starts_with(
|
|
+ "/xyz/openbmc_project/logging/rsyslog/syslog_log/"))
|
|
+ {
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"]["Syslog"]
|
|
+ [rsyslogIndex] = obj;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("Can't find bmc D-Bus object!");
|
|
+ redfish::messages::internalError(asyncResp->res);
|
|
+ return;
|
|
+ }
|
|
+ });
|
|
+ }
|
|
+ },
|
|
+ "xyz.openbmc_project.ObjectMapper",
|
|
+ "/xyz/openbmc_project/object_mapper",
|
|
+ "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
|
|
+ "/xyz/openbmc_project/logging/rsyslog", 0,
|
|
+ std::array<const char*, 1>{"xyz.openbmc_project.Logging.Rsyslog"});
|
|
+ });
|
|
+
|
|
+ BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/Oem/Luxshare/RsyslogSettings/")
|
|
+ .privileges(redfish::privileges::privilegeSetConfigureComponents)
|
|
+ .methods(boost::beast::http::verb::patch)(
|
|
+ [&app](const crow::Request& req,
|
|
+ const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
|
|
+ if (!redfish::setUpRedfishRoute(app, req, asyncResp))
|
|
+ {
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ boost::asio::spawn(
|
|
+ crow::connections::systemBus->get_io_context(),
|
|
+ [asyncResp, &req](const boost::asio::yield_context& yield) {
|
|
+ std::optional<nlohmann::json> oemLuxshareObject;
|
|
+ using InputMap =
|
|
+ std::map<std::string, std::optional<nlohmann::json>>;
|
|
+ InputMap logTypeMap = {{"Syslog", std::nullopt},
|
|
+ {"SEL", std::nullopt},
|
|
+ {"AuditLog", std::nullopt},
|
|
+ {"SOL", std::nullopt}};
|
|
+ InputMap indexMap = {{"index0", std::nullopt},
|
|
+ {"index1", std::nullopt},
|
|
+ {"index2", std::nullopt},
|
|
+ {"index3", std::nullopt}};
|
|
+ std::optional<std::string> status;
|
|
+ std::optional<std::string> addressType;
|
|
+ std::optional<std::string> address;
|
|
+ std::optional<uint16_t> ports;
|
|
+ std::optional<std::string> protocolType;
|
|
+ const std::map<std::string, std::string> dbusLogType = {
|
|
+ {"Syslog", "syslog_log"},
|
|
+ {"SEL", "sel_log"},
|
|
+ {"AuditLog", "audit_log"},
|
|
+ {"SOL", "sol_log"}};
|
|
+
|
|
+ if (!redfish::json_util::readJsonPatch(
|
|
+ req, asyncResp->res, "Oem/Luxshare", oemLuxshareObject))
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("readJsonPatch error!");
|
|
+ return;
|
|
+ }
|
|
+ if (!redfish::json_util::readJson(
|
|
+ oemLuxshareObject.value(), asyncResp->res, "Syslog",
|
|
+ logTypeMap["Syslog"], "SEL", logTypeMap["SEL"], "AuditLog",
|
|
+ logTypeMap["AuditLog"], "SOL", logTypeMap["SOL"]))
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("readJsonPatch error!");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ for (auto& logType : logTypeMap)
|
|
+ {
|
|
+ if (logType.second)
|
|
+ {
|
|
+ if (!redfish::json_util::readJson(
|
|
+ logType.second.value(), asyncResp->res, "Index0",
|
|
+ indexMap["index0"], "Index1", indexMap["index1"],
|
|
+ "Index2", indexMap["index2"], "Index3",
|
|
+ indexMap["index3"]))
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("readJson error!");
|
|
+ return;
|
|
+ }
|
|
+ for (auto& index : indexMap)
|
|
+ {
|
|
+ if (index.second)
|
|
+ {
|
|
+ status.reset();
|
|
+ addressType.reset();
|
|
+ address.reset();
|
|
+ ports.reset();
|
|
+ protocolType.reset();
|
|
+
|
|
+ if (!redfish::json_util::readJson(
|
|
+ index.second.value(), asyncResp->res,
|
|
+ "Status", status, "AddressType",
|
|
+ addressType, "Address", address, "Port",
|
|
+ ports, "ProtocolType", protocolType))
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("readJson error!");
|
|
+ return;
|
|
+ }
|
|
+ std::string dbusObj =
|
|
+ "/xyz/openbmc_project/logging/rsyslog/" +
|
|
+ dbusLogType.at(logType.first) + "/" +
|
|
+ index.first;
|
|
+
|
|
+ if (status)
|
|
+ {
|
|
+ if ((*status) != "Enabled" &&
|
|
+ (*status) != "Disabled")
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("status error: {}",
|
|
+ *status);
|
|
+ redfish::messages::propertyValueNotInList(
|
|
+ asyncResp->res, *status, "Status");
|
|
+ return;
|
|
+ }
|
|
+
|
|
+ bool dbusStatus = (*status) == "Enabled";
|
|
+ setRsyslogSettingsHelper(yield, asyncResp,
|
|
+ dbusObj, "Status",
|
|
+ dbusStatus);
|
|
+ }
|
|
+ if (addressType || address)
|
|
+ {
|
|
+ std::string dbusAddressType;
|
|
+ std::string dbusAddress;
|
|
+ // get addressType
|
|
+ if (addressType)
|
|
+ {
|
|
+ if (*addressType == "IPv6")
|
|
+ {
|
|
+ dbusAddressType =
|
|
+ "xyz.openbmc_project.Logging.Rsyslog.Type.IPv6";
|
|
+ }
|
|
+ else if (*addressType == "IPv4")
|
|
+ {
|
|
+ dbusAddressType =
|
|
+ "xyz.openbmc_project.Logging.Rsyslog.Type.IPv4";
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR(
|
|
+ "addresstype error: {}",
|
|
+ *addressType);
|
|
+ redfish::messages::
|
|
+ propertyValueNotInList(
|
|
+ asyncResp->res, *addressType,
|
|
+ "AddressType");
|
|
+ return;
|
|
+ }
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ dbusAddressType = getRsyslogSettingsHelper(
|
|
+ yield, asyncResp, dbusObj,
|
|
+ "AddressType");
|
|
+ }
|
|
+ // get address
|
|
+ if (address)
|
|
+ {
|
|
+ dbusAddress = *address;
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ dbusAddress = getRsyslogSettingsHelper(
|
|
+ yield, asyncResp, dbusObj, "Address");
|
|
+ }
|
|
+ // check if addressType and address is
|
|
+ // conflicted
|
|
+ if (!checkAddressTypeAndAddress(dbusAddressType,
|
|
+ dbusAddress))
|
|
+ {
|
|
+ BMCWEB_LOG_DEBUG(
|
|
+ "AddressType and address is conflicted");
|
|
+ redfish::messages::invalidObject(
|
|
+ asyncResp->res, "Address");
|
|
+ return;
|
|
+ }
|
|
+ // set addressType
|
|
+ if (addressType)
|
|
+ {
|
|
+ setRsyslogSettingsHelper(
|
|
+ yield, asyncResp, dbusObj,
|
|
+ "AddressType", dbusAddressType);
|
|
+ }
|
|
+ // set address
|
|
+ if (address)
|
|
+ {
|
|
+ setRsyslogSettingsHelper(yield, asyncResp,
|
|
+ dbusObj, "Address",
|
|
+ *address);
|
|
+ }
|
|
+ }
|
|
+ if (ports)
|
|
+ {
|
|
+ setRsyslogSettingsHelper(
|
|
+ yield, asyncResp, dbusObj, "Port", *ports);
|
|
+ }
|
|
+ if (protocolType)
|
|
+ {
|
|
+ std::string dbusProtocolType;
|
|
+ if (*protocolType == "UDP")
|
|
+ {
|
|
+ dbusProtocolType =
|
|
+ "xyz.openbmc_project.Logging.Rsyslog.Protocol.UDP";
|
|
+ }
|
|
+ else if (*protocolType == "TCP")
|
|
+ {
|
|
+ dbusProtocolType =
|
|
+ "xyz.openbmc_project.Logging.Rsyslog.Protocol.TCP";
|
|
+ }
|
|
+ else
|
|
+ {
|
|
+ BMCWEB_LOG_ERROR("protocolType error: {}",
|
|
+ *protocolType);
|
|
+ redfish::messages::propertyValueNotInList(
|
|
+ asyncResp->res, *protocolType,
|
|
+ "ProtocolType");
|
|
+ return;
|
|
+ }
|
|
+ setRsyslogSettingsHelper(
|
|
+ yield, asyncResp, dbusObj, "ProtocolType",
|
|
+ dbusProtocolType);
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ }
|
|
+ });
|
|
+ });
|
|
+}
|
|
+
|
|
+inline void requestRoutes(App& app)
|
|
+{
|
|
+ requestRoutesOemLuxshareRsyslogSettings(app);
|
|
+}
|
|
+
|
|
+} // namespace luxshare_dump_api
|
|
+} // namespace crow
|
|
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
|
|
index 05b8c292..7efe0335 100644
|
|
--- a/redfish-core/lib/managers.hpp
|
|
+++ b/redfish-core/lib/managers.hpp
|
|
@@ -2106,6 +2106,10 @@ inline void requestRoutesManager(App& app)
|
|
|
|
sw_util::populateSoftwareInformation(asyncResp, sw_util::bmcPurpose,
|
|
"FirmwareVersion", true);
|
|
+ nlohmann::json& luxshareOemObject =
|
|
+ asyncResp->res.jsonValue["Oem"]["Luxshare"];
|
|
+ luxshareOemObject["RsyslogSettings"]["@odata.id"] =
|
|
+ "/redfish/v1/Managers/bmc/Oem/Luxshare/RsyslogSettings";
|
|
|
|
managerGetLastResetTime(asyncResp);
|
|
|
|
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
|
|
index f4f43254..9edb9b78 100644
|
|
--- a/src/webserver_main.cpp
|
|
+++ b/src/webserver_main.cpp
|
|
@@ -30,6 +30,7 @@
|
|
|
|
#include <luxshare/sel.hpp>
|
|
#include <luxshare/firmware_update.hpp>
|
|
+#include <luxshare/dump.hpp>
|
|
|
|
#include <exception>
|
|
#include <memory>
|
|
@@ -122,6 +123,7 @@ static int run()
|
|
#ifdef BMCWEB_ENABLE_LUXSHARE_API
|
|
crow::luxshare_sel_api::requestRoutes(app);
|
|
crow::luxshare_update_firmware::requestRoutes(app);
|
|
+ crow::luxshare_dump_api::requestRoutes(app);
|
|
#endif
|
|
|
|
if (bmcwebInsecureDisableXssPrevention != 0)
|
|
--
|
|
2.25.1
|
|
|