| #include "redfish_devpath_injector.hpp" |
| |
| #include <fstream> |
| #include <memory> |
| #include <sstream> |
| #include <string> |
| #include <string_view> |
| |
| #include "absl/status/status.h" |
| #include "absl/status/statusor.h" |
| #include "absl/strings/str_cat.h" |
| #include "boost/beast/http/status.hpp" // NOLINT |
| #include "boost/beast/http/verb.hpp" // NOLINT |
| #include "g3/macros.h" |
| #include "redfish_to_uhm_mapping.pb.h" |
| #include "redfish_to_uhm_mapping_value.hpp" |
| #include "http_request.hpp" |
| |
| #include <nlohmann/json.hpp> |
| #include "topology_config.pb.h" |
| #include "tlbmc/redfish/data/stable_id.h" |
| #include "stable_id.pb.h" |
| #include "google/protobuf/text_format.h" |
| |
| namespace devpath_plugin { |
| |
| namespace { |
| |
| absl::StatusOr<std::string> ReadFileToString(std::string_view path) { |
| std::ifstream input(std::string{path}); |
| if (!input.is_open()) { |
| return absl::NotFoundError( |
| absl::StrCat("Failed to open RedfishToUhmMapping file at: ", path)); |
| } |
| std::stringstream buffer; |
| buffer << input.rdbuf(); |
| return buffer.str(); |
| } |
| |
| } // namespace |
| |
| absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> |
| RedfishDevpathInjector::Create(std::string_view mapping_config_path) { |
| ECCLESIA_ASSIGN_OR_RETURN(std::string config_content, |
| ReadFileToString(mapping_config_path)); |
| |
| RedfishToUhmMappingConfig config; |
| if (!google::protobuf::TextFormat::ParseFromString(config_content, &config)) { |
| return absl::InvalidArgumentError(absl::StrCat( |
| "Failed to parse RedfishToUhmMappingConfig textproto from: ", |
| mapping_config_path)); |
| } |
| |
| // new keyword required to access private constructor |
| std::unique_ptr<RedfishDevpathInjector> injector( |
| new RedfishDevpathInjector()); |
| for (const RedfishToUhmMapping& mapping : config.redfish_to_uhm_mapping()) { |
| std::shared_ptr<RedfishToUhmMappingValue> value = |
| std::make_shared<RedfishToUhmMappingValue>(); |
| value->uhm_monitored_component_key = mapping.uhm_monitored_component_key(); |
| value->redfish_expose_config = mapping.redfish_expose_config(); |
| |
| injector->trie_.Insert(mapping.key(), value); |
| } |
| |
| return injector; |
| } |
| |
| |
| void RedfishDevpathInjector::Inject( |
| const crow::Request& req, |
| crow::Response& res) const { |
| // No-op if response is not successful. |
| if (res.result() != boost::beast::http::status::ok) { |
| return; |
| } |
| // Only modify GET requests. |
| if (req.method() != boost::beast::http::verb::get) { |
| return; |
| } |
| |
| Key lookup_key; |
| lookup_key.set_redfish_url_pattern(std::string(req.url().path())); |
| |
| std::shared_ptr<const RedfishToUhmMappingValue> value = |
| trie_.GetMappingFromUrl(lookup_key); |
| if (value == nullptr) { |
| return; |
| } |
| |
| std::string_view barepath = value->uhm_monitored_component_key.barepath(); |
| |
| milotic_tlbmc::LocationContext location_context; |
| location_context.set_devpath(std::string(barepath)); |
| if (!value->redfish_expose_config.embedded_location_context().empty()) { |
| location_context.add_logical_identifiers( |
| value->redfish_expose_config.embedded_location_context()); |
| } |
| milotic_tlbmc::StableId stable_id = milotic_tlbmc::GetStableId( |
| location_context, /*root_chassis_location_code=*/""); |
| |
| nlohmann::json& json = res.jsonValue; |
| |
| json["Location"]["PartLocation"]["ServiceLabel"] = stable_id.service_label(); |
| |
| if (value->redfish_expose_config.set_plc_as_placeholder()) { |
| json["Location"]["PartLocationContext"] = "PlaceholderAndShouldNotBeUsed"; |
| } else if (stable_id.has_part_location_context() && |
| !stable_id.part_location_context().empty()) { |
| json["Location"]["PartLocationContext"] = stable_id.part_location_context(); |
| } |
| |
| if (value->redfish_expose_config.expose_oem_google_devpath()) { |
| json["Location"]["Oem"]["Google"]["Devpath"] = barepath; |
| } |
| |
| if (stable_id.has_embedded_location_context() && |
| !stable_id.embedded_location_context().empty()) { |
| json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"] = |
| stable_id.embedded_location_context(); |
| } |
| } |
| |
| } // namespace devpath_plugin |