xref: /openbmc/bmcweb/features/redfish/lib/network_protocol.hpp (revision 8d1b46d7f8d39db2ba048f9e9007106ca3a28c9b)
170141561SBorawski.Lukasz /*
270141561SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation
370141561SBorawski.Lukasz //
470141561SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License");
570141561SBorawski.Lukasz // you may not use this file except in compliance with the License.
670141561SBorawski.Lukasz // You may obtain a copy of the License at
770141561SBorawski.Lukasz //
870141561SBorawski.Lukasz //      http://www.apache.org/licenses/LICENSE-2.0
970141561SBorawski.Lukasz //
1070141561SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software
1170141561SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS,
1270141561SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1370141561SBorawski.Lukasz // See the License for the specific language governing permissions and
1470141561SBorawski.Lukasz // limitations under the License.
1570141561SBorawski.Lukasz */
1670141561SBorawski.Lukasz #pragma once
1770141561SBorawski.Lukasz 
183a8a0088SKowalski, Kamil #include "error_messages.hpp"
1970141561SBorawski.Lukasz #include "node.hpp"
2067a78d87STom Joseph #include "openbmc_dbus_rest.hpp"
2170141561SBorawski.Lukasz 
2220e6ea5dSraviteja-b #include <utils/json_utils.hpp>
231214b7e7SGunnar Mills 
241214b7e7SGunnar Mills #include <optional>
25abf2add6SEd Tanous #include <variant>
261abe55efSEd Tanous namespace redfish
271abe55efSEd Tanous {
2870141561SBorawski.Lukasz 
291abe55efSEd Tanous enum NetworkProtocolUnitStructFields
301abe55efSEd Tanous {
313a8a0088SKowalski, Kamil     NET_PROTO_UNIT_NAME,
323a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DESC,
333a8a0088SKowalski, Kamil     NET_PROTO_UNIT_LOAD_STATE,
343a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ACTIVE_STATE,
353a8a0088SKowalski, Kamil     NET_PROTO_UNIT_SUB_STATE,
363a8a0088SKowalski, Kamil     NET_PROTO_UNIT_DEVICE,
373a8a0088SKowalski, Kamil     NET_PROTO_UNIT_OBJ_PATH,
383a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_0,
393a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_EMPTY,
403a8a0088SKowalski, Kamil     NET_PROTO_UNIT_ALWAYS_ROOT_PATH
413a8a0088SKowalski, Kamil };
423a8a0088SKowalski, Kamil 
431abe55efSEd Tanous enum NetworkProtocolListenResponseElements
441abe55efSEd Tanous {
453a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_TYPE,
463a8a0088SKowalski, Kamil     NET_PROTO_LISTEN_STREAM
473a8a0088SKowalski, Kamil };
483a8a0088SKowalski, Kamil 
493a8a0088SKowalski, Kamil /**
503a8a0088SKowalski, Kamil  * @brief D-Bus Unit structure returned in array from ListUnits Method
513a8a0088SKowalski, Kamil  */
523a8a0088SKowalski, Kamil using UnitStruct =
533a8a0088SKowalski, Kamil     std::tuple<std::string, std::string, std::string, std::string, std::string,
543a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path, uint32_t,
553a8a0088SKowalski, Kamil                std::string, sdbusplus::message::object_path>;
563a8a0088SKowalski, Kamil 
57b0972a63SEd Tanous const static std::array<std::pair<const char*, const char*>, 3> protocolToDBus{
58b0972a63SEd Tanous     {{"SSH", "dropbear"}, {"HTTPS", "bmcweb"}, {"IPMI", "phosphor-ipmi-net"}}};
593a8a0088SKowalski, Kamil 
60d24bfc7aSJennifer Lee inline void
6181ce609eSEd Tanous     extractNTPServersAndDomainNamesData(const GetManagedObjects& dbusData,
62d24bfc7aSJennifer Lee                                         std::vector<std::string>& ntpData,
63d24bfc7aSJennifer Lee                                         std::vector<std::string>& dnData)
6420e6ea5dSraviteja-b {
6581ce609eSEd Tanous     for (const auto& obj : dbusData)
6620e6ea5dSraviteja-b     {
6720e6ea5dSraviteja-b         for (const auto& ifacePair : obj.second)
6820e6ea5dSraviteja-b         {
6920e6ea5dSraviteja-b             if (obj.first == "/xyz/openbmc_project/network/eth0")
7020e6ea5dSraviteja-b             {
7120e6ea5dSraviteja-b                 if (ifacePair.first ==
7220e6ea5dSraviteja-b                     "xyz.openbmc_project.Network.EthernetInterface")
7320e6ea5dSraviteja-b                 {
7420e6ea5dSraviteja-b                     for (const auto& propertyPair : ifacePair.second)
7520e6ea5dSraviteja-b                     {
7620e6ea5dSraviteja-b                         if (propertyPair.first == "NTPServers")
7720e6ea5dSraviteja-b                         {
7820e6ea5dSraviteja-b                             const std::vector<std::string>* ntpServers =
798d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
8020e6ea5dSraviteja-b                                     &propertyPair.second);
8120e6ea5dSraviteja-b                             if (ntpServers != nullptr)
8220e6ea5dSraviteja-b                             {
83f23b7296SEd Tanous                                 ntpData = *ntpServers;
8420e6ea5dSraviteja-b                             }
8520e6ea5dSraviteja-b                         }
86d24bfc7aSJennifer Lee                         else if (propertyPair.first == "DomainName")
87d24bfc7aSJennifer Lee                         {
88d24bfc7aSJennifer Lee                             const std::vector<std::string>* domainNames =
898d78b7a9SPatrick Williams                                 std::get_if<std::vector<std::string>>(
90d24bfc7aSJennifer Lee                                     &propertyPair.second);
91d24bfc7aSJennifer Lee                             if (domainNames != nullptr)
92d24bfc7aSJennifer Lee                             {
93f23b7296SEd Tanous                                 dnData = *domainNames;
94d24bfc7aSJennifer Lee                             }
95d24bfc7aSJennifer Lee                         }
9620e6ea5dSraviteja-b                     }
9720e6ea5dSraviteja-b                 }
9820e6ea5dSraviteja-b             }
9920e6ea5dSraviteja-b         }
10020e6ea5dSraviteja-b     }
10120e6ea5dSraviteja-b }
10220e6ea5dSraviteja-b 
10320e6ea5dSraviteja-b template <typename CallbackFunc>
10420e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback)
10520e6ea5dSraviteja-b {
10620e6ea5dSraviteja-b     crow::connections::systemBus->async_method_call(
10720e6ea5dSraviteja-b         [callback{std::move(callback)}](
10881ce609eSEd Tanous             const boost::system::error_code errorCode,
10981ce609eSEd Tanous             const GetManagedObjects& dbusData) {
11020e6ea5dSraviteja-b             std::vector<std::string> ntpServers;
111d24bfc7aSJennifer Lee             std::vector<std::string> domainNames;
11220e6ea5dSraviteja-b 
11381ce609eSEd Tanous             if (errorCode)
11420e6ea5dSraviteja-b             {
115d24bfc7aSJennifer Lee                 callback(false, ntpServers, domainNames);
11620e6ea5dSraviteja-b                 return;
11720e6ea5dSraviteja-b             }
11820e6ea5dSraviteja-b 
11981ce609eSEd Tanous             extractNTPServersAndDomainNamesData(dbusData, ntpServers,
120d24bfc7aSJennifer Lee                                                 domainNames);
12120e6ea5dSraviteja-b 
122d24bfc7aSJennifer Lee             callback(true, ntpServers, domainNames);
12320e6ea5dSraviteja-b         },
12420e6ea5dSraviteja-b         "xyz.openbmc_project.Network", "/xyz/openbmc_project/network",
12520e6ea5dSraviteja-b         "org.freedesktop.DBus.ObjectManager", "GetManagedObjects");
126271584abSEd Tanous }
12720e6ea5dSraviteja-b 
1281abe55efSEd Tanous class NetworkProtocol : public Node
1291abe55efSEd Tanous {
13070141561SBorawski.Lukasz   public:
13152cc112dSEd Tanous     NetworkProtocol(App& app) :
1327af91514SGunnar Mills         Node(app, "/redfish/v1/Managers/bmc/NetworkProtocol/")
1331abe55efSEd Tanous     {
1344b1b8683SBorawski.Lukasz         entityPrivileges = {
1354b1b8683SBorawski.Lukasz             {boost::beast::http::verb::get, {{"Login"}}},
136e0d918bcSEd Tanous             {boost::beast::http::verb::head, {{"Login"}}},
137e0d918bcSEd Tanous             {boost::beast::http::verb::patch, {{"ConfigureManager"}}},
138e0d918bcSEd Tanous             {boost::beast::http::verb::put, {{"ConfigureManager"}}},
139e0d918bcSEd Tanous             {boost::beast::http::verb::delete_, {{"ConfigureManager"}}},
140e0d918bcSEd Tanous             {boost::beast::http::verb::post, {{"ConfigureManager"}}}};
14170141561SBorawski.Lukasz     }
14270141561SBorawski.Lukasz 
14370141561SBorawski.Lukasz   private:
144*8d1b46d7Szhanghch05     void doGet(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
145*8d1b46d7Szhanghch05                const crow::Request&, const std::vector<std::string>&) override
1461abe55efSEd Tanous     {
1473a8a0088SKowalski, Kamil         getData(asyncResp);
14870141561SBorawski.Lukasz     }
14970141561SBorawski.Lukasz 
1501abe55efSEd Tanous     std::string getHostName() const
1511abe55efSEd Tanous     {
15270141561SBorawski.Lukasz         std::string hostName;
15370141561SBorawski.Lukasz 
15470141561SBorawski.Lukasz         std::array<char, HOST_NAME_MAX> hostNameCStr;
1551abe55efSEd Tanous         if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0)
1561abe55efSEd Tanous         {
15770141561SBorawski.Lukasz             hostName = hostNameCStr.data();
15870141561SBorawski.Lukasz         }
15970141561SBorawski.Lukasz         return hostName;
16070141561SBorawski.Lukasz     }
16170141561SBorawski.Lukasz 
162*8d1b46d7Szhanghch05     void getNTPProtocolEnabled(
163*8d1b46d7Szhanghch05         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
16420e6ea5dSraviteja-b     {
16520e6ea5dSraviteja-b         crow::connections::systemBus->async_method_call(
16681ce609eSEd Tanous             [asyncResp](const boost::system::error_code errorCode,
16720e6ea5dSraviteja-b                         const std::variant<std::string>& timeSyncMethod) {
16881ce609eSEd Tanous                 if (errorCode)
169cb13a392SEd Tanous                 {
170cb13a392SEd Tanous                     return;
171cb13a392SEd Tanous                 }
172cb13a392SEd Tanous 
17320e6ea5dSraviteja-b                 const std::string* s =
17420e6ea5dSraviteja-b                     std::get_if<std::string>(&timeSyncMethod);
17520e6ea5dSraviteja-b 
17620e6ea5dSraviteja-b                 if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP")
17720e6ea5dSraviteja-b                 {
17820e6ea5dSraviteja-b                     asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true;
17920e6ea5dSraviteja-b                 }
18020e6ea5dSraviteja-b                 else if (*s == "xyz.openbmc_project.Time.Synchronization."
18120e6ea5dSraviteja-b                                "Method.Manual")
18220e6ea5dSraviteja-b                 {
18320e6ea5dSraviteja-b                     asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false;
18420e6ea5dSraviteja-b                 }
18520e6ea5dSraviteja-b             },
18620e6ea5dSraviteja-b             "xyz.openbmc_project.Settings",
18720e6ea5dSraviteja-b             "/xyz/openbmc_project/time/sync_method",
18820e6ea5dSraviteja-b             "org.freedesktop.DBus.Properties", "Get",
18920e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod");
19020e6ea5dSraviteja-b     }
19120e6ea5dSraviteja-b 
192*8d1b46d7Szhanghch05     void getData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
1931abe55efSEd Tanous     {
1940f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.type"] =
19561932318SXiaochao Ma             "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol";
1960f74e643SEd Tanous         asyncResp->res.jsonValue["@odata.id"] =
1970f74e643SEd Tanous             "/redfish/v1/Managers/bmc/NetworkProtocol";
1980f74e643SEd Tanous         asyncResp->res.jsonValue["Id"] = "NetworkProtocol";
1990f74e643SEd Tanous         asyncResp->res.jsonValue["Name"] = "Manager Network Protocol";
2000f74e643SEd Tanous         asyncResp->res.jsonValue["Description"] = "Manager Network Service";
2010f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["Health"] = "OK";
2020f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK";
2030f74e643SEd Tanous         asyncResp->res.jsonValue["Status"]["State"] = "Enabled";
2040f74e643SEd Tanous 
20561932318SXiaochao Ma         // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0,
206818ea7b8SJoshi-Mansi         // but from security perspective it is not recommended to use.
207818ea7b8SJoshi-Mansi         // Hence using protocolEnabled as false to make it OCP and security-wise
208818ea7b8SJoshi-Mansi         // compliant
209818ea7b8SJoshi-Mansi         asyncResp->res.jsonValue["HTTP"]["Port"] = 0;
210818ea7b8SJoshi-Mansi         asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false;
211818ea7b8SJoshi-Mansi 
2120f74e643SEd Tanous         for (auto& protocol : protocolToDBus)
2130f74e643SEd Tanous         {
2140870f8c7SJayaprakash Mutyala             asyncResp->res.jsonValue[protocol.first]["Port"] =
2150870f8c7SJayaprakash Mutyala                 nlohmann::detail::value_t::null;
2160f74e643SEd Tanous             asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false;
2170f74e643SEd Tanous         }
2180f74e643SEd Tanous 
219d24bfc7aSJennifer Lee         std::string hostName = getHostName();
220d24bfc7aSJennifer Lee 
221d24bfc7aSJennifer Lee         asyncResp->res.jsonValue["HostName"] = hostName;
2223a8a0088SKowalski, Kamil 
22320e6ea5dSraviteja-b         getNTPProtocolEnabled(asyncResp);
22420e6ea5dSraviteja-b 
22520e6ea5dSraviteja-b         // TODO Get eth0 interface data, and call the below callback for JSON
22620e6ea5dSraviteja-b         // preparation
227271584abSEd Tanous         getEthernetIfaceData(
228271584abSEd Tanous             [hostName, asyncResp](const bool& success,
229d24bfc7aSJennifer Lee                                   const std::vector<std::string>& ntpServers,
230d24bfc7aSJennifer Lee                                   const std::vector<std::string>& domainNames) {
23120e6ea5dSraviteja-b                 if (!success)
23220e6ea5dSraviteja-b                 {
233271584abSEd Tanous                     messages::resourceNotFound(asyncResp->res,
234271584abSEd Tanous                                                "EthernetInterface", "eth0");
23520e6ea5dSraviteja-b                     return;
23620e6ea5dSraviteja-b                 }
23720e6ea5dSraviteja-b                 asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers;
238d24bfc7aSJennifer Lee                 if (hostName.empty() == false)
239d24bfc7aSJennifer Lee                 {
240f23b7296SEd Tanous                     std::string fqdn = hostName;
241d24bfc7aSJennifer Lee                     if (domainNames.empty() == false)
242d24bfc7aSJennifer Lee                     {
243f23b7296SEd Tanous                         fqdn += ".";
244f23b7296SEd Tanous                         fqdn += domainNames[0];
245d24bfc7aSJennifer Lee                     }
2462c70f800SEd Tanous                     asyncResp->res.jsonValue["FQDN"] = std::move(fqdn);
247d24bfc7aSJennifer Lee                 }
24820e6ea5dSraviteja-b             });
24920e6ea5dSraviteja-b 
250865fbb75SEd Tanous         crow::connections::systemBus->async_method_call(
251271584abSEd Tanous             [asyncResp](const boost::system::error_code e,
252271584abSEd Tanous                         const std::vector<UnitStruct>& r) {
253271584abSEd Tanous                 if (e)
2541abe55efSEd Tanous                 {
2553a8a0088SKowalski, Kamil                     asyncResp->res.jsonValue = nlohmann::json::object();
256f12894f8SJason M. Bills                     messages::internalError(asyncResp->res);
257865fbb75SEd Tanous                     return;
2583a8a0088SKowalski, Kamil                 }
2595968caeeSMarri Devender Rao                 asyncResp->res.jsonValue["HTTPS"]["Certificates"] = {
2605968caeeSMarri Devender Rao                     {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/"
261659dd62eSJason M. Bills                                   "HTTPS/Certificates"}};
2623a8a0088SKowalski, Kamil 
263271584abSEd Tanous                 for (auto& unit : r)
2641abe55efSEd Tanous                 {
265ec4974ddSAppaRao Puli                     /* Only traverse through <xyz>.socket units */
2663174e4dfSEd Tanous                     const std::string& unitName =
2673174e4dfSEd Tanous                         std::get<NET_PROTO_UNIT_NAME>(unit);
268ec4974ddSAppaRao Puli                     if (!boost::ends_with(unitName, ".socket"))
2691abe55efSEd Tanous                     {
270865fbb75SEd Tanous                         continue;
27170141561SBorawski.Lukasz                     }
27270141561SBorawski.Lukasz 
273ec4974ddSAppaRao Puli                     for (auto& kv : protocolToDBus)
274ec4974ddSAppaRao Puli                     {
275ec4974ddSAppaRao Puli                         // We are interested in services, which starts with
276ec4974ddSAppaRao Puli                         // mapped service name
277ec4974ddSAppaRao Puli                         if (!boost::starts_with(unitName, kv.second))
278ec4974ddSAppaRao Puli                         {
279ec4974ddSAppaRao Puli                             continue;
280ec4974ddSAppaRao Puli                         }
281ec4974ddSAppaRao Puli                         const char* rfServiceKey = kv.first;
2823174e4dfSEd Tanous                         const std::string& socketPath =
283ec4974ddSAppaRao Puli                             std::get<NET_PROTO_UNIT_OBJ_PATH>(unit);
2843174e4dfSEd Tanous                         const std::string& unitState =
285ec4974ddSAppaRao Puli                             std::get<NET_PROTO_UNIT_SUB_STATE>(unit);
286ec4974ddSAppaRao Puli 
287ec4974ddSAppaRao Puli                         asyncResp->res
288ec4974ddSAppaRao Puli                             .jsonValue[rfServiceKey]["ProtocolEnabled"] =
289ec4974ddSAppaRao Puli                             (unitState == "running") ||
290ec4974ddSAppaRao Puli                             (unitState == "listening");
291ec4974ddSAppaRao Puli 
292865fbb75SEd Tanous                         crow::connections::systemBus->async_method_call(
293ec4974ddSAppaRao Puli                             [asyncResp,
294ec4974ddSAppaRao Puli                              rfServiceKey{std::string(rfServiceKey)}](
295865fbb75SEd Tanous                                 const boost::system::error_code ec,
296abf2add6SEd Tanous                                 const std::variant<std::vector<std::tuple<
297abf2add6SEd Tanous                                     std::string, std::string>>>& resp) {
2981abe55efSEd Tanous                                 if (ec)
2991abe55efSEd Tanous                                 {
300a08b46ccSJason M. Bills                                     messages::internalError(asyncResp->res);
301865fbb75SEd Tanous                                     return;
3023a8a0088SKowalski, Kamil                                 }
303abf2add6SEd Tanous                                 const std::vector<
304abf2add6SEd Tanous                                     std::tuple<std::string, std::string>>*
305abf2add6SEd Tanous                                     responsePtr = std::get_if<std::vector<
306abf2add6SEd Tanous                                         std::tuple<std::string, std::string>>>(
3071b6b96c5SEd Tanous                                         &resp);
3081abe55efSEd Tanous                                 if (responsePtr == nullptr ||
3091abe55efSEd Tanous                                     responsePtr->size() < 1)
3101abe55efSEd Tanous                                 {
311865fbb75SEd Tanous                                     return;
31270141561SBorawski.Lukasz                                 }
31370141561SBorawski.Lukasz 
314865fbb75SEd Tanous                                 const std::string& listenStream =
3151abe55efSEd Tanous                                     std::get<NET_PROTO_LISTEN_STREAM>(
3161abe55efSEd Tanous                                         (*responsePtr)[0]);
3171abe55efSEd Tanous                                 std::size_t lastColonPos =
318f23b7296SEd Tanous                                     listenStream.rfind(':');
3191abe55efSEd Tanous                                 if (lastColonPos == std::string::npos)
3201abe55efSEd Tanous                                 {
321865fbb75SEd Tanous                                     // Not a port
322865fbb75SEd Tanous                                     return;
323865fbb75SEd Tanous                                 }
3241abe55efSEd Tanous                                 std::string portStr =
3251abe55efSEd Tanous                                     listenStream.substr(lastColonPos + 1);
326ec4974ddSAppaRao Puli                                 if (portStr.empty())
327ec4974ddSAppaRao Puli                                 {
328ec4974ddSAppaRao Puli                                     return;
329ec4974ddSAppaRao Puli                                 }
330865fbb75SEd Tanous                                 char* endPtr = nullptr;
331ec4974ddSAppaRao Puli                                 errno = 0;
3321abe55efSEd Tanous                                 // Use strtol instead of stroi to avoid
3331abe55efSEd Tanous                                 // exceptions
3341abe55efSEd Tanous                                 long port =
3351abe55efSEd Tanous                                     std::strtol(portStr.c_str(), &endPtr, 10);
336ec4974ddSAppaRao Puli                                 if ((errno == 0) && (*endPtr == '\0'))
3371abe55efSEd Tanous                                 {
338ec4974ddSAppaRao Puli                                     asyncResp->res
339ec4974ddSAppaRao Puli                                         .jsonValue[rfServiceKey]["Port"] = port;
3401abe55efSEd Tanous                                 }
341ec4974ddSAppaRao Puli                                 return;
342865fbb75SEd Tanous                             },
343865fbb75SEd Tanous                             "org.freedesktop.systemd1", socketPath,
344865fbb75SEd Tanous                             "org.freedesktop.DBus.Properties", "Get",
345865fbb75SEd Tanous                             "org.freedesktop.systemd1.Socket", "Listen");
346ec4974ddSAppaRao Puli 
347ec4974ddSAppaRao Puli                         // We found service, break the inner loop.
348ec4974ddSAppaRao Puli                         break;
349865fbb75SEd Tanous                     }
350865fbb75SEd Tanous                 }
351865fbb75SEd Tanous             },
352865fbb75SEd Tanous             "org.freedesktop.systemd1", "/org/freedesktop/systemd1",
353865fbb75SEd Tanous             "org.freedesktop.systemd1.Manager", "ListUnits");
354865fbb75SEd Tanous     }
355501be32bSraviteja-b 
3562db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
357*8d1b46d7Szhanghch05     void
358*8d1b46d7Szhanghch05         handleHostnamePatch(const std::string& hostName,
359*8d1b46d7Szhanghch05                             const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
360501be32bSraviteja-b     {
361501be32bSraviteja-b         crow::connections::systemBus->async_method_call(
362501be32bSraviteja-b             [asyncResp](const boost::system::error_code ec) {
363501be32bSraviteja-b                 if (ec)
364501be32bSraviteja-b                 {
365501be32bSraviteja-b                     messages::internalError(asyncResp->res);
366501be32bSraviteja-b                     return;
367501be32bSraviteja-b                 }
368501be32bSraviteja-b             },
369501be32bSraviteja-b             "xyz.openbmc_project.Network",
370501be32bSraviteja-b             "/xyz/openbmc_project/network/config",
371501be32bSraviteja-b             "org.freedesktop.DBus.Properties", "Set",
372501be32bSraviteja-b             "xyz.openbmc_project.Network.SystemConfiguration", "HostName",
373501be32bSraviteja-b             std::variant<std::string>(hostName));
374501be32bSraviteja-b     }
3752db77d34SJohnathan Mantey #endif
376501be32bSraviteja-b 
377*8d1b46d7Szhanghch05     void handleNTPProtocolEnabled(
378*8d1b46d7Szhanghch05         const bool& ntpEnabled,
379*8d1b46d7Szhanghch05         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
38020e6ea5dSraviteja-b     {
38120e6ea5dSraviteja-b         std::string timeSyncMethod;
38220e6ea5dSraviteja-b         if (ntpEnabled)
38320e6ea5dSraviteja-b         {
38420e6ea5dSraviteja-b             timeSyncMethod =
38520e6ea5dSraviteja-b                 "xyz.openbmc_project.Time.Synchronization.Method.NTP";
38620e6ea5dSraviteja-b         }
38720e6ea5dSraviteja-b         else
38820e6ea5dSraviteja-b         {
38920e6ea5dSraviteja-b             timeSyncMethod =
39020e6ea5dSraviteja-b                 "xyz.openbmc_project.Time.Synchronization.Method.Manual";
39120e6ea5dSraviteja-b         }
39220e6ea5dSraviteja-b 
39320e6ea5dSraviteja-b         crow::connections::systemBus->async_method_call(
39481ce609eSEd Tanous             [asyncResp](const boost::system::error_code errorCode) {
39581ce609eSEd Tanous                 if (errorCode)
396cb13a392SEd Tanous                 {
397cb13a392SEd Tanous                     messages::internalError(asyncResp->res);
398cb13a392SEd Tanous                 }
399cb13a392SEd Tanous             },
40020e6ea5dSraviteja-b             "xyz.openbmc_project.Settings",
40120e6ea5dSraviteja-b             "/xyz/openbmc_project/time/sync_method",
40220e6ea5dSraviteja-b             "org.freedesktop.DBus.Properties", "Set",
40320e6ea5dSraviteja-b             "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod",
40420e6ea5dSraviteja-b             std::variant<std::string>{timeSyncMethod});
40520e6ea5dSraviteja-b     }
40620e6ea5dSraviteja-b 
407*8d1b46d7Szhanghch05     void handleNTPServersPatch(
408*8d1b46d7Szhanghch05         const std::vector<std::string>& ntpServers,
409*8d1b46d7Szhanghch05         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
41020e6ea5dSraviteja-b     {
41120e6ea5dSraviteja-b         crow::connections::systemBus->async_method_call(
412cf05f9dcSJohnathan Mantey             [asyncResp](const boost::system::error_code ec) {
41320e6ea5dSraviteja-b                 if (ec)
41420e6ea5dSraviteja-b                 {
41520e6ea5dSraviteja-b                     messages::internalError(asyncResp->res);
41620e6ea5dSraviteja-b                     return;
41720e6ea5dSraviteja-b                 }
41820e6ea5dSraviteja-b             },
41920e6ea5dSraviteja-b             "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0",
42020e6ea5dSraviteja-b             "org.freedesktop.DBus.Properties", "Set",
42120e6ea5dSraviteja-b             "xyz.openbmc_project.Network.EthernetInterface", "NTPServers",
42220e6ea5dSraviteja-b             std::variant<std::vector<std::string>>{ntpServers});
42320e6ea5dSraviteja-b     }
42420e6ea5dSraviteja-b 
425*8d1b46d7Szhanghch05     void handleIpmiProtocolEnabled(
426*8d1b46d7Szhanghch05         const bool ipmiProtocolEnabled,
427*8d1b46d7Szhanghch05         const std::shared_ptr<bmcweb::AsyncResp>& asyncResp)
42867a78d87STom Joseph     {
42967a78d87STom Joseph         crow::connections::systemBus->async_method_call(
43067a78d87STom Joseph             [ipmiProtocolEnabled,
43167a78d87STom Joseph              asyncResp](const boost::system::error_code ec,
43267a78d87STom Joseph                         const crow::openbmc_mapper::GetSubTreeType& subtree) {
43367a78d87STom Joseph                 if (ec)
43467a78d87STom Joseph                 {
43567a78d87STom Joseph                     messages::internalError(asyncResp->res);
43667a78d87STom Joseph                     return;
43767a78d87STom Joseph                 }
43867a78d87STom Joseph 
43967a78d87STom Joseph                 constexpr char const* netipmidBasePath =
44067a78d87STom Joseph                     "/xyz/openbmc_project/control/service/"
44167a78d87STom Joseph                     "phosphor_2dipmi_2dnet_40";
44267a78d87STom Joseph 
44367a78d87STom Joseph                 for (const auto& entry : subtree)
44467a78d87STom Joseph                 {
44567a78d87STom Joseph                     if (boost::algorithm::starts_with(entry.first,
44667a78d87STom Joseph                                                       netipmidBasePath))
44767a78d87STom Joseph                     {
44867a78d87STom Joseph                         crow::connections::systemBus->async_method_call(
44923a21a1cSEd Tanous                             [asyncResp](const boost::system::error_code ec2) {
45023a21a1cSEd Tanous                                 if (ec2)
45167a78d87STom Joseph                                 {
45267a78d87STom Joseph                                     messages::internalError(asyncResp->res);
45367a78d87STom Joseph                                     return;
45467a78d87STom Joseph                                 }
45567a78d87STom Joseph                             },
45667a78d87STom Joseph                             entry.second.begin()->first, entry.first,
45767a78d87STom Joseph                             "org.freedesktop.DBus.Properties", "Set",
45867a78d87STom Joseph                             "xyz.openbmc_project.Control.Service.Attributes",
45967a78d87STom Joseph                             "Running", std::variant<bool>{ipmiProtocolEnabled});
46067a78d87STom Joseph 
46167a78d87STom Joseph                         crow::connections::systemBus->async_method_call(
46223a21a1cSEd Tanous                             [asyncResp](const boost::system::error_code ec2) {
46323a21a1cSEd Tanous                                 if (ec2)
46467a78d87STom Joseph                                 {
46567a78d87STom Joseph                                     messages::internalError(asyncResp->res);
46667a78d87STom Joseph                                     return;
46767a78d87STom Joseph                                 }
46867a78d87STom Joseph                             },
46967a78d87STom Joseph                             entry.second.begin()->first, entry.first,
47067a78d87STom Joseph                             "org.freedesktop.DBus.Properties", "Set",
47167a78d87STom Joseph                             "xyz.openbmc_project.Control.Service.Attributes",
47267a78d87STom Joseph                             "Enabled", std::variant<bool>{ipmiProtocolEnabled});
47367a78d87STom Joseph                     }
47467a78d87STom Joseph                 }
47567a78d87STom Joseph             },
47667a78d87STom Joseph             "xyz.openbmc_project.ObjectMapper",
47767a78d87STom Joseph             "/xyz/openbmc_project/object_mapper",
47867a78d87STom Joseph             "xyz.openbmc_project.ObjectMapper", "GetSubTree",
47967a78d87STom Joseph             "/xyz/openbmc_project/control/service", 0,
48067a78d87STom Joseph             std::array<const char*, 1>{
48167a78d87STom Joseph                 "xyz.openbmc_project.Control.Service.Attributes"});
48267a78d87STom Joseph     }
48367a78d87STom Joseph 
484*8d1b46d7Szhanghch05     void doPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp,
485*8d1b46d7Szhanghch05                  const crow::Request& req,
486cb13a392SEd Tanous                  const std::vector<std::string>&) override
487501be32bSraviteja-b     {
488*8d1b46d7Szhanghch05 
489501be32bSraviteja-b         std::optional<std::string> newHostName;
490cf05f9dcSJohnathan Mantey         std::optional<nlohmann::json> ntp;
49167a78d87STom Joseph         std::optional<nlohmann::json> ipmi;
492501be32bSraviteja-b 
493*8d1b46d7Szhanghch05         if (!json_util::readJson(req, asyncResp->res, "NTP", ntp, "HostName",
494*8d1b46d7Szhanghch05                                  newHostName, "IPMI", ipmi))
495501be32bSraviteja-b         {
496501be32bSraviteja-b             return;
497501be32bSraviteja-b         }
498cf05f9dcSJohnathan Mantey 
499*8d1b46d7Szhanghch05         asyncResp->res.result(boost::beast::http::status::no_content);
500501be32bSraviteja-b         if (newHostName)
501501be32bSraviteja-b         {
5022db77d34SJohnathan Mantey #ifdef BMCWEB_ALLOW_DEPRECATED_HOSTNAME_PATCH
503501be32bSraviteja-b             handleHostnamePatch(*newHostName, asyncResp);
5042db77d34SJohnathan Mantey #else
5052db77d34SJohnathan Mantey             messages::propertyNotWritable(asyncResp->res, "HostName");
5062db77d34SJohnathan Mantey #endif
507cf05f9dcSJohnathan Mantey         }
508cf05f9dcSJohnathan Mantey 
509cf05f9dcSJohnathan Mantey         if (ntp)
510cf05f9dcSJohnathan Mantey         {
511cf05f9dcSJohnathan Mantey             std::optional<std::vector<std::string>> ntpServers;
512cf05f9dcSJohnathan Mantey             std::optional<bool> ntpEnabled;
513*8d1b46d7Szhanghch05             if (!json_util::readJson(*ntp, asyncResp->res, "NTPServers",
514*8d1b46d7Szhanghch05                                      ntpServers, "ProtocolEnabled", ntpEnabled))
515cf05f9dcSJohnathan Mantey             {
516501be32bSraviteja-b                 return;
517501be32bSraviteja-b             }
518cf05f9dcSJohnathan Mantey 
51920e6ea5dSraviteja-b             if (ntpEnabled)
52020e6ea5dSraviteja-b             {
52120e6ea5dSraviteja-b                 handleNTPProtocolEnabled(*ntpEnabled, asyncResp);
52220e6ea5dSraviteja-b             }
523cf05f9dcSJohnathan Mantey 
52420e6ea5dSraviteja-b             if (ntpServers)
52520e6ea5dSraviteja-b             {
526dc3fbbd0STony Lee                 std::sort((*ntpServers).begin(), (*ntpServers).end());
527dc3fbbd0STony Lee                 (*ntpServers)
528dc3fbbd0STony Lee                     .erase(
529dc3fbbd0STony Lee                         std::unique((*ntpServers).begin(), (*ntpServers).end()),
530dc3fbbd0STony Lee                         (*ntpServers).end());
53120e6ea5dSraviteja-b                 handleNTPServersPatch(*ntpServers, asyncResp);
53220e6ea5dSraviteja-b             }
533501be32bSraviteja-b         }
53467a78d87STom Joseph 
53567a78d87STom Joseph         if (ipmi)
53667a78d87STom Joseph         {
53767a78d87STom Joseph             std::optional<bool> ipmiProtocolEnabled;
538*8d1b46d7Szhanghch05             if (!json_util::readJson(*ipmi, asyncResp->res, "ProtocolEnabled",
53967a78d87STom Joseph                                      ipmiProtocolEnabled))
54067a78d87STom Joseph             {
54167a78d87STom Joseph                 return;
54267a78d87STom Joseph             }
54367a78d87STom Joseph 
54467a78d87STom Joseph             if (ipmiProtocolEnabled)
54567a78d87STom Joseph             {
54667a78d87STom Joseph                 handleIpmiProtocolEnabled(*ipmiProtocolEnabled, asyncResp);
54767a78d87STom Joseph             }
54867a78d87STom Joseph         }
549cf05f9dcSJohnathan Mantey     }
55070141561SBorawski.Lukasz };
55170141561SBorawski.Lukasz 
55270141561SBorawski.Lukasz } // namespace redfish
553