blob: 1c4b9e043d80d5759adb8aab1095916d07934157 [file] [log] [blame]
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +01001/*
2// Copyright (c) 2018 Intel Corporation
3//
4// Licensed under the Apache License, Version 2.0 (the "License");
5// you may not use this file except in compliance with the License.
6// You may obtain a copy of the License at
7//
8// http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15*/
16#pragma once
17
18#include "node.hpp"
Ed Tanous1abe55e2018-09-05 08:30:59 -070019
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010020#include <boost/container/flat_map.hpp>
21
Ed Tanous1abe55e2018-09-05 08:30:59 -070022namespace redfish
23{
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010024
25/**
26 * DBus types primitives for several generic DBus interfaces
27 * TODO(Pawel) consider move this to separate file into boost::dbus
28 */
Ed Tanous55c7b7a2018-05-22 15:27:24 -070029// Note, this is not a very useful Variant, but because it isn't used to get
Ed Tanousaa2e59c2018-04-12 12:17:20 -070030// values, it should be as simple as possible
31// TODO(ed) invent a nullvariant type
Ed Tanous04a258f2018-10-15 08:00:41 -070032using VariantType = sdbusplus::message::variant<bool, std::string, uint64_t>;
Ed Tanousaa2e59c2018-04-12 12:17:20 -070033using ManagedObjectsType = std::vector<std::pair<
34 sdbusplus::message::object_path,
35 std::vector<std::pair<std::string,
36 std::vector<std::pair<std::string, VariantType>>>>>>;
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010037
Ed Tanousaa2e59c2018-04-12 12:17:20 -070038using PropertiesType = boost::container::flat_map<std::string, VariantType>;
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010039
40/**
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010041 * ChassisCollection derived class for delivering Chassis Collection Schema
42 */
Ed Tanous1abe55e2018-09-05 08:30:59 -070043class ChassisCollection : public Node
44{
45 public:
46 ChassisCollection(CrowApp &app) : Node(app, "/redfish/v1/Chassis/")
47 {
Ed Tanous1abe55e2018-09-05 08:30:59 -070048 entityPrivileges = {
49 {boost::beast::http::verb::get, {{"Login"}}},
50 {boost::beast::http::verb::head, {{"Login"}}},
51 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
52 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
53 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
54 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
55 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010056
Ed Tanous1abe55e2018-09-05 08:30:59 -070057 private:
58 /**
59 * Functions triggers appropriate requests on DBus
60 */
61 void doGet(crow::Response &res, const crow::Request &req,
62 const std::vector<std::string> &params) override
63 {
Gunnar Mills8f1ac8e2018-12-06 15:52:46 -060064 const std::array<const char *, 3> interfaces = {
Ed Tanous62d5e2e2018-09-05 16:17:25 -070065 "xyz.openbmc_project.Inventory.Item.Board",
66 "xyz.openbmc_project.Inventory.Item.Chassis",
Gunnar Mills8f1ac8e2018-12-06 15:52:46 -060067 "xyz.openbmc_project.Inventory.Item.PowerSupply"};
Ed Tanous0f74e642018-11-12 15:17:05 -080068 res.jsonValue["@odata.type"] = "#ChassisCollection.ChassisCollection";
69 res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
70 res.jsonValue["@odata.context"] =
71 "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
72 res.jsonValue["Name"] = "Chassis Collection";
73
Ed Tanous62d5e2e2018-09-05 16:17:25 -070074 auto asyncResp = std::make_shared<AsyncResp>(res);
75 crow::connections::systemBus->async_method_call(
76 [asyncResp](const boost::system::error_code ec,
77 const std::vector<std::string> &chassisList) {
78 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -070079 {
Jason M. Billsf12894f2018-10-09 12:45:45 -070080 messages::internalError(asyncResp->res);
Ed Tanous62d5e2e2018-09-05 16:17:25 -070081 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -070082 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -070083 nlohmann::json &chassisArray =
84 asyncResp->res.jsonValue["Members"];
85 chassisArray = nlohmann::json::array();
86 for (const std::string &objpath : chassisList)
87 {
88 std::size_t lastPos = objpath.rfind("/");
89 if (lastPos == std::string::npos)
90 {
91 BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
92 continue;
93 }
94 chassisArray.push_back(
95 {{"@odata.id", "/redfish/v1/Chassis/" +
96 objpath.substr(lastPos + 1)}});
97 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010098
Ed Tanous62d5e2e2018-09-05 16:17:25 -070099 asyncResp->res.jsonValue["Members@odata.count"] =
100 chassisArray.size();
101 },
102 "xyz.openbmc_project.ObjectMapper",
103 "/xyz/openbmc_project/object_mapper",
104 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
105 "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
106 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100107};
108
109/**
110 * Chassis override class for delivering Chassis Schema
111 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700112class Chassis : public Node
113{
114 public:
115 Chassis(CrowApp &app) :
116 Node(app, "/redfish/v1/Chassis/<str>/", std::string())
117 {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700118 entityPrivileges = {
119 {boost::beast::http::verb::get, {{"Login"}}},
120 {boost::beast::http::verb::head, {{"Login"}}},
121 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
122 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
123 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
124 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100125 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100126
Ed Tanous1abe55e2018-09-05 08:30:59 -0700127 private:
128 /**
129 * Functions triggers appropriate requests on DBus
130 */
131 void doGet(crow::Response &res, const crow::Request &req,
132 const std::vector<std::string> &params) override
133 {
134 // Check if there is required param, truly entering this shall be
135 // impossible.
136 if (params.size() != 1)
137 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700138 messages::internalError(res);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700139 res.end();
140 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700141 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700142
Ed Tanous0f74e642018-11-12 15:17:05 -0800143 res.jsonValue["@odata.type"] = "#Chassis.v1_4_0.Chassis";
144 res.jsonValue["@odata.id"] = "/redfish/v1/Chassis";
145 res.jsonValue["@odata.context"] =
146 "/redfish/v1/$metadata#Chassis.Chassis";
147 res.jsonValue["Name"] = "Chassis Collection";
148 res.jsonValue["ChassisType"] = "RackMount";
149 res.jsonValue["PowerState"] = "On";
150
Ed Tanous1abe55e2018-09-05 08:30:59 -0700151 const std::string &chassisId = params[0];
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700152 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700153 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700154 [asyncResp, chassisId(std::string(chassisId))](
155 const boost::system::error_code ec,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700156 const std::vector<std::pair<
157 std::string, std::vector<std::pair<
158 std::string, std::vector<std::string>>>>>
159 &subtree) {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700160 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700161 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700162 messages::internalError(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700163 return;
164 }
165 // Iterate over all retrieved ObjectPaths.
166 for (const std::pair<
167 std::string,
168 std::vector<
169 std::pair<std::string, std::vector<std::string>>>>
170 &object : subtree)
171 {
172 const std::string &path = object.first;
173 const std::vector<
174 std::pair<std::string, std::vector<std::string>>>
175 &connectionNames = object.second;
Ed Tanouse0d918b2018-03-27 17:41:04 -0700176
Ed Tanous1abe55e2018-09-05 08:30:59 -0700177 if (!boost::ends_with(path, chassisId))
178 {
179 continue;
Ed Tanousdaf36e22018-04-20 16:01:36 -0700180 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700181 if (connectionNames.size() < 1)
182 {
183 BMCWEB_LOG_ERROR << "Only got "
184 << connectionNames.size()
185 << " Connection names";
186 continue;
187 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700188
Ed Tanous1abe55e2018-09-05 08:30:59 -0700189 const std::string connectionName = connectionNames[0].first;
190 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700191 [asyncResp, chassisId(std::string(chassisId))](
192 const boost::system::error_code ec,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700193 const std::vector<std::pair<
194 std::string, VariantType>> &propertiesList) {
195 for (const std::pair<std::string, VariantType>
196 &property : propertiesList)
197 {
198 const std::string *value =
Ed Tanous1b6b96c2018-11-30 11:35:41 -0800199 sdbusplus::message::variant_ns::get_if<
200 std::string>(&property.second);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700201 if (value != nullptr)
202 {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700203 asyncResp->res.jsonValue[property.first] =
204 *value;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700205 }
206 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700207 asyncResp->res.jsonValue["Name"] = chassisId;
208 asyncResp->res.jsonValue["Id"] = chassisId;
209 asyncResp->res.jsonValue["Thermal"] = {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700210 {"@odata.id", "/redfish/v1/Chassis/" +
211 chassisId + "/Thermal"}};
Ed Tanous2474adf2018-09-05 16:31:16 -0700212 // Power object
213 asyncResp->res.jsonValue["Power"] = {
214 {"@odata.id", "/redfish/v1/Chassis/" +
215 chassisId + "/Power"}};
216
217 // TODO: An array of references to computer systems
218 // contained in this chassis.
219 // res.jsonValue["Links"]["ComputerSystems"]
220 // =
221 // {{{"@odata.id",
222 // "/redfish/v1/Systems/1"}}};
223 // An array of references to the Managers
224 // responsible for managing this chassis.
225 // res.jsonValue["Links"]["ManagedBy"] =
226 // {{{"@odata.id",
227 // "/redfish/v1/Managers/1"}}};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700228 },
229 connectionName, path, "org.freedesktop.DBus.Properties",
230 "GetAll",
231 "xyz.openbmc_project.Inventory.Decorator.Asset");
Ed Tanous1abe55e2018-09-05 08:30:59 -0700232 return;
233 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700234
Ed Tanous1abe55e2018-09-05 08:30:59 -0700235 // Couldn't find an object with that name. return an error
Jason M. Billsf12894f2018-10-09 12:45:45 -0700236 messages::resourceNotFound(
237 asyncResp->res, "#Chassis.v1_4_0.Chassis", chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700238 },
239 "xyz.openbmc_project.ObjectMapper",
240 "/xyz/openbmc_project/object_mapper",
241 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
242 "/xyz/openbmc_project/inventory", int32_t(0),
243 std::array<const char *, 1>{
244 "xyz.openbmc_project.Inventory.Decorator.Asset"});
245 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700246};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700247} // namespace redfish