blob: ea968afa7dadf1db9bec493999ee986900d0100f [file] [log] [blame]
Ed Tanous40e9b922024-09-10 13:50:16 -07001// SPDX-License-Identifier: Apache-2.0
2// SPDX-FileCopyrightText: Copyright OpenBMC Authors
3// SPDX-FileCopyrightText: Copyright 2020 Intel Corporation
AppaRao Pulie5aaf042020-03-20 01:05:52 +05304#pragma once
Ed Tanous3ccb3ad2023-01-13 17:40:03 -08005#include "app.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -08006#include "async_resp.hpp"
7#include "dbus_singleton.hpp"
8#include "dbus_utility.hpp"
9#include "error_messages.hpp"
AppaRao Pulib52664e2020-04-09 21:36:51 +053010#include "event_service_manager.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080011#include "event_service_store.hpp"
12#include "generated/enums/event_destination.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080013#include "http/utility.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080014#include "http_request.hpp"
Ed Tanous9838eb22025-01-29 16:24:42 -080015#include "io_context_singleton.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080016#include "logging.hpp"
17#include "query.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010018#include "registries.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080019#include "registries/privilege_registry.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010020#include "registries_selector.hpp"
Chicago Duan3d307082020-11-26 14:12:12 +080021#include "snmp_trap_event_clients.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080022#include "subscription.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010023#include "utils/json_utils.hpp"
AppaRao Pulie5aaf042020-03-20 01:05:52 +053024
Ed Tanousd7857202025-01-28 15:32:26 -080025#include <asm-generic/errno.h>
Ed Tanoused398212021-06-09 17:05:54 -070026
Ed Tanousd7857202025-01-28 15:32:26 -080027#include <boost/beast/http/fields.hpp>
28#include <boost/beast/http/status.hpp>
29#include <boost/beast/http/verb.hpp>
30#include <boost/system/error_code.hpp>
31#include <boost/system/result.hpp>
32#include <boost/url/format.hpp>
33#include <boost/url/parse.hpp>
34#include <boost/url/url.hpp>
35#include <sdbusplus/message/native_types.hpp>
36
37#include <algorithm>
38#include <array>
39#include <cerrno>
40#include <cstddef>
41#include <cstdint>
Chicago Duan3d307082020-11-26 14:12:12 +080042#include <memory>
Myung Bae5064a252024-10-04 09:34:25 -070043#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070044#include <ranges>
Patrick Williams1e270c52021-12-04 06:06:56 -060045#include <span>
Chicago Duan3d307082020-11-26 14:12:12 +080046#include <string>
Ed Tanousd7857202025-01-28 15:32:26 -080047#include <utility>
Ed Tanousa14c9112024-09-04 10:46:47 -070048#include <vector>
Patrick Williams1e270c52021-12-04 06:06:56 -060049
AppaRao Pulie5aaf042020-03-20 01:05:52 +053050namespace redfish
51{
52
AppaRao Puli156d6b02020-04-25 06:04:05 +053053static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
54 eventFormatType, metricReportFormatType};
Myung Baefb546102024-10-29 10:21:26 -050055static constexpr const std::array<const char*, 4> supportedRegPrefixes = {
56 "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053057static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
58 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
59
Myung Baefb546102024-10-29 10:21:26 -050060static constexpr const std::array<const char*, 2> supportedResourceTypes = {
61 "Task", "Heartbeat"};
Sunitha Harishe56f2542020-07-22 02:38:59 -050062
John Edward Broadbent7e860f12021-04-08 15:57:16 -070063inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053064{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070065 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070066 .privileges(redfish::privileges::getEventService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -040067 .methods(
68 boost::beast::http::verb::
69 get)([&app](
70 const crow::Request& req,
71 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
72 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
73 {
74 return;
75 }
Ed Tanous14766872022-03-15 10:44:42 -070076
Patrick Williamsbd79bce2024-08-16 15:22:20 -040077 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
78 asyncResp->res.jsonValue["@odata.type"] =
79 "#EventService.v1_5_0.EventService";
80 asyncResp->res.jsonValue["Id"] = "EventService";
81 asyncResp->res.jsonValue["Name"] = "Event Service";
82 asyncResp->res.jsonValue["ServerSentEventUri"] =
83 "/redfish/v1/EventService/SSE";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000084
Patrick Williamsbd79bce2024-08-16 15:22:20 -040085 asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
86 "/redfish/v1/EventService/Subscriptions";
87 asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
88 ["target"] =
89 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
AppaRao Pulie5aaf042020-03-20 01:05:52 +053090
Patrick Williamsbd79bce2024-08-16 15:22:20 -040091 const persistent_data::EventServiceConfig eventServiceConfig =
92 persistent_data::EventServiceStore::getInstance()
93 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080094
Patrick Williamsbd79bce2024-08-16 15:22:20 -040095 asyncResp->res.jsonValue["Status"]["State"] =
96 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
97 asyncResp->res.jsonValue["ServiceEnabled"] =
98 eventServiceConfig.enabled;
99 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
100 eventServiceConfig.retryAttempts;
101 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
102 eventServiceConfig.retryTimeoutInterval;
103 asyncResp->res.jsonValue["EventFormatTypes"] =
104 supportedEvtFormatTypes;
105 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
106 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530107
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400108 nlohmann::json::object_t supportedSSEFilters;
109 supportedSSEFilters["EventFormatType"] = true;
110 supportedSSEFilters["MessageId"] = true;
111 supportedSSEFilters["MetricReportDefinition"] = true;
112 supportedSSEFilters["RegistryPrefix"] = true;
113 supportedSSEFilters["OriginResource"] = false;
114 supportedSSEFilters["ResourceType"] = false;
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530115
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400116 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
117 std::move(supportedSSEFilters);
118 });
Ayushi Smriti07941a82020-05-21 15:55:34 +0530119
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700120 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -0700121 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700122 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700123 [&app](const crow::Request& req,
124 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400125 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
126 {
127 return;
128 }
129 std::optional<bool> serviceEnabled;
130 std::optional<uint32_t> retryAttemps;
131 std::optional<uint32_t> retryInterval;
Patrick Williams504af5a2025-02-03 14:29:03 -0500132 if (!json_util::readJsonPatch( //
133 req, asyncResp->res, //
134 "DeliveryRetryAttempts", retryAttemps, //
Myung Baeafc474a2024-10-09 00:53:29 -0700135 "DeliveryRetryIntervalSeconds", retryInterval, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500136 "ServiceEnabled", serviceEnabled //
Myung Baeafc474a2024-10-09 00:53:29 -0700137 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400138 {
139 return;
140 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530141
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400142 persistent_data::EventServiceConfig eventServiceConfig =
143 persistent_data::EventServiceStore::getInstance()
144 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700145
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400146 if (serviceEnabled)
147 {
148 eventServiceConfig.enabled = *serviceEnabled;
149 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500150
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400151 if (retryAttemps)
152 {
153 // Supported range [1-3]
154 if ((*retryAttemps < 1) || (*retryAttemps > 3))
155 {
156 messages::queryParameterOutOfRange(
157 asyncResp->res, std::to_string(*retryAttemps),
158 "DeliveryRetryAttempts", "[1-3]");
159 }
160 else
161 {
162 eventServiceConfig.retryAttempts = *retryAttemps;
163 }
164 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530165
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400166 if (retryInterval)
167 {
168 // Supported range [5 - 180]
169 if ((*retryInterval < 5) || (*retryInterval > 180))
170 {
171 messages::queryParameterOutOfRange(
172 asyncResp->res, std::to_string(*retryInterval),
173 "DeliveryRetryIntervalSeconds", "[5-180]");
174 }
175 else
176 {
177 eventServiceConfig.retryTimeoutInterval =
178 *retryInterval;
179 }
180 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700181
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400182 EventServiceManager::getInstance().setEventServiceConfig(
183 eventServiceConfig);
184 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700185}
186
187inline void requestRoutesSubmitTestEvent(App& app)
188{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700189 BMCWEB_ROUTE(
190 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700191 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700192 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700193 [&app](const crow::Request& req,
194 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400195 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
196 {
197 return;
198 }
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530199
200 TestEvent testEvent;
201 // clang-format off
202 if (!json_util::readJsonAction(
203 req, asyncResp->res,
204 "EventGroupId", testEvent.eventGroupId,
205 "EventId", testEvent.eventId,
206 "EventTimestamp", testEvent.eventTimestamp,
207 "Message", testEvent.message,
208 "MessageArgs", testEvent.messageArgs,
209 "MessageId", testEvent.messageId,
210 "OriginOfCondition", testEvent.originOfCondition,
211 "Resolution", testEvent.resolution,
212 "Severity", testEvent.severity))
213 {
214 return;
215 }
216 // clang-format on
217
218 if (!EventServiceManager::getInstance().sendTestEventLog(
219 testEvent))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400220 {
221 messages::serviceDisabled(asyncResp->res,
222 "/redfish/v1/EventService/");
223 return;
224 }
225 asyncResp->res.result(boost::beast::http::status::no_content);
226 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700227}
228
Chicago Duan3d307082020-11-26 14:12:12 +0800229inline void doSubscriptionCollection(
Ed Tanouse81de512023-06-27 17:07:00 -0700230 const boost::system::error_code& ec,
Chicago Duan3d307082020-11-26 14:12:12 +0800231 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
232 const dbus::utility::ManagedObjectType& resp)
233{
234 if (ec)
235 {
Ed Tanous13061012023-07-25 11:12:19 -0700236 if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
Chicago Duan3d307082020-11-26 14:12:12 +0800237 {
238 // This is an optional process so just return if it isn't there
239 return;
240 }
241
Ed Tanous62598e32023-07-17 17:06:25 -0700242 BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
Chicago Duan3d307082020-11-26 14:12:12 +0800243 messages::internalError(asyncResp->res);
244 return;
245 }
246 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
247 for (const auto& objpath : resp)
248 {
249 sdbusplus::message::object_path path(objpath.first);
250 const std::string snmpId = path.filename();
251 if (snmpId.empty())
252 {
Ed Tanous62598e32023-07-17 17:06:25 -0700253 BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
Chicago Duan3d307082020-11-26 14:12:12 +0800254 messages::internalError(asyncResp->res);
255 return;
256 }
257
258 getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
259 }
260}
261
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700262inline void requestRoutesEventDestinationCollection(App& app)
263{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000264 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700265 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700266 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700267 [&app](const crow::Request& req,
268 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400269 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
270 {
271 return;
272 }
273 asyncResp->res.jsonValue["@odata.type"] =
274 "#EventDestinationCollection.EventDestinationCollection";
275 asyncResp->res.jsonValue["@odata.id"] =
276 "/redfish/v1/EventService/Subscriptions";
277 asyncResp->res.jsonValue["Name"] =
278 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700279
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400280 nlohmann::json& memberArray =
281 asyncResp->res.jsonValue["Members"];
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700282
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400283 std::vector<std::string> subscripIds =
284 EventServiceManager::getInstance().getAllIDs();
285 memberArray = nlohmann::json::array();
286 asyncResp->res.jsonValue["Members@odata.count"] =
287 subscripIds.size();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700288
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400289 for (const std::string& id : subscripIds)
290 {
291 nlohmann::json::object_t member;
292 member["@odata.id"] = boost::urls::format(
293 "/redfish/v1/EventService/Subscriptions/{}" + id);
294 memberArray.emplace_back(std::move(member));
295 }
296 crow::connections::systemBus->async_method_call(
297 [asyncResp](const boost::system::error_code& ec,
298 const dbus::utility::ManagedObjectType& resp) {
299 doSubscriptionCollection(ec, asyncResp, resp);
300 },
301 "xyz.openbmc_project.Network.SNMP",
302 "/xyz/openbmc_project/network/snmp/manager",
303 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
304 });
Chicago Duan3d307082020-11-26 14:12:12 +0800305
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700306 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500307 .privileges(redfish::privileges::postEventDestinationCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400308 .methods(
309 boost::beast::http::verb::
310 post)([&app](
311 const crow::Request& req,
312 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
313 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
314 {
315 return;
316 }
317 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
318 maxNoOfSubscriptions)
319 {
320 messages::eventSubscriptionLimitExceeded(asyncResp->res);
321 return;
322 }
323 std::string destUrl;
324 std::string protocol;
325 std::optional<bool> verifyCertificate;
326 std::optional<std::string> context;
327 std::optional<std::string> subscriptionType;
328 std::optional<std::string> eventFormatType2;
329 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700330 std::optional<bool> sendHeartbeat;
331 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400332 std::optional<std::vector<std::string>> msgIds;
333 std::optional<std::vector<std::string>> regPrefixes;
Ed Tanousa14c9112024-09-04 10:46:47 -0700334 std::optional<std::vector<std::string>> originResources;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400335 std::optional<std::vector<std::string>> resTypes;
336 std::optional<std::vector<nlohmann::json::object_t>> headers;
337 std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800338
Patrick Williams504af5a2025-02-03 14:29:03 -0500339 if (!json_util::readJsonPatch( //
340 req, asyncResp->res, //
341 "Context", context, //
342 "DeliveryRetryPolicy", retryPolicy, //
343 "Destination", destUrl, //
344 "EventFormatType", eventFormatType2, //
Myung Bae5064a252024-10-04 09:34:25 -0700345 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500346 "HttpHeaders", headers, //
347 "MessageIds", msgIds, //
348 "MetricReportDefinitions", mrdJsonArray, //
349 "OriginResources", originResources, //
350 "Protocol", protocol, //
351 "RegistryPrefixes", regPrefixes, //
352 "ResourceTypes", resTypes, //
353 "SendHeartbeat", sendHeartbeat, //
354 "SubscriptionType", subscriptionType, //
355 "VerifyCertificate", verifyCertificate //
Myung Baeafc474a2024-10-09 00:53:29 -0700356 ))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800357 {
Ed Tanousa716aa72023-08-01 11:35:53 -0700358 return;
359 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700360 // clang-format on
Chicago Duan3d307082020-11-26 14:12:12 +0800361
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400362 // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
363 static constexpr const uint16_t maxDestinationSize = 2000;
364 if (destUrl.size() > maxDestinationSize)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800365 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400366 messages::stringValueTooLong(asyncResp->res, "Destination",
367 maxDestinationSize);
Ed Tanous002d39b2022-05-31 08:59:27 -0700368 return;
369 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700370
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400371 if (regPrefixes && msgIds)
Ed Tanous002d39b2022-05-31 08:59:27 -0700372 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400373 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700374 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400375 messages::propertyValueConflict(
376 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530377 return;
378 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800379 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530380
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400381 boost::system::result<boost::urls::url> url =
382 boost::urls::parse_absolute_uri(destUrl);
383 if (!url)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800384 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400385 BMCWEB_LOG_WARNING(
386 "Failed to validate and split destination url");
387 messages::propertyValueFormatError(asyncResp->res, destUrl,
388 "Destination");
389 return;
390 }
391 url->normalize();
George Liub07942e2024-11-01 09:59:40 +0800392
393 // port_number returns zero if it is not a valid representable port
394 if (url->has_port() && url->port_number() == 0)
395 {
396 BMCWEB_LOG_WARNING("{} is an invalid port in destination url",
397 url->port());
398 messages::propertyValueFormatError(asyncResp->res, destUrl,
399 "Destination");
400 return;
401 }
402
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400403 crow::utility::setProtocolDefaults(*url, protocol);
404 crow::utility::setPortDefaults(*url);
405
406 if (url->path().empty())
407 {
408 url->set_path("/");
409 }
410
411 if (url->has_userinfo())
412 {
413 messages::propertyValueFormatError(asyncResp->res, destUrl,
414 "Destination");
415 return;
416 }
417
418 if (protocol == "SNMPv2c")
419 {
420 if (context)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700421 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400422 messages::propertyValueConflict(asyncResp->res, "Context",
423 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530424 return;
425 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400426 if (eventFormatType2)
427 {
428 messages::propertyValueConflict(
429 asyncResp->res, "EventFormatType", "Protocol");
430 return;
431 }
432 if (retryPolicy)
433 {
434 messages::propertyValueConflict(asyncResp->res,
435 "RetryPolicy", "Protocol");
436 return;
437 }
Myung Bae5064a252024-10-04 09:34:25 -0700438 if (sendHeartbeat)
439 {
440 messages::propertyValueConflict(
441 asyncResp->res, "SendHeartbeat", "Protocol");
442 return;
443 }
444 if (hbIntervalMinutes)
445 {
446 messages::propertyValueConflict(
447 asyncResp->res, "HeartbeatIntervalMinutes", "Protocol");
448 return;
449 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400450 if (msgIds)
451 {
452 messages::propertyValueConflict(asyncResp->res,
453 "MessageIds", "Protocol");
454 return;
455 }
456 if (regPrefixes)
457 {
458 messages::propertyValueConflict(
459 asyncResp->res, "RegistryPrefixes", "Protocol");
460 return;
461 }
462 if (resTypes)
463 {
464 messages::propertyValueConflict(
465 asyncResp->res, "ResourceTypes", "Protocol");
466 return;
467 }
468 if (headers)
469 {
470 messages::propertyValueConflict(asyncResp->res,
471 "HttpHeaders", "Protocol");
472 return;
473 }
474 if (mrdJsonArray)
475 {
476 messages::propertyValueConflict(
477 asyncResp->res, "MetricReportDefinitions", "Protocol");
478 return;
479 }
480 if (url->scheme() != "snmp")
481 {
482 messages::propertyValueConflict(asyncResp->res,
483 "Destination", "Protocol");
484 return;
485 }
486
487 addSnmpTrapClient(asyncResp, url->host_address(),
488 url->port_number());
489 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700490 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700491
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400492 std::shared_ptr<Subscription> subValue =
Myung Bae21a94d52024-10-14 15:02:57 -0700493 std::make_shared<Subscription>(
Myung Bae5fe4ef32024-10-19 09:56:02 -0400494 std::make_shared<persistent_data::UserSubscription>(), *url,
Ed Tanous9838eb22025-01-29 16:24:42 -0800495 getIoContext());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400496
497 if (subscriptionType)
Ed Tanous002d39b2022-05-31 08:59:27 -0700498 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400499 if (*subscriptionType != "RedfishEvent")
500 {
501 messages::propertyValueNotInList(
502 asyncResp->res, *subscriptionType, "SubscriptionType");
503 return;
504 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400505 subValue->userSub->subscriptionType = *subscriptionType;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800506 }
507 else
508 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700509 // Default
Myung Bae5fe4ef32024-10-19 09:56:02 -0400510 subValue->userSub->subscriptionType = "RedfishEvent";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800511 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530512
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400513 if (protocol != "Redfish")
Ed Tanousfffb8c12022-02-07 23:53:03 -0800514 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400515 messages::propertyValueNotInList(asyncResp->res, protocol,
516 "Protocol");
517 return;
518 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400519 subValue->userSub->protocol = protocol;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800520
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400521 if (verifyCertificate)
522 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400523 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400524 }
525
526 if (eventFormatType2)
527 {
528 if (std::ranges::find(supportedEvtFormatTypes,
529 *eventFormatType2) ==
530 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700531 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400532 messages::propertyValueNotInList(
533 asyncResp->res, *eventFormatType2, "EventFormatType");
534 return;
535 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400536 subValue->userSub->eventFormatType = *eventFormatType2;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400537 }
538 else
539 {
540 // If not specified, use default "Event"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400541 subValue->userSub->eventFormatType = "Event";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400542 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700543
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400544 if (context)
545 {
546 // This value is selected arbitrarily.
547 constexpr const size_t maxContextSize = 256;
548 if (context->size() > maxContextSize)
549 {
550 messages::stringValueTooLong(asyncResp->res, "Context",
551 maxContextSize);
552 return;
553 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400554 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400555 }
556
557 if (headers)
558 {
559 size_t cumulativeLen = 0;
560
561 for (const nlohmann::json::object_t& headerChunk : *headers)
562 {
563 for (const auto& item : headerChunk)
Ed Tanous002d39b2022-05-31 08:59:27 -0700564 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400565 const std::string* value =
566 item.second.get_ptr<const std::string*>();
567 if (value == nullptr)
568 {
569 messages::propertyValueFormatError(
570 asyncResp->res, item.second,
571 "HttpHeaders/" + item.first);
572 return;
573 }
574 // Adding a new json value is the size of the key, +
575 // the size of the value + 2 * 2 quotes for each, +
576 // the colon and space between. example:
577 // "key": "value"
578 cumulativeLen += item.first.size() + value->size() + 6;
579 // This value is selected to mirror http_connection.hpp
580 constexpr const uint16_t maxHeaderSizeED = 8096;
581 if (cumulativeLen > maxHeaderSizeED)
582 {
583 messages::arraySizeTooLong(
584 asyncResp->res, "HttpHeaders", maxHeaderSizeED);
585 return;
586 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400587 subValue->userSub->httpHeaders.set(item.first, *value);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400588 }
589 }
590 }
591
592 if (regPrefixes)
593 {
594 for (const std::string& it : *regPrefixes)
595 {
596 if (std::ranges::find(supportedRegPrefixes, it) ==
597 supportedRegPrefixes.end())
598 {
599 messages::propertyValueNotInList(asyncResp->res, it,
600 "RegistryPrefixes");
601 return;
602 }
603 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400604 subValue->userSub->registryPrefixes = *regPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400605 }
606
Ed Tanousa14c9112024-09-04 10:46:47 -0700607 if (originResources)
608 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400609 subValue->userSub->originResources = *originResources;
Ed Tanousa14c9112024-09-04 10:46:47 -0700610 }
611
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400612 if (resTypes)
613 {
614 for (const std::string& it : *resTypes)
615 {
616 if (std::ranges::find(supportedResourceTypes, it) ==
617 supportedResourceTypes.end())
618 {
619 messages::propertyValueNotInList(asyncResp->res, it,
620 "ResourceTypes");
621 return;
622 }
623 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400624 subValue->userSub->resourceTypes = *resTypes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400625 }
626
627 if (msgIds)
628 {
629 std::vector<std::string> registryPrefix;
630
631 // If no registry prefixes are mentioned, consider all
632 // supported prefixes
Myung Bae5fe4ef32024-10-19 09:56:02 -0400633 if (subValue->userSub->registryPrefixes.empty())
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400634 {
635 registryPrefix.assign(supportedRegPrefixes.begin(),
636 supportedRegPrefixes.end());
637 }
638 else
639 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400640 registryPrefix = subValue->userSub->registryPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400641 }
642
643 for (const std::string& id : *msgIds)
644 {
645 bool validId = false;
646
647 // Check for Message ID in each of the selected Registry
648 for (const std::string& it : registryPrefix)
649 {
650 const std::span<const redfish::registries::MessageEntry>
651 registry =
652 redfish::registries::getRegistryFromPrefix(it);
653
654 if (std::ranges::any_of(
655 registry,
656 [&id](const redfish::registries::MessageEntry&
657 messageEntry) {
658 return id == messageEntry.first;
659 }))
660 {
661 validId = true;
662 break;
663 }
664 }
665
666 if (!validId)
667 {
668 messages::propertyValueNotInList(asyncResp->res, id,
669 "MessageIds");
670 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700671 }
672 }
673
Myung Bae5fe4ef32024-10-19 09:56:02 -0400674 subValue->userSub->registryMsgIds = *msgIds;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400675 }
676
677 if (retryPolicy)
678 {
679 if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
680 supportedRetryPolicies.end())
Ed Tanous002d39b2022-05-31 08:59:27 -0700681 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400682 messages::propertyValueNotInList(
683 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
Ed Tanousfffb8c12022-02-07 23:53:03 -0800684 return;
685 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400686 subValue->userSub->retryPolicy = *retryPolicy;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400687 }
688 else
689 {
690 // Default "TerminateAfterRetries"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400691 subValue->userSub->retryPolicy = "TerminateAfterRetries";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400692 }
Myung Bae5064a252024-10-04 09:34:25 -0700693 if (sendHeartbeat)
694 {
695 subValue->userSub->sendHeartbeat = *sendHeartbeat;
696 }
697 if (hbIntervalMinutes)
698 {
699 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
700 {
701 messages::propertyValueOutOfRange(
702 asyncResp->res, *hbIntervalMinutes,
703 "HeartbeatIntervalMinutes");
704 return;
705 }
706 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
707 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400708
709 if (mrdJsonArray)
710 {
711 for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
712 {
713 std::string mrdUri;
714
715 if (!json_util::readJsonObject(mrdObj, asyncResp->res,
716 "@odata.id", mrdUri))
717
718 {
719 return;
720 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400721 subValue->userSub->metricReportDefinitions.emplace_back(
Ed Tanous4b712a22023-08-02 12:56:52 -0700722 mrdUri);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400723 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800724 }
725
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400726 std::string id =
727 EventServiceManager::getInstance().addPushSubscription(
728 subValue);
729 if (id.empty())
Ed Tanousfffb8c12022-02-07 23:53:03 -0800730 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400731 messages::internalError(asyncResp->res);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800732 return;
733 }
734
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400735 messages::created(asyncResp->res);
736 asyncResp->res.addHeader(
737 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
Myung Baefb546102024-10-29 10:21:26 -0500738
739 // schedule a heartbeat
740 if (subValue->userSub->sendHeartbeat)
741 {
742 subValue->scheduleNextHeartbeatEvent();
743 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400744 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700745}
746
747inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530748{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500749 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700750 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700751 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700752 [&app](const crow::Request& req,
753 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
754 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400755 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
756 {
757 return;
758 }
Chicago Duan3d307082020-11-26 14:12:12 +0800759
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400760 if (param.starts_with("snmp"))
761 {
762 getSnmpTrapClient(asyncResp, param);
763 return;
764 }
Chicago Duan3d307082020-11-26 14:12:12 +0800765
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400766 std::shared_ptr<Subscription> subValue =
767 EventServiceManager::getInstance().getSubscription(param);
768 if (subValue == nullptr)
769 {
770 asyncResp->res.result(
771 boost::beast::http::status::not_found);
772 return;
773 }
774 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530775
Ed Tanous4b712a22023-08-02 12:56:52 -0700776 const persistent_data::UserSubscription& userSub =
Myung Bae5fe4ef32024-10-19 09:56:02 -0400777 *subValue->userSub;
zhanghch058d1b46d2021-04-01 11:18:24 +0800778
Ed Tanous4b712a22023-08-02 12:56:52 -0700779 nlohmann::json& jVal = asyncResp->res.jsonValue;
780 jVal["@odata.type"] =
781 "#EventDestination.v1_14_1.EventDestination";
782 jVal["Protocol"] =
783 event_destination::EventDestinationProtocol::Redfish;
784 jVal["@odata.id"] = boost::urls::format(
785 "/redfish/v1/EventService/Subscriptions/{}", id);
786 jVal["Id"] = id;
787 jVal["Name"] = "Event Destination " + id;
788 jVal["Destination"] = userSub.destinationUrl;
789 jVal["Context"] = userSub.customText;
790 jVal["SubscriptionType"] = userSub.subscriptionType;
791 jVal["HttpHeaders"] = nlohmann::json::array();
792 jVal["EventFormatType"] = userSub.eventFormatType;
793 jVal["RegistryPrefixes"] = userSub.registryPrefixes;
794 jVal["ResourceTypes"] = userSub.resourceTypes;
795
796 jVal["MessageIds"] = userSub.registryMsgIds;
797 jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700798 jVal["SendHeartbeat"] = userSub.sendHeartbeat;
799 jVal["HeartbeatIntervalMinutes"] = userSub.hbIntervalMinutes;
Ed Tanous4b712a22023-08-02 12:56:52 -0700800 jVal["VerifyCertificate"] = userSub.verifyCertificate;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530801
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400802 nlohmann::json::array_t mrdJsonArray;
Ed Tanous4b712a22023-08-02 12:56:52 -0700803 for (const auto& mdrUri : userSub.metricReportDefinitions)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400804 {
805 nlohmann::json::object_t mdr;
806 mdr["@odata.id"] = mdrUri;
807 mrdJsonArray.emplace_back(std::move(mdr));
808 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700809 jVal["MetricReportDefinitions"] = mrdJsonArray;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400810 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500811 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700812 // The below privilege is wrong, it should be ConfigureManager OR
813 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500814 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700815 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700816 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700817 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700818 [&app](const crow::Request& req,
819 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
820 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400821 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700822 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400823 return;
824 }
825 std::shared_ptr<Subscription> subValue =
826 EventServiceManager::getInstance().getSubscription(param);
827 if (subValue == nullptr)
828 {
829 asyncResp->res.result(
830 boost::beast::http::status::not_found);
831 return;
832 }
833
834 std::optional<std::string> context;
835 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700836 std::optional<bool> sendHeartbeat;
837 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400838 std::optional<bool> verifyCertificate;
839 std::optional<std::vector<nlohmann::json::object_t>> headers;
840
Patrick Williams504af5a2025-02-03 14:29:03 -0500841 if (!json_util::readJsonPatch( //
842 req, asyncResp->res, //
843 "Context", context, //
844 "DeliveryRetryPolicy", retryPolicy, //
Myung Bae5064a252024-10-04 09:34:25 -0700845 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500846 "HttpHeaders", headers, //
847 "SendHeartbeat", sendHeartbeat, //
848 "VerifyCertificate", verifyCertificate //
Myung Baeafc474a2024-10-09 00:53:29 -0700849 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400850 {
851 return;
852 }
853
854 if (context)
855 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400856 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400857 }
858
859 if (headers)
860 {
861 boost::beast::http::fields fields;
862 for (const nlohmann::json::object_t& headerChunk : *headers)
Ed Tanous601c71a2021-09-08 16:40:12 -0700863 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400864 for (const auto& it : headerChunk)
865 {
866 const std::string* value =
867 it.second.get_ptr<const std::string*>();
868 if (value == nullptr)
869 {
870 messages::propertyValueFormatError(
871 asyncResp->res, it.second,
872 "HttpHeaders/" + it.first);
873 return;
874 }
875 fields.set(it.first, *value);
876 }
877 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400878 subValue->userSub->httpHeaders = std::move(fields);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400879 }
880
881 if (retryPolicy)
882 {
883 if (std::ranges::find(supportedRetryPolicies,
884 *retryPolicy) ==
885 supportedRetryPolicies.end())
886 {
887 messages::propertyValueNotInList(asyncResp->res,
888 *retryPolicy,
889 "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700890 return;
891 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400892 subValue->userSub->retryPolicy = *retryPolicy;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700893 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530894
Myung Bae5064a252024-10-04 09:34:25 -0700895 if (sendHeartbeat)
896 {
897 subValue->userSub->sendHeartbeat = *sendHeartbeat;
898 }
899 if (hbIntervalMinutes)
900 {
901 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
902 {
903 messages::propertyValueOutOfRange(
904 asyncResp->res, *hbIntervalMinutes,
905 "HeartbeatIntervalMinutes");
906 return;
907 }
908 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
909 }
910
Myung Baefb546102024-10-29 10:21:26 -0500911 if (hbIntervalMinutes || sendHeartbeat)
912 {
913 // if Heartbeat interval or send heart were changed, cancel
914 // the heartbeat timer if running and start a new heartbeat
915 // if needed
916 subValue->heartbeatParametersChanged();
917 }
918
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400919 if (verifyCertificate)
920 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400921 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400922 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700923
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400924 EventServiceManager::getInstance().updateSubscriptionData();
925 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500926 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700927 // The below privilege is wrong, it should be ConfigureManager OR
928 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500929 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700930 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700931 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700932 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700933 [&app](const crow::Request& req,
934 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
935 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400936 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
937 {
938 return;
939 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700940 EventServiceManager& event = EventServiceManager::getInstance();
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400941 if (param.starts_with("snmp"))
942 {
943 deleteSnmpTrapClient(asyncResp, param);
Ed Tanous4b712a22023-08-02 12:56:52 -0700944 event.deleteSubscription(param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400945 return;
946 }
Chicago Duan3d307082020-11-26 14:12:12 +0800947
Ed Tanous4b712a22023-08-02 12:56:52 -0700948 if (!event.deleteSubscription(param))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400949 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700950 messages::resourceNotFound(asyncResp->res,
951 "EventDestination", param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400952 return;
953 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700954 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400955 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700956}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530957
958} // namespace redfish