1*664c9560SOliver Brewka // SPDX-License-Identifier: Apache-2.0 2*664c9560SOliver Brewka // SPDX-FileCopyrightText: Copyright OpenBMC Authors 3*664c9560SOliver Brewka // SPDX-FileCopyrightText: Copyright 2018 Intel Corporation 4*664c9560SOliver Brewka #pragma once 5*664c9560SOliver Brewka 6*664c9560SOliver Brewka #include "bmcweb_config.h" 7*664c9560SOliver Brewka 8*664c9560SOliver Brewka #include "app.hpp" 9*664c9560SOliver Brewka #include "async_resp.hpp" 10*664c9560SOliver Brewka #include "dbus_utility.hpp" 11*664c9560SOliver Brewka #include "error_messages.hpp" 12*664c9560SOliver Brewka #include "http_body.hpp" 13*664c9560SOliver Brewka #include "http_request.hpp" 14*664c9560SOliver Brewka #include "http_response.hpp" 15*664c9560SOliver Brewka #include "http_utility.hpp" 16*664c9560SOliver Brewka #include "logging.hpp" 17*664c9560SOliver Brewka #include "query.hpp" 18*664c9560SOliver Brewka #include "registries/privilege_registry.hpp" 19*664c9560SOliver Brewka #include "utils/dbus_event_log_entry.hpp" 20*664c9560SOliver Brewka #include "utils/dbus_utils.hpp" 21*664c9560SOliver Brewka #include "utils/json_utils.hpp" 22*664c9560SOliver Brewka #include "utils/log_services_utils.hpp" 23*664c9560SOliver Brewka #include "utils/time_utils.hpp" 24*664c9560SOliver Brewka 25*664c9560SOliver Brewka #include <asm-generic/errno.h> 26*664c9560SOliver Brewka #include <systemd/sd-bus.h> 27*664c9560SOliver Brewka #include <unistd.h> 28*664c9560SOliver Brewka 29*664c9560SOliver Brewka #include <boost/beast/http/field.hpp> 30*664c9560SOliver Brewka #include <boost/beast/http/status.hpp> 31*664c9560SOliver Brewka #include <boost/beast/http/verb.hpp> 32*664c9560SOliver Brewka #include <boost/system/linux_error.hpp> 33*664c9560SOliver Brewka #include <boost/url/format.hpp> 34*664c9560SOliver Brewka #include <boost/url/url.hpp> 35*664c9560SOliver Brewka #include <sdbusplus/message.hpp> 36*664c9560SOliver Brewka #include <sdbusplus/message/native_types.hpp> 37*664c9560SOliver Brewka #include <sdbusplus/unpack_properties.hpp> 38*664c9560SOliver Brewka 39*664c9560SOliver Brewka #include <algorithm> 40*664c9560SOliver Brewka #include <format> 41*664c9560SOliver Brewka #include <functional> 42*664c9560SOliver Brewka #include <memory> 43*664c9560SOliver Brewka #include <optional> 44*664c9560SOliver Brewka #include <string> 45*664c9560SOliver Brewka #include <string_view> 46*664c9560SOliver Brewka #include <utility> 47*664c9560SOliver Brewka #include <vector> 48*664c9560SOliver Brewka 49*664c9560SOliver Brewka namespace redfish 50*664c9560SOliver Brewka { 51*664c9560SOliver Brewka 52*664c9560SOliver Brewka inline std::optional<bool> getProviderNotifyAction(const std::string& notify) 53*664c9560SOliver Brewka { 54*664c9560SOliver Brewka std::optional<bool> notifyAction; 55*664c9560SOliver Brewka if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Notify") 56*664c9560SOliver Brewka { 57*664c9560SOliver Brewka notifyAction = true; 58*664c9560SOliver Brewka } 59*664c9560SOliver Brewka else if (notify == "xyz.openbmc_project.Logging.Entry.Notify.Inhibit") 60*664c9560SOliver Brewka { 61*664c9560SOliver Brewka notifyAction = false; 62*664c9560SOliver Brewka } 63*664c9560SOliver Brewka 64*664c9560SOliver Brewka return notifyAction; 65*664c9560SOliver Brewka } 66*664c9560SOliver Brewka 67*664c9560SOliver Brewka inline std::string translateSeverityDbusToRedfish(const std::string& s) 68*664c9560SOliver Brewka { 69*664c9560SOliver Brewka if ((s == "xyz.openbmc_project.Logging.Entry.Level.Alert") || 70*664c9560SOliver Brewka (s == "xyz.openbmc_project.Logging.Entry.Level.Critical") || 71*664c9560SOliver Brewka (s == "xyz.openbmc_project.Logging.Entry.Level.Emergency") || 72*664c9560SOliver Brewka (s == "xyz.openbmc_project.Logging.Entry.Level.Error")) 73*664c9560SOliver Brewka { 74*664c9560SOliver Brewka return "Critical"; 75*664c9560SOliver Brewka } 76*664c9560SOliver Brewka if ((s == "xyz.openbmc_project.Logging.Entry.Level.Debug") || 77*664c9560SOliver Brewka (s == "xyz.openbmc_project.Logging.Entry.Level.Informational") || 78*664c9560SOliver Brewka (s == "xyz.openbmc_project.Logging.Entry.Level.Notice")) 79*664c9560SOliver Brewka { 80*664c9560SOliver Brewka return "OK"; 81*664c9560SOliver Brewka } 82*664c9560SOliver Brewka if (s == "xyz.openbmc_project.Logging.Entry.Level.Warning") 83*664c9560SOliver Brewka { 84*664c9560SOliver Brewka return "Warning"; 85*664c9560SOliver Brewka } 86*664c9560SOliver Brewka return ""; 87*664c9560SOliver Brewka } 88*664c9560SOliver Brewka 89*664c9560SOliver Brewka inline void fillEventLogLogEntryFromDbusLogEntry( 90*664c9560SOliver Brewka const DbusEventLogEntry& entry, nlohmann::json& objectToFillOut) 91*664c9560SOliver Brewka { 92*664c9560SOliver Brewka objectToFillOut["@odata.type"] = "#LogEntry.v1_9_0.LogEntry"; 93*664c9560SOliver Brewka objectToFillOut["@odata.id"] = boost::urls::format( 94*664c9560SOliver Brewka "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}", 95*664c9560SOliver Brewka BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id)); 96*664c9560SOliver Brewka objectToFillOut["Name"] = "System Event Log Entry"; 97*664c9560SOliver Brewka objectToFillOut["Id"] = std::to_string(entry.Id); 98*664c9560SOliver Brewka objectToFillOut["Message"] = entry.Message; 99*664c9560SOliver Brewka objectToFillOut["Resolved"] = entry.Resolved; 100*664c9560SOliver Brewka std::optional<bool> notifyAction = 101*664c9560SOliver Brewka getProviderNotifyAction(entry.ServiceProviderNotify); 102*664c9560SOliver Brewka if (notifyAction) 103*664c9560SOliver Brewka { 104*664c9560SOliver Brewka objectToFillOut["ServiceProviderNotified"] = *notifyAction; 105*664c9560SOliver Brewka } 106*664c9560SOliver Brewka if ((entry.Resolution != nullptr) && !entry.Resolution->empty()) 107*664c9560SOliver Brewka { 108*664c9560SOliver Brewka objectToFillOut["Resolution"] = *entry.Resolution; 109*664c9560SOliver Brewka } 110*664c9560SOliver Brewka objectToFillOut["EntryType"] = "Event"; 111*664c9560SOliver Brewka objectToFillOut["Severity"] = 112*664c9560SOliver Brewka translateSeverityDbusToRedfish(entry.Severity); 113*664c9560SOliver Brewka objectToFillOut["Created"] = 114*664c9560SOliver Brewka redfish::time_utils::getDateTimeUintMs(entry.Timestamp); 115*664c9560SOliver Brewka objectToFillOut["Modified"] = 116*664c9560SOliver Brewka redfish::time_utils::getDateTimeUintMs(entry.UpdateTimestamp); 117*664c9560SOliver Brewka if (entry.Path != nullptr) 118*664c9560SOliver Brewka { 119*664c9560SOliver Brewka objectToFillOut["AdditionalDataURI"] = boost::urls::format( 120*664c9560SOliver Brewka "/redfish/v1/Systems/{}/LogServices/EventLog/Entries/{}/attachment", 121*664c9560SOliver Brewka BMCWEB_REDFISH_SYSTEM_URI_NAME, std::to_string(entry.Id)); 122*664c9560SOliver Brewka } 123*664c9560SOliver Brewka } 124*664c9560SOliver Brewka 125*664c9560SOliver Brewka inline void afterLogEntriesGetManagedObjects( 126*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 127*664c9560SOliver Brewka const boost::system::error_code& ec, 128*664c9560SOliver Brewka const dbus::utility::ManagedObjectType& resp) 129*664c9560SOliver Brewka { 130*664c9560SOliver Brewka if (ec) 131*664c9560SOliver Brewka { 132*664c9560SOliver Brewka // TODO Handle for specific error code 133*664c9560SOliver Brewka BMCWEB_LOG_ERROR("getLogEntriesIfaceData resp_handler got error {}", 134*664c9560SOliver Brewka ec); 135*664c9560SOliver Brewka messages::internalError(asyncResp->res); 136*664c9560SOliver Brewka return; 137*664c9560SOliver Brewka } 138*664c9560SOliver Brewka nlohmann::json::array_t entriesArray; 139*664c9560SOliver Brewka for (const auto& objectPath : resp) 140*664c9560SOliver Brewka { 141*664c9560SOliver Brewka dbus::utility::DBusPropertiesMap propsFlattened; 142*664c9560SOliver Brewka auto isEntry = 143*664c9560SOliver Brewka std::ranges::find_if(objectPath.second, [](const auto& object) { 144*664c9560SOliver Brewka return object.first == "xyz.openbmc_project.Logging.Entry"; 145*664c9560SOliver Brewka }); 146*664c9560SOliver Brewka if (isEntry == objectPath.second.end()) 147*664c9560SOliver Brewka { 148*664c9560SOliver Brewka continue; 149*664c9560SOliver Brewka } 150*664c9560SOliver Brewka 151*664c9560SOliver Brewka for (const auto& interfaceMap : objectPath.second) 152*664c9560SOliver Brewka { 153*664c9560SOliver Brewka for (const auto& propertyMap : interfaceMap.second) 154*664c9560SOliver Brewka { 155*664c9560SOliver Brewka propsFlattened.emplace_back(propertyMap.first, 156*664c9560SOliver Brewka propertyMap.second); 157*664c9560SOliver Brewka } 158*664c9560SOliver Brewka } 159*664c9560SOliver Brewka std::optional<DbusEventLogEntry> optEntry = 160*664c9560SOliver Brewka fillDbusEventLogEntryFromPropertyMap(propsFlattened); 161*664c9560SOliver Brewka 162*664c9560SOliver Brewka if (!optEntry.has_value()) 163*664c9560SOliver Brewka { 164*664c9560SOliver Brewka messages::internalError(asyncResp->res); 165*664c9560SOliver Brewka return; 166*664c9560SOliver Brewka } 167*664c9560SOliver Brewka fillEventLogLogEntryFromDbusLogEntry(*optEntry, 168*664c9560SOliver Brewka entriesArray.emplace_back()); 169*664c9560SOliver Brewka } 170*664c9560SOliver Brewka 171*664c9560SOliver Brewka redfish::json_util::sortJsonArrayByKey(entriesArray, "Id"); 172*664c9560SOliver Brewka asyncResp->res.jsonValue["Members@odata.count"] = entriesArray.size(); 173*664c9560SOliver Brewka asyncResp->res.jsonValue["Members"] = std::move(entriesArray); 174*664c9560SOliver Brewka } 175*664c9560SOliver Brewka 176*664c9560SOliver Brewka inline void dBusEventLogEntryCollection( 177*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 178*664c9560SOliver Brewka { 179*664c9560SOliver Brewka // Collections don't include the static data added by SubRoute 180*664c9560SOliver Brewka // because it has a duplicate entry for members 181*664c9560SOliver Brewka asyncResp->res.jsonValue["@odata.type"] = 182*664c9560SOliver Brewka "#LogEntryCollection.LogEntryCollection"; 183*664c9560SOliver Brewka asyncResp->res.jsonValue["@odata.id"] = 184*664c9560SOliver Brewka std::format("/redfish/v1/Systems/{}/LogServices/EventLog/Entries", 185*664c9560SOliver Brewka BMCWEB_REDFISH_SYSTEM_URI_NAME); 186*664c9560SOliver Brewka asyncResp->res.jsonValue["Name"] = "System Event Log Entries"; 187*664c9560SOliver Brewka asyncResp->res.jsonValue["Description"] = 188*664c9560SOliver Brewka "Collection of System Event Log Entries"; 189*664c9560SOliver Brewka 190*664c9560SOliver Brewka // DBus implementation of EventLog/Entries 191*664c9560SOliver Brewka // Make call to Logging Service to find all log entry objects 192*664c9560SOliver Brewka sdbusplus::message::object_path path("/xyz/openbmc_project/logging"); 193*664c9560SOliver Brewka dbus::utility::getManagedObjects( 194*664c9560SOliver Brewka "xyz.openbmc_project.Logging", path, 195*664c9560SOliver Brewka [asyncResp](const boost::system::error_code& ec, 196*664c9560SOliver Brewka const dbus::utility::ManagedObjectType& resp) { 197*664c9560SOliver Brewka afterLogEntriesGetManagedObjects(asyncResp, ec, resp); 198*664c9560SOliver Brewka }); 199*664c9560SOliver Brewka } 200*664c9560SOliver Brewka 201*664c9560SOliver Brewka inline void afterDBusEventLogEntryGet( 202*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 203*664c9560SOliver Brewka const std::string& entryID, const boost::system::error_code& ec, 204*664c9560SOliver Brewka const dbus::utility::DBusPropertiesMap& resp) 205*664c9560SOliver Brewka { 206*664c9560SOliver Brewka if (ec.value() == EBADR) 207*664c9560SOliver Brewka { 208*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "EventLogEntry", entryID); 209*664c9560SOliver Brewka return; 210*664c9560SOliver Brewka } 211*664c9560SOliver Brewka if (ec) 212*664c9560SOliver Brewka { 213*664c9560SOliver Brewka BMCWEB_LOG_ERROR("EventLogEntry (DBus) resp_handler got error {}", ec); 214*664c9560SOliver Brewka messages::internalError(asyncResp->res); 215*664c9560SOliver Brewka return; 216*664c9560SOliver Brewka } 217*664c9560SOliver Brewka 218*664c9560SOliver Brewka std::optional<DbusEventLogEntry> optEntry = 219*664c9560SOliver Brewka fillDbusEventLogEntryFromPropertyMap(resp); 220*664c9560SOliver Brewka 221*664c9560SOliver Brewka if (!optEntry.has_value()) 222*664c9560SOliver Brewka { 223*664c9560SOliver Brewka messages::internalError(asyncResp->res); 224*664c9560SOliver Brewka return; 225*664c9560SOliver Brewka } 226*664c9560SOliver Brewka 227*664c9560SOliver Brewka fillEventLogLogEntryFromDbusLogEntry(*optEntry, asyncResp->res.jsonValue); 228*664c9560SOliver Brewka } 229*664c9560SOliver Brewka 230*664c9560SOliver Brewka inline void dBusEventLogEntryGet( 231*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID) 232*664c9560SOliver Brewka { 233*664c9560SOliver Brewka dbus::utility::escapePathForDbus(entryID); 234*664c9560SOliver Brewka 235*664c9560SOliver Brewka // DBus implementation of EventLog/Entries 236*664c9560SOliver Brewka // Make call to Logging Service to find all log entry objects 237*664c9560SOliver Brewka dbus::utility::getAllProperties( 238*664c9560SOliver Brewka "xyz.openbmc_project.Logging", 239*664c9560SOliver Brewka "/xyz/openbmc_project/logging/entry/" + entryID, "", 240*664c9560SOliver Brewka std::bind_front(afterDBusEventLogEntryGet, asyncResp, entryID)); 241*664c9560SOliver Brewka } 242*664c9560SOliver Brewka 243*664c9560SOliver Brewka inline void dBusEventLogEntryPatch( 244*664c9560SOliver Brewka const crow::Request& req, 245*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 246*664c9560SOliver Brewka const std::string& entryId) 247*664c9560SOliver Brewka { 248*664c9560SOliver Brewka std::optional<bool> resolved; 249*664c9560SOliver Brewka 250*664c9560SOliver Brewka if (!json_util::readJsonPatch(req, asyncResp->res, "Resolved", resolved)) 251*664c9560SOliver Brewka { 252*664c9560SOliver Brewka return; 253*664c9560SOliver Brewka } 254*664c9560SOliver Brewka BMCWEB_LOG_DEBUG("Set Resolved"); 255*664c9560SOliver Brewka 256*664c9560SOliver Brewka setDbusProperty(asyncResp, "Resolved", "xyz.openbmc_project.Logging", 257*664c9560SOliver Brewka "/xyz/openbmc_project/logging/entry/" + entryId, 258*664c9560SOliver Brewka "xyz.openbmc_project.Logging.Entry", "Resolved", 259*664c9560SOliver Brewka resolved.value_or(false)); 260*664c9560SOliver Brewka } 261*664c9560SOliver Brewka 262*664c9560SOliver Brewka inline void dBusEventLogEntryDelete( 263*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, std::string entryID) 264*664c9560SOliver Brewka { 265*664c9560SOliver Brewka BMCWEB_LOG_DEBUG("Do delete single event entries."); 266*664c9560SOliver Brewka 267*664c9560SOliver Brewka dbus::utility::escapePathForDbus(entryID); 268*664c9560SOliver Brewka 269*664c9560SOliver Brewka // Process response from Logging service. 270*664c9560SOliver Brewka auto respHandler = [asyncResp, 271*664c9560SOliver Brewka entryID](const boost::system::error_code& ec) { 272*664c9560SOliver Brewka BMCWEB_LOG_DEBUG("EventLogEntry (DBus) doDelete callback: Done"); 273*664c9560SOliver Brewka if (ec) 274*664c9560SOliver Brewka { 275*664c9560SOliver Brewka if (ec.value() == EBADR) 276*664c9560SOliver Brewka { 277*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "LogEntry", entryID); 278*664c9560SOliver Brewka return; 279*664c9560SOliver Brewka } 280*664c9560SOliver Brewka // TODO Handle for specific error code 281*664c9560SOliver Brewka BMCWEB_LOG_ERROR( 282*664c9560SOliver Brewka "EventLogEntry (DBus) doDelete respHandler got error {}", ec); 283*664c9560SOliver Brewka asyncResp->res.result( 284*664c9560SOliver Brewka boost::beast::http::status::internal_server_error); 285*664c9560SOliver Brewka return; 286*664c9560SOliver Brewka } 287*664c9560SOliver Brewka 288*664c9560SOliver Brewka messages::success(asyncResp->res); 289*664c9560SOliver Brewka }; 290*664c9560SOliver Brewka 291*664c9560SOliver Brewka // Make call to Logging service to request Delete Log 292*664c9560SOliver Brewka dbus::utility::async_method_call( 293*664c9560SOliver Brewka asyncResp, respHandler, "xyz.openbmc_project.Logging", 294*664c9560SOliver Brewka "/xyz/openbmc_project/logging/entry/" + entryID, 295*664c9560SOliver Brewka "xyz.openbmc_project.Object.Delete", "Delete"); 296*664c9560SOliver Brewka } 297*664c9560SOliver Brewka 298*664c9560SOliver Brewka inline void dBusLogServiceActionsClear( 299*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 300*664c9560SOliver Brewka { 301*664c9560SOliver Brewka BMCWEB_LOG_DEBUG("Do delete all entries."); 302*664c9560SOliver Brewka 303*664c9560SOliver Brewka // Process response from Logging service. 304*664c9560SOliver Brewka auto respHandler = [asyncResp](const boost::system::error_code& ec) { 305*664c9560SOliver Brewka BMCWEB_LOG_DEBUG("doClearLog resp_handler callback: Done"); 306*664c9560SOliver Brewka if (ec) 307*664c9560SOliver Brewka { 308*664c9560SOliver Brewka // TODO Handle for specific error code 309*664c9560SOliver Brewka BMCWEB_LOG_ERROR("doClearLog resp_handler got error {}", ec); 310*664c9560SOliver Brewka asyncResp->res.result( 311*664c9560SOliver Brewka boost::beast::http::status::internal_server_error); 312*664c9560SOliver Brewka return; 313*664c9560SOliver Brewka } 314*664c9560SOliver Brewka 315*664c9560SOliver Brewka messages::success(asyncResp->res); 316*664c9560SOliver Brewka }; 317*664c9560SOliver Brewka 318*664c9560SOliver Brewka // Make call to Logging service to request Clear Log 319*664c9560SOliver Brewka dbus::utility::async_method_call( 320*664c9560SOliver Brewka asyncResp, respHandler, "xyz.openbmc_project.Logging", 321*664c9560SOliver Brewka "/xyz/openbmc_project/logging", 322*664c9560SOliver Brewka "xyz.openbmc_project.Collection.DeleteAll", "DeleteAll"); 323*664c9560SOliver Brewka } 324*664c9560SOliver Brewka 325*664c9560SOliver Brewka inline void downloadEventLogEntry( 326*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 327*664c9560SOliver Brewka const std::string& systemName, const std::string& entryID, 328*664c9560SOliver Brewka const std::string& dumpType) 329*664c9560SOliver Brewka { 330*664c9560SOliver Brewka if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 331*664c9560SOliver Brewka { 332*664c9560SOliver Brewka // Option currently returns no systems. TBD 333*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 334*664c9560SOliver Brewka systemName); 335*664c9560SOliver Brewka return; 336*664c9560SOliver Brewka } 337*664c9560SOliver Brewka if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 338*664c9560SOliver Brewka { 339*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 340*664c9560SOliver Brewka systemName); 341*664c9560SOliver Brewka return; 342*664c9560SOliver Brewka } 343*664c9560SOliver Brewka 344*664c9560SOliver Brewka std::string entryPath = 345*664c9560SOliver Brewka sdbusplus::message::object_path("/xyz/openbmc_project/logging/entry") / 346*664c9560SOliver Brewka entryID; 347*664c9560SOliver Brewka 348*664c9560SOliver Brewka auto downloadEventLogEntryHandler = 349*664c9560SOliver Brewka [asyncResp, entryID, 350*664c9560SOliver Brewka dumpType](const boost::system::error_code& ec, 351*664c9560SOliver Brewka const sdbusplus::message::unix_fd& unixfd) { 352*664c9560SOliver Brewka log_services_utils::downloadEntryCallback(asyncResp, entryID, 353*664c9560SOliver Brewka dumpType, ec, unixfd); 354*664c9560SOliver Brewka }; 355*664c9560SOliver Brewka 356*664c9560SOliver Brewka dbus::utility::async_method_call( 357*664c9560SOliver Brewka asyncResp, std::move(downloadEventLogEntryHandler), 358*664c9560SOliver Brewka "xyz.openbmc_project.Logging", entryPath, 359*664c9560SOliver Brewka "xyz.openbmc_project.Logging.Entry", "GetEntry"); 360*664c9560SOliver Brewka } 361*664c9560SOliver Brewka 362*664c9560SOliver Brewka inline void handleDBusEventLogEntryDownloadGet( 363*664c9560SOliver Brewka crow::App& app, const std::string& dumpType, const crow::Request& req, 364*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 365*664c9560SOliver Brewka const std::string& systemName, const std::string& entryID) 366*664c9560SOliver Brewka { 367*664c9560SOliver Brewka if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 368*664c9560SOliver Brewka { 369*664c9560SOliver Brewka return; 370*664c9560SOliver Brewka } 371*664c9560SOliver Brewka if (!http_helpers::isContentTypeAllowed( 372*664c9560SOliver Brewka req.getHeaderValue("Accept"), 373*664c9560SOliver Brewka http_helpers::ContentType::OctetStream, true)) 374*664c9560SOliver Brewka { 375*664c9560SOliver Brewka asyncResp->res.result(boost::beast::http::status::bad_request); 376*664c9560SOliver Brewka return; 377*664c9560SOliver Brewka } 378*664c9560SOliver Brewka downloadEventLogEntry(asyncResp, systemName, entryID, dumpType); 379*664c9560SOliver Brewka } 380*664c9560SOliver Brewka 381*664c9560SOliver Brewka inline void requestRoutesDBusEventLogEntryCollection(App& app) 382*664c9560SOliver Brewka { 383*664c9560SOliver Brewka BMCWEB_ROUTE(app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/") 384*664c9560SOliver Brewka .privileges(redfish::privileges::getLogEntryCollection) 385*664c9560SOliver Brewka .methods(boost::beast::http::verb::get)( 386*664c9560SOliver Brewka [&app](const crow::Request& req, 387*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 388*664c9560SOliver Brewka const std::string& systemName) { 389*664c9560SOliver Brewka if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 390*664c9560SOliver Brewka { 391*664c9560SOliver Brewka return; 392*664c9560SOliver Brewka } 393*664c9560SOliver Brewka if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 394*664c9560SOliver Brewka { 395*664c9560SOliver Brewka // Option currently returns no systems. TBD 396*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 397*664c9560SOliver Brewka systemName); 398*664c9560SOliver Brewka return; 399*664c9560SOliver Brewka } 400*664c9560SOliver Brewka if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 401*664c9560SOliver Brewka { 402*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 403*664c9560SOliver Brewka systemName); 404*664c9560SOliver Brewka return; 405*664c9560SOliver Brewka } 406*664c9560SOliver Brewka dBusEventLogEntryCollection(asyncResp); 407*664c9560SOliver Brewka }); 408*664c9560SOliver Brewka } 409*664c9560SOliver Brewka 410*664c9560SOliver Brewka inline void requestRoutesDBusEventLogEntry(App& app) 411*664c9560SOliver Brewka { 412*664c9560SOliver Brewka BMCWEB_ROUTE( 413*664c9560SOliver Brewka app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") 414*664c9560SOliver Brewka .privileges(redfish::privileges::getLogEntry) 415*664c9560SOliver Brewka .methods(boost::beast::http::verb::get)( 416*664c9560SOliver Brewka [&app](const crow::Request& req, 417*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 418*664c9560SOliver Brewka const std::string& systemName, const std::string& entryId) { 419*664c9560SOliver Brewka if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 420*664c9560SOliver Brewka { 421*664c9560SOliver Brewka return; 422*664c9560SOliver Brewka } 423*664c9560SOliver Brewka if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 424*664c9560SOliver Brewka { 425*664c9560SOliver Brewka // Option currently returns no systems. TBD 426*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 427*664c9560SOliver Brewka systemName); 428*664c9560SOliver Brewka return; 429*664c9560SOliver Brewka } 430*664c9560SOliver Brewka if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 431*664c9560SOliver Brewka { 432*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 433*664c9560SOliver Brewka systemName); 434*664c9560SOliver Brewka return; 435*664c9560SOliver Brewka } 436*664c9560SOliver Brewka 437*664c9560SOliver Brewka dBusEventLogEntryGet(asyncResp, entryId); 438*664c9560SOliver Brewka }); 439*664c9560SOliver Brewka 440*664c9560SOliver Brewka BMCWEB_ROUTE( 441*664c9560SOliver Brewka app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") 442*664c9560SOliver Brewka .privileges(redfish::privileges::patchLogEntry) 443*664c9560SOliver Brewka .methods(boost::beast::http::verb::patch)( 444*664c9560SOliver Brewka [&app](const crow::Request& req, 445*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 446*664c9560SOliver Brewka const std::string& systemName, const std::string& entryId) { 447*664c9560SOliver Brewka if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 448*664c9560SOliver Brewka { 449*664c9560SOliver Brewka return; 450*664c9560SOliver Brewka } 451*664c9560SOliver Brewka if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 452*664c9560SOliver Brewka { 453*664c9560SOliver Brewka // Option currently returns no systems. TBD 454*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 455*664c9560SOliver Brewka systemName); 456*664c9560SOliver Brewka return; 457*664c9560SOliver Brewka } 458*664c9560SOliver Brewka if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 459*664c9560SOliver Brewka { 460*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 461*664c9560SOliver Brewka systemName); 462*664c9560SOliver Brewka return; 463*664c9560SOliver Brewka } 464*664c9560SOliver Brewka 465*664c9560SOliver Brewka dBusEventLogEntryPatch(req, asyncResp, entryId); 466*664c9560SOliver Brewka }); 467*664c9560SOliver Brewka 468*664c9560SOliver Brewka BMCWEB_ROUTE( 469*664c9560SOliver Brewka app, "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/") 470*664c9560SOliver Brewka .privileges( 471*664c9560SOliver Brewka redfish::privileges:: 472*664c9560SOliver Brewka deleteLogEntrySubOverComputerSystemLogServiceCollectionLogServiceLogEntryCollection) 473*664c9560SOliver Brewka .methods(boost::beast::http::verb::delete_)( 474*664c9560SOliver Brewka [&app](const crow::Request& req, 475*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 476*664c9560SOliver Brewka const std::string& systemName, const std::string& param) { 477*664c9560SOliver Brewka if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 478*664c9560SOliver Brewka { 479*664c9560SOliver Brewka return; 480*664c9560SOliver Brewka } 481*664c9560SOliver Brewka if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 482*664c9560SOliver Brewka { 483*664c9560SOliver Brewka // Option currently returns no systems. TBD 484*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 485*664c9560SOliver Brewka systemName); 486*664c9560SOliver Brewka return; 487*664c9560SOliver Brewka } 488*664c9560SOliver Brewka if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 489*664c9560SOliver Brewka { 490*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 491*664c9560SOliver Brewka systemName); 492*664c9560SOliver Brewka return; 493*664c9560SOliver Brewka } 494*664c9560SOliver Brewka dBusEventLogEntryDelete(asyncResp, param); 495*664c9560SOliver Brewka }); 496*664c9560SOliver Brewka } 497*664c9560SOliver Brewka 498*664c9560SOliver Brewka /** 499*664c9560SOliver Brewka * DBusLogServiceActionsClear class supports POST method for ClearLog action. 500*664c9560SOliver Brewka */ 501*664c9560SOliver Brewka inline void requestRoutesDBusLogServiceActionsClear(App& app) 502*664c9560SOliver Brewka { 503*664c9560SOliver Brewka /** 504*664c9560SOliver Brewka * Function handles POST method request. 505*664c9560SOliver Brewka * The Clear Log actions does not require any parameter.The action deletes 506*664c9560SOliver Brewka * all entries found in the Entries collection for this Log Service. 507*664c9560SOliver Brewka */ 508*664c9560SOliver Brewka 509*664c9560SOliver Brewka BMCWEB_ROUTE( 510*664c9560SOliver Brewka app, 511*664c9560SOliver Brewka "/redfish/v1/Systems/<str>/LogServices/EventLog/Actions/LogService.ClearLog/") 512*664c9560SOliver Brewka .privileges(redfish::privileges:: 513*664c9560SOliver Brewka postLogServiceSubOverComputerSystemLogServiceCollection) 514*664c9560SOliver Brewka .methods(boost::beast::http::verb::post)( 515*664c9560SOliver Brewka [&app](const crow::Request& req, 516*664c9560SOliver Brewka const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 517*664c9560SOliver Brewka const std::string& systemName) { 518*664c9560SOliver Brewka if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 519*664c9560SOliver Brewka { 520*664c9560SOliver Brewka return; 521*664c9560SOliver Brewka } 522*664c9560SOliver Brewka if constexpr (BMCWEB_EXPERIMENTAL_REDFISH_MULTI_COMPUTER_SYSTEM) 523*664c9560SOliver Brewka { 524*664c9560SOliver Brewka // Option currently returns no systems. TBD 525*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 526*664c9560SOliver Brewka systemName); 527*664c9560SOliver Brewka return; 528*664c9560SOliver Brewka } 529*664c9560SOliver Brewka if (systemName != BMCWEB_REDFISH_SYSTEM_URI_NAME) 530*664c9560SOliver Brewka { 531*664c9560SOliver Brewka messages::resourceNotFound(asyncResp->res, "ComputerSystem", 532*664c9560SOliver Brewka systemName); 533*664c9560SOliver Brewka return; 534*664c9560SOliver Brewka } 535*664c9560SOliver Brewka dBusLogServiceActionsClear(asyncResp); 536*664c9560SOliver Brewka }); 537*664c9560SOliver Brewka } 538*664c9560SOliver Brewka 539*664c9560SOliver Brewka inline void requestRoutesDBusEventLogEntryDownload(App& app) 540*664c9560SOliver Brewka { 541*664c9560SOliver Brewka BMCWEB_ROUTE( 542*664c9560SOliver Brewka app, 543*664c9560SOliver Brewka "/redfish/v1/Systems/<str>/LogServices/EventLog/Entries/<str>/attachment/") 544*664c9560SOliver Brewka .privileges(redfish::privileges::getLogEntry) 545*664c9560SOliver Brewka .methods(boost::beast::http::verb::get)(std::bind_front( 546*664c9560SOliver Brewka handleDBusEventLogEntryDownloadGet, std::ref(app), "System")); 547*664c9560SOliver Brewka } 548*664c9560SOliver Brewka } // namespace redfish 549