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 183ccb3adbSEd Tanous #include "app.hpp" 193ccb3adbSEd Tanous #include "dbus_utility.hpp" 203a8a0088SKowalski, Kamil #include "error_messages.hpp" 2167a78d87STom Joseph #include "openbmc_dbus_rest.hpp" 223ccb3adbSEd Tanous #include "query.hpp" 23b4bec66bSAbhishek Patel #include "redfish_util.hpp" 243ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 253ccb3adbSEd Tanous #include "utils/json_utils.hpp" 263ccb3adbSEd Tanous #include "utils/stl_utils.hpp" 2770141561SBorawski.Lukasz 28e99073f5SGeorge Liu #include <boost/system/error_code.hpp> 291e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 301214b7e7SGunnar Mills 31e99073f5SGeorge Liu #include <array> 321214b7e7SGunnar Mills #include <optional> 33e99073f5SGeorge Liu #include <string_view> 34abf2add6SEd Tanous #include <variant> 355f4c798dSJiaqing Zhao 361abe55efSEd Tanous namespace redfish 371abe55efSEd Tanous { 3870141561SBorawski.Lukasz 397e860f15SJohn Edward Broadbent void getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp); 407e860f15SJohn Edward Broadbent std::string getHostName(); 417e860f15SJohn Edward Broadbent 4269320d54SJiaqing Zhao static constexpr const char* sshServiceName = "dropbear"; 4369320d54SJiaqing Zhao static constexpr const char* httpsServiceName = "bmcweb"; 4469320d54SJiaqing Zhao static constexpr const char* ipmiServiceName = "phosphor-ipmi-net"; 4569320d54SJiaqing Zhao static constexpr std::array<std::pair<const char*, const char*>, 3> 4669320d54SJiaqing Zhao protocolToService = {{{"SSH", sshServiceName}, 4769320d54SJiaqing Zhao {"HTTPS", httpsServiceName}, 4869320d54SJiaqing Zhao {"IPMI", ipmiServiceName}}}; 493a8a0088SKowalski, Kamil 50711ac7a9SEd Tanous inline void extractNTPServersAndDomainNamesData( 51711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData, 52532d7697SGunnar Mills std::vector<std::string>& ntpData, std::vector<std::string>& dnData) 5320e6ea5dSraviteja-b { 5481ce609eSEd Tanous for (const auto& obj : dbusData) 5520e6ea5dSraviteja-b { 5620e6ea5dSraviteja-b for (const auto& ifacePair : obj.second) 5720e6ea5dSraviteja-b { 580a052baaSGeorge Liu if (ifacePair.first != 5920e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface") 6020e6ea5dSraviteja-b { 610a052baaSGeorge Liu continue; 620a052baaSGeorge Liu } 630a052baaSGeorge Liu 6420e6ea5dSraviteja-b for (const auto& propertyPair : ifacePair.second) 6520e6ea5dSraviteja-b { 66fcd2682aSEd Tanous if (propertyPair.first == "StaticNTPServers") 6720e6ea5dSraviteja-b { 6820e6ea5dSraviteja-b const std::vector<std::string>* ntpServers = 698d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 7020e6ea5dSraviteja-b &propertyPair.second); 7120e6ea5dSraviteja-b if (ntpServers != nullptr) 7220e6ea5dSraviteja-b { 73f23b7296SEd Tanous ntpData = *ntpServers; 7420e6ea5dSraviteja-b } 7520e6ea5dSraviteja-b } 76d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName") 77d24bfc7aSJennifer Lee { 78d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames = 798d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 80d24bfc7aSJennifer Lee &propertyPair.second); 81d24bfc7aSJennifer Lee if (domainNames != nullptr) 82d24bfc7aSJennifer Lee { 83f23b7296SEd Tanous dnData = *domainNames; 84d24bfc7aSJennifer Lee } 85d24bfc7aSJennifer Lee } 8620e6ea5dSraviteja-b } 8720e6ea5dSraviteja-b } 8820e6ea5dSraviteja-b } 890225b87bSEd Tanous stl_utils::removeDuplicate(ntpData); 9020e6ea5dSraviteja-b } 9120e6ea5dSraviteja-b 9220e6ea5dSraviteja-b template <typename CallbackFunc> 9320e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback) 9420e6ea5dSraviteja-b { 9520e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 96f94c4ecfSEd Tanous [callback{std::forward<CallbackFunc>(callback)}]( 975e7e2dc5SEd Tanous const boost::system::error_code& errorCode, 98711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData) { 9920e6ea5dSraviteja-b std::vector<std::string> ntpServers; 100d24bfc7aSJennifer Lee std::vector<std::string> domainNames; 10120e6ea5dSraviteja-b 10281ce609eSEd Tanous if (errorCode) 10320e6ea5dSraviteja-b { 104532d7697SGunnar Mills callback(false, ntpServers, domainNames); 10520e6ea5dSraviteja-b return; 10620e6ea5dSraviteja-b } 10720e6ea5dSraviteja-b 108532d7697SGunnar Mills extractNTPServersAndDomainNamesData(dbusData, ntpServers, domainNames); 10920e6ea5dSraviteja-b 110532d7697SGunnar Mills callback(true, ntpServers, domainNames); 11120e6ea5dSraviteja-b }, 11220e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", 11320e6ea5dSraviteja-b "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 114271584abSEd Tanous } 11520e6ea5dSraviteja-b 1164f48d5f6SEd Tanous inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 11772048780SAbhishek Patel const crow::Request& req) 1181abe55efSEd Tanous { 119e9f71672SEd Tanous asyncResp->res.addHeader( 120e9f71672SEd Tanous boost::beast::http::field::link, 121e9f71672SEd Tanous "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/NetworkProtocol.json>; rel=describedby"); 1220f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 123532d7697SGunnar Mills "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol"; 1240f74e643SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 1250f74e643SEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol"; 1260f74e643SEd Tanous asyncResp->res.jsonValue["Id"] = "NetworkProtocol"; 1270f74e643SEd Tanous asyncResp->res.jsonValue["Name"] = "Manager Network Protocol"; 1280f74e643SEd Tanous asyncResp->res.jsonValue["Description"] = "Manager Network Service"; 1290f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 1300f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK"; 1310f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 1320f74e643SEd Tanous 13361932318SXiaochao Ma // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0, 134818ea7b8SJoshi-Mansi // but from security perspective it is not recommended to use. 135818ea7b8SJoshi-Mansi // Hence using protocolEnabled as false to make it OCP and security-wise 136818ea7b8SJoshi-Mansi // compliant 137818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["Port"] = 0; 138818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false; 139818ea7b8SJoshi-Mansi 140d24bfc7aSJennifer Lee std::string hostName = getHostName(); 141d24bfc7aSJennifer Lee 142d24bfc7aSJennifer Lee asyncResp->res.jsonValue["HostName"] = hostName; 1433a8a0088SKowalski, Kamil 14420e6ea5dSraviteja-b getNTPProtocolEnabled(asyncResp); 14520e6ea5dSraviteja-b 146002d39b4SEd Tanous getEthernetIfaceData( 147002d39b4SEd Tanous [hostName, asyncResp](const bool& success, 14802cad96eSEd Tanous const std::vector<std::string>& ntpServers, 149d24bfc7aSJennifer Lee const std::vector<std::string>& domainNames) { 15020e6ea5dSraviteja-b if (!success) 15120e6ea5dSraviteja-b { 1520a052baaSGeorge Liu messages::resourceNotFound(asyncResp->res, "ManagerNetworkProtocol", 1530a052baaSGeorge Liu "NetworkProtocol"); 15420e6ea5dSraviteja-b return; 15520e6ea5dSraviteja-b } 15620e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers; 15726f6976fSEd Tanous if (!hostName.empty()) 158d24bfc7aSJennifer Lee { 159f23b7296SEd Tanous std::string fqdn = hostName; 16026f6976fSEd Tanous if (!domainNames.empty()) 161d24bfc7aSJennifer Lee { 162f23b7296SEd Tanous fqdn += "."; 163f23b7296SEd Tanous fqdn += domainNames[0]; 164d24bfc7aSJennifer Lee } 1652c70f800SEd Tanous asyncResp->res.jsonValue["FQDN"] = std::move(fqdn); 166d24bfc7aSJennifer Lee } 16720e6ea5dSraviteja-b }); 16820e6ea5dSraviteja-b 16972048780SAbhishek Patel Privileges effectiveUserPrivileges = 17072048780SAbhishek Patel redfish::getUserPrivileges(req.userRole); 17172048780SAbhishek Patel 17272048780SAbhishek Patel // /redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates is 17372048780SAbhishek Patel // something only ConfigureManager can access then only display when 17472048780SAbhishek Patel // the user has permissions ConfigureManager 17572048780SAbhishek Patel if (isOperationAllowedWithPrivileges({{"ConfigureManager"}}, 17672048780SAbhishek Patel effectiveUserPrivileges)) 17772048780SAbhishek Patel { 1781476687dSEd Tanous asyncResp->res.jsonValue["HTTPS"]["Certificates"]["@odata.id"] = 1791476687dSEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"; 18070141561SBorawski.Lukasz } 18170141561SBorawski.Lukasz 18269320d54SJiaqing Zhao for (const auto& protocol : protocolToService) 183ec4974ddSAppaRao Puli { 184b4bec66bSAbhishek Patel const std::string& protocolName = protocol.first; 185b4bec66bSAbhishek Patel const std::string& serviceName = protocol.second; 186b4bec66bSAbhishek Patel getPortStatusAndPath( 187b4bec66bSAbhishek Patel serviceName, 1885e7e2dc5SEd Tanous [asyncResp, protocolName](const boost::system::error_code& ec, 189b4bec66bSAbhishek Patel const std::string& socketPath, 190b4bec66bSAbhishek Patel bool isProtocolEnabled) { 1914d875bd8SEd Tanous // If the service is not installed, that is not an error 1924d875bd8SEd Tanous if (ec == boost::system::errc::no_such_process) 1934d875bd8SEd Tanous { 1944d875bd8SEd Tanous asyncResp->res.jsonValue[protocolName]["Port"] = 1954d875bd8SEd Tanous nlohmann::detail::value_t::null; 1964d875bd8SEd Tanous asyncResp->res.jsonValue[protocolName]["ProtocolEnabled"] = 1974d875bd8SEd Tanous false; 1984d875bd8SEd Tanous return; 1994d875bd8SEd Tanous } 2001abe55efSEd Tanous if (ec) 2011abe55efSEd Tanous { 202a08b46ccSJason M. Bills messages::internalError(asyncResp->res); 203865fbb75SEd Tanous return; 2043a8a0088SKowalski, Kamil } 205b4bec66bSAbhishek Patel asyncResp->res.jsonValue[protocolName]["ProtocolEnabled"] = 206b4bec66bSAbhishek Patel isProtocolEnabled; 207002d39b4SEd Tanous getPortNumber(socketPath, [asyncResp, protocolName]( 2085e7e2dc5SEd Tanous const boost::system::error_code& ec2, 209002d39b4SEd Tanous int portNumber) { 2108a592810SEd Tanous if (ec2) 2111abe55efSEd Tanous { 212b4bec66bSAbhishek Patel messages::internalError(asyncResp->res); 213865fbb75SEd Tanous return; 21470141561SBorawski.Lukasz } 215002d39b4SEd Tanous asyncResp->res.jsonValue[protocolName]["Port"] = portNumber; 216b4bec66bSAbhishek Patel }); 217b4bec66bSAbhishek Patel }); 218865fbb75SEd Tanous } 219b4bec66bSAbhishek Patel } // namespace redfish 220501be32bSraviteja-b 2214f48d5f6SEd Tanous inline void handleNTPProtocolEnabled( 2227e860f15SJohn Edward Broadbent const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22320e6ea5dSraviteja-b { 22420e6ea5dSraviteja-b std::string timeSyncMethod; 22520e6ea5dSraviteja-b if (ntpEnabled) 22620e6ea5dSraviteja-b { 2277e860f15SJohn Edward Broadbent timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 22820e6ea5dSraviteja-b } 22920e6ea5dSraviteja-b else 23020e6ea5dSraviteja-b { 23120e6ea5dSraviteja-b timeSyncMethod = 23220e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 23320e6ea5dSraviteja-b } 23420e6ea5dSraviteja-b 23520e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 2365e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& errorCode) { 23781ce609eSEd Tanous if (errorCode) 238cb13a392SEd Tanous { 239cb13a392SEd Tanous messages::internalError(asyncResp->res); 240cb13a392SEd Tanous } 241cb13a392SEd Tanous }, 2427e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method", 24320e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 24420e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 245168e20c1SEd Tanous dbus::utility::DbusVariantType{timeSyncMethod}); 24620e6ea5dSraviteja-b } 24720e6ea5dSraviteja-b 2484f48d5f6SEd Tanous inline void 249287ece64SGeorge Liu handleNTPServersPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 250b9e15228SEd Tanous const std::vector<nlohmann::json>& ntpServerObjects, 251b9e15228SEd Tanous std::vector<std::string> currentNtpServers) 25220e6ea5dSraviteja-b { 253b9e15228SEd Tanous std::vector<std::string>::iterator currentNtpServer = 254b9e15228SEd Tanous currentNtpServers.begin(); 255b9e15228SEd Tanous for (size_t index = 0; index < ntpServerObjects.size(); index++) 256287ece64SGeorge Liu { 257b9e15228SEd Tanous const nlohmann::json& ntpServer = ntpServerObjects[index]; 258b9e15228SEd Tanous if (ntpServer.is_null()) 259b9e15228SEd Tanous { 260b9e15228SEd Tanous // Can't delete an item that doesn't exist 261b9e15228SEd Tanous if (currentNtpServer == currentNtpServers.end()) 262b9e15228SEd Tanous { 263b9e15228SEd Tanous messages::propertyValueNotInList(asyncResp->res, "null", 264b9e15228SEd Tanous "NTP/NTPServers/" + 265b9e15228SEd Tanous std::to_string(index)); 266b9e15228SEd Tanous 267287ece64SGeorge Liu return; 268287ece64SGeorge Liu } 269b9e15228SEd Tanous currentNtpServer = currentNtpServers.erase(currentNtpServer); 270b9e15228SEd Tanous continue; 271b9e15228SEd Tanous } 272b9e15228SEd Tanous const nlohmann::json::object_t* ntpServerObject = 273b9e15228SEd Tanous ntpServer.get_ptr<const nlohmann::json::object_t*>(); 274b9e15228SEd Tanous if (ntpServerObject != nullptr) 275b9e15228SEd Tanous { 276b9e15228SEd Tanous if (!ntpServerObject->empty()) 277b9e15228SEd Tanous { 278b9e15228SEd Tanous messages::propertyValueNotInList( 279b9e15228SEd Tanous asyncResp->res, 280b9e15228SEd Tanous ntpServer.dump(2, ' ', true, 281b9e15228SEd Tanous nlohmann::json::error_handler_t::replace), 282b9e15228SEd Tanous "NTP/NTPServers/" + std::to_string(index)); 283b9e15228SEd Tanous return; 284b9e15228SEd Tanous } 285b9e15228SEd Tanous // Can't retain an item that doesn't exist 286b9e15228SEd Tanous if (currentNtpServer == currentNtpServers.end()) 287b9e15228SEd Tanous { 288b9e15228SEd Tanous messages::propertyValueOutOfRange( 289b9e15228SEd Tanous asyncResp->res, 290b9e15228SEd Tanous ntpServer.dump(2, ' ', true, 291b9e15228SEd Tanous nlohmann::json::error_handler_t::replace), 292b9e15228SEd Tanous "NTP/NTPServers/" + std::to_string(index)); 293b9e15228SEd Tanous 294b9e15228SEd Tanous return; 295b9e15228SEd Tanous } 296b9e15228SEd Tanous // empty objects should leave the NtpServer unmodified 297b9e15228SEd Tanous currentNtpServer++; 298b9e15228SEd Tanous continue; 299b9e15228SEd Tanous } 300b9e15228SEd Tanous 301b9e15228SEd Tanous const std::string* ntpServerStr = 302b9e15228SEd Tanous ntpServer.get_ptr<const std::string*>(); 303b9e15228SEd Tanous if (ntpServerStr == nullptr) 304b9e15228SEd Tanous { 305b9e15228SEd Tanous messages::propertyValueTypeError( 306b9e15228SEd Tanous asyncResp->res, 307b9e15228SEd Tanous ntpServer.dump(2, ' ', true, 308b9e15228SEd Tanous nlohmann::json::error_handler_t::replace), 309b9e15228SEd Tanous "NTP/NTPServers/" + std::to_string(index)); 310b9e15228SEd Tanous return; 311b9e15228SEd Tanous } 312b9e15228SEd Tanous if (currentNtpServer == currentNtpServers.end()) 313b9e15228SEd Tanous { 314b9e15228SEd Tanous // if we're at the end of the list, append to the end 315b9e15228SEd Tanous currentNtpServers.push_back(*ntpServerStr); 316b9e15228SEd Tanous currentNtpServer = currentNtpServers.end(); 317b9e15228SEd Tanous continue; 318b9e15228SEd Tanous } 319b9e15228SEd Tanous *currentNtpServer = *ntpServerStr; 320b9e15228SEd Tanous currentNtpServer++; 321b9e15228SEd Tanous } 322b9e15228SEd Tanous 323b9e15228SEd Tanous // Any remaining array elements should be removed 324b9e15228SEd Tanous currentNtpServers.erase(currentNtpServer, currentNtpServers.end()); 325287ece64SGeorge Liu 326e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> ethInterfaces = { 327e99073f5SGeorge Liu "xyz.openbmc_project.Network.EthernetInterface"}; 328e99073f5SGeorge Liu dbus::utility::getSubTree( 329e99073f5SGeorge Liu "/xyz/openbmc_project", 0, ethInterfaces, 330b9e15228SEd Tanous [asyncResp, currentNtpServers]( 3312138483cSGeorge Liu const boost::system::error_code& ec, 332b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 3330a052baaSGeorge Liu if (ec) 3340a052baaSGeorge Liu { 335002d39b4SEd Tanous BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", " << ec.message(); 3360a052baaSGeorge Liu messages::internalError(asyncResp->res); 3370a052baaSGeorge Liu return; 3380a052baaSGeorge Liu } 3390a052baaSGeorge Liu 3400a052baaSGeorge Liu for (const auto& [objectPath, serviceMap] : subtree) 3410a052baaSGeorge Liu { 3420a052baaSGeorge Liu for (const auto& [service, interfaces] : serviceMap) 3430a052baaSGeorge Liu { 3440a052baaSGeorge Liu for (const auto& interface : interfaces) 3450a052baaSGeorge Liu { 3460a052baaSGeorge Liu if (interface != 3470a052baaSGeorge Liu "xyz.openbmc_project.Network.EthernetInterface") 3480a052baaSGeorge Liu { 3490a052baaSGeorge Liu continue; 3500a052baaSGeorge Liu } 3510a052baaSGeorge Liu 3520a052baaSGeorge Liu crow::connections::systemBus->async_method_call( 3535e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 3548a592810SEd Tanous if (ec2) 35520e6ea5dSraviteja-b { 35620e6ea5dSraviteja-b messages::internalError(asyncResp->res); 35720e6ea5dSraviteja-b return; 35820e6ea5dSraviteja-b } 35920e6ea5dSraviteja-b }, 360002d39b4SEd Tanous service, objectPath, "org.freedesktop.DBus.Properties", 361fcd2682aSEd Tanous "Set", interface, "StaticNTPServers", 362b9e15228SEd Tanous dbus::utility::DbusVariantType{currentNtpServers}); 36320e6ea5dSraviteja-b } 3640a052baaSGeorge Liu } 3650a052baaSGeorge Liu } 366e99073f5SGeorge Liu }); 3670a052baaSGeorge Liu } 36820e6ea5dSraviteja-b 3694f48d5f6SEd Tanous inline void 3704f48d5f6SEd Tanous handleProtocolEnabled(const bool protocolEnabled, 371e5a99777SAlbert Zhang const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 37269320d54SJiaqing Zhao const std::string& netBasePath) 37367a78d87STom Joseph { 374e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 375e99073f5SGeorge Liu "xyz.openbmc_project.Control.Service.Attributes"}; 376e99073f5SGeorge Liu dbus::utility::getSubTree( 377e99073f5SGeorge Liu "/xyz/openbmc_project/control/service", 0, interfaces, 378e5a99777SAlbert Zhang [protocolEnabled, asyncResp, 3792138483cSGeorge Liu netBasePath](const boost::system::error_code& ec, 380b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 38167a78d87STom Joseph if (ec) 38267a78d87STom Joseph { 38367a78d87STom Joseph messages::internalError(asyncResp->res); 38467a78d87STom Joseph return; 38567a78d87STom Joseph } 38667a78d87STom Joseph 38767a78d87STom Joseph for (const auto& entry : subtree) 38867a78d87STom Joseph { 389e5a99777SAlbert Zhang if (boost::algorithm::starts_with(entry.first, netBasePath)) 39067a78d87STom Joseph { 39167a78d87STom Joseph crow::connections::systemBus->async_method_call( 3925e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 39323a21a1cSEd Tanous if (ec2) 39467a78d87STom Joseph { 39567a78d87STom Joseph messages::internalError(asyncResp->res); 39667a78d87STom Joseph return; 39767a78d87STom Joseph } 39867a78d87STom Joseph }, 39967a78d87STom Joseph entry.second.begin()->first, entry.first, 40067a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 401002d39b4SEd Tanous "xyz.openbmc_project.Control.Service.Attributes", "Running", 402168e20c1SEd Tanous dbus::utility::DbusVariantType{protocolEnabled}); 40367a78d87STom Joseph 40467a78d87STom Joseph crow::connections::systemBus->async_method_call( 4055e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 40623a21a1cSEd Tanous if (ec2) 40767a78d87STom Joseph { 40867a78d87STom Joseph messages::internalError(asyncResp->res); 40967a78d87STom Joseph return; 41067a78d87STom Joseph } 41167a78d87STom Joseph }, 41267a78d87STom Joseph entry.second.begin()->first, entry.first, 41367a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 414002d39b4SEd Tanous "xyz.openbmc_project.Control.Service.Attributes", "Enabled", 415168e20c1SEd Tanous dbus::utility::DbusVariantType{protocolEnabled}); 41667a78d87STom Joseph } 41767a78d87STom Joseph } 418e99073f5SGeorge Liu }); 41967a78d87STom Joseph } 42067a78d87STom Joseph 4214f48d5f6SEd Tanous inline std::string getHostName() 422501be32bSraviteja-b { 4237e860f15SJohn Edward Broadbent std::string hostName; 4248d1b46d7Szhanghch05 425d3a9e084SEd Tanous std::array<char, HOST_NAME_MAX> hostNameCStr{}; 4267e860f15SJohn Edward Broadbent if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 4277e860f15SJohn Edward Broadbent { 4287e860f15SJohn Edward Broadbent hostName = hostNameCStr.data(); 4297e860f15SJohn Edward Broadbent } 4307e860f15SJohn Edward Broadbent return hostName; 4317e860f15SJohn Edward Broadbent } 4327e860f15SJohn Edward Broadbent 4334f48d5f6SEd Tanous inline void 4344f48d5f6SEd Tanous getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 4357e860f15SJohn Edward Broadbent { 4361e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 4371e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 4381e1e598dSJonathan Doman "/xyz/openbmc_project/time/sync_method", 4391e1e598dSJonathan Doman "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 4405e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& errorCode, 4411e1e598dSJonathan Doman const std::string& timeSyncMethod) { 4427e860f15SJohn Edward Broadbent if (errorCode) 4437e860f15SJohn Edward Broadbent { 4447e860f15SJohn Edward Broadbent return; 4457e860f15SJohn Edward Broadbent } 4467e860f15SJohn Edward Broadbent 4471e1e598dSJonathan Doman if (timeSyncMethod == 4481e1e598dSJonathan Doman "xyz.openbmc_project.Time.Synchronization.Method.NTP") 4497e860f15SJohn Edward Broadbent { 4507e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 4517e860f15SJohn Edward Broadbent } 452002d39b4SEd Tanous else if (timeSyncMethod == "xyz.openbmc_project.Time.Synchronization." 4531e1e598dSJonathan Doman "Method.Manual") 4547e860f15SJohn Edward Broadbent { 4557e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 4567e860f15SJohn Edward Broadbent } 4571e1e598dSJonathan Doman }); 4587e860f15SJohn Edward Broadbent } 4597e860f15SJohn Edward Broadbent 46069320d54SJiaqing Zhao inline std::string encodeServiceObjectPath(const std::string& serviceName) 46169320d54SJiaqing Zhao { 46269320d54SJiaqing Zhao sdbusplus::message::object_path objPath( 46369320d54SJiaqing Zhao "/xyz/openbmc_project/control/service"); 46469320d54SJiaqing Zhao objPath /= serviceName; 46569320d54SJiaqing Zhao return objPath.str; 46669320d54SJiaqing Zhao } 46769320d54SJiaqing Zhao 4680f55d946SEd Tanous inline void handleBmcNetworkProtocolHead( 469e9f71672SEd Tanous crow::App& app, const crow::Request& req, 470e9f71672SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 471e9f71672SEd Tanous { 472e9f71672SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 473e9f71672SEd Tanous { 474e9f71672SEd Tanous return; 475e9f71672SEd Tanous } 476e9f71672SEd Tanous asyncResp->res.addHeader( 477e9f71672SEd Tanous boost::beast::http::field::link, 478e9f71672SEd Tanous "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/ManagerNetworkProtocol.json>; rel=describedby"); 479e9f71672SEd Tanous } 480e9f71672SEd Tanous 481*e634b34cSEd Tanous inline void handleManagersNetworkProtocolPatch( 482*e634b34cSEd Tanous App& app, const crow::Request& req, 483*e634b34cSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 4847e860f15SJohn Edward Broadbent { 485*e634b34cSEd Tanous 4863ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 48745ca1b86SEd Tanous { 48845ca1b86SEd Tanous return; 48945ca1b86SEd Tanous } 490501be32bSraviteja-b std::optional<std::string> newHostName; 491b9e15228SEd Tanous std::optional<std::vector<nlohmann::json>> ntpServerObjects; 4925f4c798dSJiaqing Zhao std::optional<bool> ntpEnabled; 4935f4c798dSJiaqing Zhao std::optional<bool> ipmiEnabled; 4945f4c798dSJiaqing Zhao std::optional<bool> sshEnabled; 495501be32bSraviteja-b 4965f4c798dSJiaqing Zhao // clang-format off 4975f4c798dSJiaqing Zhao if (!json_util::readJsonPatch( 4985f4c798dSJiaqing Zhao req, asyncResp->res, 4995f4c798dSJiaqing Zhao "HostName", newHostName, 500b9e15228SEd Tanous "NTP/NTPServers", ntpServerObjects, 5015f4c798dSJiaqing Zhao "NTP/ProtocolEnabled", ntpEnabled, 5025f4c798dSJiaqing Zhao "IPMI/ProtocolEnabled", ipmiEnabled, 5035f4c798dSJiaqing Zhao "SSH/ProtocolEnabled", sshEnabled)) 504501be32bSraviteja-b { 505501be32bSraviteja-b return; 506501be32bSraviteja-b } 5075f4c798dSJiaqing Zhao // clang-format on 508cf05f9dcSJohnathan Mantey 5098d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 510501be32bSraviteja-b if (newHostName) 511501be32bSraviteja-b { 5122db77d34SJohnathan Mantey messages::propertyNotWritable(asyncResp->res, "HostName"); 51344fad2aaSEd Tanous return; 514cf05f9dcSJohnathan Mantey } 515cf05f9dcSJohnathan Mantey 51620e6ea5dSraviteja-b if (ntpEnabled) 51720e6ea5dSraviteja-b { 51820e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 51920e6ea5dSraviteja-b } 520b9e15228SEd Tanous if (ntpServerObjects) 52120e6ea5dSraviteja-b { 522b9e15228SEd Tanous getEthernetIfaceData( 523b9e15228SEd Tanous [asyncResp, ntpServerObjects]( 524*e634b34cSEd Tanous const bool success, std::vector<std::string>& currentNtpServers, 525b9e15228SEd Tanous const std::vector<std::string>& /*domainNames*/) { 526b9e15228SEd Tanous if (!success) 527b9e15228SEd Tanous { 528b9e15228SEd Tanous messages::internalError(asyncResp->res); 529b9e15228SEd Tanous return; 530b9e15228SEd Tanous } 531b9e15228SEd Tanous handleNTPServersPatch(asyncResp, *ntpServerObjects, 532b9e15228SEd Tanous std::move(currentNtpServers)); 533b9e15228SEd Tanous }); 53420e6ea5dSraviteja-b } 53567a78d87STom Joseph 5365f4c798dSJiaqing Zhao if (ipmiEnabled) 53767a78d87STom Joseph { 538e5a99777SAlbert Zhang handleProtocolEnabled( 5395f4c798dSJiaqing Zhao *ipmiEnabled, asyncResp, 54069320d54SJiaqing Zhao encodeServiceObjectPath(std::string(ipmiServiceName) + '@')); 541e5a99777SAlbert Zhang } 542e5a99777SAlbert Zhang 5435f4c798dSJiaqing Zhao if (sshEnabled) 544e5a99777SAlbert Zhang { 54569320d54SJiaqing Zhao handleProtocolEnabled(*sshEnabled, asyncResp, 54669320d54SJiaqing Zhao encodeServiceObjectPath(sshServiceName)); 54767a78d87STom Joseph } 548*e634b34cSEd Tanous } 549*e634b34cSEd Tanous 550*e634b34cSEd Tanous inline void handleManagersNetworkProtocolGet( 551*e634b34cSEd Tanous App& app, const crow::Request& req, 552*e634b34cSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 553*e634b34cSEd Tanous { 554*e634b34cSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 555*e634b34cSEd Tanous { 556*e634b34cSEd Tanous return; 557*e634b34cSEd Tanous } 558*e634b34cSEd Tanous getNetworkData(asyncResp, req); 559*e634b34cSEd Tanous } 560*e634b34cSEd Tanous 561*e634b34cSEd Tanous inline void requestRoutesNetworkProtocol(App& app) 562*e634b34cSEd Tanous { 563*e634b34cSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 564*e634b34cSEd Tanous .privileges(redfish::privileges::patchManagerNetworkProtocol) 565*e634b34cSEd Tanous .methods(boost::beast::http::verb::patch)( 566*e634b34cSEd Tanous std::bind_front(handleManagersNetworkProtocolPatch, std::ref(app))); 5677e860f15SJohn Edward Broadbent 5687e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 569e9f71672SEd Tanous .privileges(redfish::privileges::headManagerNetworkProtocol) 570e9f71672SEd Tanous .methods(boost::beast::http::verb::head)( 571e9f71672SEd Tanous std::bind_front(handleBmcNetworkProtocolHead, std::ref(app))); 572e9f71672SEd Tanous 573e9f71672SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 574ed398213SEd Tanous .privileges(redfish::privileges::getManagerNetworkProtocol) 5757e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 576*e634b34cSEd Tanous std::bind_front(handleManagersNetworkProtocolGet, std::ref(app))); 577cf05f9dcSJohnathan Mantey } 57870141561SBorawski.Lukasz 57970141561SBorawski.Lukasz } // namespace redfish 580