bmcweb: Implement single Redfish "system" endpoint
This commit changes the redfish behavior to move to a single, known name
under the /redfish/v1/Systems/system path. This is advantageous for a
lot of reasons.
1. Lots fewer dbus calls to determine the system name for every path.
This could be optimized in other ways, like checking the system name on
startup, but because redfish paths are not intended to be informative,
this patchset takes the opinion that less code is better.
2. Lots of lowered complexity, given that each endpoint underneath
/system doesn't need an individual "does this system exist, and is the
name right" check.
3. This makes it possible to correctly implement the "Links" property in
Chassis, which is required for the OCP base server profile
Tested By:
Very minimal testing done, but it seems to pass the validator.
Change-Id: Iea3cb5081b92a3843b6877decd009936de00561c
Signed-off-by: Ed Tanous <ed.tanous@intel.com>
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/redfish-core/lib/chassis.hpp b/redfish-core/lib/chassis.hpp
index fd03c8f..821c7b3 100644
--- a/redfish-core/lib/chassis.hpp
+++ b/redfish-core/lib/chassis.hpp
@@ -218,18 +218,16 @@
asyncResp->res.jsonValue["Power"] = {
{"@odata.id", "/redfish/v1/Chassis/" +
chassisId + "/Power"}};
+ asyncResp->res.jsonValue["Status"] = {
+ {"Health", "OK"},
+ {"State", "Enabled"},
+ };
- // TODO: An array of references to computer systems
- // contained in this chassis.
- // res.jsonValue["Links"]["ComputerSystems"]
- // =
- // {{{"@odata.id",
- // "/redfish/v1/Systems/1"}}};
- // An array of references to the Managers
- // responsible for managing this chassis.
- // res.jsonValue["Links"]["ManagedBy"] =
- // {{{"@odata.id",
- // "/redfish/v1/Managers/1"}}};
+ asyncResp->res
+ .jsonValue["Links"]["ComputerSystems"] = {
+ {{"@odata.id", "/redfish/v1/Systems/system"}}};
+ asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
+ {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
},
connectionName, path, "org.freedesktop.DBus.Properties",
"GetAll",
diff --git a/redfish-core/lib/cpudimm.hpp b/redfish-core/lib/cpudimm.hpp
index 1719fc8..4245595 100644
--- a/redfish-core/lib/cpudimm.hpp
+++ b/redfish-core/lib/cpudimm.hpp
@@ -23,13 +23,13 @@
namespace redfish
{
-void getResourceList(std::shared_ptr<AsyncResp> aResp, const std::string &name,
+void getResourceList(std::shared_ptr<AsyncResp> aResp,
const std::string &subclass,
const std::string &collectionName)
{
BMCWEB_LOG_DEBUG << "Get available system cpu/mem resources.";
crow::connections::systemBus->async_method_call(
- [name, subclass, aResp{std::move(aResp)}](
+ [subclass, aResp{std::move(aResp)}](
const boost::system::error_code ec,
const boost::container::flat_map<
std::string, boost::container::flat_map<
@@ -50,7 +50,7 @@
if ((iter != std::string::npos) && (iter < object.first.size()))
{
members.push_back(
- {{"@odata.id", "/redfish/v1/Systems/" + name + "/" +
+ {{"@odata.id", "/redfish/v1/Systems/system/" +
subclass + "/" +
object.first.substr(iter + 1)}});
}
@@ -65,12 +65,12 @@
}
void getCpuDataByService(std::shared_ptr<AsyncResp> aResp,
- const std::string &name, const std::string &cpuId,
- const std::string &service, const std::string &objPath)
+ const std::string &cpuId, const std::string &service,
+ const std::string &objPath)
{
BMCWEB_LOG_DEBUG << "Get available system cpu resources by service.";
crow::connections::systemBus->async_method_call(
- [name, cpuId, aResp{std::move(aResp)}](
+ [cpuId, aResp{std::move(aResp)}](
const boost::system::error_code ec,
const boost::container::flat_map<
std::string, std::variant<std::string, uint32_t, uint16_t>>
@@ -156,12 +156,11 @@
service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
}
-void getCpuData(std::shared_ptr<AsyncResp> aResp, const std::string &name,
- const std::string &cpuId)
+void getCpuData(std::shared_ptr<AsyncResp> aResp, const std::string &cpuId)
{
BMCWEB_LOG_DEBUG << "Get available system cpu resources.";
crow::connections::systemBus->async_method_call(
- [name, cpuId, aResp{std::move(aResp)}](
+ [cpuId, aResp{std::move(aResp)}](
const boost::system::error_code ec,
const boost::container::flat_map<
std::string, boost::container::flat_map<
@@ -179,7 +178,7 @@
{
for (const auto &service : object.second)
{
- getCpuDataByService(aResp, name, cpuId, service.first,
+ getCpuDataByService(aResp, cpuId, service.first,
object.first);
return;
}
@@ -197,13 +196,12 @@
};
void getDimmDataByService(std::shared_ptr<AsyncResp> aResp,
- const std::string &name, const std::string &dimmId,
- const std::string &service,
+ const std::string &dimmId, const std::string &service,
const std::string &objPath)
{
BMCWEB_LOG_DEBUG << "Get available system components.";
crow::connections::systemBus->async_method_call(
- [name, dimmId, aResp{std::move(aResp)}](
+ [dimmId, aResp{std::move(aResp)}](
const boost::system::error_code ec,
const boost::container::flat_map<
std::string, std::variant<std::string, uint32_t, uint16_t>>
@@ -267,12 +265,11 @@
service, objPath, "org.freedesktop.DBus.Properties", "GetAll", "");
}
-void getDimmData(std::shared_ptr<AsyncResp> aResp, const std::string &name,
- const std::string &dimmId)
+void getDimmData(std::shared_ptr<AsyncResp> aResp, const std::string &dimmId)
{
BMCWEB_LOG_DEBUG << "Get available system dimm resources.";
crow::connections::systemBus->async_method_call(
- [name, dimmId, aResp{std::move(aResp)}](
+ [dimmId, aResp{std::move(aResp)}](
const boost::system::error_code ec,
const boost::container::flat_map<
std::string, boost::container::flat_map<
@@ -291,7 +288,7 @@
{
for (const auto &service : object.second)
{
- getDimmDataByService(aResp, name, dimmId, service.first,
+ getDimmDataByService(aResp, dimmId, service.first,
object.first);
return;
}
@@ -315,7 +312,7 @@
* Default Constructor
*/
ProcessorCollection(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/Processors/", std::string())
+ Node(app, "/redfish/v1/Systems/system/Processors/")
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -333,27 +330,16 @@
void doGet(crow::Response &res, const crow::Request &req,
const std::vector<std::string> ¶ms) override
{
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 1)
- {
- messages::internalError(res);
- res.end();
- return;
- }
- const std::string &name = params[0];
-
res.jsonValue["@odata.type"] =
"#ProcessorCollection.ProcessorCollection";
res.jsonValue["Name"] = "Processor Collection";
res.jsonValue["@odata.context"] =
"/redfish/v1/$metadata#ProcessorCollection.ProcessorCollection";
- res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/" + name + "/Processors/";
+ res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Processors/";
auto asyncResp = std::make_shared<AsyncResp>(res);
- getResourceList(asyncResp, name, "Processors",
+ getResourceList(asyncResp, "Processors",
"xyz.openbmc_project.Inventory.Item.Cpu");
}
};
@@ -365,56 +351,7 @@
* Default Constructor
*/
Processor(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/Processors/<str>/", std::string(),
- std::string())
- {
- entityPrivileges = {
- {boost::beast::http::verb::get, {{"Login"}}},
- {boost::beast::http::verb::head, {{"Login"}}},
- {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
- {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
- }
-
- private:
- /**
- * Functions triggers appropriate requests on DBus
- */
- void doGet(crow::Response &res, const crow::Request &req,
- const std::vector<std::string> ¶ms) override
- {
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 2)
- {
- messages::internalError(res);
-
- res.end();
- return;
- }
- const std::string &name = params[0];
- const std::string &cpuId = params[1];
- res.jsonValue["@odata.type"] = "#Processor.v1_3_1.Processor";
- res.jsonValue["@odata.context"] =
- "/redfish/v1/$metadata#Processor.Processor";
- res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/" + name + "/Processors/" + cpuId;
-
- auto asyncResp = std::make_shared<AsyncResp>(res);
-
- getCpuData(asyncResp, name, cpuId);
- }
-};
-
-class MemoryCollection : public Node
-{
- public:
- /*
- * Default Constructor
- */
- MemoryCollection(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/Memory/", std::string())
+ Node(app, "/redfish/v1/Systems/system/Processors/<str>/", std::string())
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -441,16 +378,52 @@
res.end();
return;
}
- const std::string &name = params[0];
+ const std::string &cpuId = params[0];
+ res.jsonValue["@odata.type"] = "#Processor.v1_3_1.Processor";
+ res.jsonValue["@odata.context"] =
+ "/redfish/v1/$metadata#Processor.Processor";
+ res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/system/Processors/" + cpuId;
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+
+ getCpuData(asyncResp, cpuId);
+ }
+};
+
+class MemoryCollection : public Node
+{
+ public:
+ /*
+ * Default Constructor
+ */
+ MemoryCollection(CrowApp &app) :
+ Node(app, "/redfish/v1/Systems/system/Memory/")
+ {
+ entityPrivileges = {
+ {boost::beast::http::verb::get, {{"Login"}}},
+ {boost::beast::http::verb::head, {{"Login"}}},
+ {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
+ {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
+ }
+
+ private:
+ /**
+ * Functions triggers appropriate requests on DBus
+ */
+ void doGet(crow::Response &res, const crow::Request &req,
+ const std::vector<std::string> ¶ms) override
+ {
res.jsonValue["@odata.type"] = "#MemoryCollection.MemoryCollection";
res.jsonValue["Name"] = "Memory Module Collection";
res.jsonValue["@odata.context"] =
"/redfish/v1/$metadata#MemoryCollection.MemoryCollection";
- res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name + "/Memory/";
+ res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Memory/";
auto asyncResp = std::make_shared<AsyncResp>(res);
- getResourceList(asyncResp, name, "Memory",
+ getResourceList(asyncResp, "Memory",
"xyz.openbmc_project.Inventory.Item.Dimm");
}
};
@@ -462,8 +435,7 @@
* Default Constructor
*/
Memory(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/Memory/<str>/", std::string(),
- std::string())
+ Node(app, "/redfish/v1/Systems/system/Memory/<str>/", std::string())
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -483,22 +455,21 @@
{
// Check if there is required param, truly entering this shall be
// impossible
- if (params.size() != 2)
+ if (params.size() != 1)
{
messages::internalError(res);
res.end();
return;
}
- const std::string &name = params[0];
- const std::string &dimmId = params[1];
+ const std::string &dimmId = params[0];
res.jsonValue["@odata.type"] = "#Memory.v1_6_0.Memory";
res.jsonValue["@odata.context"] = "/redfish/v1/$metadata#Memory.Memory";
res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/" + name + "/Memory/" + dimmId;
+ "/redfish/v1/Systems/system/Memory/" + dimmId;
auto asyncResp = std::make_shared<AsyncResp>(res);
- getDimmData(asyncResp, name, dimmId);
+ getDimmData(asyncResp, dimmId);
}
};
diff --git a/redfish-core/lib/ethernet.hpp b/redfish-core/lib/ethernet.hpp
index 9147585..aecfc21 100644
--- a/redfish-core/lib/ethernet.hpp
+++ b/redfish-core/lib/ethernet.hpp
@@ -40,9 +40,10 @@
std::vector<std::pair<
std::string,
boost::container::flat_map<
- std::string,
- std::variant<std::string, bool, uint8_t, int16_t, uint16_t, int32_t,
- uint32_t, int64_t, uint64_t, double>>>>>>;
+ std::string, sdbusplus::message::variant<
+ std::string, bool, uint8_t, int16_t, uint16_t,
+ int32_t, uint32_t, int64_t, uint64_t, double,
+ std::vector<std::string>>>>>>>;
enum class LinkType
{
@@ -81,6 +82,7 @@
std::string default_gateway;
std::string mac_address;
std::optional<uint32_t> vlan_id;
+ std::vector<std::string> nameservers;
};
// Helper function that changes bits netmask notation (i.e. /24)
@@ -160,9 +162,9 @@
{
for (const auto &objpath : dbus_data)
{
- if (objpath.first == "/xyz/openbmc_project/network/" + ethiface_id)
+ for (const auto &ifacePair : objpath.second)
{
- for (const auto &ifacePair : objpath.second)
+ if (objpath.first == "/xyz/openbmc_project/network/" + ethiface_id)
{
if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress")
{
@@ -217,30 +219,45 @@
ethData.speed = *speed;
}
}
- }
- }
- else if (ifacePair.first ==
- "xyz.openbmc_project.Network.SystemConfiguration")
- {
- for (const auto &propertyPair : ifacePair.second)
- {
- if (propertyPair.first == "HostName")
+ else if (propertyPair.first == "NameServers")
{
- const std::string *hostname =
- std::get_if<std::string>(&propertyPair.second);
- if (hostname != nullptr)
+ const std::vector<std::string> *nameservers =
+ sdbusplus::message::variant_ns::get_if<
+ std::vector<std::string>>(
+ &propertyPair.second);
+ if (nameservers != nullptr)
{
- ethData.hostname = *hostname;
+ ethData.nameservers = std::move(*nameservers);
}
}
- else if (propertyPair.first == "DefaultGateway")
+ }
+ }
+ }
+ // System configuration shows up in the global namespace, so no need
+ // to check eth number
+ if (ifacePair.first ==
+ "xyz.openbmc_project.Network.SystemConfiguration")
+ {
+ for (const auto &propertyPair : ifacePair.second)
+ {
+ if (propertyPair.first == "HostName")
+ {
+ const std::string *hostname =
+ sdbusplus::message::variant_ns::get_if<std::string>(
+ &propertyPair.second);
+ if (hostname != nullptr)
{
- const std::string *defaultGateway =
- std::get_if<std::string>(&propertyPair.second);
- if (defaultGateway != nullptr)
- {
- ethData.default_gateway = *defaultGateway;
- }
+ ethData.hostname = *hostname;
+ }
+ }
+ else if (propertyPair.first == "DefaultGateway")
+ {
+ const std::string *defaultGateway =
+ sdbusplus::message::variant_ns::get_if<std::string>(
+ &propertyPair.second);
+ if (defaultGateway != nullptr)
+ {
+ ethData.default_gateway = *defaultGateway;
}
}
}
@@ -1166,7 +1183,23 @@
json_response["Id"] = iface_id;
json_response["@odata.id"] =
"/redfish/v1/Managers/bmc/EthernetInterfaces/" + iface_id;
-
+ json_response["InterfaceEnabled"] = true;
+ if (ethData.speed == 0)
+ {
+ json_response["LinkStatus"] = "NoLink";
+ json_response["Status"] = {
+ {"Health", "OK"},
+ {"State", "Disabled"},
+ };
+ }
+ else
+ {
+ json_response["LinkStatus"] = "LinkUp";
+ json_response["Status"] = {
+ {"Health", "OK"},
+ {"State", "Enabled"},
+ };
+ }
json_response["SpeedMbps"] = ethData.speed;
json_response["MACAddress"] = ethData.mac_address;
if (!ethData.hostname.empty())
@@ -1185,6 +1218,7 @@
vlanObj["VLANEnable"] = false;
vlanObj["VLANId"] = 0;
}
+ json_response["NameServers"] = ethData.nameservers;
if (ipv4Data.size() > 0)
{
@@ -1192,17 +1226,10 @@
ipv4_array = nlohmann::json::array();
for (auto &ipv4_config : ipv4Data)
{
- if (!ipv4_config.address.empty())
- {
- ipv4_array.push_back({{"AddressOrigin", ipv4_config.origin},
- {"SubnetMask", ipv4_config.netmask},
- {"Address", ipv4_config.address}});
-
- if (!ipv4_config.gateway.empty())
- {
- ipv4_array.back()["Gateway"] = ipv4_config.gateway;
- }
- }
+ ipv4_array.push_back({{"AddressOrigin", ipv4_config.origin},
+ {"SubnetMask", ipv4_config.netmask},
+ {"Address", ipv4_config.address},
+ {"Gateway", ipv4_config.gateway}});
}
}
}
diff --git a/redfish-core/lib/log_services.hpp b/redfish-core/lib/log_services.hpp
index ce5b97f..866238b 100644
--- a/redfish-core/lib/log_services.hpp
+++ b/redfish-core/lib/log_services.hpp
@@ -260,7 +260,7 @@
public:
template <typename CrowApp>
SystemLogServiceCollection(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/LogServices/", std::string())
+ Node(app, "/redfish/v1/Systems/system/LogServices/")
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -279,7 +279,6 @@
const std::vector<std::string> ¶ms) override
{
std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
- const std::string &name = params[0];
// Collections don't include the static data added by SubRoute because
// it has a duplicate entry for members
asyncResp->res.jsonValue["@odata.type"] =
@@ -287,14 +286,14 @@
asyncResp->res.jsonValue["@odata.context"] =
"/redfish/v1/$metadata#LogServiceCollection.LogServiceCollection";
asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/" + name + "/LogServices";
+ "/redfish/v1/Systems/system/LogServices";
asyncResp->res.jsonValue["Name"] = "System Log Services Collection";
asyncResp->res.jsonValue["Description"] =
"Collection of LogServices for this Computer System";
nlohmann::json &logServiceArray = asyncResp->res.jsonValue["Members"];
logServiceArray = nlohmann::json::array();
- logServiceArray.push_back({{"@odata.id", "/redfish/v1/Systems/" + name +
- "/LogServices/EventLog"}});
+ logServiceArray.push_back(
+ {{"@odata.id", "/redfish/v1/Systems/system/LogServices/EventLog"}});
asyncResp->res.jsonValue["Members@odata.count"] =
logServiceArray.size();
}
@@ -305,8 +304,7 @@
public:
template <typename CrowApp>
EventLogService(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/",
- std::string())
+ Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/")
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -325,7 +323,7 @@
const std::string &name = params[0];
asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/" + name + "/LogServices/EventLog";
+ "/redfish/v1/Systems/system/LogServices/EventLog";
asyncResp->res.jsonValue["@odata.type"] =
"#LogService.v1_1_0.LogService";
asyncResp->res.jsonValue["@odata.context"] =
@@ -336,12 +334,11 @@
asyncResp->res.jsonValue["OverWritePolicy"] = "WrapsWhenFull";
asyncResp->res.jsonValue["Entries"] = {
{"@odata.id",
- "/redfish/v1/Systems/" + name + "/LogServices/EventLog/Entries"}};
+ "/redfish/v1/Systems/system/LogServices/EventLog/Entries"}};
}
};
-static int fillEventLogEntryJson(const std::string &systemName,
- const std::string &bmcLogEntryID,
+static int fillEventLogEntryJson(const std::string &bmcLogEntryID,
const boost::string_view &messageID,
sd_journal *journal,
nlohmann::json &bmcLogEntryJson)
@@ -409,8 +406,9 @@
bmcLogEntryJson = {
{"@odata.type", "#LogEntry.v1_3_0.LogEntry"},
{"@odata.context", "/redfish/v1/$metadata#LogEntry.LogEntry"},
- {"@odata.id", "/redfish/v1/Systems/" + systemName +
- "/LogServices/EventLog/Entries/" + bmcLogEntryID},
+ {"@odata.id",
+ "/redfish/v1/Systems/system/LogServices/EventLog/Entries/" +
+ bmcLogEntryID},
{"Name", "System Event Log Entry"},
{"Id", bmcLogEntryID},
{"Message", msg},
@@ -429,8 +427,7 @@
public:
template <typename CrowApp>
EventLogEntryCollection(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/",
- std::string())
+ Node(app, "/redfish/v1/Systems/system/LogServices/EventLog/Entries/")
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -456,7 +453,6 @@
{
return;
}
- const std::string &name = params[0];
// Collections don't include the static data added by SubRoute because
// it has a duplicate entry for members
asyncResp->res.jsonValue["@odata.type"] =
@@ -464,7 +460,7 @@
asyncResp->res.jsonValue["@odata.context"] =
"/redfish/v1/$metadata#LogEntryCollection.LogEntryCollection";
asyncResp->res.jsonValue["@odata.id"] =
- "/redfish/v1/Systems/" + name + "/LogServices/EventLog/Entries";
+ "/redfish/v1/Systems/system/LogServices/EventLog/Entries";
asyncResp->res.jsonValue["Name"] = "System Event Log Entries";
asyncResp->res.jsonValue["Description"] =
"Collection of System Event Log Entries";
@@ -512,7 +508,7 @@
logEntryArray.push_back({});
nlohmann::json &bmcLogEntry = logEntryArray.back();
- if (fillEventLogEntryJson(name, idStr, messageID, journal.get(),
+ if (fillEventLogEntryJson(idStr, messageID, journal.get(),
bmcLogEntry) != 0)
{
messages::internalError(asyncResp->res);
@@ -534,8 +530,8 @@
public:
EventLogEntry(CrowApp &app) :
Node(app,
- "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/",
- std::string(), std::string())
+ "/redfish/v1/Systems/system/LogServices/EventLog/Entries/<str>/",
+ std::string())
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -551,13 +547,12 @@
const std::vector<std::string> ¶ms) override
{
std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
- if (params.size() != 2)
+ if (params.size() != 1)
{
messages::internalError(asyncResp->res);
return;
}
- const std::string &name = params[0];
- const std::string &entryID = params[1];
+ const std::string &entryID = params[0];
// Convert the unique ID back to a timestamp to find the entry
uint64_t ts = 0;
uint16_t index = 0;
@@ -598,11 +593,11 @@
getJournalMetadata(journal.get(), "REDFISH_MESSAGE_ID", messageID);
if (ret < 0)
{
- messages::resourceNotFound(asyncResp->res, "LogEntry", name);
+ messages::resourceNotFound(asyncResp->res, "LogEntry", "system");
return;
}
- if (fillEventLogEntryJson(name, entryID, messageID, journal.get(),
+ if (fillEventLogEntryJson(entryID, messageID, journal.get(),
asyncResp->res.jsonValue) != 0)
{
messages::internalError(asyncResp->res);
diff --git a/redfish-core/lib/managers.hpp b/redfish-core/lib/managers.hpp
index 33ac72c..3ada58a 100644
--- a/redfish-core/lib/managers.hpp
+++ b/redfish-core/lib/managers.hpp
@@ -878,6 +878,7 @@
res.jsonValue["Name"] = "OpenBmc Manager";
res.jsonValue["Description"] = "Baseboard Management Controller";
res.jsonValue["PowerState"] = "On";
+ res.jsonValue["Status"] = {{"State", "Enabled"}, {"Health", "OK"}};
res.jsonValue["ManagerType"] = "BMC";
res.jsonValue["UUID"] = uuid;
res.jsonValue["Model"] = "OpenBmc"; // TODO(ed), get model
@@ -910,6 +911,11 @@
"GracefulRestart"};
res.jsonValue["DateTime"] = getDateTime();
+ res.jsonValue["Links"] = {
+ {"ManagerForServers@odata.count", 1},
+ {"ManagerForServers",
+ {{{"@odata.id", "/redfish/v1/Systems/system"}}}},
+ {"ManagerForServers", nlohmann::json::array()}};
std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
crow::connections::systemBus->async_method_call(
diff --git a/redfish-core/lib/service_root.hpp b/redfish-core/lib/service_root.hpp
index f746d43..8cbab6f 100644
--- a/redfish-core/lib/service_root.hpp
+++ b/redfish-core/lib/service_root.hpp
@@ -46,7 +46,7 @@
"/redfish/v1/$metadata#ServiceRoot.ServiceRoot";
res.jsonValue["Id"] = "RootService";
res.jsonValue["Name"] = "Root Service";
- res.jsonValue["RedfishVersion"] = "1.1.0";
+ res.jsonValue["RedfishVersion"] = "1.6.1";
res.jsonValue["Links"]["Sessions"] = {
{"@odata.id", "/redfish/v1/SessionService/Sessions"}};
res.jsonValue["AccountService"] = {
diff --git a/redfish-core/lib/systems.hpp b/redfish-core/lib/systems.hpp
index e24a077..b6c0512 100644
--- a/redfish-core/lib/systems.hpp
+++ b/redfish-core/lib/systems.hpp
@@ -31,12 +31,11 @@
*
* @return None.
*/
-void getComputerSystem(std::shared_ptr<AsyncResp> aResp,
- const std::string &name)
+void getComputerSystem(std::shared_ptr<AsyncResp> aResp)
{
BMCWEB_LOG_DEBUG << "Get available system components.";
crow::connections::systemBus->async_method_call(
- [name, aResp{std::move(aResp)}](
+ [aResp{std::move(aResp)}](
const boost::system::error_code ec,
const std::vector<std::pair<
std::string,
@@ -48,7 +47,6 @@
messages::internalError(aResp->res);
return;
}
- bool foundName = false;
// Iterate over all retrieved ObjectPaths.
for (const std::pair<std::string,
std::vector<std::pair<
@@ -64,245 +62,223 @@
{
continue;
}
- // Check if computer system exist
- if (boost::ends_with(path, name))
+
+ // This is not system, so check if it's cpu, dimm, UUID or
+ // BiosVer
+ for (const auto &connection : connectionNames)
{
- foundName = true;
- BMCWEB_LOG_DEBUG << "Found name: " << name;
- const std::string connectionName = connectionNames[0].first;
- crow::connections::systemBus->async_method_call(
- [aResp, name(std::string(name))](
- const boost::system::error_code ec,
- const std::vector<std::pair<
- std::string, VariantType>> &propertiesList) {
- if (ec)
- {
- BMCWEB_LOG_ERROR << "DBUS response error: "
- << ec;
- messages::internalError(aResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG << "Got " << propertiesList.size()
- << "properties for system";
- for (const std::pair<std::string, VariantType>
- &property : propertiesList)
- {
- const std::string *value =
- std::get_if<std::string>(&property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue[property.first] =
- *value;
- }
- }
- aResp->res.jsonValue["Name"] = name;
- aResp->res.jsonValue["Id"] =
- aResp->res.jsonValue["SerialNumber"];
- },
- connectionName, path, "org.freedesktop.DBus.Properties",
- "GetAll",
- "xyz.openbmc_project.Inventory.Decorator.Asset");
- }
- else
- {
- // This is not system, so check if it's cpu, dimm, UUID or
- // BiosVer
- for (const auto &connection : connectionNames)
+ for (const auto &interfaceName : connection.second)
{
- for (const auto &interfaceName : connection.second)
+ if (interfaceName ==
+ "xyz.openbmc_project.Inventory.Item.Dimm")
{
- if (interfaceName ==
- "xyz.openbmc_project.Inventory.Item.Dimm")
- {
- BMCWEB_LOG_DEBUG
- << "Found Dimm, now get its properties.";
- crow::connections::systemBus->async_method_call(
- [aResp](
- const boost::system::error_code ec,
+ BMCWEB_LOG_DEBUG
+ << "Found Dimm, now get its properties.";
+ crow::connections::systemBus->async_method_call(
+ [aResp](const boost::system::error_code ec,
const std::vector<
std::pair<std::string, VariantType>>
&properties) {
- if (ec)
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR
+ << "DBUS response error " << ec;
+ messages::internalError(aResp->res);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Got "
+ << properties.size()
+ << "Dimm properties.";
+ for (const std::pair<std::string,
+ VariantType>
+ &property : properties)
+ {
+ if (property.first == "MemorySizeInKb")
{
- BMCWEB_LOG_ERROR
- << "DBUS response error " << ec;
- messages::internalError(aResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG << "Got "
- << properties.size()
- << "Dimm properties.";
- for (const std::pair<std::string,
- VariantType>
- &property : properties)
- {
- if (property.first ==
- "MemorySizeInKb")
+ const uint64_t *value =
+ sdbusplus::message::variant_ns::
+ get_if<uint64_t>(
+ &property.second);
+ if (value != nullptr)
{
- const uint64_t *value =
- sdbusplus::message::
- variant_ns::get_if<
- uint64_t>(
- &property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue
- ["TotalSystemMemoryGi"
- "B"] +=
- *value / (1024 * 1024);
- aResp->res.jsonValue
- ["MemorySummary"]
- ["Status"]["State"] =
- "Enabled";
- }
+ aResp->res.jsonValue
+ ["TotalSystemMemoryGi"
+ "B"] +=
+ *value / (1024 * 1024);
+ aResp->res
+ .jsonValue["MemorySummary"]
+ ["Status"]
+ ["State"] =
+ "Enabled";
}
}
- },
- connection.first, path,
- "org.freedesktop.DBus.Properties", "GetAll",
- "xyz.openbmc_project.Inventory.Item.Dimm");
- }
- else if (interfaceName ==
- "xyz.openbmc_project.Inventory.Item.Cpu")
- {
- BMCWEB_LOG_DEBUG
- << "Found Cpu, now get its properties.";
- crow::connections::systemBus->async_method_call(
- [aResp](
- const boost::system::error_code ec,
+ }
+ },
+ connection.first, path,
+ "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Inventory.Item.Dimm");
+ }
+ else if (interfaceName ==
+ "xyz.openbmc_project.Inventory.Item.Cpu")
+ {
+ BMCWEB_LOG_DEBUG
+ << "Found Cpu, now get its properties.";
+ crow::connections::systemBus->async_method_call(
+ [aResp](const boost::system::error_code ec,
const std::vector<
std::pair<std::string, VariantType>>
&properties) {
- if (ec)
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR
+ << "DBUS response error " << ec;
+ messages::internalError(aResp->res);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Got "
+ << properties.size()
+ << "Cpu properties.";
+ for (const auto &property : properties)
+ {
+ if (property.first == "ProcessorFamily")
{
- BMCWEB_LOG_ERROR
- << "DBUS response error " << ec;
- messages::internalError(aResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG << "Got "
- << properties.size()
- << "Cpu properties.";
- for (const auto &property : properties)
- {
- if (property.first ==
- "ProcessorFamily")
+ const std::string *value =
+ sdbusplus::message::variant_ns::
+ get_if<std::string>(
+ &property.second);
+ if (value != nullptr)
{
- const std::string *value =
- sdbusplus::message::
- variant_ns::get_if<
- std::string>(
- &property.second);
- if (value != nullptr)
- {
- nlohmann::json
- &procSummary =
- aResp->res.jsonValue
- ["ProcessorSumm"
- "ary"];
- nlohmann::json &procCount =
- procSummary["Count"];
+ nlohmann::json &procSummary =
+ aResp->res.jsonValue
+ ["ProcessorSumm"
+ "ary"];
+ nlohmann::json &procCount =
+ procSummary["Count"];
- procCount =
- procCount.get<int>() +
- 1;
- procSummary["Status"]
- ["State"] =
- "Enabled";
- procSummary["Model"] =
- *value;
- }
+ procCount =
+ procCount.get<int>() + 1;
+ procSummary["Status"]["State"] =
+ "Enabled";
+ procSummary["Model"] = *value;
}
}
- },
- connection.first, path,
- "org.freedesktop.DBus.Properties", "GetAll",
- "xyz.openbmc_project.Inventory.Item.Cpu");
- }
- else if (interfaceName ==
- "xyz.openbmc_project.Common.UUID")
- {
- BMCWEB_LOG_DEBUG
- << "Found UUID, now get its properties.";
- crow::connections::systemBus->async_method_call(
- [aResp](
- const boost::system::error_code ec,
+ }
+ },
+ connection.first, path,
+ "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Inventory.Item.Cpu");
+ }
+ else if (interfaceName ==
+ "xyz.openbmc_project.Common.UUID")
+ {
+ BMCWEB_LOG_DEBUG
+ << "Found UUID, now get its properties.";
+ crow::connections::systemBus->async_method_call(
+ [aResp](const boost::system::error_code ec,
const std::vector<
std::pair<std::string, VariantType>>
&properties) {
- if (ec)
+ if (ec)
+ {
+ BMCWEB_LOG_DEBUG
+ << "DBUS response error " << ec;
+ messages::internalError(aResp->res);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Got "
+ << properties.size()
+ << "UUID properties.";
+ for (const std::pair<std::string,
+ VariantType>
+ &property : properties)
+ {
+ if (property.first == "BIOSVer")
{
- BMCWEB_LOG_DEBUG
- << "DBUS response error " << ec;
- messages::internalError(aResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG << "Got "
- << properties.size()
- << "UUID properties.";
- for (const std::pair<std::string,
- VariantType>
- &property : properties)
- {
- if (property.first == "BIOSVer")
+ const std::string *value =
+ sdbusplus::message::variant_ns::
+ get_if<std::string>(
+ &property.second);
+ if (value != nullptr)
{
- const std::string *value =
- sdbusplus::message::
- variant_ns::get_if<
- std::string>(
- &property.second);
- if (value != nullptr)
- {
- aResp->res.jsonValue
- ["BiosVersion"] =
- *value;
- }
+ aResp->res
+ .jsonValue["BiosVersion"] =
+ *value;
}
- if (property.first == "UUID")
- {
- const std::string *value =
- sdbusplus::message::
- variant_ns::get_if<
- std::string>(
- &property.second);
+ }
+ if (property.first == "UUID")
+ {
+ const std::string *value =
+ sdbusplus::message::variant_ns::
+ get_if<std::string>(
+ &property.second);
- if (value != nullptr)
+ if (value != nullptr)
+ {
+ std::string valueStr = *value;
+ if (valueStr.size() == 32)
{
- std::string valueStr =
- *value;
- if (valueStr.size() == 32)
- {
- valueStr.insert(8, 1,
- '-');
- valueStr.insert(13, 1,
- '-');
- valueStr.insert(18, 1,
- '-');
- valueStr.insert(23, 1,
- '-');
- }
- BMCWEB_LOG_DEBUG
- << "UUID = "
- << valueStr;
- aResp->res
- .jsonValue["UUID"] =
- valueStr;
+ valueStr.insert(8, 1, '-');
+ valueStr.insert(13, 1, '-');
+ valueStr.insert(18, 1, '-');
+ valueStr.insert(23, 1, '-');
}
+ BMCWEB_LOG_DEBUG << "UUID = "
+ << valueStr;
+ aResp->res.jsonValue["UUID"] =
+ valueStr;
}
}
- },
- connection.first, path,
- "org.freedesktop.DBus.Properties", "GetAll",
- "xyz.openbmc_project.Common.UUID");
- }
+ }
+ },
+ connection.first, path,
+ "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Common.UUID");
+ }
+ else if (interfaceName ==
+ "xyz.openbmc_project.Inventory.Item.System")
+ {
+ crow::connections::systemBus->async_method_call(
+ [aResp](const boost::system::error_code ec,
+ const std::vector<
+ std::pair<std::string, VariantType>>
+ &propertiesList) {
+ if (ec)
+ {
+ BMCWEB_LOG_ERROR
+ << "DBUS response error: " << ec;
+ messages::internalError(aResp->res);
+ return;
+ }
+ BMCWEB_LOG_DEBUG << "Got "
+ << propertiesList.size()
+ << "properties for system";
+ for (const std::pair<std::string,
+ VariantType>
+ &property : propertiesList)
+ {
+ const std::string *value =
+ sdbusplus::message::variant_ns::
+ get_if<std::string>(
+ &property.second);
+ if (value != nullptr)
+ {
+ aResp->res
+ .jsonValue[property.first] =
+ *value;
+ }
+ }
+ aResp->res.jsonValue["Name"] = "system";
+ aResp->res.jsonValue["Id"] =
+ aResp->res.jsonValue["SerialNumber"];
+ },
+ connection.first, path,
+ "org.freedesktop.DBus.Properties", "GetAll",
+ "xyz.openbmc_project.Inventory.Decorator."
+ "Asset");
}
}
}
}
- if (foundName == false)
- {
- messages::internalError(aResp->res);
- }
},
"xyz.openbmc_project.ObjectMapper",
"/xyz/openbmc_project/object_mapper",
@@ -495,8 +471,6 @@
void doGet(crow::Response &res, const crow::Request &req,
const std::vector<std::string> ¶ms) override
{
- BMCWEB_LOG_DEBUG << "Get list of available boards.";
- std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res);
res.jsonValue["@odata.type"] =
"#ComputerSystemCollection.ComputerSystemCollection";
res.jsonValue["@odata.id"] = "/redfish/v1/Systems";
@@ -504,42 +478,10 @@
"/redfish/v1/"
"$metadata#ComputerSystemCollection.ComputerSystemCollection";
res.jsonValue["Name"] = "Computer System Collection";
- crow::connections::systemBus->async_method_call(
- [asyncResp](const boost::system::error_code ec,
- const std::vector<std::string> &resp) {
- if (ec)
- {
- messages::internalError(asyncResp->res);
- return;
- }
- BMCWEB_LOG_DEBUG << "Got " << resp.size() << " boards.";
-
- // ... prepare json array with appropriate @odata.id links
- nlohmann::json &boardArray =
- asyncResp->res.jsonValue["Members"];
- boardArray = nlohmann::json::array();
-
- // Iterate over all retrieved ObjectPaths.
- for (const std::string &objpath : resp)
- {
- std::size_t lastPos = objpath.rfind("/");
- if (lastPos != std::string::npos)
- {
- boardArray.push_back(
- {{"@odata.id", "/redfish/v1/Systems/" +
- objpath.substr(lastPos + 1)}});
- }
- }
-
- asyncResp->res.jsonValue["Members@odata.count"] =
- boardArray.size();
- },
- "xyz.openbmc_project.ObjectMapper",
- "/xyz/openbmc_project/object_mapper",
- "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
- "/xyz/openbmc_project/inventory", int32_t(0),
- std::array<const char *, 1>{
- "xyz.openbmc_project.Inventory.Item.Board"});
+ res.jsonValue["Members"] = {
+ {{"@odata.id", "/redfish/v1/Systems/system"}}};
+ res.jsonValue["Members@odata.count"] = 1;
+ res.end();
}
};
@@ -551,8 +493,7 @@
{
public:
SystemActionsReset(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/Actions/ComputerSystem.Reset/",
- std::string())
+ Node(app, "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset/")
{
entityPrivileges = {
{boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
@@ -649,8 +590,7 @@
/*
* Default Constructor
*/
- Systems(CrowApp &app) :
- Node(app, "/redfish/v1/Systems/<str>/", std::string())
+ Systems(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/")
{
entityPrivileges = {
{boost::beast::http::verb::get, {{"Login"}}},
@@ -668,20 +608,11 @@
void doGet(crow::Response &res, const crow::Request &req,
const std::vector<std::string> ¶ms) override
{
- // Check if there is required param, truly entering this shall be
- // impossible
- if (params.size() != 1)
- {
- messages::internalError(res);
- res.end();
- return;
- }
-
- const std::string &name = params[0];
-
res.jsonValue["@odata.type"] = "#ComputerSystem.v1_5_1.ComputerSystem";
res.jsonValue["@odata.context"] =
"/redfish/v1/$metadata#ComputerSystem.ComputerSystem";
+ res.jsonValue["Name"] = "Computer System";
+ res.jsonValue["Id"] = "system";
res.jsonValue["SystemType"] = "Physical";
res.jsonValue["Description"] = "Computer System";
res.jsonValue["Boot"]["BootSourceOverrideEnabled"] =
@@ -699,21 +630,22 @@
res.jsonValue["ProcessorSummary"]["Status"]["State"] = "Disabled";
res.jsonValue["MemorySummary"]["TotalSystemMemoryGiB"] = int(0);
res.jsonValue["MemorySummary"]["Status"]["State"] = "Disabled";
- res.jsonValue["@odata.id"] = "/redfish/v1/Systems/" + name;
+ res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system";
res.jsonValue["Processors"] = {
- {"@odata.id", "/redfish/v1/Systems/" + name + "/Processors"}};
+ {"@odata.id", "/redfish/v1/Systems/system/Processors"}};
res.jsonValue["Memory"] = {
- {"@odata.id", "/redfish/v1/Systems/" + name + "/Memory"}};
+ {"@odata.id", "/redfish/v1/Systems/system/Memory"}};
+
// TODO Need to support ForceRestart.
res.jsonValue["Actions"]["#ComputerSystem.Reset"] = {
{"target",
- "/redfish/v1/Systems/" + name + "/Actions/ComputerSystem.Reset"},
+ "/redfish/v1/Systems/system/Actions/ComputerSystem.Reset"},
{"ResetType@Redfish.AllowableValues",
{"On", "ForceOff", "GracefulRestart", "GracefulShutdown"}}};
res.jsonValue["LogServices"] = {
- {"@odata.id", "/redfish/v1/Systems/" + name + "/LogServices"}};
+ {"@odata.id", "/redfish/v1/Systems/system/LogServices"}};
auto asyncResp = std::make_shared<AsyncResp>(res);
@@ -739,33 +671,21 @@
aResp->res.jsonValue["IndicatorLED"] = "Off";
}
});
- getComputerSystem(asyncResp, name);
+ getComputerSystem(asyncResp);
getHostState(asyncResp);
}
void doPatch(crow::Response &res, const crow::Request &req,
const std::vector<std::string> ¶ms) override
{
- // Check if there is required param, truly entering this shall be
- // impossible
- auto asyncResp = std::make_shared<AsyncResp>(res);
- if (params.size() != 1)
- {
- messages::internalError(asyncResp->res);
- return;
- }
-
- const std::string &name = params[0];
-
- messages::success(asyncResp->res);
-
std::string indicatorLedTemp;
std::optional<std::string> indicatorLed = indicatorLedTemp;
if (!json_util::readJson(req, res, "IndicatorLed", indicatorLed))
{
return;
}
-
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+ messages::success(asyncResp->res);
if (indicatorLed)
{
std::string dbusLedState;
@@ -790,7 +710,7 @@
}
getHostState(asyncResp);
- getComputerSystem(asyncResp, name);
+ getComputerSystem(asyncResp);
// Update led group
BMCWEB_LOG_DEBUG << "Update led group.";