xref: /openbmc/bmcweb/features/redfish/lib/systems_logservices_dbus_eventlog.hpp (revision 664c95605d55d04c03a7fb40de1d0b22ce1be946)
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