xref: /openbmc/bmcweb/features/redfish/include/snmp_trap_event_clients.hpp (revision 3d30708fb65e40cd28da601b3e91a527a8862e15)
1*3d30708fSChicago Duan #pragma once
2*3d30708fSChicago Duan 
3*3d30708fSChicago Duan #include "async_resp.hpp"
4*3d30708fSChicago Duan #include "dbus_singleton.hpp"
5*3d30708fSChicago Duan #include "dbus_utility.hpp"
6*3d30708fSChicago Duan #include "error_messages.hpp"
7*3d30708fSChicago Duan #include "event_service_manager.hpp"
8*3d30708fSChicago Duan #include "http_request.hpp"
9*3d30708fSChicago Duan #include "http_response.hpp"
10*3d30708fSChicago Duan #include "logging.hpp"
11*3d30708fSChicago Duan #include "utils/dbus_utils.hpp"
12*3d30708fSChicago Duan 
13*3d30708fSChicago Duan #include <boost/system/error_code.hpp>
14*3d30708fSChicago Duan #include <boost/url/format.hpp>
15*3d30708fSChicago Duan #include <sdbusplus/unpack_properties.hpp>
16*3d30708fSChicago Duan 
17*3d30708fSChicago Duan #include <memory>
18*3d30708fSChicago Duan #include <string>
19*3d30708fSChicago Duan #include <string_view>
20*3d30708fSChicago Duan 
21*3d30708fSChicago Duan namespace redfish
22*3d30708fSChicago Duan {
23*3d30708fSChicago Duan 
24*3d30708fSChicago Duan inline void afterGetSnmpTrapClientdata(
25*3d30708fSChicago Duan     const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
26*3d30708fSChicago Duan     const boost::system::error_code& ec,
27*3d30708fSChicago Duan     const dbus::utility::DBusPropertiesMap& propertiesList)
28*3d30708fSChicago Duan {
29*3d30708fSChicago Duan     if (ec)
30*3d30708fSChicago Duan     {
31*3d30708fSChicago Duan         BMCWEB_LOG_ERROR << "D-Bus response error on GetSubTree " << ec;
32*3d30708fSChicago Duan         messages::internalError(asyncResp->res);
33*3d30708fSChicago Duan         return;
34*3d30708fSChicago Duan     }
35*3d30708fSChicago Duan 
36*3d30708fSChicago Duan     std::string address;
37*3d30708fSChicago Duan     uint16_t port = 0;
38*3d30708fSChicago Duan 
39*3d30708fSChicago Duan     bool success = sdbusplus::unpackPropertiesNoThrow(
40*3d30708fSChicago Duan         dbus_utils::UnpackErrorPrinter(), propertiesList, "Address", address,
41*3d30708fSChicago Duan         "Port", port);
42*3d30708fSChicago Duan 
43*3d30708fSChicago Duan     if (!success)
44*3d30708fSChicago Duan     {
45*3d30708fSChicago Duan         messages::internalError(asyncResp->res);
46*3d30708fSChicago Duan         return;
47*3d30708fSChicago Duan     }
48*3d30708fSChicago Duan 
49*3d30708fSChicago Duan     asyncResp->res.jsonValue["Destination"] =
50*3d30708fSChicago Duan         boost::urls::format("snmp://{}:{}", address, port);
51*3d30708fSChicago Duan }
52*3d30708fSChicago Duan 
53*3d30708fSChicago Duan inline void
54*3d30708fSChicago Duan     getSnmpTrapClientdata(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
55*3d30708fSChicago Duan                           const std::string& id, const std::string& objectPath)
56*3d30708fSChicago Duan {
57*3d30708fSChicago Duan     asyncResp->res.jsonValue["@odata.type"] =
58*3d30708fSChicago Duan         "#EventDestination.v1_8_0.EventDestination";
59*3d30708fSChicago Duan     asyncResp->res.jsonValue["Protocol"] = "SNMPv2c";
60*3d30708fSChicago Duan     asyncResp->res.jsonValue["@odata.id"] =
61*3d30708fSChicago Duan         boost::urls::format("/redfish/v1/EventService/Subscriptions/{}", id);
62*3d30708fSChicago Duan 
63*3d30708fSChicago Duan     asyncResp->res.jsonValue["Id"] = id;
64*3d30708fSChicago Duan     asyncResp->res.jsonValue["Name"] = "Event Destination";
65*3d30708fSChicago Duan 
66*3d30708fSChicago Duan     asyncResp->res.jsonValue["SubscriptionType"] = "SNMPTrap";
67*3d30708fSChicago Duan     asyncResp->res.jsonValue["EventFormatType"] = "Event";
68*3d30708fSChicago Duan 
69*3d30708fSChicago Duan     std::shared_ptr<Subscription> subValue =
70*3d30708fSChicago Duan         EventServiceManager::getInstance().getSubscription(id);
71*3d30708fSChicago Duan     if (subValue != nullptr)
72*3d30708fSChicago Duan     {
73*3d30708fSChicago Duan         asyncResp->res.jsonValue["Context"] = subValue->customText;
74*3d30708fSChicago Duan     }
75*3d30708fSChicago Duan     else
76*3d30708fSChicago Duan     {
77*3d30708fSChicago Duan         asyncResp->res.jsonValue["Context"] = "";
78*3d30708fSChicago Duan     }
79*3d30708fSChicago Duan 
80*3d30708fSChicago Duan     sdbusplus::asio::getAllProperties(
81*3d30708fSChicago Duan         *crow::connections::systemBus, "xyz.openbmc_project.Network.SNMP",
82*3d30708fSChicago Duan         objectPath, "xyz.openbmc_project.Network.Client",
83*3d30708fSChicago Duan         [asyncResp](const boost::system::error_code& ec,
84*3d30708fSChicago Duan                     const dbus::utility::DBusPropertiesMap& properties) {
85*3d30708fSChicago Duan         afterGetSnmpTrapClientdata(asyncResp, ec, properties);
86*3d30708fSChicago Duan         });
87*3d30708fSChicago Duan }
88*3d30708fSChicago Duan 
89*3d30708fSChicago Duan inline void
90*3d30708fSChicago Duan     getSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
91*3d30708fSChicago Duan                       const std::string& id)
92*3d30708fSChicago Duan {
93*3d30708fSChicago Duan     crow::connections::systemBus->async_method_call(
94*3d30708fSChicago Duan         [asyncResp, id](const boost::system::error_code& ec,
95*3d30708fSChicago Duan                         dbus::utility::ManagedObjectType& resp) {
96*3d30708fSChicago Duan         if (ec)
97*3d30708fSChicago Duan         {
98*3d30708fSChicago Duan             BMCWEB_LOG_ERROR << "D-Bus response error on GetManagedObjects "
99*3d30708fSChicago Duan                              << ec;
100*3d30708fSChicago Duan             messages::internalError(asyncResp->res);
101*3d30708fSChicago Duan             return;
102*3d30708fSChicago Duan         }
103*3d30708fSChicago Duan 
104*3d30708fSChicago Duan         for (const auto& objpath : resp)
105*3d30708fSChicago Duan         {
106*3d30708fSChicago Duan             sdbusplus::message::object_path path(objpath.first);
107*3d30708fSChicago Duan             const std::string snmpId = path.filename();
108*3d30708fSChicago Duan             if (snmpId.empty())
109*3d30708fSChicago Duan             {
110*3d30708fSChicago Duan                 BMCWEB_LOG_ERROR << "The SNMP client ID is wrong";
111*3d30708fSChicago Duan                 messages::internalError(asyncResp->res);
112*3d30708fSChicago Duan                 return;
113*3d30708fSChicago Duan             }
114*3d30708fSChicago Duan             const std::string subscriptionId = "snmp" + snmpId;
115*3d30708fSChicago Duan             if (id != subscriptionId)
116*3d30708fSChicago Duan             {
117*3d30708fSChicago Duan                 continue;
118*3d30708fSChicago Duan             }
119*3d30708fSChicago Duan 
120*3d30708fSChicago Duan             getSnmpTrapClientdata(asyncResp, id, objpath.first);
121*3d30708fSChicago Duan             return;
122*3d30708fSChicago Duan         }
123*3d30708fSChicago Duan 
124*3d30708fSChicago Duan         messages::resourceNotFound(asyncResp->res, "Subscriptions", id);
125*3d30708fSChicago Duan         EventServiceManager::getInstance().deleteSubscription(id);
126*3d30708fSChicago Duan         },
127*3d30708fSChicago Duan         "xyz.openbmc_project.Network.SNMP",
128*3d30708fSChicago Duan         "/xyz/openbmc_project/network/snmp/manager",
129*3d30708fSChicago Duan         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
130*3d30708fSChicago Duan }
131*3d30708fSChicago Duan 
132*3d30708fSChicago Duan inline void
133*3d30708fSChicago Duan     afterSnmpClientCreate(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
134*3d30708fSChicago Duan                           const boost::system::error_code& ec,
135*3d30708fSChicago Duan                           const std::string& dbusSNMPid)
136*3d30708fSChicago Duan {
137*3d30708fSChicago Duan     if (ec)
138*3d30708fSChicago Duan     {
139*3d30708fSChicago Duan         if (ec.value() != EBADR)
140*3d30708fSChicago Duan         {
141*3d30708fSChicago Duan             // SNMP not installed
142*3d30708fSChicago Duan             messages::propertyValueOutOfRange(asyncResp->res, "SNMPv2c",
143*3d30708fSChicago Duan                                               "Protocol");
144*3d30708fSChicago Duan             return;
145*3d30708fSChicago Duan         }
146*3d30708fSChicago Duan         messages::internalError(asyncResp->res);
147*3d30708fSChicago Duan         return;
148*3d30708fSChicago Duan     }
149*3d30708fSChicago Duan 
150*3d30708fSChicago Duan     sdbusplus::message::object_path path(dbusSNMPid);
151*3d30708fSChicago Duan     const std::string snmpId = path.filename();
152*3d30708fSChicago Duan     if (snmpId.empty())
153*3d30708fSChicago Duan     {
154*3d30708fSChicago Duan         messages::internalError(asyncResp->res);
155*3d30708fSChicago Duan         return;
156*3d30708fSChicago Duan     }
157*3d30708fSChicago Duan 
158*3d30708fSChicago Duan     std::string subscriptionId = "snmp" + snmpId;
159*3d30708fSChicago Duan 
160*3d30708fSChicago Duan     boost::urls::url uri = boost::urls::format(
161*3d30708fSChicago Duan         "/redfish/v1/EventService/Subscriptions/{}", subscriptionId);
162*3d30708fSChicago Duan     asyncResp->res.addHeader("Location", uri.buffer());
163*3d30708fSChicago Duan     messages::created(asyncResp->res);
164*3d30708fSChicago Duan }
165*3d30708fSChicago Duan 
166*3d30708fSChicago Duan inline void
167*3d30708fSChicago Duan     addSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
168*3d30708fSChicago Duan                       const std::string& host, uint16_t snmpTrapPort)
169*3d30708fSChicago Duan {
170*3d30708fSChicago Duan     crow::connections::systemBus->async_method_call(
171*3d30708fSChicago Duan         [asyncResp](const boost::system::error_code& ec,
172*3d30708fSChicago Duan                     const std::string& dbusSNMPid) {
173*3d30708fSChicago Duan         afterSnmpClientCreate(asyncResp, ec, dbusSNMPid);
174*3d30708fSChicago Duan         },
175*3d30708fSChicago Duan         "xyz.openbmc_project.Network.SNMP",
176*3d30708fSChicago Duan         "/xyz/openbmc_project/network/snmp/manager",
177*3d30708fSChicago Duan         "xyz.openbmc_project.Network.Client.Create", "Client", host,
178*3d30708fSChicago Duan         snmpTrapPort);
179*3d30708fSChicago Duan }
180*3d30708fSChicago Duan 
181*3d30708fSChicago Duan inline void
182*3d30708fSChicago Duan     getSnmpSubscriptionList(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
183*3d30708fSChicago Duan                             const std::string& snmpId,
184*3d30708fSChicago Duan                             nlohmann::json& memberArray)
185*3d30708fSChicago Duan {
186*3d30708fSChicago Duan     const std::string subscriptionId = "snmp" + snmpId;
187*3d30708fSChicago Duan 
188*3d30708fSChicago Duan     nlohmann::json::object_t member;
189*3d30708fSChicago Duan     member["@odata.id"] = boost::urls::format(
190*3d30708fSChicago Duan         "/redfish/v1/EventService/Subscriptions/{}", subscriptionId);
191*3d30708fSChicago Duan     memberArray.push_back(std::move(member));
192*3d30708fSChicago Duan 
193*3d30708fSChicago Duan     asyncResp->res.jsonValue["Members@odata.count"] = memberArray.size();
194*3d30708fSChicago Duan }
195*3d30708fSChicago Duan 
196*3d30708fSChicago Duan inline void
197*3d30708fSChicago Duan     deleteSnmpTrapClient(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
198*3d30708fSChicago Duan                          const std::string& param)
199*3d30708fSChicago Duan {
200*3d30708fSChicago Duan     std::string_view snmpTrapId = param;
201*3d30708fSChicago Duan 
202*3d30708fSChicago Duan     // Erase "snmp" in the request to find the corresponding
203*3d30708fSChicago Duan     // dbus snmp client id. For example, the snmpid in the
204*3d30708fSChicago Duan     // request is "snmp1", which will be "1" after being erased.
205*3d30708fSChicago Duan     snmpTrapId.remove_prefix(4);
206*3d30708fSChicago Duan 
207*3d30708fSChicago Duan     sdbusplus::message::object_path snmpPath =
208*3d30708fSChicago Duan         sdbusplus::message::object_path(
209*3d30708fSChicago Duan             "/xyz/openbmc_project/network/snmp/manager") /
210*3d30708fSChicago Duan         std::string(snmpTrapId);
211*3d30708fSChicago Duan 
212*3d30708fSChicago Duan     crow::connections::systemBus->async_method_call(
213*3d30708fSChicago Duan         [asyncResp, param](const boost::system::error_code& ec) {
214*3d30708fSChicago Duan         if (ec)
215*3d30708fSChicago Duan         {
216*3d30708fSChicago Duan             // The snmp trap id is incorrect
217*3d30708fSChicago Duan             if (ec.value() == EBADR)
218*3d30708fSChicago Duan             {
219*3d30708fSChicago Duan                 messages::resourceNotFound(asyncResp->res, "Subscription",
220*3d30708fSChicago Duan                                            param);
221*3d30708fSChicago Duan                 return;
222*3d30708fSChicago Duan             }
223*3d30708fSChicago Duan             messages::internalError(asyncResp->res);
224*3d30708fSChicago Duan             return;
225*3d30708fSChicago Duan         }
226*3d30708fSChicago Duan         messages::success(asyncResp->res);
227*3d30708fSChicago Duan         },
228*3d30708fSChicago Duan         "xyz.openbmc_project.Network.SNMP", static_cast<std::string>(snmpPath),
229*3d30708fSChicago Duan         "xyz.openbmc_project.Object.Delete", "Delete");
230*3d30708fSChicago Duan }
231*3d30708fSChicago Duan 
232*3d30708fSChicago Duan } // namespace redfish
233