xref: /openbmc/bmcweb/redfish-core/lib/chassis.hpp (revision 0f74e643)
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     {
6462d5e2e4SEd Tanous         const std::array<const char *, 4> interfaces = {
6562d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.Board",
6662d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.Chassis",
6762d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.PowerSupply",
6862d5e2e4SEd Tanous             "xyz.openbmc_project.Inventory.Item.System",
6962d5e2e4SEd Tanous         };
70*0f74e643SEd Tanous         res.jsonValue["@odata.type"] = "#ChassisCollection.ChassisCollection";
71*0f74e643SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
72*0f74e643SEd Tanous         res.jsonValue["@odata.context"] =
73*0f74e643SEd Tanous             "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
74*0f74e643SEd Tanous         res.jsonValue["Name"] = "Chassis Collection";
75*0f74e643SEd Tanous 
7662d5e2e4SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
7762d5e2e4SEd Tanous         crow::connections::systemBus->async_method_call(
7862d5e2e4SEd Tanous             [asyncResp](const boost::system::error_code ec,
7962d5e2e4SEd Tanous                         const std::vector<std::string> &chassisList) {
8062d5e2e4SEd Tanous                 if (ec)
811abe55efSEd Tanous                 {
82f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
8362d5e2e4SEd Tanous                     return;
84e37f8451SRapkiewicz, Pawel                 }
8562d5e2e4SEd Tanous                 nlohmann::json &chassisArray =
8662d5e2e4SEd Tanous                     asyncResp->res.jsonValue["Members"];
8762d5e2e4SEd Tanous                 chassisArray = nlohmann::json::array();
8862d5e2e4SEd Tanous                 for (const std::string &objpath : chassisList)
8962d5e2e4SEd Tanous                 {
9062d5e2e4SEd Tanous                     std::size_t lastPos = objpath.rfind("/");
9162d5e2e4SEd Tanous                     if (lastPos == std::string::npos)
9262d5e2e4SEd Tanous                     {
9362d5e2e4SEd Tanous                         BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
9462d5e2e4SEd Tanous                         continue;
9562d5e2e4SEd Tanous                     }
9662d5e2e4SEd Tanous                     chassisArray.push_back(
9762d5e2e4SEd Tanous                         {{"@odata.id", "/redfish/v1/Chassis/" +
9862d5e2e4SEd Tanous                                            objpath.substr(lastPos + 1)}});
99e37f8451SRapkiewicz, Pawel                 }
100e37f8451SRapkiewicz, Pawel 
10162d5e2e4SEd Tanous                 asyncResp->res.jsonValue["Members@odata.count"] =
10262d5e2e4SEd Tanous                     chassisArray.size();
10362d5e2e4SEd Tanous             },
10462d5e2e4SEd Tanous             "xyz.openbmc_project.ObjectMapper",
10562d5e2e4SEd Tanous             "/xyz/openbmc_project/object_mapper",
10662d5e2e4SEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
10762d5e2e4SEd Tanous             "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
10862d5e2e4SEd Tanous     }
109e37f8451SRapkiewicz, Pawel };
110e37f8451SRapkiewicz, Pawel 
111e37f8451SRapkiewicz, Pawel /**
112e37f8451SRapkiewicz, Pawel  * Chassis override class for delivering Chassis Schema
113e37f8451SRapkiewicz, Pawel  */
1141abe55efSEd Tanous class Chassis : public Node
1151abe55efSEd Tanous {
116e37f8451SRapkiewicz, Pawel   public:
1171abe55efSEd Tanous     Chassis(CrowApp &app) :
1181abe55efSEd Tanous         Node(app, "/redfish/v1/Chassis/<str>/", std::string())
1191abe55efSEd Tanous     {
120e0d918bcSEd Tanous         entityPrivileges = {
121e0d918bcSEd Tanous             {boost::beast::http::verb::get, {{"Login"}}},
122e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
123e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
124e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
125e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
126e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
127e37f8451SRapkiewicz, Pawel     }
128e37f8451SRapkiewicz, Pawel 
129e37f8451SRapkiewicz, Pawel   private:
130e37f8451SRapkiewicz, Pawel     /**
131e37f8451SRapkiewicz, Pawel      * Functions triggers appropriate requests on DBus
132e37f8451SRapkiewicz, Pawel      */
13355c7b7a2SEd Tanous     void doGet(crow::Response &res, const crow::Request &req,
1341abe55efSEd Tanous                const std::vector<std::string> &params) override
1351abe55efSEd Tanous     {
136e37f8451SRapkiewicz, Pawel         // Check if there is required param, truly entering this shall be
137e37f8451SRapkiewicz, Pawel         // impossible.
1381abe55efSEd Tanous         if (params.size() != 1)
1391abe55efSEd Tanous         {
140f12894f8SJason M. Bills             messages::internalError(res);
141e37f8451SRapkiewicz, Pawel             res.end();
142e37f8451SRapkiewicz, Pawel             return;
143e37f8451SRapkiewicz, Pawel         }
144e37f8451SRapkiewicz, Pawel 
145*0f74e643SEd Tanous         res.jsonValue["@odata.type"] = "#Chassis.v1_4_0.Chassis";
146*0f74e643SEd Tanous         res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
147*0f74e643SEd Tanous         res.jsonValue["@odata.context"] =
148*0f74e643SEd Tanous             "/redfish/v1/$metadata#Chassis.Chassis";
149*0f74e643SEd Tanous         res.jsonValue["Name"] = "Chassis Collection";
150*0f74e643SEd Tanous         res.jsonValue["ChassisType"] = "RackMount";
151*0f74e643SEd Tanous         res.jsonValue["PowerState"] = "On";
152*0f74e643SEd Tanous 
15355c7b7a2SEd Tanous         const std::string &chassisId = params[0];
15462d5e2e4SEd Tanous         auto asyncResp = std::make_shared<AsyncResp>(res);
15555c7b7a2SEd Tanous         crow::connections::systemBus->async_method_call(
15662d5e2e4SEd Tanous             [asyncResp, chassisId(std::string(chassisId))](
15762d5e2e4SEd Tanous                 const boost::system::error_code ec,
158daf36e2eSEd Tanous                 const std::vector<std::pair<
1591abe55efSEd Tanous                     std::string, std::vector<std::pair<
1601abe55efSEd Tanous                                      std::string, std::vector<std::string>>>>>
161daf36e2eSEd Tanous                     &subtree) {
16262d5e2e4SEd Tanous                 if (ec)
1631abe55efSEd Tanous                 {
164f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
165daf36e2eSEd Tanous                     return;
166daf36e2eSEd Tanous                 }
167daf36e2eSEd Tanous                 // Iterate over all retrieved ObjectPaths.
1681abe55efSEd Tanous                 for (const std::pair<
1691abe55efSEd Tanous                          std::string,
1701abe55efSEd Tanous                          std::vector<
1711abe55efSEd Tanous                              std::pair<std::string, std::vector<std::string>>>>
1721abe55efSEd Tanous                          &object : subtree)
1731abe55efSEd Tanous                 {
174daf36e2eSEd Tanous                     const std::string &path = object.first;
1751abe55efSEd Tanous                     const std::vector<
1761abe55efSEd Tanous                         std::pair<std::string, std::vector<std::string>>>
177daf36e2eSEd Tanous                         &connectionNames = object.second;
178e0d918bcSEd Tanous 
1791abe55efSEd Tanous                     if (!boost::ends_with(path, chassisId))
1801abe55efSEd Tanous                     {
181daf36e2eSEd Tanous                         continue;
182daf36e2eSEd Tanous                     }
1831abe55efSEd Tanous                     if (connectionNames.size() < 1)
1841abe55efSEd Tanous                     {
1851abe55efSEd Tanous                         BMCWEB_LOG_ERROR << "Only got "
1861abe55efSEd Tanous                                          << connectionNames.size()
18755c7b7a2SEd Tanous                                          << " Connection names";
188e0d918bcSEd Tanous                         continue;
189daf36e2eSEd Tanous                     }
190e0d918bcSEd Tanous 
191daf36e2eSEd Tanous                     const std::string connectionName = connectionNames[0].first;
19255c7b7a2SEd Tanous                     crow::connections::systemBus->async_method_call(
19362d5e2e4SEd Tanous                         [asyncResp, chassisId(std::string(chassisId))](
19462d5e2e4SEd Tanous                             const boost::system::error_code ec,
1951abe55efSEd Tanous                             const std::vector<std::pair<
1961abe55efSEd Tanous                                 std::string, VariantType>> &propertiesList) {
1971abe55efSEd Tanous                             for (const std::pair<std::string, VariantType>
1981abe55efSEd Tanous                                      &property : propertiesList)
1991abe55efSEd Tanous                             {
200daf36e2eSEd Tanous                                 const std::string *value =
2011abe55efSEd Tanous                                     mapbox::getPtr<const std::string>(
2021abe55efSEd Tanous                                         property.second);
2031abe55efSEd Tanous                                 if (value != nullptr)
2041abe55efSEd Tanous                                 {
20562d5e2e4SEd Tanous                                     asyncResp->res.jsonValue[property.first] =
20662d5e2e4SEd Tanous                                         *value;
207daf36e2eSEd Tanous                                 }
208daf36e2eSEd Tanous                             }
20962d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Name"] = chassisId;
21062d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Id"] = chassisId;
21162d5e2e4SEd Tanous                             asyncResp->res.jsonValue["Thermal"] = {
2121abe55efSEd Tanous                                 {"@odata.id", "/redfish/v1/Chassis/" +
2131abe55efSEd Tanous                                                   chassisId + "/Thermal"}};
2142474adfaSEd Tanous                             // Power object
2152474adfaSEd Tanous                             asyncResp->res.jsonValue["Power"] = {
2162474adfaSEd Tanous                                 {"@odata.id", "/redfish/v1/Chassis/" +
2172474adfaSEd Tanous                                                   chassisId + "/Power"}};
2182474adfaSEd Tanous 
2192474adfaSEd Tanous                             // TODO: An array of references to computer systems
2202474adfaSEd Tanous                             // contained in this chassis.
2212474adfaSEd Tanous                             // res.jsonValue["Links"]["ComputerSystems"]
2222474adfaSEd Tanous                             // =
2232474adfaSEd Tanous                             //                          {{{"@odata.id",
2242474adfaSEd Tanous                             //                          "/redfish/v1/Systems/1"}}};
2252474adfaSEd Tanous                             // An array of references to the Managers
2262474adfaSEd Tanous                             // responsible for managing this chassis.
2272474adfaSEd Tanous                             // res.jsonValue["Links"]["ManagedBy"] =
2282474adfaSEd Tanous                             //                        {{{"@odata.id",
2292474adfaSEd Tanous                             //                        "/redfish/v1/Managers/1"}}};
230daf36e2eSEd Tanous                         },
231daf36e2eSEd Tanous                         connectionName, path, "org.freedesktop.DBus.Properties",
2321abe55efSEd Tanous                         "GetAll",
2331abe55efSEd Tanous                         "xyz.openbmc_project.Inventory.Decorator.Asset");
234daf36e2eSEd Tanous                     return;
235daf36e2eSEd Tanous                 }
236e0d918bcSEd Tanous 
237daf36e2eSEd Tanous                 // Couldn't find an object with that name.  return an error
238f12894f8SJason M. Bills                 messages::resourceNotFound(
239f12894f8SJason M. Bills                     asyncResp->res, "#Chassis.v1_4_0.Chassis", chassisId);
240daf36e2eSEd Tanous             },
241daf36e2eSEd Tanous             "xyz.openbmc_project.ObjectMapper",
242daf36e2eSEd Tanous             "/xyz/openbmc_project/object_mapper",
243daf36e2eSEd Tanous             "xyz.openbmc_project.ObjectMapper", "GetSubTree",
244daf36e2eSEd Tanous             "/xyz/openbmc_project/inventory", int32_t(0),
245daf36e2eSEd Tanous             std::array<const char *, 1>{
246daf36e2eSEd Tanous                 "xyz.openbmc_project.Inventory.Decorator.Asset"});
247e37f8451SRapkiewicz, Pawel     }
24862d5e2e4SEd Tanous };
249e37f8451SRapkiewicz, Pawel } // namespace redfish
250