blob: be1336bf37016a759d5a19722f2bd9cd366476c3 [file] [log] [blame]
Ed Tanous6c068982023-02-07 15:44:38 -08001#pragma once
2
3#include "app.hpp"
4#include "error_messages.hpp"
5#include "http_request.hpp"
6#include "http_response.hpp"
7#include "query.hpp"
Carson Labrado8b2521a2023-02-18 02:33:14 +00008#include "redfish_aggregator.hpp"
Ed Tanous6c068982023-02-07 15:44:38 -08009#include "registries/privilege_registry.hpp"
10
Ed Tanousef4c65b2023-04-24 15:28:50 -070011#include <boost/url/format.hpp>
Ed Tanous6c068982023-02-07 15:44:38 -080012#include <nlohmann/json.hpp>
13
14#include <functional>
15#include <memory>
16
17namespace redfish
18{
19
20inline void handleAggregationServiceHead(
21 App& app, const crow::Request& req,
22 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
23{
24 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
25 {
26 return;
27 }
28 asyncResp->res.addHeader(
29 boost::beast::http::field::link,
30 "</redfish/v1/JsonSchemas/AggregationService/AggregationService.json>; rel=describedby");
31}
32
33inline void handleAggregationServiceGet(
34 App& app, const crow::Request& req,
35 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
36{
37 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
38 {
39 return;
40 }
41 asyncResp->res.addHeader(
42 boost::beast::http::field::link,
43 "</redfish/v1/JsonSchemas/AggregationService/AggregationService.json>; rel=describedby");
44 nlohmann::json& json = asyncResp->res.jsonValue;
45 json["@odata.id"] = "/redfish/v1/AggregationService";
46 json["@odata.type"] = "#AggregationService.v1_0_1.AggregationService";
47 json["Id"] = "AggregationService";
48 json["Name"] = "Aggregation Service";
49 json["Description"] = "Aggregation Service";
50 json["ServiceEnabled"] = true;
Carson Labrado5315c1b2023-02-18 01:02:18 +000051 json["AggregationSources"]["@odata.id"] =
52 "/redfish/v1/AggregationService/AggregationSources";
Ed Tanous6c068982023-02-07 15:44:38 -080053}
54
Carson Labrado8b2521a2023-02-18 02:33:14 +000055inline void requestRoutesAggregationService(App& app)
Ed Tanous6c068982023-02-07 15:44:38 -080056{
57 BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/")
58 .privileges(redfish::privileges::headAggregationService)
59 .methods(boost::beast::http::verb::head)(
60 std::bind_front(handleAggregationServiceHead, std::ref(app)));
61 BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/")
62 .privileges(redfish::privileges::getAggregationService)
63 .methods(boost::beast::http::verb::get)(
64 std::bind_front(handleAggregationServiceGet, std::ref(app)));
65}
66
Carson Labrado8b2521a2023-02-18 02:33:14 +000067inline void populateAggregationSourceCollection(
68 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous81c4e332023-05-18 10:30:34 -070069 const boost::system::error_code& ec,
Carson Labrado8b2521a2023-02-18 02:33:14 +000070 const std::unordered_map<std::string, boost::urls::url>& satelliteInfo)
71{
72 // Something went wrong while querying dbus
73 if (ec)
74 {
75 messages::internalError(asyncResp->res);
76 return;
77 }
78 nlohmann::json::array_t members = nlohmann::json::array();
79 for (const auto& sat : satelliteInfo)
80 {
81 nlohmann::json::object_t member;
Ed Tanousef4c65b2023-04-24 15:28:50 -070082 member["@odata.id"] = boost::urls::format(
83 "/redfish/v1/AggregationService/AggregationSources/{}", sat.first);
Patrick Williamsad539542023-05-12 10:10:08 -050084 members.emplace_back(std::move(member));
Carson Labrado8b2521a2023-02-18 02:33:14 +000085 }
86 asyncResp->res.jsonValue["Members@odata.count"] = members.size();
87 asyncResp->res.jsonValue["Members"] = std::move(members);
88}
89
90inline void handleAggregationSourceCollectionGet(
Carson Labrado5315c1b2023-02-18 01:02:18 +000091 App& app, const crow::Request& req,
92 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
93{
94 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
95 {
96 return;
97 }
98 asyncResp->res.addHeader(
99 boost::beast::http::field::link,
100 "</redfish/v1/JsonSchemas/AggregationSourceCollection/AggregationSourceCollection.json>; rel=describedby");
101 nlohmann::json& json = asyncResp->res.jsonValue;
102 json["@odata.id"] = "/redfish/v1/AggregationService/AggregationSources";
103 json["@odata.type"] =
104 "#AggregationSourceCollection.AggregationSourceCollection";
105 json["Name"] = "Aggregation Source Collection";
Carson Labrado5315c1b2023-02-18 01:02:18 +0000106
Carson Labrado8b2521a2023-02-18 02:33:14 +0000107 // Query D-Bus for satellite configs and add them to the Members array
108 RedfishAggregator::getSatelliteConfigs(
109 std::bind_front(populateAggregationSourceCollection, asyncResp));
Carson Labrado5315c1b2023-02-18 01:02:18 +0000110}
111
Carson Labrado8b2521a2023-02-18 02:33:14 +0000112inline void handleAggregationSourceCollectionHead(
113 App& app, const crow::Request& req,
114 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
115{
116 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
117 {
118 return;
119 }
120 asyncResp->res.addHeader(
121 boost::beast::http::field::link,
122 "</redfish/v1/JsonSchemas/AggregationService/AggregationSourceCollection.json>; rel=describedby");
123}
124
125inline void requestRoutesAggregationSourceCollection(App& app)
Carson Labrado5315c1b2023-02-18 01:02:18 +0000126{
127 BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/AggregationSources/")
Carson Labrado8b2521a2023-02-18 02:33:14 +0000128 .privileges(redfish::privileges::getAggregationSourceCollection)
129 .methods(boost::beast::http::verb::get)(std::bind_front(
130 handleAggregationSourceCollectionGet, std::ref(app)));
131
132 BMCWEB_ROUTE(app, "/redfish/v1/AggregationService/AggregationSources/")
133 .privileges(redfish::privileges::getAggregationSourceCollection)
134 .methods(boost::beast::http::verb::head)(std::bind_front(
135 handleAggregationSourceCollectionHead, std::ref(app)));
136}
137
138inline void populateAggregationSource(
139 const std::string& aggregationSourceId,
140 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
Ed Tanous81c4e332023-05-18 10:30:34 -0700141 const boost::system::error_code& ec,
Carson Labrado8b2521a2023-02-18 02:33:14 +0000142 const std::unordered_map<std::string, boost::urls::url>& satelliteInfo)
143{
144 asyncResp->res.addHeader(
145 boost::beast::http::field::link,
146 "</redfish/v1/JsonSchemas/AggregationSource/AggregationSource.json>; rel=describedby");
147
148 // Something went wrong while querying dbus
149 if (ec)
150 {
151 messages::internalError(asyncResp->res);
152 return;
153 }
154
155 const auto& sat = satelliteInfo.find(aggregationSourceId);
156 if (sat == satelliteInfo.end())
157 {
158 messages::resourceNotFound(asyncResp->res, "AggregationSource",
159 aggregationSourceId);
160 return;
161 }
162
Ed Tanousef4c65b2023-04-24 15:28:50 -0700163 asyncResp->res.jsonValue["@odata.id"] = boost::urls::format(
164 "/redfish/v1/AggregationService/AggregationSources/{}",
165 aggregationSourceId);
Carson Labrado8b2521a2023-02-18 02:33:14 +0000166 asyncResp->res.jsonValue["@odata.type"] =
167 "#AggregationSource.v1_3_1.AggregationSource";
168 asyncResp->res.jsonValue["Id"] = aggregationSourceId;
169
170 // TODO: We may want to change this whenever we support aggregating multiple
171 // satellite BMCs. Otherwise all AggregationSource resources will have the
172 // same "Name".
173 // TODO: We should use the "Name" from the satellite config whenever we add
174 // support for including it in the data returned in satelliteInfo.
175 asyncResp->res.jsonValue["Name"] = "Aggregation source";
176 std::string hostName(sat->second.encoded_origin());
177 asyncResp->res.jsonValue["HostName"] = std::move(hostName);
178
179 // The Redfish spec requires Password to be null in responses
180 asyncResp->res.jsonValue["Password"] = nullptr;
181}
182
183inline void handleAggregationSourceGet(
184 App& app, const crow::Request& req,
185 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
186 const std::string& aggregationSourceId)
187{
188 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
189 {
190 return;
191 }
192
193 // Query D-Bus for satellite config corresponding to the specified
194 // AggregationSource
195 RedfishAggregator::getSatelliteConfigs(std::bind_front(
196 populateAggregationSource, aggregationSourceId, asyncResp));
197}
198
199inline void handleAggregationSourceHead(
200 App& app, const crow::Request& req,
201 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
202 const std::string& aggregationSourceId)
203{
204 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
205 {
206 return;
207 }
208 asyncResp->res.addHeader(
209 boost::beast::http::field::link,
210 "</redfish/v1/JsonSchemas/AggregationService/AggregationSource.json>; rel=describedby");
211
212 // Needed to prevent unused variable error
Ed Tanous62598e32023-07-17 17:06:25 -0700213 BMCWEB_LOG_DEBUG("Added link header to response from {}",
214 aggregationSourceId);
Carson Labrado8b2521a2023-02-18 02:33:14 +0000215}
216
217inline void requestRoutesAggregationSource(App& app)
218{
219 BMCWEB_ROUTE(app,
220 "/redfish/v1/AggregationService/AggregationSources/<str>/")
221 .privileges(redfish::privileges::getAggregationSource)
Carson Labrado5315c1b2023-02-18 01:02:18 +0000222 .methods(boost::beast::http::verb::get)(
Carson Labrado8b2521a2023-02-18 02:33:14 +0000223 std::bind_front(handleAggregationSourceGet, std::ref(app)));
Carson Labrado5315c1b2023-02-18 01:02:18 +0000224}
225
Ed Tanous6c068982023-02-07 15:44:38 -0800226} // namespace redfish