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 425c3e9272SAbhishek Patel static constexpr std::string_view sshServiceName = "dropbear"; 435c3e9272SAbhishek Patel static constexpr std::string_view httpsServiceName = "bmcweb"; 445c3e9272SAbhishek Patel static constexpr std::string_view ipmiServiceName = "phosphor-ipmi-net"; 455c3e9272SAbhishek Patel 465c3e9272SAbhishek Patel // Mapping from Redfish NetworkProtocol key name to backend service that hosts 475c3e9272SAbhishek Patel // that protocol. 485c3e9272SAbhishek Patel static constexpr std::array<std::pair<std::string_view, std::string_view>, 3> 495c3e9272SAbhishek Patel networkProtocolToDbus = {{{"SSH", sshServiceName}, 5069320d54SJiaqing Zhao {"HTTPS", httpsServiceName}, 5169320d54SJiaqing Zhao {"IPMI", ipmiServiceName}}}; 523a8a0088SKowalski, Kamil 53711ac7a9SEd Tanous inline void extractNTPServersAndDomainNamesData( 54711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData, 55532d7697SGunnar Mills std::vector<std::string>& ntpData, std::vector<std::string>& dnData) 5620e6ea5dSraviteja-b { 5781ce609eSEd Tanous for (const auto& obj : dbusData) 5820e6ea5dSraviteja-b { 5920e6ea5dSraviteja-b for (const auto& ifacePair : obj.second) 6020e6ea5dSraviteja-b { 610a052baaSGeorge Liu if (ifacePair.first != 6220e6ea5dSraviteja-b "xyz.openbmc_project.Network.EthernetInterface") 6320e6ea5dSraviteja-b { 640a052baaSGeorge Liu continue; 650a052baaSGeorge Liu } 660a052baaSGeorge Liu 6720e6ea5dSraviteja-b for (const auto& propertyPair : ifacePair.second) 6820e6ea5dSraviteja-b { 69fcd2682aSEd Tanous if (propertyPair.first == "StaticNTPServers") 7020e6ea5dSraviteja-b { 7120e6ea5dSraviteja-b const std::vector<std::string>* ntpServers = 728d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 7320e6ea5dSraviteja-b &propertyPair.second); 7420e6ea5dSraviteja-b if (ntpServers != nullptr) 7520e6ea5dSraviteja-b { 76*c251fe81SJian Zhang ntpData.insert(ntpData.end(), ntpServers->begin(), 77*c251fe81SJian Zhang ntpServers->end()); 7820e6ea5dSraviteja-b } 7920e6ea5dSraviteja-b } 80d24bfc7aSJennifer Lee else if (propertyPair.first == "DomainName") 81d24bfc7aSJennifer Lee { 82d24bfc7aSJennifer Lee const std::vector<std::string>* domainNames = 838d78b7a9SPatrick Williams std::get_if<std::vector<std::string>>( 84d24bfc7aSJennifer Lee &propertyPair.second); 85d24bfc7aSJennifer Lee if (domainNames != nullptr) 86d24bfc7aSJennifer Lee { 87*c251fe81SJian Zhang dnData.insert(dnData.end(), domainNames->begin(), 88*c251fe81SJian Zhang domainNames->end()); 89d24bfc7aSJennifer Lee } 90d24bfc7aSJennifer Lee } 9120e6ea5dSraviteja-b } 9220e6ea5dSraviteja-b } 9320e6ea5dSraviteja-b } 940225b87bSEd Tanous stl_utils::removeDuplicate(ntpData); 95*c251fe81SJian Zhang stl_utils::removeDuplicate(dnData); 9620e6ea5dSraviteja-b } 9720e6ea5dSraviteja-b 9820e6ea5dSraviteja-b template <typename CallbackFunc> 9920e6ea5dSraviteja-b void getEthernetIfaceData(CallbackFunc&& callback) 10020e6ea5dSraviteja-b { 10120e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 102f94c4ecfSEd Tanous [callback{std::forward<CallbackFunc>(callback)}]( 1035e7e2dc5SEd Tanous const boost::system::error_code& errorCode, 104711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData) { 10520e6ea5dSraviteja-b std::vector<std::string> ntpServers; 106d24bfc7aSJennifer Lee std::vector<std::string> domainNames; 10720e6ea5dSraviteja-b 10881ce609eSEd Tanous if (errorCode) 10920e6ea5dSraviteja-b { 110532d7697SGunnar Mills callback(false, ntpServers, domainNames); 11120e6ea5dSraviteja-b return; 11220e6ea5dSraviteja-b } 11320e6ea5dSraviteja-b 114532d7697SGunnar Mills extractNTPServersAndDomainNamesData(dbusData, ntpServers, domainNames); 11520e6ea5dSraviteja-b 116532d7697SGunnar Mills callback(true, ntpServers, domainNames); 11720e6ea5dSraviteja-b }, 11820e6ea5dSraviteja-b "xyz.openbmc_project.Network", "/xyz/openbmc_project/network", 11920e6ea5dSraviteja-b "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 120271584abSEd Tanous } 12120e6ea5dSraviteja-b 1225c3e9272SAbhishek Patel inline void afterNetworkPortRequest( 1235c3e9272SAbhishek Patel const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 1245c3e9272SAbhishek Patel const boost::system::error_code& ec, 1255c3e9272SAbhishek Patel const std::vector<std::tuple<std::string, std::string, bool>>& socketData) 1265c3e9272SAbhishek Patel { 1275c3e9272SAbhishek Patel if (ec) 1285c3e9272SAbhishek Patel { 1295c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 1305c3e9272SAbhishek Patel return; 1315c3e9272SAbhishek Patel } 1325c3e9272SAbhishek Patel for (const auto& data : socketData) 1335c3e9272SAbhishek Patel { 1345c3e9272SAbhishek Patel const std::string& socketPath = get<0>(data); 1355c3e9272SAbhishek Patel const std::string& protocolName = get<1>(data); 1365c3e9272SAbhishek Patel bool isProtocolEnabled = get<2>(data); 1375c3e9272SAbhishek Patel 1385c3e9272SAbhishek Patel asyncResp->res.jsonValue[protocolName]["ProtocolEnabled"] = 1395c3e9272SAbhishek Patel isProtocolEnabled; 1405c3e9272SAbhishek Patel asyncResp->res.jsonValue[protocolName]["Port"] = nullptr; 1415c3e9272SAbhishek Patel getPortNumber(socketPath, [asyncResp, protocolName]( 1425c3e9272SAbhishek Patel const boost::system::error_code& ec2, 1435c3e9272SAbhishek Patel int portNumber) { 1445c3e9272SAbhishek Patel if (ec2) 1455c3e9272SAbhishek Patel { 1465c3e9272SAbhishek Patel messages::internalError(asyncResp->res); 1475c3e9272SAbhishek Patel return; 1485c3e9272SAbhishek Patel } 1495c3e9272SAbhishek Patel asyncResp->res.jsonValue[protocolName]["Port"] = portNumber; 1505c3e9272SAbhishek Patel }); 1515c3e9272SAbhishek Patel } 1525c3e9272SAbhishek Patel } 1535c3e9272SAbhishek Patel 1544f48d5f6SEd Tanous inline void getNetworkData(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 15572048780SAbhishek Patel const crow::Request& req) 1561abe55efSEd Tanous { 157e9f71672SEd Tanous asyncResp->res.addHeader( 158e9f71672SEd Tanous boost::beast::http::field::link, 159e9f71672SEd Tanous "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/NetworkProtocol.json>; rel=describedby"); 1600f74e643SEd Tanous asyncResp->res.jsonValue["@odata.type"] = 161532d7697SGunnar Mills "#ManagerNetworkProtocol.v1_5_0.ManagerNetworkProtocol"; 1620f74e643SEd Tanous asyncResp->res.jsonValue["@odata.id"] = 1630f74e643SEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol"; 1640f74e643SEd Tanous asyncResp->res.jsonValue["Id"] = "NetworkProtocol"; 1650f74e643SEd Tanous asyncResp->res.jsonValue["Name"] = "Manager Network Protocol"; 1660f74e643SEd Tanous asyncResp->res.jsonValue["Description"] = "Manager Network Service"; 1670f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["Health"] = "OK"; 1680f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["HealthRollup"] = "OK"; 1690f74e643SEd Tanous asyncResp->res.jsonValue["Status"]["State"] = "Enabled"; 1700f74e643SEd Tanous 17161932318SXiaochao Ma // HTTP is Mandatory attribute as per OCP Baseline Profile - v1.0.0, 172818ea7b8SJoshi-Mansi // but from security perspective it is not recommended to use. 173818ea7b8SJoshi-Mansi // Hence using protocolEnabled as false to make it OCP and security-wise 174818ea7b8SJoshi-Mansi // compliant 1755c3e9272SAbhishek Patel asyncResp->res.jsonValue["HTTP"]["Port"] = nullptr; 176818ea7b8SJoshi-Mansi asyncResp->res.jsonValue["HTTP"]["ProtocolEnabled"] = false; 177818ea7b8SJoshi-Mansi 178d24bfc7aSJennifer Lee std::string hostName = getHostName(); 179d24bfc7aSJennifer Lee 180d24bfc7aSJennifer Lee asyncResp->res.jsonValue["HostName"] = hostName; 1813a8a0088SKowalski, Kamil 18220e6ea5dSraviteja-b getNTPProtocolEnabled(asyncResp); 18320e6ea5dSraviteja-b 184002d39b4SEd Tanous getEthernetIfaceData( 185002d39b4SEd Tanous [hostName, asyncResp](const bool& success, 18602cad96eSEd Tanous const std::vector<std::string>& ntpServers, 187d24bfc7aSJennifer Lee const std::vector<std::string>& domainNames) { 18820e6ea5dSraviteja-b if (!success) 18920e6ea5dSraviteja-b { 1900a052baaSGeorge Liu messages::resourceNotFound(asyncResp->res, "ManagerNetworkProtocol", 1910a052baaSGeorge Liu "NetworkProtocol"); 19220e6ea5dSraviteja-b return; 19320e6ea5dSraviteja-b } 19420e6ea5dSraviteja-b asyncResp->res.jsonValue["NTP"]["NTPServers"] = ntpServers; 19526f6976fSEd Tanous if (!hostName.empty()) 196d24bfc7aSJennifer Lee { 197f23b7296SEd Tanous std::string fqdn = hostName; 19826f6976fSEd Tanous if (!domainNames.empty()) 199d24bfc7aSJennifer Lee { 200f23b7296SEd Tanous fqdn += "."; 201f23b7296SEd Tanous fqdn += domainNames[0]; 202d24bfc7aSJennifer Lee } 2032c70f800SEd Tanous asyncResp->res.jsonValue["FQDN"] = std::move(fqdn); 204d24bfc7aSJennifer Lee } 20520e6ea5dSraviteja-b }); 20620e6ea5dSraviteja-b 20772048780SAbhishek Patel Privileges effectiveUserPrivileges = 20872048780SAbhishek Patel redfish::getUserPrivileges(req.userRole); 20972048780SAbhishek Patel 21072048780SAbhishek Patel // /redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates is 21172048780SAbhishek Patel // something only ConfigureManager can access then only display when 21272048780SAbhishek Patel // the user has permissions ConfigureManager 21372048780SAbhishek Patel if (isOperationAllowedWithPrivileges({{"ConfigureManager"}}, 21472048780SAbhishek Patel effectiveUserPrivileges)) 21572048780SAbhishek Patel { 2161476687dSEd Tanous asyncResp->res.jsonValue["HTTPS"]["Certificates"]["@odata.id"] = 2171476687dSEd Tanous "/redfish/v1/Managers/bmc/NetworkProtocol/HTTPS/Certificates"; 21870141561SBorawski.Lukasz } 21970141561SBorawski.Lukasz 2205c3e9272SAbhishek Patel getPortStatusAndPath(std::span(networkProtocolToDbus), 2215c3e9272SAbhishek Patel std::bind_front(afterNetworkPortRequest, asyncResp)); 222b4bec66bSAbhishek Patel } // namespace redfish 223501be32bSraviteja-b 2244f48d5f6SEd Tanous inline void handleNTPProtocolEnabled( 2257e860f15SJohn Edward Broadbent const bool& ntpEnabled, const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 22620e6ea5dSraviteja-b { 22720e6ea5dSraviteja-b std::string timeSyncMethod; 22820e6ea5dSraviteja-b if (ntpEnabled) 22920e6ea5dSraviteja-b { 2307e860f15SJohn Edward Broadbent timeSyncMethod = "xyz.openbmc_project.Time.Synchronization.Method.NTP"; 23120e6ea5dSraviteja-b } 23220e6ea5dSraviteja-b else 23320e6ea5dSraviteja-b { 23420e6ea5dSraviteja-b timeSyncMethod = 23520e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization.Method.Manual"; 23620e6ea5dSraviteja-b } 23720e6ea5dSraviteja-b 23820e6ea5dSraviteja-b crow::connections::systemBus->async_method_call( 2395e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& errorCode) { 24081ce609eSEd Tanous if (errorCode) 241cb13a392SEd Tanous { 242cb13a392SEd Tanous messages::internalError(asyncResp->res); 243cb13a392SEd Tanous } 244cb13a392SEd Tanous }, 2457e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", "/xyz/openbmc_project/time/sync_method", 24620e6ea5dSraviteja-b "org.freedesktop.DBus.Properties", "Set", 24720e6ea5dSraviteja-b "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 248168e20c1SEd Tanous dbus::utility::DbusVariantType{timeSyncMethod}); 24920e6ea5dSraviteja-b } 25020e6ea5dSraviteja-b 2514f48d5f6SEd Tanous inline void 252287ece64SGeorge Liu handleNTPServersPatch(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 253b9e15228SEd Tanous const std::vector<nlohmann::json>& ntpServerObjects, 254b9e15228SEd Tanous std::vector<std::string> currentNtpServers) 25520e6ea5dSraviteja-b { 256b9e15228SEd Tanous std::vector<std::string>::iterator currentNtpServer = 257b9e15228SEd Tanous currentNtpServers.begin(); 258b9e15228SEd Tanous for (size_t index = 0; index < ntpServerObjects.size(); index++) 259287ece64SGeorge Liu { 260b9e15228SEd Tanous const nlohmann::json& ntpServer = ntpServerObjects[index]; 261b9e15228SEd Tanous if (ntpServer.is_null()) 262b9e15228SEd Tanous { 263b9e15228SEd Tanous // Can't delete an item that doesn't exist 264b9e15228SEd Tanous if (currentNtpServer == currentNtpServers.end()) 265b9e15228SEd Tanous { 266b9e15228SEd Tanous messages::propertyValueNotInList(asyncResp->res, "null", 267b9e15228SEd Tanous "NTP/NTPServers/" + 268b9e15228SEd Tanous std::to_string(index)); 269b9e15228SEd Tanous 270287ece64SGeorge Liu return; 271287ece64SGeorge Liu } 272b9e15228SEd Tanous currentNtpServer = currentNtpServers.erase(currentNtpServer); 273b9e15228SEd Tanous continue; 274b9e15228SEd Tanous } 275b9e15228SEd Tanous const nlohmann::json::object_t* ntpServerObject = 276b9e15228SEd Tanous ntpServer.get_ptr<const nlohmann::json::object_t*>(); 277b9e15228SEd Tanous if (ntpServerObject != nullptr) 278b9e15228SEd Tanous { 279b9e15228SEd Tanous if (!ntpServerObject->empty()) 280b9e15228SEd Tanous { 281b9e15228SEd Tanous messages::propertyValueNotInList( 282b9e15228SEd Tanous asyncResp->res, 283b9e15228SEd Tanous ntpServer.dump(2, ' ', true, 284b9e15228SEd Tanous nlohmann::json::error_handler_t::replace), 285b9e15228SEd Tanous "NTP/NTPServers/" + std::to_string(index)); 286b9e15228SEd Tanous return; 287b9e15228SEd Tanous } 288b9e15228SEd Tanous // Can't retain an item that doesn't exist 289b9e15228SEd Tanous if (currentNtpServer == currentNtpServers.end()) 290b9e15228SEd Tanous { 291b9e15228SEd Tanous messages::propertyValueOutOfRange( 292b9e15228SEd Tanous asyncResp->res, 293b9e15228SEd Tanous ntpServer.dump(2, ' ', true, 294b9e15228SEd Tanous nlohmann::json::error_handler_t::replace), 295b9e15228SEd Tanous "NTP/NTPServers/" + std::to_string(index)); 296b9e15228SEd Tanous 297b9e15228SEd Tanous return; 298b9e15228SEd Tanous } 299b9e15228SEd Tanous // empty objects should leave the NtpServer unmodified 300b9e15228SEd Tanous currentNtpServer++; 301b9e15228SEd Tanous continue; 302b9e15228SEd Tanous } 303b9e15228SEd Tanous 304b9e15228SEd Tanous const std::string* ntpServerStr = 305b9e15228SEd Tanous ntpServer.get_ptr<const std::string*>(); 306b9e15228SEd Tanous if (ntpServerStr == nullptr) 307b9e15228SEd Tanous { 308b9e15228SEd Tanous messages::propertyValueTypeError( 309b9e15228SEd Tanous asyncResp->res, 310b9e15228SEd Tanous ntpServer.dump(2, ' ', true, 311b9e15228SEd Tanous nlohmann::json::error_handler_t::replace), 312b9e15228SEd Tanous "NTP/NTPServers/" + std::to_string(index)); 313b9e15228SEd Tanous return; 314b9e15228SEd Tanous } 315b9e15228SEd Tanous if (currentNtpServer == currentNtpServers.end()) 316b9e15228SEd Tanous { 317b9e15228SEd Tanous // if we're at the end of the list, append to the end 318b9e15228SEd Tanous currentNtpServers.push_back(*ntpServerStr); 319b9e15228SEd Tanous currentNtpServer = currentNtpServers.end(); 320b9e15228SEd Tanous continue; 321b9e15228SEd Tanous } 322b9e15228SEd Tanous *currentNtpServer = *ntpServerStr; 323b9e15228SEd Tanous currentNtpServer++; 324b9e15228SEd Tanous } 325b9e15228SEd Tanous 326b9e15228SEd Tanous // Any remaining array elements should be removed 327b9e15228SEd Tanous currentNtpServers.erase(currentNtpServer, currentNtpServers.end()); 328287ece64SGeorge Liu 329e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> ethInterfaces = { 330e99073f5SGeorge Liu "xyz.openbmc_project.Network.EthernetInterface"}; 331e99073f5SGeorge Liu dbus::utility::getSubTree( 332e99073f5SGeorge Liu "/xyz/openbmc_project", 0, ethInterfaces, 333b9e15228SEd Tanous [asyncResp, currentNtpServers]( 3342138483cSGeorge Liu const boost::system::error_code& ec, 335b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 3360a052baaSGeorge Liu if (ec) 3370a052baaSGeorge Liu { 338002d39b4SEd Tanous BMCWEB_LOG_WARNING << "D-Bus error: " << ec << ", " << ec.message(); 3390a052baaSGeorge Liu messages::internalError(asyncResp->res); 3400a052baaSGeorge Liu return; 3410a052baaSGeorge Liu } 3420a052baaSGeorge Liu 3430a052baaSGeorge Liu for (const auto& [objectPath, serviceMap] : subtree) 3440a052baaSGeorge Liu { 3450a052baaSGeorge Liu for (const auto& [service, interfaces] : serviceMap) 3460a052baaSGeorge Liu { 3470a052baaSGeorge Liu for (const auto& interface : interfaces) 3480a052baaSGeorge Liu { 3490a052baaSGeorge Liu if (interface != 3500a052baaSGeorge Liu "xyz.openbmc_project.Network.EthernetInterface") 3510a052baaSGeorge Liu { 3520a052baaSGeorge Liu continue; 3530a052baaSGeorge Liu } 3540a052baaSGeorge Liu 3550a052baaSGeorge Liu crow::connections::systemBus->async_method_call( 3565e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 3578a592810SEd Tanous if (ec2) 35820e6ea5dSraviteja-b { 35920e6ea5dSraviteja-b messages::internalError(asyncResp->res); 36020e6ea5dSraviteja-b return; 36120e6ea5dSraviteja-b } 36220e6ea5dSraviteja-b }, 363002d39b4SEd Tanous service, objectPath, "org.freedesktop.DBus.Properties", 364fcd2682aSEd Tanous "Set", interface, "StaticNTPServers", 365b9e15228SEd Tanous dbus::utility::DbusVariantType{currentNtpServers}); 36620e6ea5dSraviteja-b } 3670a052baaSGeorge Liu } 3680a052baaSGeorge Liu } 369e99073f5SGeorge Liu }); 3700a052baaSGeorge Liu } 37120e6ea5dSraviteja-b 3724f48d5f6SEd Tanous inline void 3734f48d5f6SEd Tanous handleProtocolEnabled(const bool protocolEnabled, 374e5a99777SAlbert Zhang const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 37569320d54SJiaqing Zhao const std::string& netBasePath) 37667a78d87STom Joseph { 377e99073f5SGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 378e99073f5SGeorge Liu "xyz.openbmc_project.Control.Service.Attributes"}; 379e99073f5SGeorge Liu dbus::utility::getSubTree( 380e99073f5SGeorge Liu "/xyz/openbmc_project/control/service", 0, interfaces, 381e5a99777SAlbert Zhang [protocolEnabled, asyncResp, 3822138483cSGeorge Liu netBasePath](const boost::system::error_code& ec, 383b9d36b47SEd Tanous const dbus::utility::MapperGetSubTreeResponse& subtree) { 38467a78d87STom Joseph if (ec) 38567a78d87STom Joseph { 38667a78d87STom Joseph messages::internalError(asyncResp->res); 38767a78d87STom Joseph return; 38867a78d87STom Joseph } 38967a78d87STom Joseph 39067a78d87STom Joseph for (const auto& entry : subtree) 39167a78d87STom Joseph { 392e5a99777SAlbert Zhang if (boost::algorithm::starts_with(entry.first, netBasePath)) 39367a78d87STom Joseph { 39467a78d87STom Joseph crow::connections::systemBus->async_method_call( 3955e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 39623a21a1cSEd Tanous if (ec2) 39767a78d87STom Joseph { 39867a78d87STom Joseph messages::internalError(asyncResp->res); 39967a78d87STom Joseph return; 40067a78d87STom Joseph } 40167a78d87STom Joseph }, 40267a78d87STom Joseph entry.second.begin()->first, entry.first, 40367a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 404002d39b4SEd Tanous "xyz.openbmc_project.Control.Service.Attributes", "Running", 405168e20c1SEd Tanous dbus::utility::DbusVariantType{protocolEnabled}); 40667a78d87STom Joseph 40767a78d87STom Joseph crow::connections::systemBus->async_method_call( 4085e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec2) { 40923a21a1cSEd Tanous if (ec2) 41067a78d87STom Joseph { 41167a78d87STom Joseph messages::internalError(asyncResp->res); 41267a78d87STom Joseph return; 41367a78d87STom Joseph } 41467a78d87STom Joseph }, 41567a78d87STom Joseph entry.second.begin()->first, entry.first, 41667a78d87STom Joseph "org.freedesktop.DBus.Properties", "Set", 417002d39b4SEd Tanous "xyz.openbmc_project.Control.Service.Attributes", "Enabled", 418168e20c1SEd Tanous dbus::utility::DbusVariantType{protocolEnabled}); 41967a78d87STom Joseph } 42067a78d87STom Joseph } 421e99073f5SGeorge Liu }); 42267a78d87STom Joseph } 42367a78d87STom Joseph 4244f48d5f6SEd Tanous inline std::string getHostName() 425501be32bSraviteja-b { 4267e860f15SJohn Edward Broadbent std::string hostName; 4278d1b46d7Szhanghch05 428d3a9e084SEd Tanous std::array<char, HOST_NAME_MAX> hostNameCStr{}; 4297e860f15SJohn Edward Broadbent if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 4307e860f15SJohn Edward Broadbent { 4317e860f15SJohn Edward Broadbent hostName = hostNameCStr.data(); 4327e860f15SJohn Edward Broadbent } 4337e860f15SJohn Edward Broadbent return hostName; 4347e860f15SJohn Edward Broadbent } 4357e860f15SJohn Edward Broadbent 4364f48d5f6SEd Tanous inline void 4374f48d5f6SEd Tanous getNTPProtocolEnabled(const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 4387e860f15SJohn Edward Broadbent { 4391e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 4401e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.Settings", 4411e1e598dSJonathan Doman "/xyz/openbmc_project/time/sync_method", 4421e1e598dSJonathan Doman "xyz.openbmc_project.Time.Synchronization", "TimeSyncMethod", 4435e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& errorCode, 4441e1e598dSJonathan Doman const std::string& timeSyncMethod) { 4457e860f15SJohn Edward Broadbent if (errorCode) 4467e860f15SJohn Edward Broadbent { 4477e860f15SJohn Edward Broadbent return; 4487e860f15SJohn Edward Broadbent } 4497e860f15SJohn Edward Broadbent 4501e1e598dSJonathan Doman if (timeSyncMethod == 4511e1e598dSJonathan Doman "xyz.openbmc_project.Time.Synchronization.Method.NTP") 4527e860f15SJohn Edward Broadbent { 4537e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = true; 4547e860f15SJohn Edward Broadbent } 455002d39b4SEd Tanous else if (timeSyncMethod == "xyz.openbmc_project.Time.Synchronization." 4561e1e598dSJonathan Doman "Method.Manual") 4577e860f15SJohn Edward Broadbent { 4587e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["NTP"]["ProtocolEnabled"] = false; 4597e860f15SJohn Edward Broadbent } 4601e1e598dSJonathan Doman }); 4617e860f15SJohn Edward Broadbent } 4627e860f15SJohn Edward Broadbent 4635c3e9272SAbhishek Patel inline std::string encodeServiceObjectPath(std::string_view serviceName) 46469320d54SJiaqing Zhao { 46569320d54SJiaqing Zhao sdbusplus::message::object_path objPath( 46669320d54SJiaqing Zhao "/xyz/openbmc_project/control/service"); 46769320d54SJiaqing Zhao objPath /= serviceName; 46869320d54SJiaqing Zhao return objPath.str; 46969320d54SJiaqing Zhao } 47069320d54SJiaqing Zhao 4710f55d946SEd Tanous inline void handleBmcNetworkProtocolHead( 472e9f71672SEd Tanous crow::App& app, const crow::Request& req, 473e9f71672SEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 474e9f71672SEd Tanous { 475e9f71672SEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 476e9f71672SEd Tanous { 477e9f71672SEd Tanous return; 478e9f71672SEd Tanous } 479e9f71672SEd Tanous asyncResp->res.addHeader( 480e9f71672SEd Tanous boost::beast::http::field::link, 481e9f71672SEd Tanous "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/ManagerNetworkProtocol.json>; rel=describedby"); 482e9f71672SEd Tanous } 483e9f71672SEd Tanous 484e634b34cSEd Tanous inline void handleManagersNetworkProtocolPatch( 485e634b34cSEd Tanous App& app, const crow::Request& req, 486e634b34cSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 4877e860f15SJohn Edward Broadbent { 488e634b34cSEd Tanous 4893ba00073SCarson Labrado if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 49045ca1b86SEd Tanous { 49145ca1b86SEd Tanous return; 49245ca1b86SEd Tanous } 493501be32bSraviteja-b std::optional<std::string> newHostName; 494b9e15228SEd Tanous std::optional<std::vector<nlohmann::json>> ntpServerObjects; 4955f4c798dSJiaqing Zhao std::optional<bool> ntpEnabled; 4965f4c798dSJiaqing Zhao std::optional<bool> ipmiEnabled; 4975f4c798dSJiaqing Zhao std::optional<bool> sshEnabled; 498501be32bSraviteja-b 4995f4c798dSJiaqing Zhao // clang-format off 5005f4c798dSJiaqing Zhao if (!json_util::readJsonPatch( 5015f4c798dSJiaqing Zhao req, asyncResp->res, 5025f4c798dSJiaqing Zhao "HostName", newHostName, 503b9e15228SEd Tanous "NTP/NTPServers", ntpServerObjects, 5045f4c798dSJiaqing Zhao "NTP/ProtocolEnabled", ntpEnabled, 5055f4c798dSJiaqing Zhao "IPMI/ProtocolEnabled", ipmiEnabled, 5065f4c798dSJiaqing Zhao "SSH/ProtocolEnabled", sshEnabled)) 507501be32bSraviteja-b { 508501be32bSraviteja-b return; 509501be32bSraviteja-b } 5105f4c798dSJiaqing Zhao // clang-format on 511cf05f9dcSJohnathan Mantey 5128d1b46d7Szhanghch05 asyncResp->res.result(boost::beast::http::status::no_content); 513501be32bSraviteja-b if (newHostName) 514501be32bSraviteja-b { 5152db77d34SJohnathan Mantey messages::propertyNotWritable(asyncResp->res, "HostName"); 51644fad2aaSEd Tanous return; 517cf05f9dcSJohnathan Mantey } 518cf05f9dcSJohnathan Mantey 51920e6ea5dSraviteja-b if (ntpEnabled) 52020e6ea5dSraviteja-b { 52120e6ea5dSraviteja-b handleNTPProtocolEnabled(*ntpEnabled, asyncResp); 52220e6ea5dSraviteja-b } 523b9e15228SEd Tanous if (ntpServerObjects) 52420e6ea5dSraviteja-b { 525b9e15228SEd Tanous getEthernetIfaceData( 526b9e15228SEd Tanous [asyncResp, ntpServerObjects]( 527e634b34cSEd Tanous const bool success, std::vector<std::string>& currentNtpServers, 528b9e15228SEd Tanous const std::vector<std::string>& /*domainNames*/) { 529b9e15228SEd Tanous if (!success) 530b9e15228SEd Tanous { 531b9e15228SEd Tanous messages::internalError(asyncResp->res); 532b9e15228SEd Tanous return; 533b9e15228SEd Tanous } 534b9e15228SEd Tanous handleNTPServersPatch(asyncResp, *ntpServerObjects, 535b9e15228SEd Tanous std::move(currentNtpServers)); 536b9e15228SEd Tanous }); 53720e6ea5dSraviteja-b } 53867a78d87STom Joseph 5395f4c798dSJiaqing Zhao if (ipmiEnabled) 54067a78d87STom Joseph { 541e5a99777SAlbert Zhang handleProtocolEnabled( 5425f4c798dSJiaqing Zhao *ipmiEnabled, asyncResp, 54369320d54SJiaqing Zhao encodeServiceObjectPath(std::string(ipmiServiceName) + '@')); 544e5a99777SAlbert Zhang } 545e5a99777SAlbert Zhang 5465f4c798dSJiaqing Zhao if (sshEnabled) 547e5a99777SAlbert Zhang { 54869320d54SJiaqing Zhao handleProtocolEnabled(*sshEnabled, asyncResp, 54969320d54SJiaqing Zhao encodeServiceObjectPath(sshServiceName)); 55067a78d87STom Joseph } 551e634b34cSEd Tanous } 552e634b34cSEd Tanous 553af20dd1cSEd Tanous inline void handleManagersNetworkProtocolHead( 554e634b34cSEd Tanous App& app, const crow::Request& req, 555e634b34cSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 556e634b34cSEd Tanous { 557e634b34cSEd Tanous if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 558e634b34cSEd Tanous { 559e634b34cSEd Tanous return; 560e634b34cSEd Tanous } 561af20dd1cSEd Tanous asyncResp->res.addHeader( 562af20dd1cSEd Tanous boost::beast::http::field::link, 563af20dd1cSEd Tanous "</redfish/v1/JsonSchemas/ManagerNetworkProtocol/ManagerNetworkProtocol.json>; rel=describedby"); 564af20dd1cSEd Tanous } 565af20dd1cSEd Tanous 566af20dd1cSEd Tanous inline void handleManagersNetworkProtocolGet( 567af20dd1cSEd Tanous App& app, const crow::Request& req, 568af20dd1cSEd Tanous const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 569af20dd1cSEd Tanous { 570af20dd1cSEd Tanous handleManagersNetworkProtocolHead(app, req, asyncResp); 571e634b34cSEd Tanous getNetworkData(asyncResp, req); 572e634b34cSEd Tanous } 573e634b34cSEd Tanous 574e634b34cSEd Tanous inline void requestRoutesNetworkProtocol(App& app) 575e634b34cSEd Tanous { 576e634b34cSEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 577e634b34cSEd Tanous .privileges(redfish::privileges::patchManagerNetworkProtocol) 578e634b34cSEd Tanous .methods(boost::beast::http::verb::patch)( 579e634b34cSEd Tanous std::bind_front(handleManagersNetworkProtocolPatch, std::ref(app))); 5807e860f15SJohn Edward Broadbent 5817e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 582e9f71672SEd Tanous .privileges(redfish::privileges::headManagerNetworkProtocol) 583e9f71672SEd Tanous .methods(boost::beast::http::verb::head)( 584af20dd1cSEd Tanous std::bind_front(handleManagersNetworkProtocolHead, std::ref(app))); 585e9f71672SEd Tanous 586e9f71672SEd Tanous BMCWEB_ROUTE(app, "/redfish/v1/Managers/bmc/NetworkProtocol/") 587ed398213SEd Tanous .privileges(redfish::privileges::getManagerNetworkProtocol) 5887e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::get)( 589e634b34cSEd Tanous std::bind_front(handleManagersNetworkProtocolGet, std::ref(app))); 590cf05f9dcSJohnathan Mantey } 59170141561SBorawski.Lukasz 59270141561SBorawski.Lukasz } // namespace redfish 593