xref: /openbmc/bmcweb/redfish-core/lib/chassis.hpp (revision 8f1ac8e9)
1e37f8451SRapkiewicz, Pawel /*
2e37f8451SRapkiewicz, Pawel // Copyright (c) 2018 Intel Corporation
3e37f8451SRapkiewicz, Pawel //
4e37f8451SRapkiewicz, Pawel // Licensed under the Apache License, Version 2.0 (the "License");
5e37f8451SRapkiewicz, Pawel // you may not use this file except in compliance with the License.
6e37f8451SRapkiewicz, Pawel // You may obtain a copy of the License at
7e37f8451SRapkiewicz, Pawel //
8e37f8451SRapkiewicz, Pawel //      http://www.apache.org/licenses/LICENSE-2.0
9e37f8451SRapkiewicz, Pawel //
10e37f8451SRapkiewicz, Pawel // Unless required by applicable law or agreed to in writing, software
11e37f8451SRapkiewicz, Pawel // distributed under the License is distributed on an "AS IS" BASIS,
12e37f8451SRapkiewicz, Pawel // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13e37f8451SRapkiewicz, Pawel // See the License for the specific language governing permissions and
14e37f8451SRapkiewicz, Pawel // limitations under the License.
15e37f8451SRapkiewicz, Pawel */
16e37f8451SRapkiewicz, Pawel #pragma once
17e37f8451SRapkiewicz, Pawel 
18e37f8451SRapkiewicz, Pawel #include "node.hpp"
191abe55efSEd Tanous 
20e37f8451SRapkiewicz, Pawel #include <boost/container/flat_map.hpp>
21e37f8451SRapkiewicz, Pawel 
221abe55efSEd Tanous namespace redfish
231abe55efSEd Tanous {
24e37f8451SRapkiewicz, Pawel 
25e37f8451SRapkiewicz, Pawel /**
26e37f8451SRapkiewicz, Pawel  * DBus types primitives for several generic DBus interfaces
27e37f8451SRapkiewicz, Pawel  * TODO(Pawel) consider move this to separate file into boost::dbus
28e37f8451SRapkiewicz, Pawel  */
2955c7b7a2SEd Tanous // Note, this is not a very useful Variant, but because it isn't used to get
30aa2e59c1SEd Tanous // values, it should be as simple as possible
31aa2e59c1SEd Tanous // TODO(ed) invent a nullvariant type
3204a258f4SEd Tanous using VariantType = sdbusplus::message::variant<bool, std::string, uint64_t>;
33aa2e59c1SEd Tanous using ManagedObjectsType = std::vector<std::pair<
34aa2e59c1SEd Tanous     sdbusplus::message::object_path,
35aa2e59c1SEd Tanous     std::vector<std::pair<std::string,
36aa2e59c1SEd Tanous                           std::vector<std::pair<std::string, VariantType>>>>>>;
37e37f8451SRapkiewicz, Pawel 
38aa2e59c1SEd Tanous using PropertiesType = boost::container::flat_map<std::string, VariantType>;
39e37f8451SRapkiewicz, Pawel 
40e37f8451SRapkiewicz, Pawel /**
41e37f8451SRapkiewicz, Pawel  * ChassisCollection derived class for delivering Chassis Collection Schema
42e37f8451SRapkiewicz, Pawel  */
431abe55efSEd Tanous class ChassisCollection : public Node
441abe55efSEd Tanous {
45e37f8451SRapkiewicz, Pawel   public:
461abe55efSEd Tanous     ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/")
471abe55efSEd Tanous     {
48e0d918bcSEd Tanous         entityPrivileges = {
49e0d918bcSEd Tanous             {boost::beast::http::verb::get, {{"Login"}}},
50e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
51e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
52e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
53e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
54e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
55e37f8451SRapkiewicz, Pawel     }
56e37f8451SRapkiewicz, Pawel 
57e37f8451SRapkiewicz, Pawel   private:
58e37f8451SRapkiewicz, Pawel     /**
59e37f8451SRapkiewicz, Pawel      * Functions triggers appropriate requests on DBus
60e37f8451SRapkiewicz, Pawel      */
6155c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
621abe55efSEd Tanous                const std::vector<std::string> &params) override
631abe55efSEd Tanous     {
64*8f1ac8e9SGunnar Mills         const std::array<const char *, 3> interfaces = {
6562d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.Board",
6662d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.Chassis",
67*8f1ac8e9SGunnar Mills             "xyz.openbmc_project.Inventory.Item.PowerSupply"};
680f74e643SEd Tanous         res.jsonValue["@odata.type"] = "#ChassisCollection.ChassisCollection";
690f74e643SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
700f74e643SEd Tanous         res.jsonValue["@odata.context"] =
710f74e643SEd Tanous             "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
720f74e643SEd Tanous         res.jsonValue["Name"] = "Chassis Collection";
730f74e643SEd Tanous 
7462d5e2e4SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
7562d5e2e4SEd Tanous         crow::connections::systemBus->async_method_call(
7662d5e2e4SEd Tanous             [asyncResp](const boost::system::error_code ec,
7762d5e2e4SEd Tanous                         const std::vector<std::string> &chassisList) {
7862d5e2e4SEd Tanous                 if (ec)
791abe55efSEd Tanous                 {
80f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
8162d5e2e4SEd Tanous                     return;
82e37f8451SRapkiewicz, Pawel                 }
8362d5e2e4SEd Tanous                 nlohmann::json &chassisArray =
8462d5e2e4SEd Tanous                     asyncResp->res.jsonValue["Members"];
8562d5e2e4SEd Tanous                 chassisArray = nlohmann::json::array();
8662d5e2e4SEd Tanous                 for (const std::string &objpath : chassisList)
8762d5e2e4SEd Tanous                 {
8862d5e2e4SEd Tanous                     std::size_t lastPos = objpath.rfind("/");
8962d5e2e4SEd Tanous                     if (lastPos == std::string::npos)
9062d5e2e4SEd Tanous                     {
9162d5e2e4SEd Tanous                         BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
9262d5e2e4SEd Tanous                         continue;
9362d5e2e4SEd Tanous                     }
9462d5e2e4SEd Tanous                     chassisArray.push_back(
9562d5e2e4SEd Tanous                         {{"@odata.id", "/redfish/v1/Chassis/" +
9662d5e2e4SEd Tanous                                            objpath.substr(lastPos + 1)}});
97e37f8451SRapkiewicz, Pawel                 }
98e37f8451SRapkiewicz, Pawel 
9962d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] =
10062d5e2e4SEd Tanous                     chassisArray.size();
10162d5e2e4SEd Tanous             },
10262d5e2e4SEd Tanous             "xyz.openbmc_project.ObjectMapper",
10362d5e2e4SEd Tanous             "/xyz/openbmc_project/object_mapper",
10462d5e2e4SEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
10562d5e2e4SEd Tanous             "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
10662d5e2e4SEd Tanous     }
107e37f8451SRapkiewicz, Pawel };
108e37f8451SRapkiewicz, Pawel 
109e37f8451SRapkiewicz, Pawel /**
110e37f8451SRapkiewicz, Pawel  * Chassis override class for delivering Chassis Schema
111e37f8451SRapkiewicz, Pawel  */
1121abe55efSEd Tanous class Chassis : public Node
1131abe55efSEd Tanous {
114e37f8451SRapkiewicz, Pawel   public:
1151abe55efSEd Tanous     Chassis(CrowApp &app) :
1161abe55efSEd Tanous         Node(app, "/redfish/v1/Chassis/<str>/", std::string())
1171abe55efSEd Tanous     {
118e0d918bcSEd Tanous         entityPrivileges = {
119e0d918bcSEd Tanous             {boost::beast::http::verb::get, {{"Login"}}},
120e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
121e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
122e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
123e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
124e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
125e37f8451SRapkiewicz, Pawel     }
126e37f8451SRapkiewicz, Pawel 
127e37f8451SRapkiewicz, Pawel   private:
128e37f8451SRapkiewicz, Pawel     /**
129e37f8451SRapkiewicz, Pawel      * Functions triggers appropriate requests on DBus
130e37f8451SRapkiewicz, Pawel      */
13155c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
1321abe55efSEd Tanous                const std::vector<std::string> &params) override
1331abe55efSEd Tanous     {
134e37f8451SRapkiewicz, Pawel         // Check if there is required param, truly entering this shall be
135e37f8451SRapkiewicz, Pawel         // impossible.
1361abe55efSEd Tanous         if (params.size() != 1)
1371abe55efSEd Tanous         {
138f12894f8SJason M. Bills             messages::internalError(res);
139e37f8451SRapkiewicz, Pawel             res.end();
140e37f8451SRapkiewicz, Pawel             return;
141e37f8451SRapkiewicz, Pawel         }
142e37f8451SRapkiewicz, Pawel 
1430f74e643SEd Tanous         res.jsonValue["@odata.type"] = "#Chassis.v1_4_0.Chassis";
1440f74e643SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
1450f74e643SEd Tanous         res.jsonValue["@odata.context"] =
1460f74e643SEd Tanous             "/redfish/v1/$metadata#Chassis.Chassis";
1470f74e643SEd Tanous         res.jsonValue["Name"] = "Chassis Collection";
1480f74e643SEd Tanous         res.jsonValue["ChassisType"] = "RackMount";
1490f74e643SEd Tanous         res.jsonValue["PowerState"] = "On";
1500f74e643SEd Tanous 
15155c7b7a2SEd Tanous         const std::string &chassisId = params[0];
15262d5e2e4SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
15355c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
15462d5e2e4SEd Tanous             [asyncResp, chassisId(std::string(chassisId))](
15562d5e2e4SEd Tanous                 const boost::system::error_code ec,
156daf36e2eSEd Tanous                 const std::vector<std::pair<
1571abe55efSEd Tanous                     std::string, std::vector<std::pair<
1581abe55efSEd Tanous                                      std::string, std::vector<std::string>>>>>
159daf36e2eSEd Tanous                     &subtree) {
16062d5e2e4SEd Tanous                 if (ec)
1611abe55efSEd Tanous                 {
162f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
163daf36e2eSEd Tanous                     return;
164daf36e2eSEd Tanous                 }
165daf36e2eSEd Tanous                 // Iterate over all retrieved ObjectPaths.
1661abe55efSEd Tanous                 for (const std::pair<
1671abe55efSEd Tanous                          std::string,
1681abe55efSEd Tanous                          std::vector<
1691abe55efSEd Tanous                              std::pair<std::string, std::vector<std::string>>>>
1701abe55efSEd Tanous                          &object : subtree)
1711abe55efSEd Tanous                 {
172daf36e2eSEd Tanous                     const std::string &path = object.first;
1731abe55efSEd Tanous                     const std::vector<
1741abe55efSEd Tanous                         std::pair<std::string, std::vector<std::string>>>
175daf36e2eSEd Tanous                         &connectionNames = object.second;
176e0d918bcSEd Tanous 
1771abe55efSEd Tanous                     if (!boost::ends_with(path, chassisId))
1781abe55efSEd Tanous                     {
179daf36e2eSEd Tanous                         continue;
180daf36e2eSEd Tanous                     }
1811abe55efSEd Tanous                     if (connectionNames.size() < 1)
1821abe55efSEd Tanous                     {
1831abe55efSEd Tanous                         BMCWEB_LOG_ERROR << "Only got "
1841abe55efSEd Tanous                                          << connectionNames.size()
18555c7b7a2SEd Tanous                                          << " Connection names";
186e0d918bcSEd Tanous                         continue;
187daf36e2eSEd Tanous                     }
188e0d918bcSEd Tanous 
189daf36e2eSEd Tanous                     const std::string connectionName = connectionNames[0].first;
19055c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
19162d5e2e4SEd Tanous                         [asyncResp, chassisId(std::string(chassisId))](
19262d5e2e4SEd Tanous                             const boost::system::error_code ec,
1931abe55efSEd Tanous                             const std::vector<std::pair<
1941abe55efSEd Tanous                                 std::string, VariantType>> &propertiesList) {
1951abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
1961abe55efSEd Tanous                                      &property : propertiesList)
1971abe55efSEd Tanous                             {
198daf36e2eSEd Tanous                                 const std::string *value =
1991b6b96c5SEd Tanous                                     sdbusplus::message::variant_ns::get_if<
2001b6b96c5SEd Tanous                                         std::string>(&property.second);
2011abe55efSEd Tanous                                 if (value != nullptr)
2021abe55efSEd Tanous                                 {
20362d5e2e4SEd Tanous                                     asyncResp->res.jsonValue[property.first] =
20462d5e2e4SEd Tanous                                         *value;
205daf36e2eSEd Tanous                                 }
206daf36e2eSEd Tanous                             }
20762d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Name"] = chassisId;
20862d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Id"] = chassisId;
20962d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Thermal"] = {
2101abe55efSEd Tanous                                 {"@odata.id", "/redfish/v1/Chassis/" +
2111abe55efSEd Tanous                                                   chassisId + "/Thermal"}};
2122474adfaSEd Tanous                             // Power object
2132474adfaSEd Tanous                             asyncResp->res.jsonValue["Power"] = {
2142474adfaSEd Tanous                                 {"@odata.id", "/redfish/v1/Chassis/" +
2152474adfaSEd Tanous                                                   chassisId + "/Power"}};
2162474adfaSEd Tanous 
2172474adfaSEd Tanous                             // TODO: An array of references to computer systems
2182474adfaSEd Tanous                             // contained in this chassis.
2192474adfaSEd Tanous                             // res.jsonValue["Links"]["ComputerSystems"]
2202474adfaSEd Tanous                             // =
2212474adfaSEd Tanous                             //                          {{{"@odata.id",
2222474adfaSEd Tanous                             //                          "/redfish/v1/Systems/1"}}};
2232474adfaSEd Tanous                             // An array of references to the Managers
2242474adfaSEd Tanous                             // responsible for managing this chassis.
2252474adfaSEd Tanous                             // res.jsonValue["Links"]["ManagedBy"] =
2262474adfaSEd Tanous                             //                        {{{"@odata.id",
2272474adfaSEd Tanous                             //                        "/redfish/v1/Managers/1"}}};
228daf36e2eSEd Tanous                         },
229daf36e2eSEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
2301abe55efSEd Tanous                         "GetAll",
2311abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
232daf36e2eSEd Tanous                     return;
233daf36e2eSEd Tanous                 }
234e0d918bcSEd Tanous 
235daf36e2eSEd Tanous                 // Couldn't find an object with that name.  return an error
236f12894f8SJason M. Bills                 messages::resourceNotFound(
237f12894f8SJason M. Bills                     asyncResp->res, "#Chassis.v1_4_0.Chassis", chassisId);
238daf36e2eSEd Tanous             },
239daf36e2eSEd Tanous             "xyz.openbmc_project.ObjectMapper",
240daf36e2eSEd Tanous             "/xyz/openbmc_project/object_mapper",
241daf36e2eSEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTree",
242daf36e2eSEd Tanous             "/xyz/openbmc_project/inventory", int32_t(0),
243daf36e2eSEd Tanous             std::array<const char *, 1>{
244daf36e2eSEd Tanous                 "xyz.openbmc_project.Inventory.Decorator.Asset"});
245e37f8451SRapkiewicz, Pawel     }
24662d5e2e4SEd Tanous };
247e37f8451SRapkiewicz, Pawel } // namespace redfish
248