summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--meson.build3
-rw-r--r--meson_options.txt8
-rw-r--r--redfish-core/include/redfish_aggregator.hpp228
-rw-r--r--src/webserver_main.cpp9
4 files changed, 247 insertions, 1 deletions
diff --git a/meson.build b/meson.build
index d81270fa07..054b35fae0 100644
--- a/meson.build
+++ b/meson.build
@@ -72,6 +72,7 @@ feature_map = {
'insecure-tftp-update' : '-DBMCWEB_INSECURE_ENABLE_REDFISH_FW_TFTP_UPDATE',
'kvm' : '-DBMCWEB_ENABLE_KVM' ,
'mutual-tls-auth' : '-DBMCWEB_ENABLE_MUTUAL_TLS_AUTHENTICATION',
+ 'redfish-aggregation' : '-DBMCWEB_ENABLE_REDFISH_AGGREGATION',
'redfish-allow-deprecated-power-thermal' : '-DBMCWEB_ALLOW_DEPRECATED_POWER_THERMAL',
'redfish-bmc-journal' : '-DBMCWEB_ENABLE_REDFISH_BMC_JOURNAL',
'redfish-cpu-log' : '-DBMCWEB_ENABLE_REDFISH_CPU_LOG',
@@ -313,6 +314,8 @@ xss_enabled = get_option('insecure-disable-xss')
conf_data.set10('BMCWEB_INSECURE_DISABLE_XSS_PREVENTION', xss_enabled.enabled())
enable_redfish_query = get_option('insecure-enable-redfish-query')
conf_data.set10('BMCWEB_INSECURE_ENABLE_QUERY_PARAMS', enable_redfish_query.enabled())
+# enable_redfish_aggregation = get_option('redfish-aggregation')
+# conf_data.set10('BMCWEB_ENABLE_REDFISH_AGGREGATION', enable_redfish_aggregation.enabled())
insecure_push_style_notification = get_option('insecure-push-style-notification')
conf_data.set10('BMCWEB_INSECURE_ENABLE_HTTP_PUSH_STYLE_EVENTING', insecure_push_style_notification.enabled())
conf_data.set('MESON_INSTALL_PREFIX', get_option('prefix'))
diff --git a/meson_options.txt b/meson_options.txt
index f2b4f377ca..c81f185fd8 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -223,7 +223,6 @@ option(
Option will be removed Q4 2022.'''
)
-
option(
'https_port',
type: 'integer',
@@ -233,6 +232,13 @@ option(
description: 'HTTPS Port number.'
)
+option(
+ 'redfish-aggregation',
+ type: 'feature',
+ value: 'disabled',
+ description: 'Allows this BMC to aggregate resources from satellite BMCs'
+)
+
# Insecure options. Every option that starts with a `insecure` flag should
# not be enabled by default for any platform, unless the author fully comprehends
# the implications of doing so.In general, enabling these options will cause security
diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp
new file mode 100644
index 0000000000..d076c6c1ea
--- /dev/null
+++ b/redfish-core/include/redfish_aggregator.hpp
@@ -0,0 +1,228 @@
+#pragma once
+
+#include <http_client.hpp>
+
+namespace redfish
+{
+
+class RedfishAggregator
+{
+ private:
+ RedfishAggregator()
+ {
+ getSatelliteConfigs(constructorCallback);
+ }
+
+ // Dummy callback used by the Constructor so that it can report the number
+ // of satellite configs when the class is first created
+ static void constructorCallback(
+ const std::unordered_map<std::string, boost::urls::url>& satelliteInfo)
+ {
+ BMCWEB_LOG_DEBUG << "There were "
+ << std::to_string(satelliteInfo.size())
+ << " satellite configs found at startup";
+ }
+
+ // Polls D-Bus to get all available satellite config information
+ // Expects a handler which interacts with the returned configs
+ static void getSatelliteConfigs(
+ const std::function<void(
+ const std::unordered_map<std::string, boost::urls::url>&)>& handler)
+ {
+ BMCWEB_LOG_DEBUG << "Gathering satellite configs";
+ crow::connections::systemBus->async_method_call(
+ [handler](const boost::system::error_code ec,
+ const dbus::utility::ManagedObjectType& objects) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR << "DBUS response error " << ec.value()
+ << ", " << ec.message();
+ return;
+ }
+
+ // Maps a chosen alias representing a satellite BMC to a url
+ // containing the information required to create a http
+ // connection to the satellite
+ std::unordered_map<std::string, boost::urls::url> satelliteInfo;
+
+ findSatelliteConfigs(objects, satelliteInfo);
+
+ if (!satelliteInfo.empty())
+ {
+ BMCWEB_LOG_DEBUG << "Redfish Aggregation enabled with "
+ << std::to_string(satelliteInfo.size())
+ << " satellite BMCs";
+ }
+ else
+ {
+ BMCWEB_LOG_DEBUG
+ << "No satellite BMCs detected. Redfish Aggregation not enabled";
+ }
+ handler(satelliteInfo);
+ },
+ "xyz.openbmc_project.EntityManager", "/",
+ "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
+ }
+
+ // Search D-Bus objects for satellite config objects and add their
+ // information if valid
+ static void findSatelliteConfigs(
+ const dbus::utility::ManagedObjectType& objects,
+ std::unordered_map<std::string, boost::urls::url>& satelliteInfo)
+ {
+ for (const auto& objectPath : objects)
+ {
+ for (const auto& interface : objectPath.second)
+ {
+ if (interface.first ==
+ "xyz.openbmc_project.Configuration.SatelliteController")
+ {
+ BMCWEB_LOG_DEBUG << "Found Satellite Controller at "
+ << objectPath.first.str;
+
+ addSatelliteConfig(interface.second, satelliteInfo);
+ }
+ }
+ }
+ }
+
+ // Parse the properties of a satellite config object and add the
+ // configuration if the properties are valid
+ static void addSatelliteConfig(
+ const dbus::utility::DBusPropertiesMap& properties,
+ std::unordered_map<std::string, boost::urls::url>& satelliteInfo)
+ {
+ boost::urls::url url;
+ std::string name;
+
+ for (const auto& prop : properties)
+ {
+ if (prop.first == "Name")
+ {
+ const std::string* propVal =
+ std::get_if<std::string>(&prop.second);
+ if (propVal == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Invalid Name value";
+ return;
+ }
+
+ // The IDs will become <Name>_<ID> so the name should not
+ // contain a '_'
+ if (propVal->find('_') != std::string::npos)
+ {
+ BMCWEB_LOG_ERROR << "Name cannot contain a \"_\"";
+ return;
+ }
+ name = *propVal;
+ }
+
+ else if (prop.first == "Hostname")
+ {
+ const std::string* propVal =
+ std::get_if<std::string>(&prop.second);
+ if (propVal == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Invalid Hostname value";
+ return;
+ }
+ url.set_host(*propVal);
+ }
+
+ else if (prop.first == "Port")
+ {
+ const uint64_t* propVal = std::get_if<uint64_t>(&prop.second);
+ if (propVal == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Invalid Port value";
+ return;
+ }
+
+ if (*propVal > std::numeric_limits<uint16_t>::max())
+ {
+ BMCWEB_LOG_ERROR << "Port value out of range";
+ return;
+ }
+ url.set_port(static_cast<uint16_t>(*propVal));
+ }
+
+ else if (prop.first == "AuthType")
+ {
+ const std::string* propVal =
+ std::get_if<std::string>(&prop.second);
+ if (propVal == nullptr)
+ {
+ BMCWEB_LOG_ERROR << "Invalid AuthType value";
+ return;
+ }
+
+ // For now assume authentication not required to communicate
+ // with the satellite BMC
+ if (*propVal != "None")
+ {
+ BMCWEB_LOG_ERROR
+ << "Unsupported AuthType value: " << *propVal
+ << ", only \"none\" is supported";
+ return;
+ }
+ url.set_scheme("http");
+ }
+ } // Finished reading properties
+
+ // Make sure all required config information was made available
+ if (name.empty())
+ {
+ BMCWEB_LOG_ERROR << "Satellite config missing Name";
+ return;
+ }
+
+ if (url.host().empty())
+ {
+ BMCWEB_LOG_ERROR << "Satellite config " << name << " missing Host";
+ return;
+ }
+
+ if (!url.has_port())
+ {
+ BMCWEB_LOG_ERROR << "Satellite config " << name << " missing Port";
+ return;
+ }
+
+ if (!url.has_scheme())
+ {
+ BMCWEB_LOG_ERROR << "Satellite config " << name
+ << " missing AuthType";
+ return;
+ }
+
+ std::string resultString;
+ auto result = satelliteInfo.insert_or_assign(name, std::move(url));
+ if (result.second)
+ {
+ resultString = "Added new satellite config ";
+ }
+ else
+ {
+ resultString = "Updated existing satellite config ";
+ }
+
+ BMCWEB_LOG_DEBUG << resultString << name << " at "
+ << result.first->second.scheme() << "://"
+ << result.first->second.encoded_host_and_port();
+ }
+
+ public:
+ RedfishAggregator(const RedfishAggregator&) = delete;
+ RedfishAggregator& operator=(const RedfishAggregator&) = delete;
+ RedfishAggregator(RedfishAggregator&&) = delete;
+ RedfishAggregator& operator=(RedfishAggregator&&) = delete;
+ ~RedfishAggregator() = default;
+
+ static RedfishAggregator& getInstance()
+ {
+ static RedfishAggregator handler;
+ return handler;
+ }
+};
+
+} // namespace redfish
diff --git a/src/webserver_main.cpp b/src/webserver_main.cpp
index 6bdce98163..9d2aa8a13d 100644
--- a/src/webserver_main.cpp
+++ b/src/webserver_main.cpp
@@ -15,6 +15,7 @@
#include <obmc_console.hpp>
#include <openbmc_dbus_rest.hpp>
#include <redfish.hpp>
+#include <redfish_aggregator.hpp>
#include <redfish_v1.hpp>
#include <sdbusplus/asio/connection.hpp>
#include <sdbusplus/bus.hpp>
@@ -86,8 +87,16 @@ static int run()
redfish::requestRoutes(app);
redfish::RedfishService redfish(app);
+ // Create HttpClient instance and initialize Config
+ crow::HttpClient::getInstance();
+
// Create EventServiceManager instance and initialize Config
redfish::EventServiceManager::getInstance();
+
+#ifdef BMCWEB_ENABLE_REDFISH_AGGREGATION
+ // Create RedfishAggregator instance and initialize Config
+ redfish::RedfishAggregator::getInstance();
+#endif
#endif
#ifdef BMCWEB_ENABLE_DBUS_REST