summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarson Labrado <clabrado@google.com>2022-04-19 02:26:56 +0300
committerEd Tanous <ed@tanous.net>2022-05-23 22:20:39 +0300
commit7fb33566cfccc26694e95b2c3601eb477359c54a (patch)
tree746b313b0c3615ae225d5224ed8a962fae34aa18
parent3a097b2cf6260b7accfb42930b73589655ee4e2b (diff)
downloadbmcweb-7fb33566cfccc26694e95b2c3601eb477359c54a.tar.xz
bmcweb: Fetch Satellite Config from D-Bus
Adds a RedfishAggregator class which is able to pull configuration information from D-Bus for Satellite BMCs. These BMCs will be aggregated by Redfish Aggregation. Also added is a new compiler option which will be used to enable Redfish Aggregation. This patch only allows configurations with unencrypted and unauthenticated satellite BMC communication. Support for encryption and authentication willneed to be added in future patches. Note that this patch does not actually use the config information after it has been fetched. That functionality will be added in future patches. Tested: I made this example config information available on D-Bus busctl introspect xyz.openbmc_project.EntityManager \ /xyz/openbmc_project/inventory/system/board/SatelliteBMC/aggregated0 \ xyz.openbmc_project.Configuration.SatelliteController NAME TYPE SIGNATURE RESULT/VALUE FLAGS .AuthType property s "None" emits-change .Hostname property s "127.0.0.1" emits-change .Name property s "aggregated0" emits-change .Port property t 443 emits-change .Type property s "SatelliteController" emits-change That information was picked up by the changes in this CL: [DEBUG "redfish_aggregator.hpp":80] Found Satellite Controller at /xyz/openbmc_project/inventory/system/board/SatelliteBMC/aggregated0 [DEBUG "redfish_aggregator.hpp":209] Added satellite config aggregated0 at http://127.0.0.1:443 [DEBUG "redfish_aggregator.hpp":52] Redfish Aggregation enabled with 1 satellite BMCs [DEBUG "redfish_aggregator.hpp":21] There were 1 satellite configs found at startup Signed-off-by: Carson Labrado <clabrado@google.com> Change-Id: Ib5eee2c93aeb209157191055975c127759d73627
-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