blob: eb02ab8f8ae87a858542819b20df330289a89cc4 [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"
Ed Tanousd7857202025-01-28 15:32:26 -08007#include "dbus_utility.hpp"
8#include "error_messages.hpp"
AppaRao Pulib52664e2020-04-09 21:36:51 +05309#include "event_service_manager.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080010#include "event_service_store.hpp"
11#include "generated/enums/event_destination.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080012#include "http/utility.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080013#include "http_request.hpp"
Ed Tanous9838eb22025-01-29 16:24:42 -080014#include "io_context_singleton.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080015#include "logging.hpp"
16#include "query.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010017#include "registries.hpp"
Ed Tanous3ccb3ad2023-01-13 17:40:03 -080018#include "registries/privilege_registry.hpp"
Chicago Duan3d307082020-11-26 14:12:12 +080019#include "snmp_trap_event_clients.hpp"
Ed Tanousd7857202025-01-28 15:32:26 -080020#include "subscription.hpp"
Alexander Hansend109e2b2024-11-18 14:38:06 +010021#include "utils/json_utils.hpp"
AppaRao Pulie5aaf042020-03-20 01:05:52 +053022
Ed Tanousd7857202025-01-28 15:32:26 -080023#include <asm-generic/errno.h>
Ed Tanoused398212021-06-09 17:05:54 -070024
Ed Tanousd7857202025-01-28 15:32:26 -080025#include <boost/beast/http/status.hpp>
26#include <boost/beast/http/verb.hpp>
27#include <boost/system/error_code.hpp>
28#include <boost/system/result.hpp>
29#include <boost/url/format.hpp>
30#include <boost/url/parse.hpp>
31#include <boost/url/url.hpp>
32#include <sdbusplus/message/native_types.hpp>
33
34#include <algorithm>
35#include <array>
36#include <cerrno>
37#include <cstddef>
38#include <cstdint>
Chicago Duan3d307082020-11-26 14:12:12 +080039#include <memory>
Myung Bae5064a252024-10-04 09:34:25 -070040#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070041#include <ranges>
Chicago Duan3d307082020-11-26 14:12:12 +080042#include <string>
Ed Tanousd7857202025-01-28 15:32:26 -080043#include <utility>
Ed Tanousa14c9112024-09-04 10:46:47 -070044#include <vector>
Patrick Williams1e270c52021-12-04 06:06:56 -060045
AppaRao Pulie5aaf042020-03-20 01:05:52 +053046namespace redfish
47{
48
AppaRao Puli156d6b02020-04-25 06:04:05 +053049static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
50 eventFormatType, metricReportFormatType};
Myung Baefb546102024-10-29 10:21:26 -050051static constexpr const std::array<const char*, 4> supportedRegPrefixes = {
52 "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053053static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
54 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
55
Myung Baefb546102024-10-29 10:21:26 -050056static constexpr const std::array<const char*, 2> supportedResourceTypes = {
57 "Task", "Heartbeat"};
Sunitha Harishe56f2542020-07-22 02:38:59 -050058
John Edward Broadbent7e860f12021-04-08 15:57:16 -070059inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053060{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070061 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070062 .privileges(redfish::privileges::getEventService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -040063 .methods(
64 boost::beast::http::verb::
65 get)([&app](
66 const crow::Request& req,
67 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
68 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
69 {
70 return;
71 }
Ed Tanous14766872022-03-15 10:44:42 -070072
Patrick Williamsbd79bce2024-08-16 15:22:20 -040073 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
74 asyncResp->res.jsonValue["@odata.type"] =
75 "#EventService.v1_5_0.EventService";
76 asyncResp->res.jsonValue["Id"] = "EventService";
77 asyncResp->res.jsonValue["Name"] = "Event Service";
78 asyncResp->res.jsonValue["ServerSentEventUri"] =
79 "/redfish/v1/EventService/SSE";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000080
Patrick Williamsbd79bce2024-08-16 15:22:20 -040081 asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
82 "/redfish/v1/EventService/Subscriptions";
83 asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
84 ["target"] =
85 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
AppaRao Pulie5aaf042020-03-20 01:05:52 +053086
Patrick Williamsbd79bce2024-08-16 15:22:20 -040087 const persistent_data::EventServiceConfig eventServiceConfig =
88 persistent_data::EventServiceStore::getInstance()
89 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080090
Patrick Williamsbd79bce2024-08-16 15:22:20 -040091 asyncResp->res.jsonValue["Status"]["State"] =
92 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
93 asyncResp->res.jsonValue["ServiceEnabled"] =
94 eventServiceConfig.enabled;
95 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
96 eventServiceConfig.retryAttempts;
97 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
98 eventServiceConfig.retryTimeoutInterval;
99 asyncResp->res.jsonValue["EventFormatTypes"] =
100 supportedEvtFormatTypes;
101 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
102 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530103
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400104 nlohmann::json::object_t supportedSSEFilters;
105 supportedSSEFilters["EventFormatType"] = true;
106 supportedSSEFilters["MessageId"] = true;
107 supportedSSEFilters["MetricReportDefinition"] = true;
108 supportedSSEFilters["RegistryPrefix"] = true;
109 supportedSSEFilters["OriginResource"] = false;
110 supportedSSEFilters["ResourceType"] = false;
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530111
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400112 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
113 std::move(supportedSSEFilters);
114 });
Ayushi Smriti07941a82020-05-21 15:55:34 +0530115
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700116 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -0700117 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700118 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700119 [&app](const crow::Request& req,
120 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400121 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
122 {
123 return;
124 }
125 std::optional<bool> serviceEnabled;
126 std::optional<uint32_t> retryAttemps;
127 std::optional<uint32_t> retryInterval;
Patrick Williams504af5a2025-02-03 14:29:03 -0500128 if (!json_util::readJsonPatch( //
129 req, asyncResp->res, //
130 "DeliveryRetryAttempts", retryAttemps, //
Myung Baeafc474a2024-10-09 00:53:29 -0700131 "DeliveryRetryIntervalSeconds", retryInterval, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500132 "ServiceEnabled", serviceEnabled //
Myung Baeafc474a2024-10-09 00:53:29 -0700133 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400134 {
135 return;
136 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530137
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400138 persistent_data::EventServiceConfig eventServiceConfig =
139 persistent_data::EventServiceStore::getInstance()
140 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700141
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400142 if (serviceEnabled)
143 {
144 eventServiceConfig.enabled = *serviceEnabled;
145 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500146
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400147 if (retryAttemps)
148 {
149 // Supported range [1-3]
150 if ((*retryAttemps < 1) || (*retryAttemps > 3))
151 {
152 messages::queryParameterOutOfRange(
153 asyncResp->res, std::to_string(*retryAttemps),
154 "DeliveryRetryAttempts", "[1-3]");
155 }
156 else
157 {
158 eventServiceConfig.retryAttempts = *retryAttemps;
159 }
160 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530161
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400162 if (retryInterval)
163 {
164 // Supported range [5 - 180]
165 if ((*retryInterval < 5) || (*retryInterval > 180))
166 {
167 messages::queryParameterOutOfRange(
168 asyncResp->res, std::to_string(*retryInterval),
169 "DeliveryRetryIntervalSeconds", "[5-180]");
170 }
171 else
172 {
173 eventServiceConfig.retryTimeoutInterval =
174 *retryInterval;
175 }
176 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700177
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400178 EventServiceManager::getInstance().setEventServiceConfig(
179 eventServiceConfig);
180 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700181}
182
183inline void requestRoutesSubmitTestEvent(App& app)
184{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700185 BMCWEB_ROUTE(
186 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700187 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700188 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700189 [&app](const crow::Request& req,
190 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400191 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
192 {
193 return;
194 }
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530195
Ed Tanous4a19a7b2025-01-27 10:44:15 -0800196 // From the Redfish spec on EventId
197 // A service can ignore this value and replace it with its own.
198 // note that this parameter is intentionally ignored
199
200 std::optional<std::string> eventId;
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530201 TestEvent testEvent;
202 // clang-format off
203 if (!json_util::readJsonAction(
204 req, asyncResp->res,
205 "EventGroupId", testEvent.eventGroupId,
Ed Tanous4a19a7b2025-01-27 10:44:15 -0800206 "EventId", eventId,
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530207 "EventTimestamp", testEvent.eventTimestamp,
208 "Message", testEvent.message,
209 "MessageArgs", testEvent.messageArgs,
210 "MessageId", testEvent.messageId,
211 "OriginOfCondition", testEvent.originOfCondition,
212 "Resolution", testEvent.resolution,
213 "Severity", testEvent.severity))
214 {
215 return;
216 }
217 // clang-format on
218
219 if (!EventServiceManager::getInstance().sendTestEventLog(
220 testEvent))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400221 {
222 messages::serviceDisabled(asyncResp->res,
223 "/redfish/v1/EventService/");
224 return;
225 }
226 asyncResp->res.result(boost::beast::http::status::no_content);
227 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700228}
229
Chicago Duan3d307082020-11-26 14:12:12 +0800230inline void doSubscriptionCollection(
Ed Tanouse81de512023-06-27 17:07:00 -0700231 const boost::system::error_code& ec,
Chicago Duan3d307082020-11-26 14:12:12 +0800232 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
233 const dbus::utility::ManagedObjectType& resp)
234{
235 if (ec)
236 {
Ed Tanous13061012023-07-25 11:12:19 -0700237 if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
Chicago Duan3d307082020-11-26 14:12:12 +0800238 {
239 // This is an optional process so just return if it isn't there
240 return;
241 }
242
Ed Tanous62598e32023-07-17 17:06:25 -0700243 BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
Chicago Duan3d307082020-11-26 14:12:12 +0800244 messages::internalError(asyncResp->res);
245 return;
246 }
247 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
248 for (const auto& objpath : resp)
249 {
250 sdbusplus::message::object_path path(objpath.first);
251 const std::string snmpId = path.filename();
252 if (snmpId.empty())
253 {
Ed Tanous62598e32023-07-17 17:06:25 -0700254 BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
Chicago Duan3d307082020-11-26 14:12:12 +0800255 messages::internalError(asyncResp->res);
256 return;
257 }
258
259 getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
260 }
261}
262
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700263inline void requestRoutesEventDestinationCollection(App& app)
264{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000265 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700266 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700267 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700268 [&app](const crow::Request& req,
269 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400270 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
271 {
272 return;
273 }
274 asyncResp->res.jsonValue["@odata.type"] =
275 "#EventDestinationCollection.EventDestinationCollection";
276 asyncResp->res.jsonValue["@odata.id"] =
277 "/redfish/v1/EventService/Subscriptions";
278 asyncResp->res.jsonValue["Name"] =
279 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700280
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400281 nlohmann::json& memberArray =
282 asyncResp->res.jsonValue["Members"];
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700283
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400284 std::vector<std::string> subscripIds =
285 EventServiceManager::getInstance().getAllIDs();
286 memberArray = nlohmann::json::array();
287 asyncResp->res.jsonValue["Members@odata.count"] =
288 subscripIds.size();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700289
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400290 for (const std::string& id : subscripIds)
291 {
292 nlohmann::json::object_t member;
293 member["@odata.id"] = boost::urls::format(
294 "/redfish/v1/EventService/Subscriptions/{}" + id);
295 memberArray.emplace_back(std::move(member));
296 }
Ed Tanous177612a2025-02-14 15:16:09 -0800297 dbus::utility::async_method_call(
298 asyncResp,
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400299 [asyncResp](const boost::system::error_code& ec,
300 const dbus::utility::ManagedObjectType& resp) {
301 doSubscriptionCollection(ec, asyncResp, resp);
302 },
303 "xyz.openbmc_project.Network.SNMP",
304 "/xyz/openbmc_project/network/snmp/manager",
305 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
306 });
Chicago Duan3d307082020-11-26 14:12:12 +0800307
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700308 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500309 .privileges(redfish::privileges::postEventDestinationCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400310 .methods(
311 boost::beast::http::verb::
312 post)([&app](
313 const crow::Request& req,
314 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
315 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
316 {
317 return;
318 }
319 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
320 maxNoOfSubscriptions)
321 {
322 messages::eventSubscriptionLimitExceeded(asyncResp->res);
323 return;
324 }
325 std::string destUrl;
326 std::string protocol;
327 std::optional<bool> verifyCertificate;
328 std::optional<std::string> context;
329 std::optional<std::string> subscriptionType;
330 std::optional<std::string> eventFormatType2;
331 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700332 std::optional<bool> sendHeartbeat;
333 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400334 std::optional<std::vector<std::string>> msgIds;
335 std::optional<std::vector<std::string>> regPrefixes;
Ed Tanousa14c9112024-09-04 10:46:47 -0700336 std::optional<std::vector<std::string>> originResources;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400337 std::optional<std::vector<std::string>> resTypes;
338 std::optional<std::vector<nlohmann::json::object_t>> headers;
339 std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800340
Patrick Williams504af5a2025-02-03 14:29:03 -0500341 if (!json_util::readJsonPatch( //
342 req, asyncResp->res, //
343 "Context", context, //
344 "DeliveryRetryPolicy", retryPolicy, //
345 "Destination", destUrl, //
346 "EventFormatType", eventFormatType2, //
Myung Bae5064a252024-10-04 09:34:25 -0700347 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500348 "HttpHeaders", headers, //
349 "MessageIds", msgIds, //
350 "MetricReportDefinitions", mrdJsonArray, //
351 "OriginResources", originResources, //
352 "Protocol", protocol, //
353 "RegistryPrefixes", regPrefixes, //
354 "ResourceTypes", resTypes, //
355 "SendHeartbeat", sendHeartbeat, //
356 "SubscriptionType", subscriptionType, //
357 "VerifyCertificate", verifyCertificate //
Myung Baeafc474a2024-10-09 00:53:29 -0700358 ))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800359 {
Ed Tanousa716aa72023-08-01 11:35:53 -0700360 return;
361 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700362 // clang-format on
Chicago Duan3d307082020-11-26 14:12:12 +0800363
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400364 // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
365 static constexpr const uint16_t maxDestinationSize = 2000;
366 if (destUrl.size() > maxDestinationSize)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800367 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400368 messages::stringValueTooLong(asyncResp->res, "Destination",
369 maxDestinationSize);
Ed Tanous002d39b2022-05-31 08:59:27 -0700370 return;
371 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700372
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400373 if (regPrefixes && msgIds)
Ed Tanous002d39b2022-05-31 08:59:27 -0700374 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400375 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700376 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400377 messages::propertyValueConflict(
378 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530379 return;
380 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800381 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530382
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400383 boost::system::result<boost::urls::url> url =
384 boost::urls::parse_absolute_uri(destUrl);
385 if (!url)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800386 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400387 BMCWEB_LOG_WARNING(
388 "Failed to validate and split destination url");
389 messages::propertyValueFormatError(asyncResp->res, destUrl,
390 "Destination");
391 return;
392 }
393 url->normalize();
George Liub07942e2024-11-01 09:59:40 +0800394
395 // port_number returns zero if it is not a valid representable port
396 if (url->has_port() && url->port_number() == 0)
397 {
398 BMCWEB_LOG_WARNING("{} is an invalid port in destination url",
399 url->port());
400 messages::propertyValueFormatError(asyncResp->res, destUrl,
401 "Destination");
402 return;
403 }
404
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400405 crow::utility::setProtocolDefaults(*url, protocol);
406 crow::utility::setPortDefaults(*url);
407
408 if (url->path().empty())
409 {
410 url->set_path("/");
411 }
412
413 if (url->has_userinfo())
414 {
415 messages::propertyValueFormatError(asyncResp->res, destUrl,
416 "Destination");
417 return;
418 }
419
420 if (protocol == "SNMPv2c")
421 {
422 if (context)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700423 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400424 messages::propertyValueConflict(asyncResp->res, "Context",
425 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530426 return;
427 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400428 if (eventFormatType2)
429 {
430 messages::propertyValueConflict(
431 asyncResp->res, "EventFormatType", "Protocol");
432 return;
433 }
434 if (retryPolicy)
435 {
436 messages::propertyValueConflict(asyncResp->res,
437 "RetryPolicy", "Protocol");
438 return;
439 }
Myung Bae5064a252024-10-04 09:34:25 -0700440 if (sendHeartbeat)
441 {
442 messages::propertyValueConflict(
443 asyncResp->res, "SendHeartbeat", "Protocol");
444 return;
445 }
446 if (hbIntervalMinutes)
447 {
448 messages::propertyValueConflict(
449 asyncResp->res, "HeartbeatIntervalMinutes", "Protocol");
450 return;
451 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400452 if (msgIds)
453 {
454 messages::propertyValueConflict(asyncResp->res,
455 "MessageIds", "Protocol");
456 return;
457 }
458 if (regPrefixes)
459 {
460 messages::propertyValueConflict(
461 asyncResp->res, "RegistryPrefixes", "Protocol");
462 return;
463 }
464 if (resTypes)
465 {
466 messages::propertyValueConflict(
467 asyncResp->res, "ResourceTypes", "Protocol");
468 return;
469 }
470 if (headers)
471 {
472 messages::propertyValueConflict(asyncResp->res,
473 "HttpHeaders", "Protocol");
474 return;
475 }
476 if (mrdJsonArray)
477 {
478 messages::propertyValueConflict(
479 asyncResp->res, "MetricReportDefinitions", "Protocol");
480 return;
481 }
482 if (url->scheme() != "snmp")
483 {
484 messages::propertyValueConflict(asyncResp->res,
485 "Destination", "Protocol");
486 return;
487 }
488
489 addSnmpTrapClient(asyncResp, url->host_address(),
490 url->port_number());
491 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700492 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700493
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400494 std::shared_ptr<Subscription> subValue =
Myung Bae21a94d52024-10-14 15:02:57 -0700495 std::make_shared<Subscription>(
Myung Bae5fe4ef32024-10-19 09:56:02 -0400496 std::make_shared<persistent_data::UserSubscription>(), *url,
Ed Tanous9838eb22025-01-29 16:24:42 -0800497 getIoContext());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400498
499 if (subscriptionType)
Ed Tanous002d39b2022-05-31 08:59:27 -0700500 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400501 if (*subscriptionType != "RedfishEvent")
502 {
503 messages::propertyValueNotInList(
504 asyncResp->res, *subscriptionType, "SubscriptionType");
505 return;
506 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400507 subValue->userSub->subscriptionType = *subscriptionType;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800508 }
509 else
510 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700511 // Default
Myung Bae5fe4ef32024-10-19 09:56:02 -0400512 subValue->userSub->subscriptionType = "RedfishEvent";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800513 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530514
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400515 if (protocol != "Redfish")
Ed Tanousfffb8c12022-02-07 23:53:03 -0800516 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400517 messages::propertyValueNotInList(asyncResp->res, protocol,
518 "Protocol");
519 return;
520 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400521 subValue->userSub->protocol = protocol;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800522
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400523 if (verifyCertificate)
524 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400525 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400526 }
527
528 if (eventFormatType2)
529 {
530 if (std::ranges::find(supportedEvtFormatTypes,
531 *eventFormatType2) ==
532 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700533 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400534 messages::propertyValueNotInList(
535 asyncResp->res, *eventFormatType2, "EventFormatType");
536 return;
537 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400538 subValue->userSub->eventFormatType = *eventFormatType2;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400539 }
540 else
541 {
542 // If not specified, use default "Event"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400543 subValue->userSub->eventFormatType = "Event";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400544 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700545
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400546 if (context)
547 {
548 // This value is selected arbitrarily.
549 constexpr const size_t maxContextSize = 256;
550 if (context->size() > maxContextSize)
551 {
552 messages::stringValueTooLong(asyncResp->res, "Context",
553 maxContextSize);
554 return;
555 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400556 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400557 }
558
559 if (headers)
560 {
561 size_t cumulativeLen = 0;
562
563 for (const nlohmann::json::object_t& headerChunk : *headers)
564 {
565 for (const auto& item : headerChunk)
Ed Tanous002d39b2022-05-31 08:59:27 -0700566 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400567 const std::string* value =
568 item.second.get_ptr<const std::string*>();
569 if (value == nullptr)
570 {
571 messages::propertyValueFormatError(
572 asyncResp->res, item.second,
573 "HttpHeaders/" + item.first);
574 return;
575 }
576 // Adding a new json value is the size of the key, +
577 // the size of the value + 2 * 2 quotes for each, +
578 // the colon and space between. example:
579 // "key": "value"
580 cumulativeLen += item.first.size() + value->size() + 6;
581 // This value is selected to mirror http_connection.hpp
582 constexpr const uint16_t maxHeaderSizeED = 8096;
583 if (cumulativeLen > maxHeaderSizeED)
584 {
585 messages::arraySizeTooLong(
586 asyncResp->res, "HttpHeaders", maxHeaderSizeED);
587 return;
588 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400589 subValue->userSub->httpHeaders.set(item.first, *value);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400590 }
591 }
592 }
593
594 if (regPrefixes)
595 {
596 for (const std::string& it : *regPrefixes)
597 {
598 if (std::ranges::find(supportedRegPrefixes, it) ==
599 supportedRegPrefixes.end())
600 {
601 messages::propertyValueNotInList(asyncResp->res, it,
602 "RegistryPrefixes");
603 return;
604 }
605 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400606 subValue->userSub->registryPrefixes = *regPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400607 }
608
Ed Tanousa14c9112024-09-04 10:46:47 -0700609 if (originResources)
610 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400611 subValue->userSub->originResources = *originResources;
Ed Tanousa14c9112024-09-04 10:46:47 -0700612 }
613
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400614 if (resTypes)
615 {
616 for (const std::string& it : *resTypes)
617 {
618 if (std::ranges::find(supportedResourceTypes, it) ==
619 supportedResourceTypes.end())
620 {
621 messages::propertyValueNotInList(asyncResp->res, it,
622 "ResourceTypes");
623 return;
624 }
625 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400626 subValue->userSub->resourceTypes = *resTypes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400627 }
628
629 if (msgIds)
630 {
631 std::vector<std::string> registryPrefix;
632
633 // If no registry prefixes are mentioned, consider all
634 // supported prefixes
Myung Bae5fe4ef32024-10-19 09:56:02 -0400635 if (subValue->userSub->registryPrefixes.empty())
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400636 {
637 registryPrefix.assign(supportedRegPrefixes.begin(),
638 supportedRegPrefixes.end());
639 }
640 else
641 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400642 registryPrefix = subValue->userSub->registryPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400643 }
644
645 for (const std::string& id : *msgIds)
646 {
647 bool validId = false;
648
649 // Check for Message ID in each of the selected Registry
650 for (const std::string& it : registryPrefix)
651 {
Patrick Williams4a102cd2025-02-27 14:52:54 -0500652 const registries::MessageEntries registry =
653 redfish::registries::getRegistryMessagesFromPrefix(
654 it);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400655
656 if (std::ranges::any_of(
657 registry,
658 [&id](const redfish::registries::MessageEntry&
659 messageEntry) {
660 return id == messageEntry.first;
661 }))
662 {
663 validId = true;
664 break;
665 }
666 }
667
668 if (!validId)
669 {
670 messages::propertyValueNotInList(asyncResp->res, id,
671 "MessageIds");
672 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700673 }
674 }
675
Myung Bae5fe4ef32024-10-19 09:56:02 -0400676 subValue->userSub->registryMsgIds = *msgIds;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400677 }
678
679 if (retryPolicy)
680 {
681 if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
682 supportedRetryPolicies.end())
Ed Tanous002d39b2022-05-31 08:59:27 -0700683 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400684 messages::propertyValueNotInList(
685 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
Ed Tanousfffb8c12022-02-07 23:53:03 -0800686 return;
687 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400688 subValue->userSub->retryPolicy = *retryPolicy;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400689 }
690 else
691 {
692 // Default "TerminateAfterRetries"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400693 subValue->userSub->retryPolicy = "TerminateAfterRetries";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400694 }
Myung Bae5064a252024-10-04 09:34:25 -0700695 if (sendHeartbeat)
696 {
697 subValue->userSub->sendHeartbeat = *sendHeartbeat;
698 }
699 if (hbIntervalMinutes)
700 {
701 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
702 {
703 messages::propertyValueOutOfRange(
704 asyncResp->res, *hbIntervalMinutes,
705 "HeartbeatIntervalMinutes");
706 return;
707 }
708 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
709 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400710
711 if (mrdJsonArray)
712 {
713 for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
714 {
715 std::string mrdUri;
716
717 if (!json_util::readJsonObject(mrdObj, asyncResp->res,
718 "@odata.id", mrdUri))
719
720 {
721 return;
722 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400723 subValue->userSub->metricReportDefinitions.emplace_back(
Ed Tanous4b712a22023-08-02 12:56:52 -0700724 mrdUri);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400725 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800726 }
727
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400728 std::string id =
729 EventServiceManager::getInstance().addPushSubscription(
730 subValue);
731 if (id.empty())
Ed Tanousfffb8c12022-02-07 23:53:03 -0800732 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400733 messages::internalError(asyncResp->res);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800734 return;
735 }
736
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400737 messages::created(asyncResp->res);
738 asyncResp->res.addHeader(
739 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
Myung Baefb546102024-10-29 10:21:26 -0500740
741 // schedule a heartbeat
742 if (subValue->userSub->sendHeartbeat)
743 {
744 subValue->scheduleNextHeartbeatEvent();
745 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400746 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700747}
748
749inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530750{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500751 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700752 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700753 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700754 [&app](const crow::Request& req,
755 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
756 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400757 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
758 {
759 return;
760 }
Chicago Duan3d307082020-11-26 14:12:12 +0800761
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400762 if (param.starts_with("snmp"))
763 {
764 getSnmpTrapClient(asyncResp, param);
765 return;
766 }
Chicago Duan3d307082020-11-26 14:12:12 +0800767
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400768 std::shared_ptr<Subscription> subValue =
769 EventServiceManager::getInstance().getSubscription(param);
770 if (subValue == nullptr)
771 {
772 asyncResp->res.result(
773 boost::beast::http::status::not_found);
774 return;
775 }
776 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530777
Ed Tanous4b712a22023-08-02 12:56:52 -0700778 const persistent_data::UserSubscription& userSub =
Myung Bae5fe4ef32024-10-19 09:56:02 -0400779 *subValue->userSub;
zhanghch058d1b46d2021-04-01 11:18:24 +0800780
Ed Tanous4b712a22023-08-02 12:56:52 -0700781 nlohmann::json& jVal = asyncResp->res.jsonValue;
782 jVal["@odata.type"] =
783 "#EventDestination.v1_14_1.EventDestination";
784 jVal["Protocol"] =
785 event_destination::EventDestinationProtocol::Redfish;
786 jVal["@odata.id"] = boost::urls::format(
787 "/redfish/v1/EventService/Subscriptions/{}", id);
788 jVal["Id"] = id;
789 jVal["Name"] = "Event Destination " + id;
790 jVal["Destination"] = userSub.destinationUrl;
791 jVal["Context"] = userSub.customText;
792 jVal["SubscriptionType"] = userSub.subscriptionType;
793 jVal["HttpHeaders"] = nlohmann::json::array();
794 jVal["EventFormatType"] = userSub.eventFormatType;
795 jVal["RegistryPrefixes"] = userSub.registryPrefixes;
796 jVal["ResourceTypes"] = userSub.resourceTypes;
797
798 jVal["MessageIds"] = userSub.registryMsgIds;
799 jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700800 jVal["SendHeartbeat"] = userSub.sendHeartbeat;
801 jVal["HeartbeatIntervalMinutes"] = userSub.hbIntervalMinutes;
Ed Tanous4b712a22023-08-02 12:56:52 -0700802 jVal["VerifyCertificate"] = userSub.verifyCertificate;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530803
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400804 nlohmann::json::array_t mrdJsonArray;
Ed Tanous4b712a22023-08-02 12:56:52 -0700805 for (const auto& mdrUri : userSub.metricReportDefinitions)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400806 {
807 nlohmann::json::object_t mdr;
808 mdr["@odata.id"] = mdrUri;
809 mrdJsonArray.emplace_back(std::move(mdr));
810 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700811 jVal["MetricReportDefinitions"] = mrdJsonArray;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400812 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500813 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700814 // The below privilege is wrong, it should be ConfigureManager OR
815 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500816 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700817 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700818 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700819 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700820 [&app](const crow::Request& req,
821 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
822 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400823 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700824 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400825 return;
826 }
827 std::shared_ptr<Subscription> subValue =
828 EventServiceManager::getInstance().getSubscription(param);
829 if (subValue == nullptr)
830 {
831 asyncResp->res.result(
832 boost::beast::http::status::not_found);
833 return;
834 }
835
836 std::optional<std::string> context;
837 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700838 std::optional<bool> sendHeartbeat;
839 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400840 std::optional<bool> verifyCertificate;
841 std::optional<std::vector<nlohmann::json::object_t>> headers;
842
Patrick Williams504af5a2025-02-03 14:29:03 -0500843 if (!json_util::readJsonPatch( //
844 req, asyncResp->res, //
845 "Context", context, //
846 "DeliveryRetryPolicy", retryPolicy, //
Myung Bae5064a252024-10-04 09:34:25 -0700847 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500848 "HttpHeaders", headers, //
849 "SendHeartbeat", sendHeartbeat, //
850 "VerifyCertificate", verifyCertificate //
Myung Baeafc474a2024-10-09 00:53:29 -0700851 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400852 {
853 return;
854 }
855
856 if (context)
857 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400858 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400859 }
860
861 if (headers)
862 {
863 boost::beast::http::fields fields;
864 for (const nlohmann::json::object_t& headerChunk : *headers)
Ed Tanous601c71a2021-09-08 16:40:12 -0700865 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400866 for (const auto& it : headerChunk)
867 {
868 const std::string* value =
869 it.second.get_ptr<const std::string*>();
870 if (value == nullptr)
871 {
872 messages::propertyValueFormatError(
873 asyncResp->res, it.second,
874 "HttpHeaders/" + it.first);
875 return;
876 }
877 fields.set(it.first, *value);
878 }
879 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400880 subValue->userSub->httpHeaders = std::move(fields);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400881 }
882
883 if (retryPolicy)
884 {
885 if (std::ranges::find(supportedRetryPolicies,
886 *retryPolicy) ==
887 supportedRetryPolicies.end())
888 {
889 messages::propertyValueNotInList(asyncResp->res,
890 *retryPolicy,
891 "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700892 return;
893 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400894 subValue->userSub->retryPolicy = *retryPolicy;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700895 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530896
Myung Bae5064a252024-10-04 09:34:25 -0700897 if (sendHeartbeat)
898 {
899 subValue->userSub->sendHeartbeat = *sendHeartbeat;
900 }
901 if (hbIntervalMinutes)
902 {
903 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
904 {
905 messages::propertyValueOutOfRange(
906 asyncResp->res, *hbIntervalMinutes,
907 "HeartbeatIntervalMinutes");
908 return;
909 }
910 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
911 }
912
Myung Baefb546102024-10-29 10:21:26 -0500913 if (hbIntervalMinutes || sendHeartbeat)
914 {
915 // if Heartbeat interval or send heart were changed, cancel
916 // the heartbeat timer if running and start a new heartbeat
917 // if needed
918 subValue->heartbeatParametersChanged();
919 }
920
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400921 if (verifyCertificate)
922 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400923 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400924 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700925
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400926 EventServiceManager::getInstance().updateSubscriptionData();
927 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500928 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700929 // The below privilege is wrong, it should be ConfigureManager OR
930 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500931 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700932 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700933 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700934 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700935 [&app](const crow::Request& req,
936 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
937 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400938 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
939 {
940 return;
941 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700942 EventServiceManager& event = EventServiceManager::getInstance();
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400943 if (param.starts_with("snmp"))
944 {
945 deleteSnmpTrapClient(asyncResp, param);
Ed Tanous4b712a22023-08-02 12:56:52 -0700946 event.deleteSubscription(param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400947 return;
948 }
Chicago Duan3d307082020-11-26 14:12:12 +0800949
Ed Tanous4b712a22023-08-02 12:56:52 -0700950 if (!event.deleteSubscription(param))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400951 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700952 messages::resourceNotFound(asyncResp->res,
953 "EventDestination", param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400954 return;
955 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700956 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400957 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700958}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530959
960} // namespace redfish