xref: /openbmc/bmcweb/redfish-core/lib/chassis.hpp (revision 029573d4)
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>
21abf2add6SEd Tanous #include <variant>
22e37f8451SRapkiewicz, Pawel 
231abe55efSEd Tanous namespace redfish
241abe55efSEd Tanous {
25e37f8451SRapkiewicz, Pawel 
26e37f8451SRapkiewicz, Pawel /**
27e37f8451SRapkiewicz, Pawel  * DBus types primitives for several generic DBus interfaces
28e37f8451SRapkiewicz, Pawel  * TODO(Pawel) consider move this to separate file into boost::dbus
29e37f8451SRapkiewicz, Pawel  */
3055c7b7a2SEd Tanous // Note, this is not a very useful Variant, but because it isn't used to get
31aa2e59c1SEd Tanous // values, it should be as simple as possible
32aa2e59c1SEd Tanous // TODO(ed) invent a nullvariant type
33abf2add6SEd Tanous using VariantType = std::variant<bool, std::string, uint64_t>;
34aa2e59c1SEd Tanous using ManagedObjectsType = std::vector<std::pair<
35aa2e59c1SEd Tanous     sdbusplus::message::object_path,
36aa2e59c1SEd Tanous     std::vector<std::pair<std::string,
37aa2e59c1SEd Tanous                           std::vector<std::pair<std::string, VariantType>>>>>>;
38e37f8451SRapkiewicz, Pawel 
39aa2e59c1SEd Tanous using PropertiesType = boost::container::flat_map<std::string, VariantType>;
40e37f8451SRapkiewicz, Pawel 
41e37f8451SRapkiewicz, Pawel /**
42e37f8451SRapkiewicz, Pawel  * ChassisCollection derived class for delivering Chassis Collection Schema
43e37f8451SRapkiewicz, Pawel  */
441abe55efSEd Tanous class ChassisCollection : public Node
451abe55efSEd Tanous {
46e37f8451SRapkiewicz, Pawel   public:
471abe55efSEd Tanous     ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/")
481abe55efSEd Tanous     {
49e0d918bcSEd Tanous         entityPrivileges = {
50e0d918bcSEd Tanous             {boost::beast::http::verb::get, {{"Login"}}},
51e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
52e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
53e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
54e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
55e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
56e37f8451SRapkiewicz, Pawel     }
57e37f8451SRapkiewicz, Pawel 
58e37f8451SRapkiewicz, Pawel   private:
59e37f8451SRapkiewicz, Pawel     /**
60e37f8451SRapkiewicz, Pawel      * Functions triggers appropriate requests on DBus
61e37f8451SRapkiewicz, Pawel      */
6255c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
631abe55efSEd Tanous                const std::vector<std::string> &params) override
641abe55efSEd Tanous     {
658f1ac8e9SGunnar Mills         const std::array<const char *, 3> interfaces = {
6662d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.Board",
6762d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.Chassis",
688f1ac8e9SGunnar Mills             "xyz.openbmc_project.Inventory.Item.PowerSupply"};
690f74e643SEd Tanous         res.jsonValue["@odata.type"] = "#ChassisCollection.ChassisCollection";
700f74e643SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
710f74e643SEd Tanous         res.jsonValue["@odata.context"] =
720f74e643SEd Tanous             "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
730f74e643SEd Tanous         res.jsonValue["Name"] = "Chassis Collection";
740f74e643SEd Tanous 
7562d5e2e4SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
7662d5e2e4SEd Tanous         crow::connections::systemBus->async_method_call(
7762d5e2e4SEd Tanous             [asyncResp](const boost::system::error_code ec,
7862d5e2e4SEd Tanous                         const std::vector<std::string> &chassisList) {
7962d5e2e4SEd Tanous                 if (ec)
801abe55efSEd Tanous                 {
81f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
8262d5e2e4SEd Tanous                     return;
83e37f8451SRapkiewicz, Pawel                 }
8462d5e2e4SEd Tanous                 nlohmann::json &chassisArray =
8562d5e2e4SEd Tanous                     asyncResp->res.jsonValue["Members"];
8662d5e2e4SEd Tanous                 chassisArray = nlohmann::json::array();
8762d5e2e4SEd Tanous                 for (const std::string &objpath : chassisList)
8862d5e2e4SEd Tanous                 {
8962d5e2e4SEd Tanous                     std::size_t lastPos = objpath.rfind("/");
9062d5e2e4SEd Tanous                     if (lastPos == std::string::npos)
9162d5e2e4SEd Tanous                     {
9262d5e2e4SEd Tanous                         BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
9362d5e2e4SEd Tanous                         continue;
9462d5e2e4SEd Tanous                     }
9562d5e2e4SEd Tanous                     chassisArray.push_back(
9662d5e2e4SEd Tanous                         {{"@odata.id", "/redfish/v1/Chassis/" +
9762d5e2e4SEd Tanous                                            objpath.substr(lastPos + 1)}});
98e37f8451SRapkiewicz, Pawel                 }
99e37f8451SRapkiewicz, Pawel 
10062d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] =
10162d5e2e4SEd Tanous                     chassisArray.size();
10262d5e2e4SEd Tanous             },
10362d5e2e4SEd Tanous             "xyz.openbmc_project.ObjectMapper",
10462d5e2e4SEd Tanous             "/xyz/openbmc_project/object_mapper",
10562d5e2e4SEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
106734bfe90SGunnar Mills             "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
10762d5e2e4SEd Tanous     }
108e37f8451SRapkiewicz, Pawel };
109e37f8451SRapkiewicz, Pawel 
110e37f8451SRapkiewicz, Pawel /**
111e37f8451SRapkiewicz, Pawel  * Chassis override class for delivering Chassis Schema
112e37f8451SRapkiewicz, Pawel  */
1131abe55efSEd Tanous class Chassis : public Node
1141abe55efSEd Tanous {
115e37f8451SRapkiewicz, Pawel   public:
1161abe55efSEd Tanous     Chassis(CrowApp &app) :
1171abe55efSEd Tanous         Node(app, "/redfish/v1/Chassis/<str>/", std::string())
1181abe55efSEd Tanous     {
119e0d918bcSEd Tanous         entityPrivileges = {
120e0d918bcSEd Tanous             {boost::beast::http::verb::get, {{"Login"}}},
121e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
122e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
123e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
124e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
125e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
126e37f8451SRapkiewicz, Pawel     }
127e37f8451SRapkiewicz, Pawel 
128e37f8451SRapkiewicz, Pawel   private:
129e37f8451SRapkiewicz, Pawel     /**
130e37f8451SRapkiewicz, Pawel      * Functions triggers appropriate requests on DBus
131e37f8451SRapkiewicz, Pawel      */
13255c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
1331abe55efSEd Tanous                const std::vector<std::string> &params) override
1341abe55efSEd Tanous     {
135734bfe90SGunnar Mills         const std::array<const char *, 3> interfaces = {
136734bfe90SGunnar Mills             "xyz.openbmc_project.Inventory.Item.Board",
137734bfe90SGunnar Mills             "xyz.openbmc_project.Inventory.Item.Chassis",
138734bfe90SGunnar Mills             "xyz.openbmc_project.Inventory.Item.PowerSupply"};
139734bfe90SGunnar Mills 
140e37f8451SRapkiewicz, Pawel         // Check if there is required param, truly entering this shall be
141e37f8451SRapkiewicz, Pawel         // impossible.
1421abe55efSEd Tanous         if (params.size() != 1)
1431abe55efSEd Tanous         {
144f12894f8SJason M. Bills             messages::internalError(res);
145e37f8451SRapkiewicz, Pawel             res.end();
146e37f8451SRapkiewicz, Pawel             return;
147e37f8451SRapkiewicz, Pawel         }
148e37f8451SRapkiewicz, Pawel 
1490f74e643SEd Tanous         res.jsonValue["@odata.type"] = "#Chassis.v1_4_0.Chassis";
1500f74e643SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
1510f74e643SEd Tanous         res.jsonValue["@odata.context"] =
1520f74e643SEd Tanous             "/redfish/v1/$metadata#Chassis.Chassis";
1530f74e643SEd Tanous         res.jsonValue["Name"] = "Chassis Collection";
1540f74e643SEd Tanous         res.jsonValue["ChassisType"] = "RackMount";
1550f74e643SEd Tanous         res.jsonValue["PowerState"] = "On";
1560f74e643SEd Tanous 
15755c7b7a2SEd Tanous         const std::string &chassisId = params[0];
15862d5e2e4SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
15955c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
16062d5e2e4SEd Tanous             [asyncResp, chassisId(std::string(chassisId))](
16162d5e2e4SEd Tanous                 const boost::system::error_code ec,
162daf36e2eSEd Tanous                 const std::vector<std::pair<
1631abe55efSEd Tanous                     std::string, std::vector<std::pair<
1641abe55efSEd Tanous                                      std::string, std::vector<std::string>>>>>
165daf36e2eSEd Tanous                     &subtree) {
16662d5e2e4SEd Tanous                 if (ec)
1671abe55efSEd Tanous                 {
168f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
169daf36e2eSEd Tanous                     return;
170daf36e2eSEd Tanous                 }
171daf36e2eSEd Tanous                 // Iterate over all retrieved ObjectPaths.
1721abe55efSEd Tanous                 for (const std::pair<
1731abe55efSEd Tanous                          std::string,
1741abe55efSEd Tanous                          std::vector<
1751abe55efSEd Tanous                              std::pair<std::string, std::vector<std::string>>>>
1761abe55efSEd Tanous                          &object : subtree)
1771abe55efSEd Tanous                 {
178daf36e2eSEd Tanous                     const std::string &path = object.first;
1791abe55efSEd Tanous                     const std::vector<
1801abe55efSEd Tanous                         std::pair<std::string, std::vector<std::string>>>
181daf36e2eSEd Tanous                         &connectionNames = object.second;
182e0d918bcSEd Tanous 
1831abe55efSEd Tanous                     if (!boost::ends_with(path, chassisId))
1841abe55efSEd Tanous                     {
185daf36e2eSEd Tanous                         continue;
186daf36e2eSEd Tanous                     }
1871abe55efSEd Tanous                     if (connectionNames.size() < 1)
1881abe55efSEd Tanous                     {
1891abe55efSEd Tanous                         BMCWEB_LOG_ERROR << "Only got "
1901abe55efSEd Tanous                                          << connectionNames.size()
19155c7b7a2SEd Tanous                                          << " Connection names";
192e0d918bcSEd Tanous                         continue;
193daf36e2eSEd Tanous                     }
194e0d918bcSEd Tanous 
195daf36e2eSEd Tanous                     const std::string connectionName = connectionNames[0].first;
19655c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
19762d5e2e4SEd Tanous                         [asyncResp, chassisId(std::string(chassisId))](
19862d5e2e4SEd Tanous                             const boost::system::error_code ec,
1991abe55efSEd Tanous                             const std::vector<std::pair<
2001abe55efSEd Tanous                                 std::string, VariantType>> &propertiesList) {
2011abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
2021abe55efSEd Tanous                                      &property : propertiesList)
2031abe55efSEd Tanous                             {
204daf36e2eSEd Tanous                                 const std::string *value =
205abf2add6SEd Tanous                                     std::get_if<std::string>(&property.second);
2061abe55efSEd Tanous                                 if (value != nullptr)
2071abe55efSEd Tanous                                 {
20862d5e2e4SEd Tanous                                     asyncResp->res.jsonValue[property.first] =
20962d5e2e4SEd Tanous                                         *value;
210daf36e2eSEd Tanous                                 }
211daf36e2eSEd Tanous                             }
21262d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Name"] = chassisId;
21362d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Id"] = chassisId;
21462d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Thermal"] = {
2151abe55efSEd Tanous                                 {"@odata.id", "/redfish/v1/Chassis/" +
2161abe55efSEd Tanous                                                   chassisId + "/Thermal"}};
2172474adfaSEd Tanous                             // Power object
2182474adfaSEd Tanous                             asyncResp->res.jsonValue["Power"] = {
2192474adfaSEd Tanous                                 {"@odata.id", "/redfish/v1/Chassis/" +
2202474adfaSEd Tanous                                                   chassisId + "/Power"}};
221*029573d4SEd Tanous                             asyncResp->res.jsonValue["Status"] = {
222*029573d4SEd Tanous                                 {"Health", "OK"},
223*029573d4SEd Tanous                                 {"State", "Enabled"},
224*029573d4SEd Tanous                             };
2252474adfaSEd Tanous 
226*029573d4SEd Tanous                             asyncResp->res
227*029573d4SEd Tanous                                 .jsonValue["Links"]["ComputerSystems"] = {
228*029573d4SEd Tanous                                 {{"@odata.id", "/redfish/v1/Systems/system"}}};
229*029573d4SEd Tanous                             asyncResp->res.jsonValue["Links"]["ManagedBy"] = {
230*029573d4SEd Tanous                                 {{"@odata.id", "/redfish/v1/Managers/bmc"}}};
231daf36e2eSEd Tanous                         },
232daf36e2eSEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
2331abe55efSEd Tanous                         "GetAll",
2341abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
235daf36e2eSEd Tanous                     return;
236daf36e2eSEd Tanous                 }
237e0d918bcSEd Tanous 
238daf36e2eSEd Tanous                 // Couldn't find an object with that name.  return an error
239f12894f8SJason M. Bills                 messages::resourceNotFound(
240f12894f8SJason M. Bills                     asyncResp->res, "#Chassis.v1_4_0.Chassis", chassisId);
241daf36e2eSEd Tanous             },
242daf36e2eSEd Tanous             "xyz.openbmc_project.ObjectMapper",
243daf36e2eSEd Tanous             "/xyz/openbmc_project/object_mapper",
244daf36e2eSEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTree",
245734bfe90SGunnar Mills             "/xyz/openbmc_project/inventory", int32_t(0), interfaces);
246e37f8451SRapkiewicz, Pawel     }
24762d5e2e4SEd Tanous };
248e37f8451SRapkiewicz, Pawel } // namespace redfish
249