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" 2070141561SBorawski.Lukasz 21*20e6ea5dSraviteja-b #include <optional> 22*20e6ea5dSraviteja-b #include <utils/json_utils.hpp> 23abf2add6SEd Tanous #include <variant> 241abe55efSEd Tanous namespace redfish 251abe55efSEd Tanous { 2670141561SBorawski.Lukasz 271abe55efSEd Tanous enum NetworkProtocolUnitStructFields 281abe55efSEd Tanous { 293a8a0088SKowalski, Kamil NET_PROTO_UNIT_NAME, 303a8a0088SKowalski, Kamil NET_PROTO_UNIT_DESC, 313a8a0088SKowalski, Kamil NET_PROTO_UNIT_LOAD_STATE, 323a8a0088SKowalski, Kamil NET_PROTO_UNIT_ACTIVE_STATE, 333a8a0088SKowalski, Kamil NET_PROTO_UNIT_SUB_STATE, 343a8a0088SKowalski, Kamil NET_PROTO_UNIT_DEVICE, 353a8a0088SKowalski, Kamil NET_PROTO_UNIT_OBJ_PATH, 363a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_0, 373a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_EMPTY, 383a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_ROOT_PATH 393a8a0088SKowalski, Kamil }; 403a8a0088SKowalski, Kamil 411abe55efSEd Tanous enum NetworkProtocolListenResponseElements 421abe55efSEd Tanous { 433a8a0088SKowalski, Kamil NET_PROTO_LISTEN_TYPE, 443a8a0088SKowalski, Kamil NET_PROTO_LISTEN_STREAM 453a8a0088SKowalski, Kamil }; 463a8a0088SKowalski, Kamil 473a8a0088SKowalski, Kamil /** 483a8a0088SKowalski, Kamil * @brief D-Bus Unit structure returned in array from ListUnits Method 493a8a0088SKowalski, Kamil */ 503a8a0088SKowalski, Kamil using UnitStruct = 513a8a0088SKowalski, Kamil std::tuple<std::string, std::string, std::string, std::string, std::string, 523a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path, uint32_t, 533a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path>; 543a8a0088SKowalski, Kamil 551abe55efSEd Tanous struct ServiceConfiguration 561abe55efSEd Tanous { 57865fbb75SEd Tanous const char* serviceName; 58865fbb75SEd Tanous const char* socketPath; 593a8a0088SKowalski, Kamil }; 603a8a0088SKowalski, Kamil 61865fbb75SEd Tanous const static boost::container::flat_map<const char*, ServiceConfiguration> 62865fbb75SEd Tanous protocolToDBus{ 63865fbb75SEd Tanous {"SSH", 645ded8c79SJennifer Lee {"dropbear.socket", 65865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/dropbear_2esocket"}}, 66865fbb75SEd Tanous {"HTTPS", 675ded8c79SJennifer Lee {"bmcweb.service", 685ded8c79SJennifer Lee "/org/freedesktop/systemd1/unit/" 695ded8c79SJennifer Lee "bmcweb_2esocket"}}, //"/org/freedesktop/systemd1/unit/phosphor_2dgevent_2esocket"}}, 70865fbb75SEd Tanous {"IPMI", 715ded8c79SJennifer Lee {"phosphor-ipmi-net.socket", "/org/freedesktop/systemd1/unit/" 725ded8c79SJennifer Lee "phosphor_2dipmi_2dnet_2esocket"}}}; 733a8a0088SKowalski, Kamil 74*20e6ea5dSraviteja-b inline void extractNTPServersData(const GetManagedObjects& dbus_data, 75*20e6ea5dSraviteja-b std::vector<std::string>& ntpData) 76*20e6ea5dSraviteja-b { 77*20e6ea5dSraviteja-b for (const auto& obj : dbus_data) 78*20e6ea5dSraviteja-b { 79*20e6ea5dSraviteja-b for (const auto& ifacePair : obj.second) 80*20e6ea5dSraviteja-b { 81*20e6ea5dSraviteja-b if (obj.first == "/xyz/openbmc_project/network/eth0") 82*20e6ea5dSraviteja-b { 83*20e6ea5dSraviteja-b if (ifacePair.first == 84*20e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface") 85*20e6ea5dSraviteja-b { 86*20e6ea5dSraviteja-b for (const auto& propertyPair : ifacePair.second) 87*20e6ea5dSraviteja-b { 88*20e6ea5dSraviteja-b if (propertyPair.first == "NTPServers") 89*20e6ea5dSraviteja-b { 90*20e6ea5dSraviteja-b const std::vector<std::string>* ntpServers = 91*20e6ea5dSraviteja-b sdbusplus::message::variant_ns::get_if< 92*20e6ea5dSraviteja-b std::vector<std::string>>( 93*20e6ea5dSraviteja-b &propertyPair.second); 94*20e6ea5dSraviteja-b if (ntpServers != nullptr) 95*20e6ea5dSraviteja-b { 96*20e6ea5dSraviteja-b ntpData = std::move(*ntpServers); 97*20e6ea5dSraviteja-b } 98*20e6ea5dSraviteja-b } 99*20e6ea5dSraviteja-b } 100*20e6ea5dSraviteja-b } 101*20e6ea5dSraviteja-b } 102*20e6ea5dSraviteja-b } 103*20e6ea5dSraviteja-b } 104*20e6ea5dSraviteja-b } 105*20e6ea5dSraviteja-b 106*20e6ea5dSraviteja-b template <typename CallbackFunc> 107*20e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback) 108*20e6ea5dSraviteja-b { 109*20e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 110*20e6ea5dSraviteja-b [callback{std::move(callback)}]( 111*20e6ea5dSraviteja-b const boost::system::error_code error_code, 112*20e6ea5dSraviteja-b const GetManagedObjects& dbus_data) { 113*20e6ea5dSraviteja-b std::vector<std::string> ntpServers; 114*20e6ea5dSraviteja-b 115*20e6ea5dSraviteja-b if (error_code) 116*20e6ea5dSraviteja-b { 117*20e6ea5dSraviteja-b callback(false, ntpServers); 118*20e6ea5dSraviteja-b return; 119*20e6ea5dSraviteja-b } 120*20e6ea5dSraviteja-b 121*20e6ea5dSraviteja-b extractNTPServersData(dbus_data, ntpServers); 122*20e6ea5dSraviteja-b 123*20e6ea5dSraviteja-b callback(true, ntpServers); 124*20e6ea5dSraviteja-b }, 125*20e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", 126*20e6ea5dSraviteja-b "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 127*20e6ea5dSraviteja-b }; 128*20e6ea5dSraviteja-b 1291abe55efSEd Tanous class NetworkProtocol : public Node 1301abe55efSEd Tanous { 13170141561SBorawski.Lukasz public: 1321abe55efSEd Tanous NetworkProtocol(CrowApp& app) : 13397b7ccf3SEd Tanous Node(app, "/redfish/v1/Managers/bmc/NetworkProtocol") 1341abe55efSEd Tanous { 1354b1b8683SBorawski.Lukasz entityPrivileges = { 1364b1b8683SBorawski.Lukasz {boost::beast::http::verb::get, {{"Login"}}}, 137e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 138e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 139e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 140e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 141e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 14270141561SBorawski.Lukasz } 14370141561SBorawski.Lukasz 14470141561SBorawski.Lukasz private: 14555c7b7a2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 1461abe55efSEd Tanous const std::vector<std::string>& params) override 1471abe55efSEd Tanous { 1483a8a0088SKowalski, Kamil std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 1493a8a0088SKowalski, Kamil 1503a8a0088SKowalski, Kamil getData(asyncResp); 15170141561SBorawski.Lukasz } 15270141561SBorawski.Lukasz 1531abe55efSEd Tanous std::string getHostName() const 1541abe55efSEd Tanous { 15570141561SBorawski.Lukasz std::string hostName; 15670141561SBorawski.Lukasz 15770141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 1581abe55efSEd Tanous if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 1591abe55efSEd Tanous { 16070141561SBorawski.Lukasz hostName = hostNameCStr.data(); 16170141561SBorawski.Lukasz } 16270141561SBorawski.Lukasz return hostName; 16370141561SBorawski.Lukasz } 16470141561SBorawski.Lukasz 165*20e6ea5dSraviteja-b void getNTPProtocolEnabled(const std::shared_ptr<AsyncResp>& asyncResp) 166*20e6ea5dSraviteja-b { 167*20e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 168*20e6ea5dSraviteja-b [asyncResp](const boost::system::error_code error_code, 169*20e6ea5dSraviteja-b const std::variant<std::string>& timeSyncMethod) { 170*20e6ea5dSraviteja-b const std::string* s = 171*20e6ea5dSraviteja-b std::get_if<std::string>(&timeSyncMethod); 172*20e6ea5dSraviteja-b 173*20e6ea5dSraviteja-b if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP") 174*20e6ea5dSraviteja-b { 175*20e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 176*20e6ea5dSraviteja-b } 177*20e6ea5dSraviteja-b else if (*s == "xyz.openbmc_project.Time.Synchronization." 178*20e6ea5dSraviteja-b "Method.Manual") 179*20e6ea5dSraviteja-b { 180*20e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 181*20e6ea5dSraviteja-b } 182*20e6ea5dSraviteja-b }, 183*20e6ea5dSraviteja-b "xyz.openbmc_project.Settings", 184*20e6ea5dSraviteja-b "/xyz/openbmc_project/time/sync_method", 185*20e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Get", 186*20e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod"); 187*20e6ea5dSraviteja-b } 188*20e6ea5dSraviteja-b 1891abe55efSEd Tanous void getData(const std::shared_ptr<AsyncResp>& asyncResp) 1901abe55efSEd Tanous { 1910f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 1920f74e643SEd Tanous "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol"; 1930f74e643SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 1940f74e643SEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol"; 1950f74e643SEd Tanous asyncResp->res.jsonValue["@odata.context"] = 1960f74e643SEd Tanous "/redfish/v1/" 1970f74e643SEd Tanous "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol"; 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 2050f74e643SEd Tanous for (auto& protocol : protocolToDBus) 2060f74e643SEd Tanous { 2070f74e643SEd Tanous asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false; 2080f74e643SEd Tanous } 2090f74e643SEd Tanous 2100f74e643SEd Tanous asyncResp->res.jsonValue["HostName"] = getHostName(); 2113a8a0088SKowalski, Kamil 212*20e6ea5dSraviteja-b getNTPProtocolEnabled(asyncResp); 213*20e6ea5dSraviteja-b 214*20e6ea5dSraviteja-b // TODO Get eth0 interface data, and call the below callback for JSON 215*20e6ea5dSraviteja-b // preparation 216*20e6ea5dSraviteja-b getEthernetIfaceData( 217*20e6ea5dSraviteja-b [this, asyncResp](const bool& success, 218*20e6ea5dSraviteja-b const std::vector<std::string>& ntpServers) { 219*20e6ea5dSraviteja-b if (!success) 220*20e6ea5dSraviteja-b { 221*20e6ea5dSraviteja-b messages::resourceNotFound(asyncResp->res, 222*20e6ea5dSraviteja-b "EthernetInterface", "eth0"); 223*20e6ea5dSraviteja-b return; 224*20e6ea5dSraviteja-b } 225*20e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers; 226*20e6ea5dSraviteja-b }); 227*20e6ea5dSraviteja-b 228865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 229865fbb75SEd Tanous [asyncResp](const boost::system::error_code ec, 2303a8a0088SKowalski, Kamil const std::vector<UnitStruct>& resp) { 2311abe55efSEd Tanous if (ec) 2321abe55efSEd Tanous { 2333a8a0088SKowalski, Kamil asyncResp->res.jsonValue = nlohmann::json::object(); 234f12894f8SJason M. Bills messages::internalError(asyncResp->res); 235865fbb75SEd Tanous return; 2363a8a0088SKowalski, Kamil } 2373a8a0088SKowalski, Kamil 2381abe55efSEd Tanous for (auto& unit : resp) 2391abe55efSEd Tanous { 2401abe55efSEd Tanous for (auto& kv : protocolToDBus) 2411abe55efSEd Tanous { 2425ded8c79SJennifer Lee if (kv.second.serviceName != 2431abe55efSEd Tanous std::get<NET_PROTO_UNIT_NAME>(unit)) 2441abe55efSEd Tanous { 245865fbb75SEd Tanous continue; 24670141561SBorawski.Lukasz } 247865fbb75SEd Tanous const char* service = kv.first; 248865fbb75SEd Tanous const char* socketPath = kv.second.socketPath; 24970141561SBorawski.Lukasz 250865fbb75SEd Tanous asyncResp->res.jsonValue[service]["ProtocolEnabled"] = 2515ded8c79SJennifer Lee (std::get<NET_PROTO_UNIT_SUB_STATE>(unit) == 2525ded8c79SJennifer Lee "running") || 2535ded8c79SJennifer Lee (std::get<NET_PROTO_UNIT_SUB_STATE>(unit) == 2545ded8c79SJennifer Lee "listening"); 255865fbb75SEd Tanous 256865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 25743b761d0SEd Tanous [asyncResp, service{std::string(service)}]( 258865fbb75SEd Tanous const boost::system::error_code ec, 259abf2add6SEd Tanous const std::variant<std::vector<std::tuple< 260abf2add6SEd Tanous std::string, std::string>>>& resp) { 2611abe55efSEd Tanous if (ec) 2621abe55efSEd Tanous { 263a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 264865fbb75SEd Tanous return; 2653a8a0088SKowalski, Kamil } 266abf2add6SEd Tanous const std::vector< 267abf2add6SEd Tanous std::tuple<std::string, std::string>>* 268abf2add6SEd Tanous responsePtr = std::get_if<std::vector< 269abf2add6SEd Tanous std::tuple<std::string, std::string>>>( 2701b6b96c5SEd Tanous &resp); 2711abe55efSEd Tanous if (responsePtr == nullptr || 2721abe55efSEd Tanous responsePtr->size() < 1) 2731abe55efSEd Tanous { 274865fbb75SEd Tanous return; 27570141561SBorawski.Lukasz } 27670141561SBorawski.Lukasz 277865fbb75SEd Tanous const std::string& listenStream = 2781abe55efSEd Tanous std::get<NET_PROTO_LISTEN_STREAM>( 2791abe55efSEd Tanous (*responsePtr)[0]); 2801abe55efSEd Tanous std::size_t lastColonPos = 2811abe55efSEd Tanous listenStream.rfind(":"); 2821abe55efSEd Tanous if (lastColonPos == std::string::npos) 2831abe55efSEd Tanous { 284865fbb75SEd Tanous // Not a port 285865fbb75SEd Tanous return; 286865fbb75SEd Tanous } 2871abe55efSEd Tanous std::string portStr = 2881abe55efSEd Tanous listenStream.substr(lastColonPos + 1); 289865fbb75SEd Tanous char* endPtr = nullptr; 2901abe55efSEd Tanous // Use strtol instead of stroi to avoid 2911abe55efSEd Tanous // exceptions 2921abe55efSEd Tanous long port = 2931abe55efSEd Tanous std::strtol(portStr.c_str(), &endPtr, 10); 294865fbb75SEd Tanous 2951abe55efSEd Tanous if (*endPtr != '\0' || portStr.empty()) 2961abe55efSEd Tanous { 297865fbb75SEd Tanous // Invalid value 2981abe55efSEd Tanous asyncResp->res.jsonValue[service]["Port"] = 2991abe55efSEd Tanous nullptr; 3001abe55efSEd Tanous } 3011abe55efSEd Tanous else 3021abe55efSEd Tanous { 303865fbb75SEd Tanous // Everything OK 3041abe55efSEd Tanous asyncResp->res.jsonValue[service]["Port"] = 3051abe55efSEd Tanous port; 306865fbb75SEd Tanous } 307865fbb75SEd Tanous }, 308865fbb75SEd Tanous "org.freedesktop.systemd1", socketPath, 309865fbb75SEd Tanous "org.freedesktop.DBus.Properties", "Get", 310865fbb75SEd Tanous "org.freedesktop.systemd1.Socket", "Listen"); 311865fbb75SEd Tanous } 312865fbb75SEd Tanous } 313865fbb75SEd Tanous }, 314865fbb75SEd Tanous "org.freedesktop.systemd1", "/org/freedesktop/systemd1", 315865fbb75SEd Tanous "org.freedesktop.systemd1.Manager", "ListUnits"); 316865fbb75SEd Tanous } 317501be32bSraviteja-b 318501be32bSraviteja-b void handleHostnamePatch(const std::string& hostName, 319501be32bSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 320501be32bSraviteja-b { 321501be32bSraviteja-b crow::connections::systemBus->async_method_call( 322501be32bSraviteja-b [asyncResp](const boost::system::error_code ec) { 323501be32bSraviteja-b if (ec) 324501be32bSraviteja-b { 325501be32bSraviteja-b messages::internalError(asyncResp->res); 326501be32bSraviteja-b return; 327501be32bSraviteja-b } 328501be32bSraviteja-b messages::success(asyncResp->res); 329501be32bSraviteja-b }, 330501be32bSraviteja-b "xyz.openbmc_project.Network", 331501be32bSraviteja-b "/xyz/openbmc_project/network/config", 332501be32bSraviteja-b "org.freedesktop.DBus.Properties", "Set", 333501be32bSraviteja-b "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 334501be32bSraviteja-b std::variant<std::string>(hostName)); 335501be32bSraviteja-b } 336501be32bSraviteja-b 337*20e6ea5dSraviteja-b void handleNTPProtocolEnabled(const bool& ntpEnabled, 338*20e6ea5dSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 339*20e6ea5dSraviteja-b { 340*20e6ea5dSraviteja-b std::string timeSyncMethod; 341*20e6ea5dSraviteja-b if (ntpEnabled) 342*20e6ea5dSraviteja-b { 343*20e6ea5dSraviteja-b timeSyncMethod = 344*20e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 345*20e6ea5dSraviteja-b } 346*20e6ea5dSraviteja-b else 347*20e6ea5dSraviteja-b { 348*20e6ea5dSraviteja-b timeSyncMethod = 349*20e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 350*20e6ea5dSraviteja-b } 351*20e6ea5dSraviteja-b 352*20e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 353*20e6ea5dSraviteja-b [asyncResp, 354*20e6ea5dSraviteja-b ntpEnabled](const boost::system::error_code error_code) { 355*20e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = ntpEnabled; 356*20e6ea5dSraviteja-b }, 357*20e6ea5dSraviteja-b "xyz.openbmc_project.Settings", 358*20e6ea5dSraviteja-b "/xyz/openbmc_project/time/sync_method", 359*20e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 360*20e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 361*20e6ea5dSraviteja-b std::variant<std::string>{timeSyncMethod}); 362*20e6ea5dSraviteja-b } 363*20e6ea5dSraviteja-b 364*20e6ea5dSraviteja-b void handleNTPServersPatch(const std::vector<std::string>& ntpServers, 365*20e6ea5dSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 366*20e6ea5dSraviteja-b { 367*20e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 368*20e6ea5dSraviteja-b [asyncResp, ntpServers](const boost::system::error_code ec) { 369*20e6ea5dSraviteja-b if (ec) 370*20e6ea5dSraviteja-b { 371*20e6ea5dSraviteja-b messages::internalError(asyncResp->res); 372*20e6ea5dSraviteja-b return; 373*20e6ea5dSraviteja-b } 374*20e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = 375*20e6ea5dSraviteja-b std::move(ntpServers); 376*20e6ea5dSraviteja-b }, 377*20e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0", 378*20e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 379*20e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface", "NTPServers", 380*20e6ea5dSraviteja-b std::variant<std::vector<std::string>>{ntpServers}); 381*20e6ea5dSraviteja-b } 382*20e6ea5dSraviteja-b 383501be32bSraviteja-b void doPatch(crow::Response& res, const crow::Request& req, 384501be32bSraviteja-b const std::vector<std::string>& params) override 385501be32bSraviteja-b { 386501be32bSraviteja-b std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 387501be32bSraviteja-b std::optional<std::string> newHostName; 388*20e6ea5dSraviteja-b std::optional<std::vector<std::string>> ntpServers; 389*20e6ea5dSraviteja-b std::optional<bool> ntpEnabled; 390501be32bSraviteja-b 391*20e6ea5dSraviteja-b if (!json_util::readJson(req, res, "HostName", newHostName, 392*20e6ea5dSraviteja-b "NTPServers", ntpServers, "NTPEnabled", 393*20e6ea5dSraviteja-b ntpEnabled)) 394501be32bSraviteja-b { 395501be32bSraviteja-b return; 396501be32bSraviteja-b } 397501be32bSraviteja-b if (newHostName) 398501be32bSraviteja-b { 399501be32bSraviteja-b handleHostnamePatch(*newHostName, asyncResp); 400501be32bSraviteja-b return; 401501be32bSraviteja-b } 402*20e6ea5dSraviteja-b if (ntpEnabled) 403*20e6ea5dSraviteja-b { 404*20e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 405*20e6ea5dSraviteja-b } 406*20e6ea5dSraviteja-b if (ntpServers) 407*20e6ea5dSraviteja-b { 408*20e6ea5dSraviteja-b handleNTPServersPatch(*ntpServers, asyncResp); 409*20e6ea5dSraviteja-b } 410501be32bSraviteja-b } 41170141561SBorawski.Lukasz }; 41270141561SBorawski.Lukasz 41370141561SBorawski.Lukasz } // namespace redfish 414