diff --git a/redfish-core/include/redfish_aggregator.hpp b/redfish-core/include/redfish_aggregator.hpp index 00c6e5590..ad61deaa6 100644 --- a/redfish-core/include/redfish_aggregator.hpp +++ b/redfish-core/include/redfish_aggregator.hpp @@ -450,15 +450,8 @@ class RedfishAggregator BMCWEB_LOG_DEBUG("Found Satellite Controller at {}", objectPath.first.str); - if (!satelliteInfo.empty()) - { - BMCWEB_LOG_ERROR( - "Redfish Aggregation only supports one satellite!"); - BMCWEB_LOG_DEBUG("Clearing all satellite data"); - satelliteInfo.clear(); - return; - } - + // For now assume there will only be one satellite config. + // Assign it the name/prefix "5B247A" addSatelliteConfig(interface.second, satelliteInfo); } } @@ -473,7 +466,6 @@ class RedfishAggregator { boost::urls::url url; std::string prefix; - for (const auto& prop : properties) { if (prop.first == "Hostname") @@ -517,14 +509,21 @@ class RedfishAggregator // For now assume authentication not required to communicate // with the satellite BMC - if (*propVal != "None") + if (*propVal == "None") + { + url.set_scheme("http"); + } + else if (*propVal == "MTLS") + { + url.set_scheme("https"); + } + else { BMCWEB_LOG_ERROR( - "Unsupported AuthType value: {}, only \"none\" is supported", + R"(Unsupported AuthType value: {} , only "none" "MTLS" is supported)", *propVal); return; } - url.set_scheme("http"); } else if (prop.first == "Name") { @@ -608,22 +607,11 @@ class RedfishAggregator } } - // Create a copy of thisReq so we we can still locally process the req - std::error_code ec; auto localReq = std::make_shared(thisReq.copy()); - if (ec) - { - BMCWEB_LOG_ERROR("Failed to create copy of request"); - if (aggType == AggregationType::Resource) - { - messages::internalError(asyncResp->res); - } - return; - } - + localReq->addHeader("X-Forwarded-For", "bmcweb"); + boost::urls::url& urlNew = localReq->url(); if (aggType == AggregationType::Collection) { - boost::urls::url& urlNew = localReq->url(); auto paramsIt = urlNew.params().begin(); while (paramsIt != urlNew.params().end()) { @@ -647,9 +635,8 @@ class RedfishAggregator // Pass all other parameters paramsIt++; } - localReq->target(urlNew.buffer()); } - + localReq->target(urlNew.buffer()); getSatelliteConfigs( std::bind_front(aggregateAndHandle, aggType, localReq, asyncResp)); } @@ -995,9 +982,10 @@ class RedfishAggregator if ((resp.result() == boost::beast::http::status::too_many_requests) || (resp.result() == boost::beast::http::status::bad_gateway)) { + BMCWEB_LOG_DEBUG("Connection to satellite \"{}\" failed", prefix); return; } - + BMCWEB_LOG_DEBUG("Connection to satellite \"{}\" succeded", prefix); if (resp.resultInt() != 200) { BMCWEB_LOG_DEBUG( @@ -1268,7 +1256,20 @@ class RedfishAggregator using crow::utility::OrMorePaths; using crow::utility::readUrlSegments; boost::urls::url_view url = thisReq.url(); - + BMCWEB_LOG_DEBUG("Checking if aggregation is required for {}", + thisReq.target().data()); + // keeping forwarded for bmcweb right now. This is sufficient for fully + // connected bmc topology for mutual aggression and deduplication. + // The property can be enhanced to support for different bmc topologies + // in future. + auto forwardedHeader = thisReq.getHeaderValue("X-Forwarded-For"); + if (!forwardedHeader.empty() && forwardedHeader == "bmcweb") + { + BMCWEB_LOG_DEBUG( + "Already handled reqest, skipping remote aggregation"); + return Result::LocalHandle; + } + BMCWEB_LOG_DEBUG("Begin aggregation"); // We don't need to aggregate JsonSchemas due to potential issues such // as version mismatches between aggregator and satellite BMCs. For // now assume that the aggregator has all the schemas and versions that @@ -1311,7 +1312,7 @@ class RedfishAggregator // satellites due to // /redfish/v1/AggregationService/AggregationSources/5B247A // being a local resource describing the satellite - if (collectionItem.starts_with("5B247A_")) + if (segmentHasPrefix(collectionItem)) { BMCWEB_LOG_DEBUG("Need to forward a request"); @@ -1362,6 +1363,32 @@ class RedfishAggregator BMCWEB_LOG_DEBUG("Aggregation not required for {}", url.buffer()); return Result::LocalHandle; } + + // Check if the given URL segment matches with any satellite prefix + // Assumes the given segment starts with _ + static bool segmentHasPrefix(const std::string& urlSegment) + { + // TODO: handle this better + // For now 5B247A_ wont be in the aggregationSources map so + // check explicitly for now + if (urlSegment.starts_with("5B247A_")) + { + return true; + } + + // Find the first underscore + std::size_t underscorePos = urlSegment.find('_'); + if (underscorePos == std::string::npos) + { + return false; // No underscore, can't be a satellite prefix + } + return true; + // // Extract the prefix + // std::string prefix = urlSegment.substr(0, underscorePos); + + // // Check if this prefix exists + // return aggregationSources.contains(prefix); + } }; } // namespace redfish