1 // SPDX-License-Identifier: Apache-2.0
2 // SPDX-FileCopyrightText: Copyright OpenBMC Authors
3 // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation
4 #pragma once
5
6 #include "bmcweb_config.h"
7
8 #include "app.hpp"
9 #include "async_resp.hpp"
10 #include "http_request.hpp"
11 #include "persistent_data.hpp"
12 #include "query.hpp"
13 #include "registries/privilege_registry.hpp"
14 #include "utils/manager_utils.hpp"
15
16 #include <boost/beast/http/field.hpp>
17 #include <boost/beast/http/verb.hpp>
18 #include <boost/url/format.hpp>
19 #include <nlohmann/json.hpp>
20
21 #include <functional>
22 #include <memory>
23 #include <string>
24
25 namespace redfish
26 {
27
handleServiceRootHead(App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)28 inline void handleServiceRootHead(
29 App& app, const crow::Request& req,
30 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
31 {
32 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
33 {
34 return;
35 }
36
37 asyncResp->res.addHeader(
38 boost::beast::http::field::link,
39 "</redfish/v1/JsonSchemas/ServiceRoot/ServiceRoot.json>; rel=describedby");
40 }
41
handleServiceRootGetImpl(const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)42 inline void handleServiceRootGetImpl(
43 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
44 {
45 asyncResp->res.addHeader(
46 boost::beast::http::field::link,
47 "</redfish/v1/JsonSchemas/ServiceRoot/ServiceRoot.json>; rel=describedby");
48
49 std::string uuid = persistent_data::getConfig().systemUuid;
50 asyncResp->res.jsonValue["@odata.type"] =
51 "#ServiceRoot.v1_15_0.ServiceRoot";
52 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1";
53 asyncResp->res.jsonValue["Id"] = "RootService";
54 asyncResp->res.jsonValue["Name"] = "Root Service";
55 asyncResp->res.jsonValue["RedfishVersion"] = "1.17.0";
56 asyncResp->res.jsonValue["Links"]["Sessions"]["@odata.id"] =
57 "/redfish/v1/SessionService/Sessions";
58 asyncResp->res.jsonValue["AccountService"]["@odata.id"] =
59 "/redfish/v1/AccountService";
60 if constexpr (BMCWEB_REDFISH_AGGREGATION)
61 {
62 asyncResp->res.jsonValue["AggregationService"]["@odata.id"] =
63 "/redfish/v1/AggregationService";
64 }
65 asyncResp->res.jsonValue["Chassis"]["@odata.id"] = "/redfish/v1/Chassis";
66 asyncResp->res.jsonValue["JsonSchemas"]["@odata.id"] =
67 "/redfish/v1/JsonSchemas";
68 asyncResp->res.jsonValue["Managers"]["@odata.id"] = "/redfish/v1/Managers";
69 asyncResp->res.jsonValue["SessionService"]["@odata.id"] =
70 "/redfish/v1/SessionService";
71 asyncResp->res.jsonValue["Systems"]["@odata.id"] = "/redfish/v1/Systems";
72 asyncResp->res.jsonValue["Registries"]["@odata.id"] =
73 "/redfish/v1/Registries";
74 asyncResp->res.jsonValue["UpdateService"]["@odata.id"] =
75 "/redfish/v1/UpdateService";
76 asyncResp->res.jsonValue["UUID"] = uuid;
77 asyncResp->res.jsonValue["CertificateService"]["@odata.id"] =
78 "/redfish/v1/CertificateService";
79 asyncResp->res.jsonValue["Tasks"]["@odata.id"] = "/redfish/v1/TaskService";
80 asyncResp->res.jsonValue["EventService"]["@odata.id"] =
81 "/redfish/v1/EventService";
82 asyncResp->res.jsonValue["TelemetryService"]["@odata.id"] =
83 "/redfish/v1/TelemetryService";
84 manager_utils::getServiceIdentification(asyncResp, true);
85 asyncResp->res.jsonValue["Cables"]["@odata.id"] = "/redfish/v1/Cables";
86
87 asyncResp->res.jsonValue["Links"]["ManagerProvidingService"]["@odata.id"] =
88 boost::urls::format("/redfish/v1/Managers/{}",
89 BMCWEB_REDFISH_MANAGER_URI_NAME);
90
91 nlohmann::json& protocolFeatures =
92 asyncResp->res.jsonValue["ProtocolFeaturesSupported"];
93 protocolFeatures["ExcerptQuery"] = false;
94
95 protocolFeatures["ExpandQuery"]["ExpandAll"] =
96 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
97 // This is the maximum level defined in ServiceRoot.v1_13_0.json
98 if constexpr (BMCWEB_INSECURE_ENABLE_REDFISH_QUERY)
99 {
100 protocolFeatures["ExpandQuery"]["MaxLevels"] = 6;
101 }
102 protocolFeatures["ExpandQuery"]["Levels"] =
103 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
104 protocolFeatures["ExpandQuery"]["Links"] =
105 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
106 protocolFeatures["ExpandQuery"]["NoLinks"] =
107 BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
108 protocolFeatures["FilterQuery"] = BMCWEB_INSECURE_ENABLE_REDFISH_QUERY;
109 protocolFeatures["OnlyMemberQuery"] = true;
110 protocolFeatures["SelectQuery"] = true;
111 protocolFeatures["DeepOperations"]["DeepPOST"] = false;
112 protocolFeatures["DeepOperations"]["DeepPATCH"] = false;
113 }
handleServiceRootGet(App & app,const crow::Request & req,const std::shared_ptr<bmcweb::AsyncResp> & asyncResp)114 inline void handleServiceRootGet(
115 App& app, const crow::Request& req,
116 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
117 {
118 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
119 {
120 return;
121 }
122
123 handleServiceRootGetImpl(asyncResp);
124 }
125
requestRoutesServiceRoot(App & app)126 inline void requestRoutesServiceRoot(App& app)
127 {
128 BMCWEB_ROUTE(app, "/redfish/v1/")
129 .privileges(redfish::privileges::headServiceRoot)
130 .methods(boost::beast::http::verb::head)(
131 std::bind_front(handleServiceRootHead, std::ref(app)));
132 BMCWEB_ROUTE(app, "/redfish/v1/")
133 .privileges(redfish::privileges::getServiceRoot)
134 .methods(boost::beast::http::verb::get)(
135 std::bind_front(handleServiceRootGet, std::ref(app)));
136 }
137
138 } // namespace redfish
139