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 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 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 } 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 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