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