blob: a9093b3ba82eef19073a4f83b98e3a460a1b7e3a [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/fields.hpp>
26#include <boost/beast/http/status.hpp>
27#include <boost/beast/http/verb.hpp>
28#include <boost/system/error_code.hpp>
29#include <boost/system/result.hpp>
30#include <boost/url/format.hpp>
31#include <boost/url/parse.hpp>
32#include <boost/url/url.hpp>
33#include <sdbusplus/message/native_types.hpp>
34
35#include <algorithm>
36#include <array>
37#include <cerrno>
38#include <cstddef>
39#include <cstdint>
Chicago Duan3d307082020-11-26 14:12:12 +080040#include <memory>
Myung Bae5064a252024-10-04 09:34:25 -070041#include <optional>
Ed Tanous3544d2a2023-08-06 18:12:20 -070042#include <ranges>
Chicago Duan3d307082020-11-26 14:12:12 +080043#include <string>
Ed Tanousd7857202025-01-28 15:32:26 -080044#include <utility>
Ed Tanousa14c9112024-09-04 10:46:47 -070045#include <vector>
Patrick Williams1e270c52021-12-04 06:06:56 -060046
AppaRao Pulie5aaf042020-03-20 01:05:52 +053047namespace redfish
48{
49
AppaRao Puli156d6b02020-04-25 06:04:05 +053050static constexpr const std::array<const char*, 2> supportedEvtFormatTypes = {
51 eventFormatType, metricReportFormatType};
Myung Baefb546102024-10-29 10:21:26 -050052static constexpr const std::array<const char*, 4> supportedRegPrefixes = {
53 "Base", "OpenBMC", "TaskEvent", "HeartbeatEvent"};
AppaRao Pulie5aaf042020-03-20 01:05:52 +053054static constexpr const std::array<const char*, 3> supportedRetryPolicies = {
55 "TerminateAfterRetries", "SuspendRetries", "RetryForever"};
56
Myung Baefb546102024-10-29 10:21:26 -050057static constexpr const std::array<const char*, 2> supportedResourceTypes = {
58 "Task", "Heartbeat"};
Sunitha Harishe56f2542020-07-22 02:38:59 -050059
John Edward Broadbent7e860f12021-04-08 15:57:16 -070060inline void requestRoutesEventService(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +053061{
John Edward Broadbent7e860f12021-04-08 15:57:16 -070062 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -070063 .privileges(redfish::privileges::getEventService)
Patrick Williamsbd79bce2024-08-16 15:22:20 -040064 .methods(
65 boost::beast::http::verb::
66 get)([&app](
67 const crow::Request& req,
68 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
69 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
70 {
71 return;
72 }
Ed Tanous14766872022-03-15 10:44:42 -070073
Patrick Williamsbd79bce2024-08-16 15:22:20 -040074 asyncResp->res.jsonValue["@odata.id"] = "/redfish/v1/EventService";
75 asyncResp->res.jsonValue["@odata.type"] =
76 "#EventService.v1_5_0.EventService";
77 asyncResp->res.jsonValue["Id"] = "EventService";
78 asyncResp->res.jsonValue["Name"] = "Event Service";
79 asyncResp->res.jsonValue["ServerSentEventUri"] =
80 "/redfish/v1/EventService/SSE";
AppaRao Puli5e44e3d2021-03-16 15:37:24 +000081
Patrick Williamsbd79bce2024-08-16 15:22:20 -040082 asyncResp->res.jsonValue["Subscriptions"]["@odata.id"] =
83 "/redfish/v1/EventService/Subscriptions";
84 asyncResp->res.jsonValue["Actions"]["#EventService.SubmitTestEvent"]
85 ["target"] =
86 "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent";
AppaRao Pulie5aaf042020-03-20 01:05:52 +053087
Patrick Williamsbd79bce2024-08-16 15:22:20 -040088 const persistent_data::EventServiceConfig eventServiceConfig =
89 persistent_data::EventServiceStore::getInstance()
90 .getEventServiceConfig();
zhanghch058d1b46d2021-04-01 11:18:24 +080091
Patrick Williamsbd79bce2024-08-16 15:22:20 -040092 asyncResp->res.jsonValue["Status"]["State"] =
93 (eventServiceConfig.enabled ? "Enabled" : "Disabled");
94 asyncResp->res.jsonValue["ServiceEnabled"] =
95 eventServiceConfig.enabled;
96 asyncResp->res.jsonValue["DeliveryRetryAttempts"] =
97 eventServiceConfig.retryAttempts;
98 asyncResp->res.jsonValue["DeliveryRetryIntervalSeconds"] =
99 eventServiceConfig.retryTimeoutInterval;
100 asyncResp->res.jsonValue["EventFormatTypes"] =
101 supportedEvtFormatTypes;
102 asyncResp->res.jsonValue["RegistryPrefixes"] = supportedRegPrefixes;
103 asyncResp->res.jsonValue["ResourceTypes"] = supportedResourceTypes;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530104
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400105 nlohmann::json::object_t supportedSSEFilters;
106 supportedSSEFilters["EventFormatType"] = true;
107 supportedSSEFilters["MessageId"] = true;
108 supportedSSEFilters["MetricReportDefinition"] = true;
109 supportedSSEFilters["RegistryPrefix"] = true;
110 supportedSSEFilters["OriginResource"] = false;
111 supportedSSEFilters["ResourceType"] = false;
AppaRao Puli7d1cc382020-05-16 02:42:22 +0530112
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400113 asyncResp->res.jsonValue["SSEFilterPropertiesSupported"] =
114 std::move(supportedSSEFilters);
115 });
Ayushi Smriti07941a82020-05-21 15:55:34 +0530116
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700117 BMCWEB_ROUTE(app, "/redfish/v1/EventService/")
Ed Tanoused398212021-06-09 17:05:54 -0700118 .privileges(redfish::privileges::patchEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700119 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700120 [&app](const crow::Request& req,
121 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400122 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
123 {
124 return;
125 }
126 std::optional<bool> serviceEnabled;
127 std::optional<uint32_t> retryAttemps;
128 std::optional<uint32_t> retryInterval;
Patrick Williams504af5a2025-02-03 14:29:03 -0500129 if (!json_util::readJsonPatch( //
130 req, asyncResp->res, //
131 "DeliveryRetryAttempts", retryAttemps, //
Myung Baeafc474a2024-10-09 00:53:29 -0700132 "DeliveryRetryIntervalSeconds", retryInterval, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500133 "ServiceEnabled", serviceEnabled //
Myung Baeafc474a2024-10-09 00:53:29 -0700134 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400135 {
136 return;
137 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530138
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400139 persistent_data::EventServiceConfig eventServiceConfig =
140 persistent_data::EventServiceStore::getInstance()
141 .getEventServiceConfig();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700142
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400143 if (serviceEnabled)
144 {
145 eventServiceConfig.enabled = *serviceEnabled;
146 }
Sunitha Harishe56f2542020-07-22 02:38:59 -0500147
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400148 if (retryAttemps)
149 {
150 // Supported range [1-3]
151 if ((*retryAttemps < 1) || (*retryAttemps > 3))
152 {
153 messages::queryParameterOutOfRange(
154 asyncResp->res, std::to_string(*retryAttemps),
155 "DeliveryRetryAttempts", "[1-3]");
156 }
157 else
158 {
159 eventServiceConfig.retryAttempts = *retryAttemps;
160 }
161 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530162
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400163 if (retryInterval)
164 {
165 // Supported range [5 - 180]
166 if ((*retryInterval < 5) || (*retryInterval > 180))
167 {
168 messages::queryParameterOutOfRange(
169 asyncResp->res, std::to_string(*retryInterval),
170 "DeliveryRetryIntervalSeconds", "[5-180]");
171 }
172 else
173 {
174 eventServiceConfig.retryTimeoutInterval =
175 *retryInterval;
176 }
177 }
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700178
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400179 EventServiceManager::getInstance().setEventServiceConfig(
180 eventServiceConfig);
181 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700182}
183
184inline void requestRoutesSubmitTestEvent(App& app)
185{
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700186 BMCWEB_ROUTE(
187 app, "/redfish/v1/EventService/Actions/EventService.SubmitTestEvent/")
Ed Tanoused398212021-06-09 17:05:54 -0700188 .privileges(redfish::privileges::postEventService)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700189 .methods(boost::beast::http::verb::post)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700190 [&app](const crow::Request& req,
191 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400192 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
193 {
194 return;
195 }
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530196
Ed Tanous4a19a7b2025-01-27 10:44:15 -0800197 // From the Redfish spec on EventId
198 // A service can ignore this value and replace it with its own.
199 // note that this parameter is intentionally ignored
200
201 std::optional<std::string> eventId;
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530202 TestEvent testEvent;
203 // clang-format off
204 if (!json_util::readJsonAction(
205 req, asyncResp->res,
206 "EventGroupId", testEvent.eventGroupId,
Ed Tanous4a19a7b2025-01-27 10:44:15 -0800207 "EventId", eventId,
Chandramohan Harkude81ee0e72024-12-20 19:22:12 +0530208 "EventTimestamp", testEvent.eventTimestamp,
209 "Message", testEvent.message,
210 "MessageArgs", testEvent.messageArgs,
211 "MessageId", testEvent.messageId,
212 "OriginOfCondition", testEvent.originOfCondition,
213 "Resolution", testEvent.resolution,
214 "Severity", testEvent.severity))
215 {
216 return;
217 }
218 // clang-format on
219
220 if (!EventServiceManager::getInstance().sendTestEventLog(
221 testEvent))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400222 {
223 messages::serviceDisabled(asyncResp->res,
224 "/redfish/v1/EventService/");
225 return;
226 }
227 asyncResp->res.result(boost::beast::http::status::no_content);
228 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700229}
230
Chicago Duan3d307082020-11-26 14:12:12 +0800231inline void doSubscriptionCollection(
Ed Tanouse81de512023-06-27 17:07:00 -0700232 const boost::system::error_code& ec,
Chicago Duan3d307082020-11-26 14:12:12 +0800233 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
234 const dbus::utility::ManagedObjectType& resp)
235{
236 if (ec)
237 {
Ed Tanous13061012023-07-25 11:12:19 -0700238 if (ec.value() == EBADR || ec.value() == EHOSTUNREACH)
Chicago Duan3d307082020-11-26 14:12:12 +0800239 {
240 // This is an optional process so just return if it isn't there
241 return;
242 }
243
Ed Tanous62598e32023-07-17 17:06:25 -0700244 BMCWEB_LOG_ERROR("D-Bus response error on GetManagedObjects {}", ec);
Chicago Duan3d307082020-11-26 14:12:12 +0800245 messages::internalError(asyncResp->res);
246 return;
247 }
248 nlohmann::json& memberArray = asyncResp->res.jsonValue["Members"];
249 for (const auto& objpath : resp)
250 {
251 sdbusplus::message::object_path path(objpath.first);
252 const std::string snmpId = path.filename();
253 if (snmpId.empty())
254 {
Ed Tanous62598e32023-07-17 17:06:25 -0700255 BMCWEB_LOG_ERROR("The SNMP client ID is wrong");
Chicago Duan3d307082020-11-26 14:12:12 +0800256 messages::internalError(asyncResp->res);
257 return;
258 }
259
260 getSnmpSubscriptionList(asyncResp, snmpId, memberArray);
261 }
262}
263
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700264inline void requestRoutesEventDestinationCollection(App& app)
265{
Gayathri Leburu1ebe3e42022-02-09 10:45:19 +0000266 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Ed Tanoused398212021-06-09 17:05:54 -0700267 .privileges(redfish::privileges::getEventDestinationCollection)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700268 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700269 [&app](const crow::Request& req,
270 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400271 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
272 {
273 return;
274 }
275 asyncResp->res.jsonValue["@odata.type"] =
276 "#EventDestinationCollection.EventDestinationCollection";
277 asyncResp->res.jsonValue["@odata.id"] =
278 "/redfish/v1/EventService/Subscriptions";
279 asyncResp->res.jsonValue["Name"] =
280 "Event Destination Collections";
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700281
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400282 nlohmann::json& memberArray =
283 asyncResp->res.jsonValue["Members"];
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700284
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400285 std::vector<std::string> subscripIds =
286 EventServiceManager::getInstance().getAllIDs();
287 memberArray = nlohmann::json::array();
288 asyncResp->res.jsonValue["Members@odata.count"] =
289 subscripIds.size();
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700290
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400291 for (const std::string& id : subscripIds)
292 {
293 nlohmann::json::object_t member;
294 member["@odata.id"] = boost::urls::format(
295 "/redfish/v1/EventService/Subscriptions/{}" + id);
296 memberArray.emplace_back(std::move(member));
297 }
Ed Tanous177612a2025-02-14 15:16:09 -0800298 dbus::utility::async_method_call(
299 asyncResp,
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400300 [asyncResp](const boost::system::error_code& ec,
301 const dbus::utility::ManagedObjectType& resp) {
302 doSubscriptionCollection(ec, asyncResp, resp);
303 },
304 "xyz.openbmc_project.Network.SNMP",
305 "/xyz/openbmc_project/network/snmp/manager",
306 "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
307 });
Chicago Duan3d307082020-11-26 14:12:12 +0800308
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700309 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/")
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500310 .privileges(redfish::privileges::postEventDestinationCollection)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400311 .methods(
312 boost::beast::http::verb::
313 post)([&app](
314 const crow::Request& req,
315 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) {
316 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
317 {
318 return;
319 }
320 if (EventServiceManager::getInstance().getNumberOfSubscriptions() >=
321 maxNoOfSubscriptions)
322 {
323 messages::eventSubscriptionLimitExceeded(asyncResp->res);
324 return;
325 }
326 std::string destUrl;
327 std::string protocol;
328 std::optional<bool> verifyCertificate;
329 std::optional<std::string> context;
330 std::optional<std::string> subscriptionType;
331 std::optional<std::string> eventFormatType2;
332 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700333 std::optional<bool> sendHeartbeat;
334 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400335 std::optional<std::vector<std::string>> msgIds;
336 std::optional<std::vector<std::string>> regPrefixes;
Ed Tanousa14c9112024-09-04 10:46:47 -0700337 std::optional<std::vector<std::string>> originResources;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400338 std::optional<std::vector<std::string>> resTypes;
339 std::optional<std::vector<nlohmann::json::object_t>> headers;
340 std::optional<std::vector<nlohmann::json::object_t>> mrdJsonArray;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800341
Patrick Williams504af5a2025-02-03 14:29:03 -0500342 if (!json_util::readJsonPatch( //
343 req, asyncResp->res, //
344 "Context", context, //
345 "DeliveryRetryPolicy", retryPolicy, //
346 "Destination", destUrl, //
347 "EventFormatType", eventFormatType2, //
Myung Bae5064a252024-10-04 09:34:25 -0700348 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500349 "HttpHeaders", headers, //
350 "MessageIds", msgIds, //
351 "MetricReportDefinitions", mrdJsonArray, //
352 "OriginResources", originResources, //
353 "Protocol", protocol, //
354 "RegistryPrefixes", regPrefixes, //
355 "ResourceTypes", resTypes, //
356 "SendHeartbeat", sendHeartbeat, //
357 "SubscriptionType", subscriptionType, //
358 "VerifyCertificate", verifyCertificate //
Myung Baeafc474a2024-10-09 00:53:29 -0700359 ))
Ed Tanousfffb8c12022-02-07 23:53:03 -0800360 {
Ed Tanousa716aa72023-08-01 11:35:53 -0700361 return;
362 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700363 // clang-format on
Chicago Duan3d307082020-11-26 14:12:12 +0800364
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400365 // https://stackoverflow.com/questions/417142/what-is-the-maximum-length-of-a-url-in-different-browsers
366 static constexpr const uint16_t maxDestinationSize = 2000;
367 if (destUrl.size() > maxDestinationSize)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800368 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400369 messages::stringValueTooLong(asyncResp->res, "Destination",
370 maxDestinationSize);
Ed Tanous002d39b2022-05-31 08:59:27 -0700371 return;
372 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700373
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400374 if (regPrefixes && msgIds)
Ed Tanous002d39b2022-05-31 08:59:27 -0700375 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400376 if (!regPrefixes->empty() && !msgIds->empty())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700377 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400378 messages::propertyValueConflict(
379 asyncResp->res, "MessageIds", "RegistryPrefixes");
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530380 return;
381 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800382 }
P Dheeraj Srujan Kumarb304bd72021-01-29 17:46:35 +0530383
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400384 boost::system::result<boost::urls::url> url =
385 boost::urls::parse_absolute_uri(destUrl);
386 if (!url)
Ed Tanousfffb8c12022-02-07 23:53:03 -0800387 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400388 BMCWEB_LOG_WARNING(
389 "Failed to validate and split destination url");
390 messages::propertyValueFormatError(asyncResp->res, destUrl,
391 "Destination");
392 return;
393 }
394 url->normalize();
George Liub07942e2024-11-01 09:59:40 +0800395
396 // port_number returns zero if it is not a valid representable port
397 if (url->has_port() && url->port_number() == 0)
398 {
399 BMCWEB_LOG_WARNING("{} is an invalid port in destination url",
400 url->port());
401 messages::propertyValueFormatError(asyncResp->res, destUrl,
402 "Destination");
403 return;
404 }
405
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400406 crow::utility::setProtocolDefaults(*url, protocol);
407 crow::utility::setPortDefaults(*url);
408
409 if (url->path().empty())
410 {
411 url->set_path("/");
412 }
413
414 if (url->has_userinfo())
415 {
416 messages::propertyValueFormatError(asyncResp->res, destUrl,
417 "Destination");
418 return;
419 }
420
421 if (protocol == "SNMPv2c")
422 {
423 if (context)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700424 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400425 messages::propertyValueConflict(asyncResp->res, "Context",
426 "Protocol");
AppaRao Puli144b6312020-08-03 22:23:12 +0530427 return;
428 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400429 if (eventFormatType2)
430 {
431 messages::propertyValueConflict(
432 asyncResp->res, "EventFormatType", "Protocol");
433 return;
434 }
435 if (retryPolicy)
436 {
437 messages::propertyValueConflict(asyncResp->res,
438 "RetryPolicy", "Protocol");
439 return;
440 }
Myung Bae5064a252024-10-04 09:34:25 -0700441 if (sendHeartbeat)
442 {
443 messages::propertyValueConflict(
444 asyncResp->res, "SendHeartbeat", "Protocol");
445 return;
446 }
447 if (hbIntervalMinutes)
448 {
449 messages::propertyValueConflict(
450 asyncResp->res, "HeartbeatIntervalMinutes", "Protocol");
451 return;
452 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400453 if (msgIds)
454 {
455 messages::propertyValueConflict(asyncResp->res,
456 "MessageIds", "Protocol");
457 return;
458 }
459 if (regPrefixes)
460 {
461 messages::propertyValueConflict(
462 asyncResp->res, "RegistryPrefixes", "Protocol");
463 return;
464 }
465 if (resTypes)
466 {
467 messages::propertyValueConflict(
468 asyncResp->res, "ResourceTypes", "Protocol");
469 return;
470 }
471 if (headers)
472 {
473 messages::propertyValueConflict(asyncResp->res,
474 "HttpHeaders", "Protocol");
475 return;
476 }
477 if (mrdJsonArray)
478 {
479 messages::propertyValueConflict(
480 asyncResp->res, "MetricReportDefinitions", "Protocol");
481 return;
482 }
483 if (url->scheme() != "snmp")
484 {
485 messages::propertyValueConflict(asyncResp->res,
486 "Destination", "Protocol");
487 return;
488 }
489
490 addSnmpTrapClient(asyncResp, url->host_address(),
491 url->port_number());
492 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700493 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700494
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400495 std::shared_ptr<Subscription> subValue =
Myung Bae21a94d52024-10-14 15:02:57 -0700496 std::make_shared<Subscription>(
Myung Bae5fe4ef32024-10-19 09:56:02 -0400497 std::make_shared<persistent_data::UserSubscription>(), *url,
Ed Tanous9838eb22025-01-29 16:24:42 -0800498 getIoContext());
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400499
500 if (subscriptionType)
Ed Tanous002d39b2022-05-31 08:59:27 -0700501 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400502 if (*subscriptionType != "RedfishEvent")
503 {
504 messages::propertyValueNotInList(
505 asyncResp->res, *subscriptionType, "SubscriptionType");
506 return;
507 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400508 subValue->userSub->subscriptionType = *subscriptionType;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800509 }
510 else
511 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700512 // Default
Myung Bae5fe4ef32024-10-19 09:56:02 -0400513 subValue->userSub->subscriptionType = "RedfishEvent";
Ed Tanousfffb8c12022-02-07 23:53:03 -0800514 }
AppaRao Puli156d6b02020-04-25 06:04:05 +0530515
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400516 if (protocol != "Redfish")
Ed Tanousfffb8c12022-02-07 23:53:03 -0800517 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400518 messages::propertyValueNotInList(asyncResp->res, protocol,
519 "Protocol");
520 return;
521 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400522 subValue->userSub->protocol = protocol;
Ed Tanousfffb8c12022-02-07 23:53:03 -0800523
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400524 if (verifyCertificate)
525 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400526 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400527 }
528
529 if (eventFormatType2)
530 {
531 if (std::ranges::find(supportedEvtFormatTypes,
532 *eventFormatType2) ==
533 supportedEvtFormatTypes.end())
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700534 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400535 messages::propertyValueNotInList(
536 asyncResp->res, *eventFormatType2, "EventFormatType");
537 return;
538 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400539 subValue->userSub->eventFormatType = *eventFormatType2;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400540 }
541 else
542 {
543 // If not specified, use default "Event"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400544 subValue->userSub->eventFormatType = "Event";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400545 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700546
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400547 if (context)
548 {
549 // This value is selected arbitrarily.
550 constexpr const size_t maxContextSize = 256;
551 if (context->size() > maxContextSize)
552 {
553 messages::stringValueTooLong(asyncResp->res, "Context",
554 maxContextSize);
555 return;
556 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400557 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400558 }
559
560 if (headers)
561 {
562 size_t cumulativeLen = 0;
563
564 for (const nlohmann::json::object_t& headerChunk : *headers)
565 {
566 for (const auto& item : headerChunk)
Ed Tanous002d39b2022-05-31 08:59:27 -0700567 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400568 const std::string* value =
569 item.second.get_ptr<const std::string*>();
570 if (value == nullptr)
571 {
572 messages::propertyValueFormatError(
573 asyncResp->res, item.second,
574 "HttpHeaders/" + item.first);
575 return;
576 }
577 // Adding a new json value is the size of the key, +
578 // the size of the value + 2 * 2 quotes for each, +
579 // the colon and space between. example:
580 // "key": "value"
581 cumulativeLen += item.first.size() + value->size() + 6;
582 // This value is selected to mirror http_connection.hpp
583 constexpr const uint16_t maxHeaderSizeED = 8096;
584 if (cumulativeLen > maxHeaderSizeED)
585 {
586 messages::arraySizeTooLong(
587 asyncResp->res, "HttpHeaders", maxHeaderSizeED);
588 return;
589 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400590 subValue->userSub->httpHeaders.set(item.first, *value);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400591 }
592 }
593 }
594
595 if (regPrefixes)
596 {
597 for (const std::string& it : *regPrefixes)
598 {
599 if (std::ranges::find(supportedRegPrefixes, it) ==
600 supportedRegPrefixes.end())
601 {
602 messages::propertyValueNotInList(asyncResp->res, it,
603 "RegistryPrefixes");
604 return;
605 }
606 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400607 subValue->userSub->registryPrefixes = *regPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400608 }
609
Ed Tanousa14c9112024-09-04 10:46:47 -0700610 if (originResources)
611 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400612 subValue->userSub->originResources = *originResources;
Ed Tanousa14c9112024-09-04 10:46:47 -0700613 }
614
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400615 if (resTypes)
616 {
617 for (const std::string& it : *resTypes)
618 {
619 if (std::ranges::find(supportedResourceTypes, it) ==
620 supportedResourceTypes.end())
621 {
622 messages::propertyValueNotInList(asyncResp->res, it,
623 "ResourceTypes");
624 return;
625 }
626 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400627 subValue->userSub->resourceTypes = *resTypes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400628 }
629
630 if (msgIds)
631 {
632 std::vector<std::string> registryPrefix;
633
634 // If no registry prefixes are mentioned, consider all
635 // supported prefixes
Myung Bae5fe4ef32024-10-19 09:56:02 -0400636 if (subValue->userSub->registryPrefixes.empty())
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400637 {
638 registryPrefix.assign(supportedRegPrefixes.begin(),
639 supportedRegPrefixes.end());
640 }
641 else
642 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400643 registryPrefix = subValue->userSub->registryPrefixes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400644 }
645
646 for (const std::string& id : *msgIds)
647 {
648 bool validId = false;
649
650 // Check for Message ID in each of the selected Registry
651 for (const std::string& it : registryPrefix)
652 {
Patrick Williams4a102cd2025-02-27 14:52:54 -0500653 const registries::MessageEntries registry =
654 redfish::registries::getRegistryMessagesFromPrefix(
655 it);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400656
657 if (std::ranges::any_of(
658 registry,
659 [&id](const redfish::registries::MessageEntry&
660 messageEntry) {
661 return id == messageEntry.first;
662 }))
663 {
664 validId = true;
665 break;
666 }
667 }
668
669 if (!validId)
670 {
671 messages::propertyValueNotInList(asyncResp->res, id,
672 "MessageIds");
673 return;
Ed Tanous002d39b2022-05-31 08:59:27 -0700674 }
675 }
676
Myung Bae5fe4ef32024-10-19 09:56:02 -0400677 subValue->userSub->registryMsgIds = *msgIds;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400678 }
679
680 if (retryPolicy)
681 {
682 if (std::ranges::find(supportedRetryPolicies, *retryPolicy) ==
683 supportedRetryPolicies.end())
Ed Tanous002d39b2022-05-31 08:59:27 -0700684 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400685 messages::propertyValueNotInList(
686 asyncResp->res, *retryPolicy, "DeliveryRetryPolicy");
Ed Tanousfffb8c12022-02-07 23:53:03 -0800687 return;
688 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400689 subValue->userSub->retryPolicy = *retryPolicy;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400690 }
691 else
692 {
693 // Default "TerminateAfterRetries"
Myung Bae5fe4ef32024-10-19 09:56:02 -0400694 subValue->userSub->retryPolicy = "TerminateAfterRetries";
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400695 }
Myung Bae5064a252024-10-04 09:34:25 -0700696 if (sendHeartbeat)
697 {
698 subValue->userSub->sendHeartbeat = *sendHeartbeat;
699 }
700 if (hbIntervalMinutes)
701 {
702 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
703 {
704 messages::propertyValueOutOfRange(
705 asyncResp->res, *hbIntervalMinutes,
706 "HeartbeatIntervalMinutes");
707 return;
708 }
709 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
710 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400711
712 if (mrdJsonArray)
713 {
714 for (nlohmann::json::object_t& mrdObj : *mrdJsonArray)
715 {
716 std::string mrdUri;
717
718 if (!json_util::readJsonObject(mrdObj, asyncResp->res,
719 "@odata.id", mrdUri))
720
721 {
722 return;
723 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400724 subValue->userSub->metricReportDefinitions.emplace_back(
Ed Tanous4b712a22023-08-02 12:56:52 -0700725 mrdUri);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400726 }
Ed Tanousfffb8c12022-02-07 23:53:03 -0800727 }
728
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400729 std::string id =
730 EventServiceManager::getInstance().addPushSubscription(
731 subValue);
732 if (id.empty())
Ed Tanousfffb8c12022-02-07 23:53:03 -0800733 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400734 messages::internalError(asyncResp->res);
Ed Tanousfffb8c12022-02-07 23:53:03 -0800735 return;
736 }
737
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400738 messages::created(asyncResp->res);
739 asyncResp->res.addHeader(
740 "Location", "/redfish/v1/EventService/Subscriptions/" + id);
Myung Baefb546102024-10-29 10:21:26 -0500741
742 // schedule a heartbeat
743 if (subValue->userSub->sendHeartbeat)
744 {
745 subValue->scheduleNextHeartbeatEvent();
746 }
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400747 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700748}
749
750inline void requestRoutesEventDestination(App& app)
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530751{
Ravi Teja9d41aec2021-07-23 01:57:01 -0500752 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700753 .privileges(redfish::privileges::getEventDestination)
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700754 .methods(boost::beast::http::verb::get)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700755 [&app](const crow::Request& req,
756 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
757 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400758 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
759 {
760 return;
761 }
Chicago Duan3d307082020-11-26 14:12:12 +0800762
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400763 if (param.starts_with("snmp"))
764 {
765 getSnmpTrapClient(asyncResp, param);
766 return;
767 }
Chicago Duan3d307082020-11-26 14:12:12 +0800768
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400769 std::shared_ptr<Subscription> subValue =
770 EventServiceManager::getInstance().getSubscription(param);
771 if (subValue == nullptr)
772 {
773 asyncResp->res.result(
774 boost::beast::http::status::not_found);
775 return;
776 }
777 const std::string& id = param;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530778
Ed Tanous4b712a22023-08-02 12:56:52 -0700779 const persistent_data::UserSubscription& userSub =
Myung Bae5fe4ef32024-10-19 09:56:02 -0400780 *subValue->userSub;
zhanghch058d1b46d2021-04-01 11:18:24 +0800781
Ed Tanous4b712a22023-08-02 12:56:52 -0700782 nlohmann::json& jVal = asyncResp->res.jsonValue;
783 jVal["@odata.type"] =
784 "#EventDestination.v1_14_1.EventDestination";
785 jVal["Protocol"] =
786 event_destination::EventDestinationProtocol::Redfish;
787 jVal["@odata.id"] = boost::urls::format(
788 "/redfish/v1/EventService/Subscriptions/{}", id);
789 jVal["Id"] = id;
790 jVal["Name"] = "Event Destination " + id;
791 jVal["Destination"] = userSub.destinationUrl;
792 jVal["Context"] = userSub.customText;
793 jVal["SubscriptionType"] = userSub.subscriptionType;
794 jVal["HttpHeaders"] = nlohmann::json::array();
795 jVal["EventFormatType"] = userSub.eventFormatType;
796 jVal["RegistryPrefixes"] = userSub.registryPrefixes;
797 jVal["ResourceTypes"] = userSub.resourceTypes;
798
799 jVal["MessageIds"] = userSub.registryMsgIds;
800 jVal["DeliveryRetryPolicy"] = userSub.retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700801 jVal["SendHeartbeat"] = userSub.sendHeartbeat;
802 jVal["HeartbeatIntervalMinutes"] = userSub.hbIntervalMinutes;
Ed Tanous4b712a22023-08-02 12:56:52 -0700803 jVal["VerifyCertificate"] = userSub.verifyCertificate;
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530804
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400805 nlohmann::json::array_t mrdJsonArray;
Ed Tanous4b712a22023-08-02 12:56:52 -0700806 for (const auto& mdrUri : userSub.metricReportDefinitions)
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400807 {
808 nlohmann::json::object_t mdr;
809 mdr["@odata.id"] = mdrUri;
810 mrdJsonArray.emplace_back(std::move(mdr));
811 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700812 jVal["MetricReportDefinitions"] = mrdJsonArray;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400813 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500814 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700815 // The below privilege is wrong, it should be ConfigureManager OR
816 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500817 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700818 //.privileges(redfish::privileges::patchEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700819 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700820 .methods(boost::beast::http::verb::patch)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700821 [&app](const crow::Request& req,
822 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
823 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400824 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700825 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400826 return;
827 }
828 std::shared_ptr<Subscription> subValue =
829 EventServiceManager::getInstance().getSubscription(param);
830 if (subValue == nullptr)
831 {
832 asyncResp->res.result(
833 boost::beast::http::status::not_found);
834 return;
835 }
836
837 std::optional<std::string> context;
838 std::optional<std::string> retryPolicy;
Myung Bae5064a252024-10-04 09:34:25 -0700839 std::optional<bool> sendHeartbeat;
840 std::optional<uint64_t> hbIntervalMinutes;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400841 std::optional<bool> verifyCertificate;
842 std::optional<std::vector<nlohmann::json::object_t>> headers;
843
Patrick Williams504af5a2025-02-03 14:29:03 -0500844 if (!json_util::readJsonPatch( //
845 req, asyncResp->res, //
846 "Context", context, //
847 "DeliveryRetryPolicy", retryPolicy, //
Myung Bae5064a252024-10-04 09:34:25 -0700848 "HeartbeatIntervalMinutes", hbIntervalMinutes, //
Patrick Williams504af5a2025-02-03 14:29:03 -0500849 "HttpHeaders", headers, //
850 "SendHeartbeat", sendHeartbeat, //
851 "VerifyCertificate", verifyCertificate //
Myung Baeafc474a2024-10-09 00:53:29 -0700852 ))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400853 {
854 return;
855 }
856
857 if (context)
858 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400859 subValue->userSub->customText = *context;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400860 }
861
862 if (headers)
863 {
864 boost::beast::http::fields fields;
865 for (const nlohmann::json::object_t& headerChunk : *headers)
Ed Tanous601c71a2021-09-08 16:40:12 -0700866 {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400867 for (const auto& it : headerChunk)
868 {
869 const std::string* value =
870 it.second.get_ptr<const std::string*>();
871 if (value == nullptr)
872 {
873 messages::propertyValueFormatError(
874 asyncResp->res, it.second,
875 "HttpHeaders/" + it.first);
876 return;
877 }
878 fields.set(it.first, *value);
879 }
880 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400881 subValue->userSub->httpHeaders = std::move(fields);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400882 }
883
884 if (retryPolicy)
885 {
886 if (std::ranges::find(supportedRetryPolicies,
887 *retryPolicy) ==
888 supportedRetryPolicies.end())
889 {
890 messages::propertyValueNotInList(asyncResp->res,
891 *retryPolicy,
892 "DeliveryRetryPolicy");
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700893 return;
894 }
Myung Bae5fe4ef32024-10-19 09:56:02 -0400895 subValue->userSub->retryPolicy = *retryPolicy;
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700896 }
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530897
Myung Bae5064a252024-10-04 09:34:25 -0700898 if (sendHeartbeat)
899 {
900 subValue->userSub->sendHeartbeat = *sendHeartbeat;
901 }
902 if (hbIntervalMinutes)
903 {
904 if (*hbIntervalMinutes < 1 || *hbIntervalMinutes > 65535)
905 {
906 messages::propertyValueOutOfRange(
907 asyncResp->res, *hbIntervalMinutes,
908 "HeartbeatIntervalMinutes");
909 return;
910 }
911 subValue->userSub->hbIntervalMinutes = *hbIntervalMinutes;
912 }
913
Myung Baefb546102024-10-29 10:21:26 -0500914 if (hbIntervalMinutes || sendHeartbeat)
915 {
916 // if Heartbeat interval or send heart were changed, cancel
917 // the heartbeat timer if running and start a new heartbeat
918 // if needed
919 subValue->heartbeatParametersChanged();
920 }
921
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400922 if (verifyCertificate)
923 {
Myung Bae5fe4ef32024-10-19 09:56:02 -0400924 subValue->userSub->verifyCertificate = *verifyCertificate;
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400925 }
Ed Tanous002d39b2022-05-31 08:59:27 -0700926
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400927 EventServiceManager::getInstance().updateSubscriptionData();
928 });
Ravi Teja9d41aec2021-07-23 01:57:01 -0500929 BMCWEB_ROUTE(app, "/redfish/v1/EventService/Subscriptions/<str>/")
Ed Tanoused398212021-06-09 17:05:54 -0700930 // The below privilege is wrong, it should be ConfigureManager OR
931 // ConfigureSelf
Abhishek Patel7eeafa72021-07-28 10:59:16 -0500932 // https://github.com/openbmc/bmcweb/issues/220
Ed Tanoused398212021-06-09 17:05:54 -0700933 //.privileges(redfish::privileges::deleteEventDestination)
Ed Tanous432a8902021-06-14 15:28:56 -0700934 .privileges({{"ConfigureManager"}})
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700935 .methods(boost::beast::http::verb::delete_)(
Ed Tanous45ca1b82022-03-25 13:07:27 -0700936 [&app](const crow::Request& req,
937 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
938 const std::string& param) {
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400939 if (!redfish::setUpRedfishRoute(app, req, asyncResp))
940 {
941 return;
942 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700943 EventServiceManager& event = EventServiceManager::getInstance();
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400944 if (param.starts_with("snmp"))
945 {
946 deleteSnmpTrapClient(asyncResp, param);
Ed Tanous4b712a22023-08-02 12:56:52 -0700947 event.deleteSubscription(param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400948 return;
949 }
Chicago Duan3d307082020-11-26 14:12:12 +0800950
Ed Tanous4b712a22023-08-02 12:56:52 -0700951 if (!event.deleteSubscription(param))
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400952 {
Ed Tanous4b712a22023-08-02 12:56:52 -0700953 messages::resourceNotFound(asyncResp->res,
954 "EventDestination", param);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400955 return;
956 }
Ed Tanous4b712a22023-08-02 12:56:52 -0700957 messages::success(asyncResp->res);
Patrick Williamsbd79bce2024-08-16 15:22:20 -0400958 });
John Edward Broadbent7e860f12021-04-08 15:57:16 -0700959}
AppaRao Pulie5aaf042020-03-20 01:05:52 +0530960
961} // namespace redfish