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 2120e6ea5dSraviteja-b #include <optional> 2220e6ea5dSraviteja-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 55ec4974ddSAppaRao Puli const static boost::container::flat_map<const char*, std::string> 56ec4974ddSAppaRao Puli protocolToDBus{{"SSH", "dropbear"}, 57ec4974ddSAppaRao Puli {"HTTPS", "bmcweb"}, 58ec4974ddSAppaRao Puli {"IPMI", "phosphor-ipmi-net"}}; 593a8a0088SKowalski, Kamil 60d24bfc7aSJennifer Lee inline void 61d24bfc7aSJennifer Lee extractNTPServersAndDomainNamesData(const GetManagedObjects& dbus_data, 62d24bfc7aSJennifer Lee std::vector<std::string>& ntpData, 63d24bfc7aSJennifer Lee std::vector<std::string>& dnData) 6420e6ea5dSraviteja-b { 6520e6ea5dSraviteja-b for (const auto& obj : dbus_data) 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 = 79*8d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 8020e6ea5dSraviteja-b &propertyPair.second); 8120e6ea5dSraviteja-b if (ntpServers != nullptr) 8220e6ea5dSraviteja-b { 8320e6ea5dSraviteja-b ntpData = std::move(*ntpServers); 8420e6ea5dSraviteja-b } 8520e6ea5dSraviteja-b } 86d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName") 87d24bfc7aSJennifer Lee { 88d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames = 89*8d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 90d24bfc7aSJennifer Lee &propertyPair.second); 91d24bfc7aSJennifer Lee if (domainNames != nullptr) 92d24bfc7aSJennifer Lee { 93d24bfc7aSJennifer Lee dnData = std::move(*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)}]( 10820e6ea5dSraviteja-b const boost::system::error_code error_code, 10920e6ea5dSraviteja-b const GetManagedObjects& dbus_data) { 11020e6ea5dSraviteja-b std::vector<std::string> ntpServers; 111d24bfc7aSJennifer Lee std::vector<std::string> domainNames; 11220e6ea5dSraviteja-b 11320e6ea5dSraviteja-b if (error_code) 11420e6ea5dSraviteja-b { 115d24bfc7aSJennifer Lee callback(false, ntpServers, domainNames); 11620e6ea5dSraviteja-b return; 11720e6ea5dSraviteja-b } 11820e6ea5dSraviteja-b 119d24bfc7aSJennifer Lee extractNTPServersAndDomainNamesData(dbus_data, 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: 1311abe55efSEd Tanous NetworkProtocol(CrowApp& 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: 14455c7b7a2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 1451abe55efSEd Tanous const std::vector<std::string>& params) override 1461abe55efSEd Tanous { 1473a8a0088SKowalski, Kamil std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 1483a8a0088SKowalski, Kamil 1493a8a0088SKowalski, Kamil getData(asyncResp); 15070141561SBorawski.Lukasz } 15170141561SBorawski.Lukasz 1521abe55efSEd Tanous std::string getHostName() const 1531abe55efSEd Tanous { 15470141561SBorawski.Lukasz std::string hostName; 15570141561SBorawski.Lukasz 15670141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 1571abe55efSEd Tanous if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 1581abe55efSEd Tanous { 15970141561SBorawski.Lukasz hostName = hostNameCStr.data(); 16070141561SBorawski.Lukasz } 16170141561SBorawski.Lukasz return hostName; 16270141561SBorawski.Lukasz } 16370141561SBorawski.Lukasz 16420e6ea5dSraviteja-b void getNTPProtocolEnabled(const std::shared_ptr<AsyncResp>& asyncResp) 16520e6ea5dSraviteja-b { 16620e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 16720e6ea5dSraviteja-b [asyncResp](const boost::system::error_code error_code, 16820e6ea5dSraviteja-b const std::variant<std::string>& timeSyncMethod) { 16920e6ea5dSraviteja-b const std::string* s = 17020e6ea5dSraviteja-b std::get_if<std::string>(&timeSyncMethod); 17120e6ea5dSraviteja-b 17220e6ea5dSraviteja-b if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP") 17320e6ea5dSraviteja-b { 17420e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 17520e6ea5dSraviteja-b } 17620e6ea5dSraviteja-b else if (*s == "xyz.openbmc_project.Time.Synchronization." 17720e6ea5dSraviteja-b "Method.Manual") 17820e6ea5dSraviteja-b { 17920e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 18020e6ea5dSraviteja-b } 18120e6ea5dSraviteja-b }, 18220e6ea5dSraviteja-b "xyz.openbmc_project.Settings", 18320e6ea5dSraviteja-b "/xyz/openbmc_project/time/sync_method", 18420e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Get", 18520e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod"); 18620e6ea5dSraviteja-b } 18720e6ea5dSraviteja-b 1881abe55efSEd Tanous void getData(const std::shared_ptr<AsyncResp>& asyncResp) 1891abe55efSEd Tanous { 1900f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 19161932318SXiaochao Ma "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol"; 1920f74e643SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 1930f74e643SEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol"; 1940f74e643SEd Tanous asyncResp->res.jsonValue["Id"] = "NetworkProtocol"; 1950f74e643SEd Tanous asyncResp->res.jsonValue["Name"] = "Manager Network Protocol"; 1960f74e643SEd Tanous asyncResp->res.jsonValue["Description"] = "Manager Network Service"; 1970f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 1980f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK"; 1990f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 20061932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["ProtocolEnabled"] = true; 20161932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["Port"] = 161; 20261932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["AuthenticationProtocol"] = 20361932318SXiaochao Ma "CommunityString"; 20461932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["CommunityAccessMode"] = "Full"; 20561932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["HideCommunityStrings"] = true; 20661932318SXiaochao Ma asyncResp->res 20761932318SXiaochao Ma .jsonValue["SNMP"]["EngineId"]["EnterpriseSpecificMethod"] = 20861932318SXiaochao Ma nullptr; 20961932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EngineId"]["PrivateEnterpriseId"] = 21061932318SXiaochao Ma nullptr; 21161932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EnableSNMPv1"] = false; 21261932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EnableSNMPv2c"] = true; 21361932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EnableSNMPv3"] = false; 21461932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EncryptionProtocol"] = "None"; 21561932318SXiaochao Ma nlohmann::json& memberArray = 21661932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["CommunityStrings"]; 21761932318SXiaochao Ma memberArray = nlohmann::json::array(); 21861932318SXiaochao Ma memberArray.push_back({{"AccessMode", "Full"}}); 21961932318SXiaochao Ma memberArray.push_back({{"CommunityString", ""}}); 22061932318SXiaochao Ma memberArray.push_back({{"Name", ""}}); 2210f74e643SEd Tanous 22261932318SXiaochao Ma // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0, 223818ea7b8SJoshi-Mansi // but from security perspective it is not recommended to use. 224818ea7b8SJoshi-Mansi // Hence using protocolEnabled as false to make it OCP and security-wise 225818ea7b8SJoshi-Mansi // compliant 226818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["Port"] = 0; 227818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false; 228818ea7b8SJoshi-Mansi 2290f74e643SEd Tanous for (auto& protocol : protocolToDBus) 2300f74e643SEd Tanous { 2310f74e643SEd Tanous asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false; 2320f74e643SEd Tanous } 2330f74e643SEd Tanous 234d24bfc7aSJennifer Lee std::string hostName = getHostName(); 235d24bfc7aSJennifer Lee 236d24bfc7aSJennifer Lee asyncResp->res.jsonValue["HostName"] = hostName; 2373a8a0088SKowalski, Kamil 23820e6ea5dSraviteja-b getNTPProtocolEnabled(asyncResp); 23920e6ea5dSraviteja-b 24020e6ea5dSraviteja-b // TODO Get eth0 interface data, and call the below callback for JSON 24120e6ea5dSraviteja-b // preparation 242271584abSEd Tanous getEthernetIfaceData( 243271584abSEd Tanous [hostName, asyncResp](const bool& success, 244d24bfc7aSJennifer Lee const std::vector<std::string>& ntpServers, 245d24bfc7aSJennifer Lee const std::vector<std::string>& domainNames) { 24620e6ea5dSraviteja-b if (!success) 24720e6ea5dSraviteja-b { 248271584abSEd Tanous messages::resourceNotFound(asyncResp->res, 249271584abSEd Tanous "EthernetInterface", "eth0"); 25020e6ea5dSraviteja-b return; 25120e6ea5dSraviteja-b } 25220e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers; 253d24bfc7aSJennifer Lee if (hostName.empty() == false) 254d24bfc7aSJennifer Lee { 255749dad7dSRatan Gupta std::string FQDN = std::move(hostName); 256d24bfc7aSJennifer Lee if (domainNames.empty() == false) 257d24bfc7aSJennifer Lee { 258749dad7dSRatan Gupta FQDN += "." + domainNames[0]; 259d24bfc7aSJennifer Lee } 260749dad7dSRatan Gupta asyncResp->res.jsonValue["FQDN"] = std::move(FQDN); 261d24bfc7aSJennifer Lee } 26220e6ea5dSraviteja-b }); 26320e6ea5dSraviteja-b 264865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 265271584abSEd Tanous [asyncResp](const boost::system::error_code e, 266271584abSEd Tanous const std::vector<UnitStruct>& r) { 267271584abSEd Tanous if (e) 2681abe55efSEd Tanous { 2693a8a0088SKowalski, Kamil asyncResp->res.jsonValue = nlohmann::json::object(); 270f12894f8SJason M. Bills messages::internalError(asyncResp->res); 271865fbb75SEd Tanous return; 2723a8a0088SKowalski, Kamil } 2735968caeeSMarri Devender Rao asyncResp->res.jsonValue["HTTPS"]["Certificates"] = { 2745968caeeSMarri Devender Rao {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/" 275659dd62eSJason M. Bills "HTTPS/Certificates"}}; 2763a8a0088SKowalski, Kamil 277271584abSEd Tanous for (auto& unit : r) 2781abe55efSEd Tanous { 279ec4974ddSAppaRao Puli /* Only traverse through <xyz>.socket units */ 280ec4974ddSAppaRao Puli std::string unitName = std::get<NET_PROTO_UNIT_NAME>(unit); 281ec4974ddSAppaRao Puli if (!boost::ends_with(unitName, ".socket")) 2821abe55efSEd Tanous { 283865fbb75SEd Tanous continue; 28470141561SBorawski.Lukasz } 28570141561SBorawski.Lukasz 286ec4974ddSAppaRao Puli for (auto& kv : protocolToDBus) 287ec4974ddSAppaRao Puli { 288ec4974ddSAppaRao Puli // We are interested in services, which starts with 289ec4974ddSAppaRao Puli // mapped service name 290ec4974ddSAppaRao Puli if (!boost::starts_with(unitName, kv.second)) 291ec4974ddSAppaRao Puli { 292ec4974ddSAppaRao Puli continue; 293ec4974ddSAppaRao Puli } 294ec4974ddSAppaRao Puli const char* rfServiceKey = kv.first; 295ec4974ddSAppaRao Puli std::string socketPath = 296ec4974ddSAppaRao Puli std::get<NET_PROTO_UNIT_OBJ_PATH>(unit); 297ec4974ddSAppaRao Puli std::string unitState = 298ec4974ddSAppaRao Puli std::get<NET_PROTO_UNIT_SUB_STATE>(unit); 299ec4974ddSAppaRao Puli 300ec4974ddSAppaRao Puli asyncResp->res 301ec4974ddSAppaRao Puli .jsonValue[rfServiceKey]["ProtocolEnabled"] = 302ec4974ddSAppaRao Puli (unitState == "running") || 303ec4974ddSAppaRao Puli (unitState == "listening"); 304ec4974ddSAppaRao Puli 305865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 306ec4974ddSAppaRao Puli [asyncResp, 307ec4974ddSAppaRao Puli rfServiceKey{std::string(rfServiceKey)}]( 308865fbb75SEd Tanous const boost::system::error_code ec, 309abf2add6SEd Tanous const std::variant<std::vector<std::tuple< 310abf2add6SEd Tanous std::string, std::string>>>& resp) { 3111abe55efSEd Tanous if (ec) 3121abe55efSEd Tanous { 313a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 314865fbb75SEd Tanous return; 3153a8a0088SKowalski, Kamil } 316abf2add6SEd Tanous const std::vector< 317abf2add6SEd Tanous std::tuple<std::string, std::string>>* 318abf2add6SEd Tanous responsePtr = std::get_if<std::vector< 319abf2add6SEd Tanous std::tuple<std::string, std::string>>>( 3201b6b96c5SEd Tanous &resp); 3211abe55efSEd Tanous if (responsePtr == nullptr || 3221abe55efSEd Tanous responsePtr->size() < 1) 3231abe55efSEd Tanous { 324865fbb75SEd Tanous return; 32570141561SBorawski.Lukasz } 32670141561SBorawski.Lukasz 327865fbb75SEd Tanous const std::string& listenStream = 3281abe55efSEd Tanous std::get<NET_PROTO_LISTEN_STREAM>( 3291abe55efSEd Tanous (*responsePtr)[0]); 3301abe55efSEd Tanous std::size_t lastColonPos = 3311abe55efSEd Tanous listenStream.rfind(":"); 3321abe55efSEd Tanous if (lastColonPos == std::string::npos) 3331abe55efSEd Tanous { 334865fbb75SEd Tanous // Not a port 335865fbb75SEd Tanous return; 336865fbb75SEd Tanous } 3371abe55efSEd Tanous std::string portStr = 3381abe55efSEd Tanous listenStream.substr(lastColonPos + 1); 339ec4974ddSAppaRao Puli if (portStr.empty()) 340ec4974ddSAppaRao Puli { 341ec4974ddSAppaRao Puli return; 342ec4974ddSAppaRao Puli } 343865fbb75SEd Tanous char* endPtr = nullptr; 344ec4974ddSAppaRao Puli errno = 0; 3451abe55efSEd Tanous // Use strtol instead of stroi to avoid 3461abe55efSEd Tanous // exceptions 3471abe55efSEd Tanous long port = 3481abe55efSEd Tanous std::strtol(portStr.c_str(), &endPtr, 10); 349ec4974ddSAppaRao Puli if ((errno == 0) && (*endPtr == '\0')) 3501abe55efSEd Tanous { 351ec4974ddSAppaRao Puli asyncResp->res 352ec4974ddSAppaRao Puli .jsonValue[rfServiceKey]["Port"] = port; 3531abe55efSEd Tanous } 354ec4974ddSAppaRao Puli return; 355865fbb75SEd Tanous }, 356865fbb75SEd Tanous "org.freedesktop.systemd1", socketPath, 357865fbb75SEd Tanous "org.freedesktop.DBus.Properties", "Get", 358865fbb75SEd Tanous "org.freedesktop.systemd1.Socket", "Listen"); 359ec4974ddSAppaRao Puli 360ec4974ddSAppaRao Puli // We found service, break the inner loop. 361ec4974ddSAppaRao Puli break; 362865fbb75SEd Tanous } 363865fbb75SEd Tanous } 364865fbb75SEd Tanous }, 365865fbb75SEd Tanous "org.freedesktop.systemd1", "/org/freedesktop/systemd1", 366865fbb75SEd Tanous "org.freedesktop.systemd1.Manager", "ListUnits"); 367865fbb75SEd Tanous } 368501be32bSraviteja-b 369501be32bSraviteja-b void handleHostnamePatch(const std::string& hostName, 370501be32bSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 371501be32bSraviteja-b { 372501be32bSraviteja-b crow::connections::systemBus->async_method_call( 373501be32bSraviteja-b [asyncResp](const boost::system::error_code ec) { 374501be32bSraviteja-b if (ec) 375501be32bSraviteja-b { 376501be32bSraviteja-b messages::internalError(asyncResp->res); 377501be32bSraviteja-b return; 378501be32bSraviteja-b } 379501be32bSraviteja-b }, 380501be32bSraviteja-b "xyz.openbmc_project.Network", 381501be32bSraviteja-b "/xyz/openbmc_project/network/config", 382501be32bSraviteja-b "org.freedesktop.DBus.Properties", "Set", 383501be32bSraviteja-b "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 384501be32bSraviteja-b std::variant<std::string>(hostName)); 385501be32bSraviteja-b } 386501be32bSraviteja-b 38720e6ea5dSraviteja-b void handleNTPProtocolEnabled(const bool& ntpEnabled, 38820e6ea5dSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 38920e6ea5dSraviteja-b { 39020e6ea5dSraviteja-b std::string timeSyncMethod; 39120e6ea5dSraviteja-b if (ntpEnabled) 39220e6ea5dSraviteja-b { 39320e6ea5dSraviteja-b timeSyncMethod = 39420e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 39520e6ea5dSraviteja-b } 39620e6ea5dSraviteja-b else 39720e6ea5dSraviteja-b { 39820e6ea5dSraviteja-b timeSyncMethod = 39920e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 40020e6ea5dSraviteja-b } 40120e6ea5dSraviteja-b 40220e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 403cf05f9dcSJohnathan Mantey [asyncResp](const boost::system::error_code error_code) {}, 40420e6ea5dSraviteja-b "xyz.openbmc_project.Settings", 40520e6ea5dSraviteja-b "/xyz/openbmc_project/time/sync_method", 40620e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 40720e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 40820e6ea5dSraviteja-b std::variant<std::string>{timeSyncMethod}); 40920e6ea5dSraviteja-b } 41020e6ea5dSraviteja-b 41120e6ea5dSraviteja-b void handleNTPServersPatch(const std::vector<std::string>& ntpServers, 41220e6ea5dSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 41320e6ea5dSraviteja-b { 41420e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 415cf05f9dcSJohnathan Mantey [asyncResp](const boost::system::error_code ec) { 41620e6ea5dSraviteja-b if (ec) 41720e6ea5dSraviteja-b { 41820e6ea5dSraviteja-b messages::internalError(asyncResp->res); 41920e6ea5dSraviteja-b return; 42020e6ea5dSraviteja-b } 42120e6ea5dSraviteja-b }, 42220e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0", 42320e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 42420e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface", "NTPServers", 42520e6ea5dSraviteja-b std::variant<std::vector<std::string>>{ntpServers}); 42620e6ea5dSraviteja-b } 42720e6ea5dSraviteja-b 428501be32bSraviteja-b void doPatch(crow::Response& res, const crow::Request& req, 429501be32bSraviteja-b const std::vector<std::string>& params) override 430501be32bSraviteja-b { 431501be32bSraviteja-b std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 432501be32bSraviteja-b std::optional<std::string> newHostName; 433cf05f9dcSJohnathan Mantey std::optional<nlohmann::json> ntp; 434501be32bSraviteja-b 435cf05f9dcSJohnathan Mantey if (!json_util::readJson(req, res, "HostName", newHostName, "NTP", ntp)) 436501be32bSraviteja-b { 437501be32bSraviteja-b return; 438501be32bSraviteja-b } 439cf05f9dcSJohnathan Mantey 440cf05f9dcSJohnathan Mantey res.result(boost::beast::http::status::no_content); 441501be32bSraviteja-b if (newHostName) 442501be32bSraviteja-b { 443501be32bSraviteja-b handleHostnamePatch(*newHostName, asyncResp); 444cf05f9dcSJohnathan Mantey } 445cf05f9dcSJohnathan Mantey 446cf05f9dcSJohnathan Mantey if (ntp) 447cf05f9dcSJohnathan Mantey { 448cf05f9dcSJohnathan Mantey std::optional<std::vector<std::string>> ntpServers; 449cf05f9dcSJohnathan Mantey std::optional<bool> ntpEnabled; 450cf05f9dcSJohnathan Mantey if (!json_util::readJson(*ntp, res, "NTPServers", ntpServers, 451cf05f9dcSJohnathan Mantey "ProtocolEnabled", ntpEnabled)) 452cf05f9dcSJohnathan Mantey { 453501be32bSraviteja-b return; 454501be32bSraviteja-b } 455cf05f9dcSJohnathan Mantey 45620e6ea5dSraviteja-b if (ntpEnabled) 45720e6ea5dSraviteja-b { 45820e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 45920e6ea5dSraviteja-b } 460cf05f9dcSJohnathan Mantey 46120e6ea5dSraviteja-b if (ntpServers) 46220e6ea5dSraviteja-b { 46320e6ea5dSraviteja-b handleNTPServersPatch(*ntpServers, asyncResp); 46420e6ea5dSraviteja-b } 465501be32bSraviteja-b } 466cf05f9dcSJohnathan Mantey } 46770141561SBorawski.Lukasz }; 46870141561SBorawski.Lukasz 46970141561SBorawski.Lukasz } // namespace redfish 470