blob: 66157608342f72db40b722dcf23c695110e72e61 [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 {
48 Node::json["@odata.type"] = "#ChassisCollection.ChassisCollection";
49 Node::json["@odata.id"] = "/redfish/v1/Chassis";
50 Node::json["@odata.context"] =
51 "/redfish/v1/$metadata#ChassisCollection.ChassisCollection";
52 Node::json["Name"] = "Chassis Collection";
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010053
Ed Tanous1abe55e2018-09-05 08:30:59 -070054 entityPrivileges = {
55 {boost::beast::http::verb::get, {{"Login"}}},
56 {boost::beast::http::verb::head, {{"Login"}}},
57 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
58 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
59 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
60 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
61 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +010062
Ed Tanous1abe55e2018-09-05 08:30:59 -070063 private:
64 /**
65 * Functions triggers appropriate requests on DBus
66 */
67 void doGet(crow::Response &res, const crow::Request &req,
68 const std::vector<std::string> &params) override
69 {
Ed Tanous62d5e2e2018-09-05 16:17:25 -070070 const std::array<const char *, 4> interfaces = {
71 "xyz.openbmc_project.Inventory.Item.Board",
72 "xyz.openbmc_project.Inventory.Item.Chassis",
73 "xyz.openbmc_project.Inventory.Item.PowerSupply",
74 "xyz.openbmc_project.Inventory.Item.System",
75 };
76 res.jsonValue = Node::json;
77 auto asyncResp = std::make_shared<AsyncResp>(res);
78 crow::connections::systemBus->async_method_call(
79 [asyncResp](const boost::system::error_code ec,
80 const std::vector<std::string> &chassisList) {
81 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -070082 {
Jason M. Billsf12894f2018-10-09 12:45:45 -070083 messages::internalError(asyncResp->res);
Ed Tanous62d5e2e2018-09-05 16:17:25 -070084 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -070085 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -070086 nlohmann::json &chassisArray =
87 asyncResp->res.jsonValue["Members"];
88 chassisArray = nlohmann::json::array();
89 for (const std::string &objpath : chassisList)
90 {
91 std::size_t lastPos = objpath.rfind("/");
92 if (lastPos == std::string::npos)
93 {
94 BMCWEB_LOG_ERROR << "Failed to find '/' in " << objpath;
95 continue;
96 }
97 chassisArray.push_back(
98 {{"@odata.id", "/redfish/v1/Chassis/" +
99 objpath.substr(lastPos + 1)}});
100 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100101
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700102 asyncResp->res.jsonValue["Members@odata.count"] =
103 chassisArray.size();
104 },
105 "xyz.openbmc_project.ObjectMapper",
106 "/xyz/openbmc_project/object_mapper",
107 "xyz.openbmc_project.ObjectMapper", "GetSubTreePaths",
108 "/xyz/openbmc_project/inventory", int32_t(3), interfaces);
109 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100110};
111
112/**
113 * Chassis override class for delivering Chassis Schema
114 */
Ed Tanous1abe55e2018-09-05 08:30:59 -0700115class Chassis : public Node
116{
117 public:
118 Chassis(CrowApp &app) :
119 Node(app, "/redfish/v1/Chassis/<str>/", std::string())
120 {
121 Node::json["@odata.type"] = "#Chassis.v1_4_0.Chassis";
122 Node::json["@odata.id"] = "/redfish/v1/Chassis";
123 Node::json["@odata.context"] = "/redfish/v1/$metadata#Chassis.Chassis";
124 Node::json["Name"] = "Chassis Collection";
125 Node::json["ChassisType"] = "RackMount";
Ed Tanousaef72902018-10-12 13:45:21 -0700126 Node::json["PowerState"] = "On";
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100127
Ed Tanous1abe55e2018-09-05 08:30:59 -0700128 entityPrivileges = {
129 {boost::beast::http::verb::get, {{"Login"}}},
130 {boost::beast::http::verb::head, {{"Login"}}},
131 {boost::beast::http::verb::patch, {{"ConfigureComponents"}}},
132 {boost::beast::http::verb::put, {{"ConfigureComponents"}}},
133 {boost::beast::http::verb::delete_, {{"ConfigureComponents"}}},
134 {boost::beast::http::verb::post, {{"ConfigureComponents"}}}};
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100135 }
Rapkiewicz, Pawele37f8452018-03-09 13:49:50 +0100136
Ed Tanous1abe55e2018-09-05 08:30:59 -0700137 private:
138 /**
139 * Functions triggers appropriate requests on DBus
140 */
141 void doGet(crow::Response &res, const crow::Request &req,
142 const std::vector<std::string> &params) override
143 {
144 // Check if there is required param, truly entering this shall be
145 // impossible.
146 if (params.size() != 1)
147 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700148 messages::internalError(res);
Ed Tanousdaf36e22018-04-20 16:01:36 -0700149 res.end();
150 return;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700151 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700152
Ed Tanous1abe55e2018-09-05 08:30:59 -0700153 res.jsonValue = Node::json;
154 const std::string &chassisId = params[0];
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700155 auto asyncResp = std::make_shared<AsyncResp>(res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700156 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700157 [asyncResp, chassisId(std::string(chassisId))](
158 const boost::system::error_code ec,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700159 const std::vector<std::pair<
160 std::string, std::vector<std::pair<
161 std::string, std::vector<std::string>>>>>
162 &subtree) {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700163 if (ec)
Ed Tanous1abe55e2018-09-05 08:30:59 -0700164 {
Jason M. Billsf12894f2018-10-09 12:45:45 -0700165 messages::internalError(asyncResp->res);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700166 return;
167 }
168 // Iterate over all retrieved ObjectPaths.
169 for (const std::pair<
170 std::string,
171 std::vector<
172 std::pair<std::string, std::vector<std::string>>>>
173 &object : subtree)
174 {
175 const std::string &path = object.first;
176 const std::vector<
177 std::pair<std::string, std::vector<std::string>>>
178 &connectionNames = object.second;
Ed Tanouse0d918b2018-03-27 17:41:04 -0700179
Ed Tanous1abe55e2018-09-05 08:30:59 -0700180 if (!boost::ends_with(path, chassisId))
181 {
182 continue;
Ed Tanousdaf36e22018-04-20 16:01:36 -0700183 }
Ed Tanous1abe55e2018-09-05 08:30:59 -0700184 if (connectionNames.size() < 1)
185 {
186 BMCWEB_LOG_ERROR << "Only got "
187 << connectionNames.size()
188 << " Connection names";
189 continue;
190 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700191
Ed Tanous1abe55e2018-09-05 08:30:59 -0700192 const std::string connectionName = connectionNames[0].first;
193 crow::connections::systemBus->async_method_call(
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700194 [asyncResp, chassisId(std::string(chassisId))](
195 const boost::system::error_code ec,
Ed Tanous1abe55e2018-09-05 08:30:59 -0700196 const std::vector<std::pair<
197 std::string, VariantType>> &propertiesList) {
198 for (const std::pair<std::string, VariantType>
199 &property : propertiesList)
200 {
201 const std::string *value =
202 mapbox::getPtr<const std::string>(
203 property.second);
204 if (value != nullptr)
205 {
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700206 asyncResp->res.jsonValue[property.first] =
207 *value;
Ed Tanous1abe55e2018-09-05 08:30:59 -0700208 }
209 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700210 asyncResp->res.jsonValue["Name"] = chassisId;
211 asyncResp->res.jsonValue["Id"] = chassisId;
212 asyncResp->res.jsonValue["Thermal"] = {
Ed Tanous1abe55e2018-09-05 08:30:59 -0700213 {"@odata.id", "/redfish/v1/Chassis/" +
214 chassisId + "/Thermal"}};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700215 },
216 connectionName, path, "org.freedesktop.DBus.Properties",
217 "GetAll",
218 "xyz.openbmc_project.Inventory.Decorator.Asset");
Ed Tanous1abe55e2018-09-05 08:30:59 -0700219 return;
220 }
Ed Tanouse0d918b2018-03-27 17:41:04 -0700221
Ed Tanous1abe55e2018-09-05 08:30:59 -0700222 // Couldn't find an object with that name. return an error
Jason M. Billsf12894f2018-10-09 12:45:45 -0700223 messages::resourceNotFound(
224 asyncResp->res, "#Chassis.v1_4_0.Chassis", chassisId);
Ed Tanous1abe55e2018-09-05 08:30:59 -0700225 },
226 "xyz.openbmc_project.ObjectMapper",
227 "/xyz/openbmc_project/object_mapper",
228 "xyz.openbmc_project.ObjectMapper", "GetSubTree",
229 "/xyz/openbmc_project/inventory", int32_t(0),
230 std::array<const char *, 1>{
231 "xyz.openbmc_project.Inventory.Decorator.Asset"});
232 }
Ed Tanous62d5e2e2018-09-05 16:17:25 -0700233};
Ed Tanous1abe55e2018-09-05 08:30:59 -0700234} // namespace redfish