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 57ec4974ddSAppaRao Puli const static boost::container::flat_map<const char*, std::string> 58ec4974ddSAppaRao Puli protocolToDBus{{"SSH", "dropbear"}, 59ec4974ddSAppaRao Puli {"HTTPS", "bmcweb"}, 60ec4974ddSAppaRao Puli {"IPMI", "phosphor-ipmi-net"}}; 613a8a0088SKowalski, Kamil 62d24bfc7aSJennifer Lee inline void 63d24bfc7aSJennifer Lee extractNTPServersAndDomainNamesData(const GetManagedObjects& dbus_data, 64d24bfc7aSJennifer Lee std::vector<std::string>& ntpData, 65d24bfc7aSJennifer Lee std::vector<std::string>& dnData) 6620e6ea5dSraviteja-b { 6720e6ea5dSraviteja-b for (const auto& obj : dbus_data) 6820e6ea5dSraviteja-b { 6920e6ea5dSraviteja-b for (const auto& ifacePair : obj.second) 7020e6ea5dSraviteja-b { 7120e6ea5dSraviteja-b if (obj.first == "/xyz/openbmc_project/network/eth0") 7220e6ea5dSraviteja-b { 7320e6ea5dSraviteja-b if (ifacePair.first == 7420e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface") 7520e6ea5dSraviteja-b { 7620e6ea5dSraviteja-b for (const auto& propertyPair : ifacePair.second) 7720e6ea5dSraviteja-b { 7820e6ea5dSraviteja-b if (propertyPair.first == "NTPServers") 7920e6ea5dSraviteja-b { 8020e6ea5dSraviteja-b const std::vector<std::string>* ntpServers = 818d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 8220e6ea5dSraviteja-b &propertyPair.second); 8320e6ea5dSraviteja-b if (ntpServers != nullptr) 8420e6ea5dSraviteja-b { 8520e6ea5dSraviteja-b ntpData = std::move(*ntpServers); 8620e6ea5dSraviteja-b } 8720e6ea5dSraviteja-b } 88d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName") 89d24bfc7aSJennifer Lee { 90d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames = 918d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 92d24bfc7aSJennifer Lee &propertyPair.second); 93d24bfc7aSJennifer Lee if (domainNames != nullptr) 94d24bfc7aSJennifer Lee { 95d24bfc7aSJennifer Lee dnData = std::move(*domainNames); 96d24bfc7aSJennifer Lee } 97d24bfc7aSJennifer Lee } 9820e6ea5dSraviteja-b } 9920e6ea5dSraviteja-b } 10020e6ea5dSraviteja-b } 10120e6ea5dSraviteja-b } 10220e6ea5dSraviteja-b } 10320e6ea5dSraviteja-b } 10420e6ea5dSraviteja-b 10520e6ea5dSraviteja-b template <typename CallbackFunc> 10620e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback) 10720e6ea5dSraviteja-b { 10820e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 10920e6ea5dSraviteja-b [callback{std::move(callback)}]( 11020e6ea5dSraviteja-b const boost::system::error_code error_code, 11120e6ea5dSraviteja-b const GetManagedObjects& dbus_data) { 11220e6ea5dSraviteja-b std::vector<std::string> ntpServers; 113d24bfc7aSJennifer Lee std::vector<std::string> domainNames; 11420e6ea5dSraviteja-b 11520e6ea5dSraviteja-b if (error_code) 11620e6ea5dSraviteja-b { 117d24bfc7aSJennifer Lee callback(false, ntpServers, domainNames); 11820e6ea5dSraviteja-b return; 11920e6ea5dSraviteja-b } 12020e6ea5dSraviteja-b 121d24bfc7aSJennifer Lee extractNTPServersAndDomainNamesData(dbus_data, ntpServers, 122d24bfc7aSJennifer Lee domainNames); 12320e6ea5dSraviteja-b 124d24bfc7aSJennifer Lee callback(true, ntpServers, domainNames); 12520e6ea5dSraviteja-b }, 12620e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", 12720e6ea5dSraviteja-b "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 128271584abSEd Tanous } 12920e6ea5dSraviteja-b 1301abe55efSEd Tanous class NetworkProtocol : public Node 1311abe55efSEd Tanous { 13270141561SBorawski.Lukasz public: 13352cc112dSEd Tanous NetworkProtocol(App& app) : 1347af91514SGunnar Mills Node(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 1351abe55efSEd Tanous { 1364b1b8683SBorawski.Lukasz entityPrivileges = { 1374b1b8683SBorawski.Lukasz {boost::beast::http::verb::get, {{"Login"}}}, 138e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 139e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 140e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 141e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 142e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 14370141561SBorawski.Lukasz } 14470141561SBorawski.Lukasz 14570141561SBorawski.Lukasz private: 146*cb13a392SEd Tanous void doGet(crow::Response& res, const crow::Request&, 147*cb13a392SEd Tanous const std::vector<std::string>&) override 1481abe55efSEd Tanous { 1493a8a0088SKowalski, Kamil std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 1503a8a0088SKowalski, Kamil 1513a8a0088SKowalski, Kamil getData(asyncResp); 15270141561SBorawski.Lukasz } 15370141561SBorawski.Lukasz 1541abe55efSEd Tanous std::string getHostName() const 1551abe55efSEd Tanous { 15670141561SBorawski.Lukasz std::string hostName; 15770141561SBorawski.Lukasz 15870141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 1591abe55efSEd Tanous if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 1601abe55efSEd Tanous { 16170141561SBorawski.Lukasz hostName = hostNameCStr.data(); 16270141561SBorawski.Lukasz } 16370141561SBorawski.Lukasz return hostName; 16470141561SBorawski.Lukasz } 16570141561SBorawski.Lukasz 16620e6ea5dSraviteja-b void getNTPProtocolEnabled(const std::shared_ptr<AsyncResp>& asyncResp) 16720e6ea5dSraviteja-b { 16820e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 16920e6ea5dSraviteja-b [asyncResp](const boost::system::error_code error_code, 17020e6ea5dSraviteja-b const std::variant<std::string>& timeSyncMethod) { 171*cb13a392SEd Tanous if (error_code) 172*cb13a392SEd Tanous { 173*cb13a392SEd Tanous return; 174*cb13a392SEd Tanous } 175*cb13a392SEd Tanous 17620e6ea5dSraviteja-b const std::string* s = 17720e6ea5dSraviteja-b std::get_if<std::string>(&timeSyncMethod); 17820e6ea5dSraviteja-b 17920e6ea5dSraviteja-b if (*s == "xyz.openbmc_project.Time.Synchronization.Method.NTP") 18020e6ea5dSraviteja-b { 18120e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 18220e6ea5dSraviteja-b } 18320e6ea5dSraviteja-b else if (*s == "xyz.openbmc_project.Time.Synchronization." 18420e6ea5dSraviteja-b "Method.Manual") 18520e6ea5dSraviteja-b { 18620e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 18720e6ea5dSraviteja-b } 18820e6ea5dSraviteja-b }, 18920e6ea5dSraviteja-b "xyz.openbmc_project.Settings", 19020e6ea5dSraviteja-b "/xyz/openbmc_project/time/sync_method", 19120e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Get", 19220e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod"); 19320e6ea5dSraviteja-b } 19420e6ea5dSraviteja-b 1951abe55efSEd Tanous void getData(const std::shared_ptr<AsyncResp>& asyncResp) 1961abe55efSEd Tanous { 1970f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 19861932318SXiaochao Ma "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol"; 1990f74e643SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 2000f74e643SEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol"; 2010f74e643SEd Tanous asyncResp->res.jsonValue["Id"] = "NetworkProtocol"; 2020f74e643SEd Tanous asyncResp->res.jsonValue["Name"] = "Manager Network Protocol"; 2030f74e643SEd Tanous asyncResp->res.jsonValue["Description"] = "Manager Network Service"; 2040f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 2050f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK"; 2060f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 20761932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["ProtocolEnabled"] = true; 20861932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["Port"] = 161; 20961932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["AuthenticationProtocol"] = 21061932318SXiaochao Ma "CommunityString"; 21161932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["CommunityAccessMode"] = "Full"; 21261932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["HideCommunityStrings"] = true; 21361932318SXiaochao Ma asyncResp->res 21461932318SXiaochao Ma .jsonValue["SNMP"]["EngineId"]["EnterpriseSpecificMethod"] = 21561932318SXiaochao Ma nullptr; 21661932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EngineId"]["PrivateEnterpriseId"] = 21761932318SXiaochao Ma nullptr; 21861932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EnableSNMPv1"] = false; 21961932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EnableSNMPv2c"] = true; 22061932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EnableSNMPv3"] = false; 22161932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["EncryptionProtocol"] = "None"; 22261932318SXiaochao Ma nlohmann::json& memberArray = 22361932318SXiaochao Ma asyncResp->res.jsonValue["SNMP"]["CommunityStrings"]; 22461932318SXiaochao Ma memberArray = nlohmann::json::array(); 22561932318SXiaochao Ma memberArray.push_back({{"AccessMode", "Full"}}); 22661932318SXiaochao Ma memberArray.push_back({{"CommunityString", ""}}); 22761932318SXiaochao Ma memberArray.push_back({{"Name", ""}}); 2280f74e643SEd Tanous 22961932318SXiaochao Ma // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0, 230818ea7b8SJoshi-Mansi // but from security perspective it is not recommended to use. 231818ea7b8SJoshi-Mansi // Hence using protocolEnabled as false to make it OCP and security-wise 232818ea7b8SJoshi-Mansi // compliant 233818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["Port"] = 0; 234818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false; 235818ea7b8SJoshi-Mansi 2360f74e643SEd Tanous for (auto& protocol : protocolToDBus) 2370f74e643SEd Tanous { 2380870f8c7SJayaprakash Mutyala asyncResp->res.jsonValue[protocol.first]["Port"] = 2390870f8c7SJayaprakash Mutyala nlohmann::detail::value_t::null; 2400f74e643SEd Tanous asyncResp->res.jsonValue[protocol.first]["ProtocolEnabled"] = false; 2410f74e643SEd Tanous } 2420f74e643SEd Tanous 243d24bfc7aSJennifer Lee std::string hostName = getHostName(); 244d24bfc7aSJennifer Lee 245d24bfc7aSJennifer Lee asyncResp->res.jsonValue["HostName"] = hostName; 2463a8a0088SKowalski, Kamil 24720e6ea5dSraviteja-b getNTPProtocolEnabled(asyncResp); 24820e6ea5dSraviteja-b 24920e6ea5dSraviteja-b // TODO Get eth0 interface data, and call the below callback for JSON 25020e6ea5dSraviteja-b // preparation 251271584abSEd Tanous getEthernetIfaceData( 252271584abSEd Tanous [hostName, asyncResp](const bool& success, 253d24bfc7aSJennifer Lee const std::vector<std::string>& ntpServers, 254d24bfc7aSJennifer Lee const std::vector<std::string>& domainNames) { 25520e6ea5dSraviteja-b if (!success) 25620e6ea5dSraviteja-b { 257271584abSEd Tanous messages::resourceNotFound(asyncResp->res, 258271584abSEd Tanous "EthernetInterface", "eth0"); 25920e6ea5dSraviteja-b return; 26020e6ea5dSraviteja-b } 26120e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers; 262d24bfc7aSJennifer Lee if (hostName.empty() == false) 263d24bfc7aSJennifer Lee { 264749dad7dSRatan Gupta std::string FQDN = std::move(hostName); 265d24bfc7aSJennifer Lee if (domainNames.empty() == false) 266d24bfc7aSJennifer Lee { 267749dad7dSRatan Gupta FQDN += "." + domainNames[0]; 268d24bfc7aSJennifer Lee } 269749dad7dSRatan Gupta asyncResp->res.jsonValue["FQDN"] = std::move(FQDN); 270d24bfc7aSJennifer Lee } 27120e6ea5dSraviteja-b }); 27220e6ea5dSraviteja-b 273865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 274271584abSEd Tanous [asyncResp](const boost::system::error_code e, 275271584abSEd Tanous const std::vector<UnitStruct>& r) { 276271584abSEd Tanous if (e) 2771abe55efSEd Tanous { 2783a8a0088SKowalski, Kamil asyncResp->res.jsonValue = nlohmann::json::object(); 279f12894f8SJason M. Bills messages::internalError(asyncResp->res); 280865fbb75SEd Tanous return; 2813a8a0088SKowalski, Kamil } 2825968caeeSMarri Devender Rao asyncResp->res.jsonValue["HTTPS"]["Certificates"] = { 2835968caeeSMarri Devender Rao {"@odata.id", "/redfish/v1/Managers/bmc/NetworkProtocol/" 284659dd62eSJason M. Bills "HTTPS/Certificates"}}; 2853a8a0088SKowalski, Kamil 286271584abSEd Tanous for (auto& unit : r) 2871abe55efSEd Tanous { 288ec4974ddSAppaRao Puli /* Only traverse through <xyz>.socket units */ 289ec4974ddSAppaRao Puli std::string unitName = std::get<NET_PROTO_UNIT_NAME>(unit); 290ec4974ddSAppaRao Puli if (!boost::ends_with(unitName, ".socket")) 2911abe55efSEd Tanous { 292865fbb75SEd Tanous continue; 29370141561SBorawski.Lukasz } 29470141561SBorawski.Lukasz 295ec4974ddSAppaRao Puli for (auto& kv : protocolToDBus) 296ec4974ddSAppaRao Puli { 297ec4974ddSAppaRao Puli // We are interested in services, which starts with 298ec4974ddSAppaRao Puli // mapped service name 299ec4974ddSAppaRao Puli if (!boost::starts_with(unitName, kv.second)) 300ec4974ddSAppaRao Puli { 301ec4974ddSAppaRao Puli continue; 302ec4974ddSAppaRao Puli } 303ec4974ddSAppaRao Puli const char* rfServiceKey = kv.first; 304ec4974ddSAppaRao Puli std::string socketPath = 305ec4974ddSAppaRao Puli std::get<NET_PROTO_UNIT_OBJ_PATH>(unit); 306ec4974ddSAppaRao Puli std::string unitState = 307ec4974ddSAppaRao Puli std::get<NET_PROTO_UNIT_SUB_STATE>(unit); 308ec4974ddSAppaRao Puli 309ec4974ddSAppaRao Puli asyncResp->res 310ec4974ddSAppaRao Puli .jsonValue[rfServiceKey]["ProtocolEnabled"] = 311ec4974ddSAppaRao Puli (unitState == "running") || 312ec4974ddSAppaRao Puli (unitState == "listening"); 313ec4974ddSAppaRao Puli 314865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 315ec4974ddSAppaRao Puli [asyncResp, 316ec4974ddSAppaRao Puli rfServiceKey{std::string(rfServiceKey)}]( 317865fbb75SEd Tanous const boost::system::error_code ec, 318abf2add6SEd Tanous const std::variant<std::vector<std::tuple< 319abf2add6SEd Tanous std::string, std::string>>>& resp) { 3201abe55efSEd Tanous if (ec) 3211abe55efSEd Tanous { 322a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 323865fbb75SEd Tanous return; 3243a8a0088SKowalski, Kamil } 325abf2add6SEd Tanous const std::vector< 326abf2add6SEd Tanous std::tuple<std::string, std::string>>* 327abf2add6SEd Tanous responsePtr = std::get_if<std::vector< 328abf2add6SEd Tanous std::tuple<std::string, std::string>>>( 3291b6b96c5SEd Tanous &resp); 3301abe55efSEd Tanous if (responsePtr == nullptr || 3311abe55efSEd Tanous responsePtr->size() < 1) 3321abe55efSEd Tanous { 333865fbb75SEd Tanous return; 33470141561SBorawski.Lukasz } 33570141561SBorawski.Lukasz 336865fbb75SEd Tanous const std::string& listenStream = 3371abe55efSEd Tanous std::get<NET_PROTO_LISTEN_STREAM>( 3381abe55efSEd Tanous (*responsePtr)[0]); 3391abe55efSEd Tanous std::size_t lastColonPos = 3401abe55efSEd Tanous listenStream.rfind(":"); 3411abe55efSEd Tanous if (lastColonPos == std::string::npos) 3421abe55efSEd Tanous { 343865fbb75SEd Tanous // Not a port 344865fbb75SEd Tanous return; 345865fbb75SEd Tanous } 3461abe55efSEd Tanous std::string portStr = 3471abe55efSEd Tanous listenStream.substr(lastColonPos + 1); 348ec4974ddSAppaRao Puli if (portStr.empty()) 349ec4974ddSAppaRao Puli { 350ec4974ddSAppaRao Puli return; 351ec4974ddSAppaRao Puli } 352865fbb75SEd Tanous char* endPtr = nullptr; 353ec4974ddSAppaRao Puli errno = 0; 3541abe55efSEd Tanous // Use strtol instead of stroi to avoid 3551abe55efSEd Tanous // exceptions 3561abe55efSEd Tanous long port = 3571abe55efSEd Tanous std::strtol(portStr.c_str(), &endPtr, 10); 358ec4974ddSAppaRao Puli if ((errno == 0) && (*endPtr == '\0')) 3591abe55efSEd Tanous { 360ec4974ddSAppaRao Puli asyncResp->res 361ec4974ddSAppaRao Puli .jsonValue[rfServiceKey]["Port"] = port; 3621abe55efSEd Tanous } 363ec4974ddSAppaRao Puli return; 364865fbb75SEd Tanous }, 365865fbb75SEd Tanous "org.freedesktop.systemd1", socketPath, 366865fbb75SEd Tanous "org.freedesktop.DBus.Properties", "Get", 367865fbb75SEd Tanous "org.freedesktop.systemd1.Socket", "Listen"); 368ec4974ddSAppaRao Puli 369ec4974ddSAppaRao Puli // We found service, break the inner loop. 370ec4974ddSAppaRao Puli break; 371865fbb75SEd Tanous } 372865fbb75SEd Tanous } 373865fbb75SEd Tanous }, 374865fbb75SEd Tanous "org.freedesktop.systemd1", "/org/freedesktop/systemd1", 375865fbb75SEd Tanous "org.freedesktop.systemd1.Manager", "ListUnits"); 376865fbb75SEd Tanous } 377501be32bSraviteja-b 378501be32bSraviteja-b void handleHostnamePatch(const std::string& hostName, 379501be32bSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 380501be32bSraviteja-b { 381501be32bSraviteja-b crow::connections::systemBus->async_method_call( 382501be32bSraviteja-b [asyncResp](const boost::system::error_code ec) { 383501be32bSraviteja-b if (ec) 384501be32bSraviteja-b { 385501be32bSraviteja-b messages::internalError(asyncResp->res); 386501be32bSraviteja-b return; 387501be32bSraviteja-b } 388501be32bSraviteja-b }, 389501be32bSraviteja-b "xyz.openbmc_project.Network", 390501be32bSraviteja-b "/xyz/openbmc_project/network/config", 391501be32bSraviteja-b "org.freedesktop.DBus.Properties", "Set", 392501be32bSraviteja-b "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 393501be32bSraviteja-b std::variant<std::string>(hostName)); 394501be32bSraviteja-b } 395501be32bSraviteja-b 39620e6ea5dSraviteja-b void handleNTPProtocolEnabled(const bool& ntpEnabled, 39720e6ea5dSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 39820e6ea5dSraviteja-b { 39920e6ea5dSraviteja-b std::string timeSyncMethod; 40020e6ea5dSraviteja-b if (ntpEnabled) 40120e6ea5dSraviteja-b { 40220e6ea5dSraviteja-b timeSyncMethod = 40320e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 40420e6ea5dSraviteja-b } 40520e6ea5dSraviteja-b else 40620e6ea5dSraviteja-b { 40720e6ea5dSraviteja-b timeSyncMethod = 40820e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 40920e6ea5dSraviteja-b } 41020e6ea5dSraviteja-b 41120e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 412*cb13a392SEd Tanous [asyncResp](const boost::system::error_code error_code) { 413*cb13a392SEd Tanous if (error_code) 414*cb13a392SEd Tanous { 415*cb13a392SEd Tanous messages::internalError(asyncResp->res); 416*cb13a392SEd Tanous } 417*cb13a392SEd Tanous }, 41820e6ea5dSraviteja-b "xyz.openbmc_project.Settings", 41920e6ea5dSraviteja-b "/xyz/openbmc_project/time/sync_method", 42020e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 42120e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 42220e6ea5dSraviteja-b std::variant<std::string>{timeSyncMethod}); 42320e6ea5dSraviteja-b } 42420e6ea5dSraviteja-b 42520e6ea5dSraviteja-b void handleNTPServersPatch(const std::vector<std::string>& ntpServers, 42620e6ea5dSraviteja-b const std::shared_ptr<AsyncResp>& asyncResp) 42720e6ea5dSraviteja-b { 42820e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 429cf05f9dcSJohnathan Mantey [asyncResp](const boost::system::error_code ec) { 43020e6ea5dSraviteja-b if (ec) 43120e6ea5dSraviteja-b { 43220e6ea5dSraviteja-b messages::internalError(asyncResp->res); 43320e6ea5dSraviteja-b return; 43420e6ea5dSraviteja-b } 43520e6ea5dSraviteja-b }, 43620e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network/eth0", 43720e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 43820e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface", "NTPServers", 43920e6ea5dSraviteja-b std::variant<std::vector<std::string>>{ntpServers}); 44020e6ea5dSraviteja-b } 44120e6ea5dSraviteja-b 44267a78d87STom Joseph void handleIpmiProtocolEnabled(const bool ipmiProtocolEnabled, 44367a78d87STom Joseph const std::shared_ptr<AsyncResp>& asyncResp) 44467a78d87STom Joseph { 44567a78d87STom Joseph crow::connections::systemBus->async_method_call( 44667a78d87STom Joseph [ipmiProtocolEnabled, 44767a78d87STom Joseph asyncResp](const boost::system::error_code ec, 44867a78d87STom Joseph const crow::openbmc_mapper::GetSubTreeType& subtree) { 44967a78d87STom Joseph if (ec) 45067a78d87STom Joseph { 45167a78d87STom Joseph messages::internalError(asyncResp->res); 45267a78d87STom Joseph return; 45367a78d87STom Joseph } 45467a78d87STom Joseph 45567a78d87STom Joseph constexpr char const* netipmidBasePath = 45667a78d87STom Joseph "/xyz/openbmc_project/control/service/" 45767a78d87STom Joseph "phosphor_2dipmi_2dnet_40"; 45867a78d87STom Joseph 45967a78d87STom Joseph for (const auto& entry : subtree) 46067a78d87STom Joseph { 46167a78d87STom Joseph if (boost::algorithm::starts_with(entry.first, 46267a78d87STom Joseph netipmidBasePath)) 46367a78d87STom Joseph { 46467a78d87STom Joseph crow::connections::systemBus->async_method_call( 46523a21a1cSEd Tanous [asyncResp](const boost::system::error_code ec2) { 46623a21a1cSEd Tanous if (ec2) 46767a78d87STom Joseph { 46867a78d87STom Joseph messages::internalError(asyncResp->res); 46967a78d87STom Joseph return; 47067a78d87STom Joseph } 47167a78d87STom Joseph }, 47267a78d87STom Joseph entry.second.begin()->first, entry.first, 47367a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 47467a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes", 47567a78d87STom Joseph "Running", std::variant<bool>{ipmiProtocolEnabled}); 47667a78d87STom Joseph 47767a78d87STom Joseph crow::connections::systemBus->async_method_call( 47823a21a1cSEd Tanous [asyncResp](const boost::system::error_code ec2) { 47923a21a1cSEd Tanous if (ec2) 48067a78d87STom Joseph { 48167a78d87STom Joseph messages::internalError(asyncResp->res); 48267a78d87STom Joseph return; 48367a78d87STom Joseph } 48467a78d87STom Joseph }, 48567a78d87STom Joseph entry.second.begin()->first, entry.first, 48667a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 48767a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes", 48867a78d87STom Joseph "Enabled", std::variant<bool>{ipmiProtocolEnabled}); 48967a78d87STom Joseph } 49067a78d87STom Joseph } 49167a78d87STom Joseph }, 49267a78d87STom Joseph "xyz.openbmc_project.ObjectMapper", 49367a78d87STom Joseph "/xyz/openbmc_project/object_mapper", 49467a78d87STom Joseph "xyz.openbmc_project.ObjectMapper", "GetSubTree", 49567a78d87STom Joseph "/xyz/openbmc_project/control/service", 0, 49667a78d87STom Joseph std::array<const char*, 1>{ 49767a78d87STom Joseph "xyz.openbmc_project.Control.Service.Attributes"}); 49867a78d87STom Joseph } 49967a78d87STom Joseph 500501be32bSraviteja-b void doPatch(crow::Response& res, const crow::Request& req, 501*cb13a392SEd Tanous const std::vector<std::string>&) override 502501be32bSraviteja-b { 503501be32bSraviteja-b std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 504501be32bSraviteja-b std::optional<std::string> newHostName; 505cf05f9dcSJohnathan Mantey std::optional<nlohmann::json> ntp; 50667a78d87STom Joseph std::optional<nlohmann::json> ipmi; 507501be32bSraviteja-b 50867a78d87STom Joseph if (!json_util::readJson(req, res, "HostName", newHostName, "NTP", ntp, 50967a78d87STom Joseph "IPMI", ipmi)) 510501be32bSraviteja-b { 511501be32bSraviteja-b return; 512501be32bSraviteja-b } 513cf05f9dcSJohnathan Mantey 514cf05f9dcSJohnathan Mantey res.result(boost::beast::http::status::no_content); 515501be32bSraviteja-b if (newHostName) 516501be32bSraviteja-b { 517501be32bSraviteja-b handleHostnamePatch(*newHostName, asyncResp); 518cf05f9dcSJohnathan Mantey } 519cf05f9dcSJohnathan Mantey 520cf05f9dcSJohnathan Mantey if (ntp) 521cf05f9dcSJohnathan Mantey { 522cf05f9dcSJohnathan Mantey std::optional<std::vector<std::string>> ntpServers; 523cf05f9dcSJohnathan Mantey std::optional<bool> ntpEnabled; 524cf05f9dcSJohnathan Mantey if (!json_util::readJson(*ntp, res, "NTPServers", ntpServers, 525cf05f9dcSJohnathan Mantey "ProtocolEnabled", ntpEnabled)) 526cf05f9dcSJohnathan Mantey { 527501be32bSraviteja-b return; 528501be32bSraviteja-b } 529cf05f9dcSJohnathan Mantey 53020e6ea5dSraviteja-b if (ntpEnabled) 53120e6ea5dSraviteja-b { 53220e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 53320e6ea5dSraviteja-b } 534cf05f9dcSJohnathan Mantey 53520e6ea5dSraviteja-b if (ntpServers) 53620e6ea5dSraviteja-b { 537dc3fbbd0STony Lee std::sort((*ntpServers).begin(), (*ntpServers).end()); 538dc3fbbd0STony Lee (*ntpServers) 539dc3fbbd0STony Lee .erase( 540dc3fbbd0STony Lee std::unique((*ntpServers).begin(), (*ntpServers).end()), 541dc3fbbd0STony Lee (*ntpServers).end()); 54220e6ea5dSraviteja-b handleNTPServersPatch(*ntpServers, asyncResp); 54320e6ea5dSraviteja-b } 544501be32bSraviteja-b } 54567a78d87STom Joseph 54667a78d87STom Joseph if (ipmi) 54767a78d87STom Joseph { 54867a78d87STom Joseph std::optional<bool> ipmiProtocolEnabled; 54967a78d87STom Joseph if (!json_util::readJson(*ipmi, res, "ProtocolEnabled", 55067a78d87STom Joseph ipmiProtocolEnabled)) 55167a78d87STom Joseph { 55267a78d87STom Joseph return; 55367a78d87STom Joseph } 55467a78d87STom Joseph 55567a78d87STom Joseph if (ipmiProtocolEnabled) 55667a78d87STom Joseph { 55767a78d87STom Joseph handleIpmiProtocolEnabled(*ipmiProtocolEnabled, asyncResp); 55867a78d87STom Joseph } 55967a78d87STom Joseph } 560cf05f9dcSJohnathan Mantey } 56170141561SBorawski.Lukasz }; 56270141561SBorawski.Lukasz 56370141561SBorawski.Lukasz } // namespace redfish 564