Support injecting PhysicalLocation instead of Location in Redfish devpath injector This change adds a use_physical_location option to the Redfish expose configuration. When enabled, the injector writes location properties to the "PhysicalLocation" field instead of "Location". Google-Bug-Id:511148872 PiperOrigin-RevId: 978192791 Change-Id: I13cba09751e4b43518230eb1e9750e3b81454788
diff --git a/devpath_plugin/redfish_devpath_injector.cpp b/devpath_plugin/redfish_devpath_injector.cpp index 97e6673..fbd287c 100644 --- a/devpath_plugin/redfish_devpath_injector.cpp +++ b/devpath_plugin/redfish_devpath_injector.cpp
@@ -99,24 +99,29 @@ milotic_tlbmc::StableId stable_id = milotic_tlbmc::GetStableId( location_context, /*root_chassis_location_code=*/""); - nlohmann::json& json = res.jsonValue; + std::string_view location_key = + value->redfish_expose_config.use_physical_location() ? "PhysicalLocation" + : "Location"; + nlohmann::json& location_json = res.jsonValue[location_key]; - json["Location"]["PartLocation"]["ServiceLabel"] = stable_id.service_label(); + location_json["PartLocation"]["ServiceLabel"] = stable_id.service_label(); if (value->redfish_expose_config.set_plc_as_placeholder()) { - json["Location"]["PartLocationContext"] = "PlaceholderAndShouldNotBeUsed"; + location_json["PartLocationContext"] = "PlaceholderAndShouldNotBeUsed"; } else if (stable_id.has_part_location_context() && !stable_id.part_location_context().empty()) { - json["Location"]["PartLocationContext"] = stable_id.part_location_context(); + location_json["PartLocationContext"] = stable_id.part_location_context(); + } else { + location_json.erase("PartLocationContext"); } if (value->redfish_expose_config.expose_oem_google_devpath()) { - json["Location"]["Oem"]["Google"]["Devpath"] = barepath; + location_json["Oem"]["Google"]["Devpath"] = barepath; } if (stable_id.has_embedded_location_context() && !stable_id.embedded_location_context().empty()) { - json["Location"]["Oem"]["Google"]["EmbeddedLocationContext"] = + location_json["Oem"]["Google"]["EmbeddedLocationContext"] = stable_id.embedded_location_context(); } }
diff --git a/devpath_plugin/redfish_to_uhm_mapping.proto b/devpath_plugin/redfish_to_uhm_mapping.proto index 45c6feb..0fec16e 100644 --- a/devpath_plugin/redfish_to_uhm_mapping.proto +++ b/devpath_plugin/redfish_to_uhm_mapping.proto
@@ -29,6 +29,7 @@ bool expose_oem_google_devpath = 1; bool set_plc_as_placeholder = 2; string embedded_location_context = 3; + bool use_physical_location = 4; } // Individual Redfish to UHM entry.
diff --git a/test/devpath_plugin/redfish_devpath_injector_test.cpp b/test/devpath_plugin/redfish_devpath_injector_test.cpp index b58c17c..cc449b9 100644 --- a/test/devpath_plugin/redfish_devpath_injector_test.cpp +++ b/test/devpath_plugin/redfish_devpath_injector_test.cpp
@@ -98,6 +98,15 @@ set_plc_as_placeholder: false } } + redfish_to_uhm_mapping { + key { redfish_url_pattern: "/redfish/v1/Chassis/ChassisA/Drives/Drive0" } + uhm_monitored_component_key { barepath: "/phys/BoardA/SLOT0" } + redfish_expose_config { + expose_oem_google_devpath: true + set_plc_as_placeholder: false + use_physical_location: true + } + } )pb"; std::string config_path = WriteTmpFile("injectable_config.textproto", config_content); @@ -153,6 +162,129 @@ EXPECT_EQ(json["Location"]["PartLocation"]["ServiceLabel"], "BoardA"); EXPECT_FALSE(json["Location"].contains("PartLocationContext")); } + + // Test Component 4 with use_physical_location enabled + { + crow::Request req = + CreateRequest("/redfish/v1/Chassis/ChassisA/Drives/Drive0"); + crow::Response res; + res.result(boost::beast::http::status::ok); + + (*injector)->Inject(req, res); + + EXPECT_EQ(res.jsonValue, nlohmann::json::parse(R"json( + { + "PhysicalLocation": { + "Oem": { + "Google": { + "Devpath": "/phys/BoardA/SLOT0" + } + }, + "PartLocation": { + "ServiceLabel": "SLOT0" + }, + "PartLocationContext": "BoardA" + } + } + )json")); + } +} + +TEST(RedfishDevpathInjectorTest, + InjectPhysicalLocationOverridesPreexistingFields) { + std::string config_content = R"pb( + redfish_to_uhm_mapping { + key { redfish_url_pattern: "/redfish/v1/Chassis/ChassisA/Drives/Drive1" } + uhm_monitored_component_key { barepath: "/phys/HPM0/DOWNLINK/PE1A/SLOT2" } + redfish_expose_config { + expose_oem_google_devpath: true + set_plc_as_placeholder: false + use_physical_location: true + } + } + redfish_to_uhm_mapping { + key { redfish_url_pattern: "/redfish/v1/Chassis/ChassisA/Drives/Drive2" } + uhm_monitored_component_key { barepath: "/phys/SLOT0" } + redfish_expose_config { + expose_oem_google_devpath: false + set_plc_as_placeholder: false + use_physical_location: true + } + } + )pb"; + std::string config_path = + WriteTmpFile("override_config.textproto", config_content); + + absl::StatusOr<std::unique_ptr<RedfishDevpathInjector>> injector = + RedfishDevpathInjector::Create(config_path); + ASSERT_OK(injector.status()); + + // Case 1: Pre-existing wrong Devpath and placeholder PLC from handler are + // overwritten when expose_oem_google_devpath is true. + { + crow::Request req = + CreateRequest("/redfish/v1/Chassis/ChassisA/Drives/Drive1"); + crow::Response res; + res.result(boost::beast::http::status::ok); + res.jsonValue = nlohmann::json::parse(R"json( + { + "PhysicalLocation": { + "Oem": { + "Google": { + "Devpath": "/phys/HPM0/DOWNLINK/PE1A/DOWNLINK" + } + }, + "PartLocationContext": "PlaceHolderAndShouldNotBeUsed" + } + } + )json"); + + (*injector)->Inject(req, res); + + EXPECT_EQ(res.jsonValue, nlohmann::json::parse(R"json( + { + "PhysicalLocation": { + "Oem": { + "Google": { + "Devpath": "/phys/HPM0/DOWNLINK/PE1A/SLOT2" + } + }, + "PartLocation": { + "ServiceLabel": "SLOT2" + }, + "PartLocationContext": "HPM0/DOWNLINK/PE1A" + } + } + )json")); + } + + // Case 2: Pre-existing placeholder PLC is erased when part_location_context + // is empty and set_plc_as_placeholder is false. + { + crow::Request req = + CreateRequest("/redfish/v1/Chassis/ChassisA/Drives/Drive2"); + crow::Response res; + res.result(boost::beast::http::status::ok); + res.jsonValue = nlohmann::json::parse(R"json( + { + "PhysicalLocation": { + "PartLocationContext": "PlaceHolderAndShouldNotBeUsed" + } + } + )json"); + + (*injector)->Inject(req, res); + + EXPECT_EQ(res.jsonValue, nlohmann::json::parse(R"json( + { + "PhysicalLocation": { + "PartLocation": { + "ServiceLabel": "SLOT0" + } + } + } + )json")); + } } TEST(RedfishDevpathInjectorTest, InjectNonGetRequestReturnsNoOp) {