summaryrefslogtreecommitdiff
path: root/redfish-core/lib/storage.hpp
diff options
context:
space:
mode:
authorNikhil Potade <nikhil.potade@linux.intel.com>2019-08-24 02:35:26 +0300
committerEd Tanous <ed.tanous@intel.com>2019-10-01 00:06:48 +0300
commite56c7b7092298c609831a65bcc8c21e62d422ba7 (patch)
treeb7d67ab493242e8330ad3c334b955253bcb34f2d /redfish-core/lib/storage.hpp
parent3929aca1036033994610f6b3424aad124bf41d51 (diff)
downloadbmcweb-e56c7b7092298c609831a65bcc8c21e62d422ba7.tar.xz
Add Storage Schema for NVMe on Redfish
This provides an implementation for the Get methods for the Storage schemas using following classes : - StorageCollection - Storage Tested: - Ran Redfish Service Validator to verify no issues are reported. - Tested that the NVMe drives in the system show up and proper fields are populated with appropriate data. - Tested with no drives present. Made sure the Storage interface shows no drives and Drive interface returns error message. Signed-off-by: Nikhil Potade <nikhil.potade@linux.intel.com> Change-Id: I9fa9f4cd69fe07cde15604c5405a6987774065fd
Diffstat (limited to 'redfish-core/lib/storage.hpp')
-rw-r--r--redfish-core/lib/storage.hpp250
1 files changed, 250 insertions, 0 deletions
diff --git a/redfish-core/lib/storage.hpp b/redfish-core/lib/storage.hpp
new file mode 100644
index 0000000000..8daead7632
--- /dev/null
+++ b/redfish-core/lib/storage.hpp
@@ -0,0 +1,250 @@
+/*
+// Copyright (c) 2019 Intel Corporation
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+*/
+#pragma once
+
+#include <node.hpp>
+
+namespace redfish
+{
+class StorageCollection : public Node
+{
+ public:
+ StorageCollection(CrowApp &app) :
+ Node(app, "/redfish/v1/Systems/system/Storage/")
+ {
+ 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:
+ void doGet(crow::Response &res, const crow::Request &req,
+ const std::vector<std::string> &params) override
+ {
+ res.jsonValue["@odata.type"] = "#StorageCollection.StorageCollection";
+ res.jsonValue["@odata.context"] =
+ "/redfish/v1/$metadata#StorageCollection.StorageCollection";
+ res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Storage";
+ res.jsonValue["Name"] = "Storage Collection";
+ res.jsonValue["Members"] = {
+ {"@odata.id", "/redfish/v1/Systems/system/Storage/1"}};
+ res.jsonValue["Members@odata.count"] = 1;
+ }
+};
+
+class Storage : public Node
+{
+ public:
+ Storage(CrowApp &app) : Node(app, "/redfish/v1/Systems/system/Storage/1")
+ {
+ 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:
+ void doGet(crow::Response &res, const crow::Request &req,
+ const std::vector<std::string> &params) override
+ {
+ res.jsonValue["@odata.type"] = "#Storage.v1_2_0.Storage";
+ res.jsonValue["@odata.context"] =
+ "/redfish/v1/$metadata#Storage.Storage";
+ res.jsonValue["@odata.id"] = "/redfish/v1/Systems/system/Storage/1";
+ res.jsonValue["Name"] = "Storage Controller";
+ res.jsonValue["Id"] = "NVMe Controller";
+
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+ crow::connections::systemBus->async_method_call(
+ [asyncResp](const boost::system::error_code ec,
+ const std::vector<std::string> &storageList) {
+ nlohmann::json &storageArray =
+ asyncResp->res.jsonValue["Drives"];
+ storageArray = nlohmann::json::array();
+ asyncResp->res.jsonValue["Drives@odata.count"] = 0;
+ if (ec)
+ {
+ return;
+ }
+ for (const std::string &objpath : storageList)
+ {
+ std::size_t lastPos = objpath.rfind("/");
+ if (lastPos == std::string::npos ||
+ objpath.size() <= lastPos + 1)
+ {
+ BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
+ continue;
+ }
+
+ storageArray.push_back(
+ {{"@odata.id",
+ "/redfish/v1/Systems/system/Storage/1/Drive/" +
+ objpath.substr(lastPos + 1)}});
+ }
+
+ asyncResp->res.jsonValue["Drives@odata.count"] =
+ storageArray.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.Drive"});
+ }
+};
+
+class Drive : public Node
+{
+ public:
+ Drive(CrowApp &app) :
+ Node(app, "/redfish/v1/Systems/system/Storage/1/Drive/<str>/",
+ 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:
+ void doGet(crow::Response &res, const crow::Request &req,
+ const std::vector<std::string> &params) override
+ {
+ const std::string &driveId = params[0];
+
+ auto asyncResp = std::make_shared<AsyncResp>(res);
+
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, driveId](
+ const boost::system::error_code ec,
+ const std::vector<std::pair<
+ std::string, std::vector<std::pair<
+ std::string, std::vector<std::string>>>>>
+ &subtree) {
+ if (ec)
+ {
+ messages::resourceNotFound(asyncResp->res, "Drive",
+ driveId);
+ return;
+ }
+
+ for (const std::pair<
+ std::string,
+ std::vector<
+ std::pair<std::string, std::vector<std::string>>>>
+ &object : subtree)
+ {
+ const std::string &path = object.first;
+ const std::vector<
+ std::pair<std::string, std::vector<std::string>>>
+ &connectionNames = object.second;
+
+ if (!boost::ends_with(path, "/" + driveId))
+ {
+ continue;
+ }
+
+ asyncResp->res.jsonValue["@odata.type"] =
+ "#Drive.v1_2_0.Drive";
+ asyncResp->res.jsonValue["@odata.context"] =
+ "/redfish/v1/$metadata#Drive.Drive";
+ asyncResp->res.jsonValue["@odata.id"] =
+ "/redfish/v1/Systems/system/Storage/1/Drive/" + driveId;
+
+ if (connectionNames.size() != 1)
+ {
+ BMCWEB_LOG_ERROR << "Connection size "
+ << connectionNames.size()
+ << ", greater than 1";
+ continue;
+ }
+
+ const std::string &connectionName =
+ connectionNames[0].first;
+ crow::connections::systemBus->async_method_call(
+ [asyncResp, driveId](
+ const boost::system::error_code ec,
+ const std::vector<std::pair<
+ std::string,
+ std::variant<bool, std::string, uint64_t>>>
+ &propertiesList) {
+ for (const std::pair<
+ std::string,
+ std::variant<bool, std::string, uint64_t>>
+ &property : propertiesList)
+ {
+ // Store DBus properties that are also
+ // Redfish properties with same name and a
+ // string value
+ const std::string &propertyName =
+ property.first;
+ if ((propertyName == "PartNumber") ||
+ (propertyName == "SerialNumber") ||
+ (propertyName == "Manufacturer") ||
+ (propertyName == "Model"))
+ {
+ const std::string *value =
+ std::get_if<std::string>(
+ &property.second);
+ if (value != nullptr)
+ {
+ asyncResp->res.jsonValue[propertyName] =
+ *value;
+ }
+ }
+ }
+ asyncResp->res.jsonValue["Name"] = driveId;
+ asyncResp->res.jsonValue["Id"] = driveId;
+
+ getMainChassisId(
+ asyncResp, [](const std::string &chassisId,
+ std::shared_ptr<AsyncResp> aRsp) {
+ aRsp->res.jsonValue["Links"]["Chassis"] = {
+ {"@odata.id",
+ "/redfish/v1/Chassis/" + chassisId}};
+ });
+ },
+ connectionName, path, "org.freedesktop.DBus.Properties",
+ "GetAll",
+ "xyz.openbmc_project.Inventory.Decorator.Asset");
+
+ return;
+ }
+
+ // no object found with that name
+ messages::resourceNotFound(asyncResp->res, "Drive", driveId);
+ return;
+ },
+ "xyz.openbmc_project.ObjectMapper",
+ "/xyz/openbmc_project/object_mapper",
+ "xyz.openbmc_project.ObjectMapper", "GetSubTree",
+ "/xyz/openbmc_project/inventory", int32_t(0),
+ std::array<const char *, 1>{
+ "xyz.openbmc_project.Inventory.Item.Drive"});
+ }
+};
+} // namespace redfish \ No newline at end of file