1d5afb2caSAndrew Geissler #pragma once 2d5afb2caSAndrew Geissler 33ccb3adbSEd Tanous #include "app.hpp" 43ccb3adbSEd Tanous #include "dbus_singleton.hpp" 57a1dbc48SGeorge Liu #include "dbus_utility.hpp" 63ccb3adbSEd Tanous #include "error_messages.hpp" 73ccb3adbSEd Tanous #include "ethernet.hpp" 83ccb3adbSEd Tanous #include "query.hpp" 93ccb3adbSEd Tanous #include "registries/privilege_registry.hpp" 10033f1e4dSEd Tanous #include "utils/ip_utils.hpp" 113ccb3adbSEd Tanous #include "utils/json_utils.hpp" 12033f1e4dSEd Tanous 13d5afb2caSAndrew Geissler #include <boost/container/flat_set.hpp> 141e1e598dSJonathan Doman #include <sdbusplus/asio/property.hpp> 15d5afb2caSAndrew Geissler 167a1dbc48SGeorge Liu #include <array> 17d5afb2caSAndrew Geissler #include <optional> 187a1dbc48SGeorge Liu #include <string_view> 19d5afb2caSAndrew Geissler #include <utility> 20d5afb2caSAndrew Geissler 2188a8a174SEd Tanous namespace redfish 22d5afb2caSAndrew Geissler { 23d5afb2caSAndrew Geissler 24d5afb2caSAndrew Geissler /** 25cc0bb6f2SAndrew Geissler * @brief Retrieves hypervisor state properties over dbus 26cc0bb6f2SAndrew Geissler * 27cc0bb6f2SAndrew Geissler * The hypervisor state object is optional so this function will only set the 28cc0bb6f2SAndrew Geissler * state variables if the object is found 29cc0bb6f2SAndrew Geissler * 30cc0bb6f2SAndrew Geissler * @param[in] aResp Shared pointer for completing asynchronous calls. 31cc0bb6f2SAndrew Geissler * 32cc0bb6f2SAndrew Geissler * @return None. 33cc0bb6f2SAndrew Geissler */ 348d1b46d7Szhanghch05 inline void getHypervisorState(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 35cc0bb6f2SAndrew Geissler { 36cc0bb6f2SAndrew Geissler BMCWEB_LOG_DEBUG << "Get hypervisor state information."; 371e1e598dSJonathan Doman sdbusplus::asio::getProperty<std::string>( 381e1e598dSJonathan Doman *crow::connections::systemBus, "xyz.openbmc_project.State.Hypervisor", 391e1e598dSJonathan Doman "/xyz/openbmc_project/state/hypervisor0", 401e1e598dSJonathan Doman "xyz.openbmc_project.State.Host", "CurrentHostState", 415e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec, 421e1e598dSJonathan Doman const std::string& hostState) { 43cc0bb6f2SAndrew Geissler if (ec) 44cc0bb6f2SAndrew Geissler { 45cc0bb6f2SAndrew Geissler BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 46cc0bb6f2SAndrew Geissler // This is an optional D-Bus object so just return if 47cc0bb6f2SAndrew Geissler // error occurs 48cc0bb6f2SAndrew Geissler return; 49cc0bb6f2SAndrew Geissler } 50cc0bb6f2SAndrew Geissler 511e1e598dSJonathan Doman BMCWEB_LOG_DEBUG << "Hypervisor state: " << hostState; 52cc0bb6f2SAndrew Geissler // Verify Host State 531e1e598dSJonathan Doman if (hostState == "xyz.openbmc_project.State.Host.HostState.Running") 54cc0bb6f2SAndrew Geissler { 55cc0bb6f2SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 56cc0bb6f2SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Enabled"; 57cc0bb6f2SAndrew Geissler } 581e1e598dSJonathan Doman else if (hostState == "xyz.openbmc_project.State.Host.HostState." 591e1e598dSJonathan Doman "Quiesced") 60cc0bb6f2SAndrew Geissler { 61cc0bb6f2SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 62cc0bb6f2SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Quiesced"; 63cc0bb6f2SAndrew Geissler } 641e1e598dSJonathan Doman else if (hostState == "xyz.openbmc_project.State.Host.HostState." 651e1e598dSJonathan Doman "Standby") 66cc0bb6f2SAndrew Geissler { 67cc0bb6f2SAndrew Geissler aResp->res.jsonValue["PowerState"] = "On"; 68cc0bb6f2SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "StandbyOffline"; 69cc0bb6f2SAndrew Geissler } 701e1e598dSJonathan Doman else if (hostState == "xyz.openbmc_project.State.Host.HostState." 711e1e598dSJonathan Doman "TransitioningToRunning") 72cc0bb6f2SAndrew Geissler { 73cc0bb6f2SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOn"; 74cc0bb6f2SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Starting"; 75cc0bb6f2SAndrew Geissler } 761e1e598dSJonathan Doman else if (hostState == "xyz.openbmc_project.State.Host.HostState." 771e1e598dSJonathan Doman "TransitioningToOff") 78cc0bb6f2SAndrew Geissler { 79cc0bb6f2SAndrew Geissler aResp->res.jsonValue["PowerState"] = "PoweringOff"; 80cc0bb6f2SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Enabled"; 81cc0bb6f2SAndrew Geissler } 82002d39b4SEd Tanous else if (hostState == "xyz.openbmc_project.State.Host.HostState.Off") 83cc0bb6f2SAndrew Geissler { 84cc0bb6f2SAndrew Geissler aResp->res.jsonValue["PowerState"] = "Off"; 85cc0bb6f2SAndrew Geissler aResp->res.jsonValue["Status"]["State"] = "Disabled"; 86cc0bb6f2SAndrew Geissler } 87cc0bb6f2SAndrew Geissler else 88cc0bb6f2SAndrew Geissler { 89cc0bb6f2SAndrew Geissler messages::internalError(aResp->res); 90cc0bb6f2SAndrew Geissler return; 91cc0bb6f2SAndrew Geissler } 921e1e598dSJonathan Doman }); 93cc0bb6f2SAndrew Geissler } 94cc0bb6f2SAndrew Geissler 95cc0bb6f2SAndrew Geissler /** 964fbaf64aSAndrew Geissler * @brief Populate Actions if any are valid for hypervisor object 974fbaf64aSAndrew Geissler * 984fbaf64aSAndrew Geissler * The hypervisor state object is optional so this function will only set the 994fbaf64aSAndrew Geissler * Action if the object is found 1004fbaf64aSAndrew Geissler * 1014fbaf64aSAndrew Geissler * @param[in] aResp Shared pointer for completing asynchronous calls. 1024fbaf64aSAndrew Geissler * 1034fbaf64aSAndrew Geissler * @return None. 1044fbaf64aSAndrew Geissler */ 1058d1b46d7Szhanghch05 inline void 1068d1b46d7Szhanghch05 getHypervisorActions(const std::shared_ptr<bmcweb::AsyncResp>& aResp) 1074fbaf64aSAndrew Geissler { 1084fbaf64aSAndrew Geissler BMCWEB_LOG_DEBUG << "Get hypervisor actions."; 1092b73119cSGeorge Liu constexpr std::array<std::string_view, 1> interfaces = { 1102b73119cSGeorge Liu "xyz.openbmc_project.State.Host"}; 1112b73119cSGeorge Liu dbus::utility::getDbusObject( 1122b73119cSGeorge Liu "/xyz/openbmc_project/state/hypervisor0", interfaces, 1134fbaf64aSAndrew Geissler [aResp]( 1142b73119cSGeorge Liu const boost::system::error_code& ec, 1154fbaf64aSAndrew Geissler const std::vector<std::pair<std::string, std::vector<std::string>>>& 1164fbaf64aSAndrew Geissler objInfo) { 1174fbaf64aSAndrew Geissler if (ec) 1184fbaf64aSAndrew Geissler { 1194fbaf64aSAndrew Geissler BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 1204fbaf64aSAndrew Geissler // This is an optional D-Bus object so just return if 1214fbaf64aSAndrew Geissler // error occurs 1224fbaf64aSAndrew Geissler return; 1234fbaf64aSAndrew Geissler } 1244fbaf64aSAndrew Geissler 12526f6976fSEd Tanous if (objInfo.empty()) 1264fbaf64aSAndrew Geissler { 1274fbaf64aSAndrew Geissler // As noted above, this is an optional interface so just return 1284fbaf64aSAndrew Geissler // if there is no instance found 1294fbaf64aSAndrew Geissler return; 1304fbaf64aSAndrew Geissler } 1314fbaf64aSAndrew Geissler 1324fbaf64aSAndrew Geissler if (objInfo.size() > 1) 1334fbaf64aSAndrew Geissler { 1344fbaf64aSAndrew Geissler // More then one hypervisor object is not supported and is an 1354fbaf64aSAndrew Geissler // error 1364fbaf64aSAndrew Geissler messages::internalError(aResp->res); 1374fbaf64aSAndrew Geissler return; 1384fbaf64aSAndrew Geissler } 1394fbaf64aSAndrew Geissler 1404fbaf64aSAndrew Geissler // Object present so system support limited ComputerSystem Action 141613dabeaSEd Tanous nlohmann::json& reset = 142613dabeaSEd Tanous aResp->res.jsonValue["Actions"]["#ComputerSystem.Reset"]; 143613dabeaSEd Tanous reset["target"] = 144613dabeaSEd Tanous "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset"; 145613dabeaSEd Tanous reset["@Redfish.ActionInfo"] = 146613dabeaSEd Tanous "/redfish/v1/Systems/hypervisor/ResetActionInfo"; 1472b73119cSGeorge Liu }); 1484fbaf64aSAndrew Geissler } 1494fbaf64aSAndrew Geissler 150d5afb2caSAndrew Geissler inline bool extractHypervisorInterfaceData( 151711ac7a9SEd Tanous const std::string& ethIfaceId, 152711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& dbusData, 153d5afb2caSAndrew Geissler EthernetInterfaceData& ethData, 154d5afb2caSAndrew Geissler boost::container::flat_set<IPv4AddressData>& ipv4Config) 155d5afb2caSAndrew Geissler { 156d5afb2caSAndrew Geissler bool idFound = false; 157d5afb2caSAndrew Geissler for (const auto& objpath : dbusData) 158d5afb2caSAndrew Geissler { 159d5afb2caSAndrew Geissler for (const auto& ifacePair : objpath.second) 160d5afb2caSAndrew Geissler { 161d5afb2caSAndrew Geissler if (objpath.first == 162d5afb2caSAndrew Geissler "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId) 163d5afb2caSAndrew Geissler { 164d5afb2caSAndrew Geissler idFound = true; 165d5afb2caSAndrew Geissler if (ifacePair.first == "xyz.openbmc_project.Network.MACAddress") 166d5afb2caSAndrew Geissler { 167d5afb2caSAndrew Geissler for (const auto& propertyPair : ifacePair.second) 168d5afb2caSAndrew Geissler { 169d5afb2caSAndrew Geissler if (propertyPair.first == "MACAddress") 170d5afb2caSAndrew Geissler { 171d5afb2caSAndrew Geissler const std::string* mac = 172d5afb2caSAndrew Geissler std::get_if<std::string>(&propertyPair.second); 173d5afb2caSAndrew Geissler if (mac != nullptr) 174d5afb2caSAndrew Geissler { 17582695a5bSJiaqing Zhao ethData.macAddress = *mac; 176d5afb2caSAndrew Geissler } 177d5afb2caSAndrew Geissler } 178d5afb2caSAndrew Geissler } 179d5afb2caSAndrew Geissler } 180d5afb2caSAndrew Geissler else if (ifacePair.first == 181d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.EthernetInterface") 182d5afb2caSAndrew Geissler { 183d5afb2caSAndrew Geissler for (const auto& propertyPair : ifacePair.second) 184d5afb2caSAndrew Geissler { 185d5afb2caSAndrew Geissler if (propertyPair.first == "DHCPEnabled") 186d5afb2caSAndrew Geissler { 187d5afb2caSAndrew Geissler const std::string* dhcp = 188d5afb2caSAndrew Geissler std::get_if<std::string>(&propertyPair.second); 189d5afb2caSAndrew Geissler if (dhcp != nullptr) 190d5afb2caSAndrew Geissler { 19182695a5bSJiaqing Zhao ethData.dhcpEnabled = *dhcp; 192d5afb2caSAndrew Geissler break; // Interested on only "DHCPEnabled". 193d5afb2caSAndrew Geissler // Stop parsing since we got the 194d5afb2caSAndrew Geissler // "DHCPEnabled" value. 195d5afb2caSAndrew Geissler } 196d5afb2caSAndrew Geissler } 197d5afb2caSAndrew Geissler } 198d5afb2caSAndrew Geissler } 199d5afb2caSAndrew Geissler } 200d5afb2caSAndrew Geissler if (objpath.first == "/xyz/openbmc_project/network/hypervisor/" + 201d5afb2caSAndrew Geissler ethIfaceId + "/ipv4/addr0") 202d5afb2caSAndrew Geissler { 203d5afb2caSAndrew Geissler std::pair<boost::container::flat_set<IPv4AddressData>::iterator, 204d5afb2caSAndrew Geissler bool> 205d5afb2caSAndrew Geissler it = ipv4Config.insert(IPv4AddressData{}); 206d5afb2caSAndrew Geissler IPv4AddressData& ipv4Address = *it.first; 207d5afb2caSAndrew Geissler if (ifacePair.first == "xyz.openbmc_project.Object.Enable") 208d5afb2caSAndrew Geissler { 2099eb808c1SEd Tanous for (const auto& property : ifacePair.second) 210d5afb2caSAndrew Geissler { 211d5afb2caSAndrew Geissler if (property.first == "Enabled") 212d5afb2caSAndrew Geissler { 213d5afb2caSAndrew Geissler const bool* intfEnable = 214d5afb2caSAndrew Geissler std::get_if<bool>(&property.second); 215d5afb2caSAndrew Geissler if (intfEnable != nullptr) 216d5afb2caSAndrew Geissler { 217d5afb2caSAndrew Geissler ipv4Address.isActive = *intfEnable; 218d5afb2caSAndrew Geissler break; 219d5afb2caSAndrew Geissler } 220d5afb2caSAndrew Geissler } 221d5afb2caSAndrew Geissler } 222d5afb2caSAndrew Geissler } 223d5afb2caSAndrew Geissler if (ifacePair.first == "xyz.openbmc_project.Network.IP") 224d5afb2caSAndrew Geissler { 2259eb808c1SEd Tanous for (const auto& property : ifacePair.second) 226d5afb2caSAndrew Geissler { 227d5afb2caSAndrew Geissler if (property.first == "Address") 228d5afb2caSAndrew Geissler { 229d5afb2caSAndrew Geissler const std::string* address = 230d5afb2caSAndrew Geissler std::get_if<std::string>(&property.second); 231d5afb2caSAndrew Geissler if (address != nullptr) 232d5afb2caSAndrew Geissler { 233d5afb2caSAndrew Geissler ipv4Address.address = *address; 234d5afb2caSAndrew Geissler } 235d5afb2caSAndrew Geissler } 236d5afb2caSAndrew Geissler else if (property.first == "Origin") 237d5afb2caSAndrew Geissler { 238d5afb2caSAndrew Geissler const std::string* origin = 239d5afb2caSAndrew Geissler std::get_if<std::string>(&property.second); 240d5afb2caSAndrew Geissler if (origin != nullptr) 241d5afb2caSAndrew Geissler { 242d5afb2caSAndrew Geissler ipv4Address.origin = 243d5afb2caSAndrew Geissler translateAddressOriginDbusToRedfish(*origin, 244d5afb2caSAndrew Geissler true); 245d5afb2caSAndrew Geissler } 246d5afb2caSAndrew Geissler } 247d5afb2caSAndrew Geissler else if (property.first == "PrefixLength") 248d5afb2caSAndrew Geissler { 249d5afb2caSAndrew Geissler const uint8_t* mask = 250d5afb2caSAndrew Geissler std::get_if<uint8_t>(&property.second); 251d5afb2caSAndrew Geissler if (mask != nullptr) 252d5afb2caSAndrew Geissler { 253d5afb2caSAndrew Geissler // convert it to the string 254d5afb2caSAndrew Geissler ipv4Address.netmask = getNetmask(*mask); 255d5afb2caSAndrew Geissler } 256d5afb2caSAndrew Geissler } 257889ff694SAsmitha Karunanithi else if (property.first == "Type" || 258889ff694SAsmitha Karunanithi property.first == "Gateway") 259889ff694SAsmitha Karunanithi { 260889ff694SAsmitha Karunanithi // Type & Gateway is not used 261889ff694SAsmitha Karunanithi continue; 262889ff694SAsmitha Karunanithi } 263d5afb2caSAndrew Geissler else 264d5afb2caSAndrew Geissler { 265d5afb2caSAndrew Geissler BMCWEB_LOG_ERROR 266d5afb2caSAndrew Geissler << "Got extra property: " << property.first 267d5afb2caSAndrew Geissler << " on the " << objpath.first.str << " object"; 268d5afb2caSAndrew Geissler } 269d5afb2caSAndrew Geissler } 270d5afb2caSAndrew Geissler } 271d5afb2caSAndrew Geissler } 272d5afb2caSAndrew Geissler if (objpath.first == "/xyz/openbmc_project/network/hypervisor") 273d5afb2caSAndrew Geissler { 274d5afb2caSAndrew Geissler // System configuration shows up in the global namespace, so no 275d5afb2caSAndrew Geissler // need to check eth number 276d5afb2caSAndrew Geissler if (ifacePair.first == 277d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.SystemConfiguration") 278d5afb2caSAndrew Geissler { 279d5afb2caSAndrew Geissler for (const auto& propertyPair : ifacePair.second) 280d5afb2caSAndrew Geissler { 281d5afb2caSAndrew Geissler if (propertyPair.first == "HostName") 282d5afb2caSAndrew Geissler { 283d5afb2caSAndrew Geissler const std::string* hostName = 284d5afb2caSAndrew Geissler std::get_if<std::string>(&propertyPair.second); 285d5afb2caSAndrew Geissler if (hostName != nullptr) 286d5afb2caSAndrew Geissler { 28782695a5bSJiaqing Zhao ethData.hostName = *hostName; 288d5afb2caSAndrew Geissler } 289d5afb2caSAndrew Geissler } 290d5afb2caSAndrew Geissler else if (propertyPair.first == "DefaultGateway") 291d5afb2caSAndrew Geissler { 292d5afb2caSAndrew Geissler const std::string* defaultGateway = 293d5afb2caSAndrew Geissler std::get_if<std::string>(&propertyPair.second); 294d5afb2caSAndrew Geissler if (defaultGateway != nullptr) 295d5afb2caSAndrew Geissler { 29682695a5bSJiaqing Zhao ethData.defaultGateway = *defaultGateway; 297d5afb2caSAndrew Geissler } 298d5afb2caSAndrew Geissler } 299d5afb2caSAndrew Geissler } 300d5afb2caSAndrew Geissler } 301d5afb2caSAndrew Geissler } 302d5afb2caSAndrew Geissler } 303d5afb2caSAndrew Geissler } 304d5afb2caSAndrew Geissler return idFound; 305d5afb2caSAndrew Geissler } 306d5afb2caSAndrew Geissler /** 307d5afb2caSAndrew Geissler * Function that retrieves all properties for given Hypervisor Ethernet 308d5afb2caSAndrew Geissler * Interface Object from Settings Manager 309d5afb2caSAndrew Geissler * @param ethIfaceId Hypervisor ethernet interface id to query on DBus 310d5afb2caSAndrew Geissler * @param callback a function that shall be called to convert Dbus output 311d5afb2caSAndrew Geissler * into JSON 312d5afb2caSAndrew Geissler */ 313d5afb2caSAndrew Geissler template <typename CallbackFunc> 314d5afb2caSAndrew Geissler void getHypervisorIfaceData(const std::string& ethIfaceId, 315d5afb2caSAndrew Geissler CallbackFunc&& callback) 316d5afb2caSAndrew Geissler { 317d5afb2caSAndrew Geissler crow::connections::systemBus->async_method_call( 318f94c4ecfSEd Tanous [ethIfaceId{std::string{ethIfaceId}}, 319f94c4ecfSEd Tanous callback{std::forward<CallbackFunc>(callback)}]( 3205e7e2dc5SEd Tanous const boost::system::error_code& error, 321711ac7a9SEd Tanous const dbus::utility::ManagedObjectType& resp) { 322d5afb2caSAndrew Geissler EthernetInterfaceData ethData{}; 323d5afb2caSAndrew Geissler boost::container::flat_set<IPv4AddressData> ipv4Data; 324d5afb2caSAndrew Geissler if (error) 325d5afb2caSAndrew Geissler { 326d5afb2caSAndrew Geissler callback(false, ethData, ipv4Data); 327d5afb2caSAndrew Geissler return; 328d5afb2caSAndrew Geissler } 329d5afb2caSAndrew Geissler 33089492a15SPatrick Williams bool found = extractHypervisorInterfaceData(ethIfaceId, resp, ethData, 33189492a15SPatrick Williams ipv4Data); 332d5afb2caSAndrew Geissler if (!found) 333d5afb2caSAndrew Geissler { 334d5afb2caSAndrew Geissler BMCWEB_LOG_INFO << "Hypervisor Interface not found"; 335d5afb2caSAndrew Geissler } 336d5afb2caSAndrew Geissler callback(found, ethData, ipv4Data); 337d5afb2caSAndrew Geissler }, 338d5afb2caSAndrew Geissler "xyz.openbmc_project.Settings", "/", 339d5afb2caSAndrew Geissler "org.freedesktop.DBus.ObjectManager", "GetManagedObjects"); 340d5afb2caSAndrew Geissler } 341d5afb2caSAndrew Geissler 342d5afb2caSAndrew Geissler /** 343d5afb2caSAndrew Geissler * @brief Sets the Hypervisor Interface IPAddress DBUS 344d5afb2caSAndrew Geissler * 345d5afb2caSAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 346d5afb2caSAndrew Geissler * @param[in] ipv4Address Address from the incoming request 347d5afb2caSAndrew Geissler * @param[in] ethIfaceId Hypervisor Interface Id 348d5afb2caSAndrew Geissler * 349d5afb2caSAndrew Geissler * @return None. 350d5afb2caSAndrew Geissler */ 3518d1b46d7Szhanghch05 inline void 3528d1b46d7Szhanghch05 setHypervisorIPv4Address(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 353d5afb2caSAndrew Geissler const std::string& ethIfaceId, 354d5afb2caSAndrew Geissler const std::string& ipv4Address) 355d5afb2caSAndrew Geissler { 356d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG << "Setting the Hypervisor IPaddress : " << ipv4Address 357d5afb2caSAndrew Geissler << " on Iface: " << ethIfaceId; 358d5afb2caSAndrew Geissler crow::connections::systemBus->async_method_call( 3595e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 360d5afb2caSAndrew Geissler if (ec) 361d5afb2caSAndrew Geissler { 362d5afb2caSAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 363d5afb2caSAndrew Geissler return; 364d5afb2caSAndrew Geissler } 365d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG << "Hypervisor IPaddress is Set"; 366d5afb2caSAndrew Geissler }, 367d5afb2caSAndrew Geissler "xyz.openbmc_project.Settings", 368d5afb2caSAndrew Geissler "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId + "/ipv4/addr0", 369d5afb2caSAndrew Geissler "org.freedesktop.DBus.Properties", "Set", 370d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.IP", "Address", 371168e20c1SEd Tanous dbus::utility::DbusVariantType(ipv4Address)); 372d5afb2caSAndrew Geissler } 373d5afb2caSAndrew Geissler 374d5afb2caSAndrew Geissler /** 375d5afb2caSAndrew Geissler * @brief Sets the Hypervisor Interface SubnetMask DBUS 376d5afb2caSAndrew Geissler * 377d5afb2caSAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 378d5afb2caSAndrew Geissler * @param[in] subnet SubnetMask from the incoming request 379d5afb2caSAndrew Geissler * @param[in] ethIfaceId Hypervisor Interface Id 380d5afb2caSAndrew Geissler * 381d5afb2caSAndrew Geissler * @return None. 382d5afb2caSAndrew Geissler */ 3838d1b46d7Szhanghch05 inline void 3848d1b46d7Szhanghch05 setHypervisorIPv4Subnet(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 3858d1b46d7Szhanghch05 const std::string& ethIfaceId, const uint8_t subnet) 386d5afb2caSAndrew Geissler { 387d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG << "Setting the Hypervisor subnet : " << subnet 388d5afb2caSAndrew Geissler << " on Iface: " << ethIfaceId; 389d5afb2caSAndrew Geissler 390d5afb2caSAndrew Geissler crow::connections::systemBus->async_method_call( 3915e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 392d5afb2caSAndrew Geissler if (ec) 393d5afb2caSAndrew Geissler { 394d5afb2caSAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 395d5afb2caSAndrew Geissler return; 396d5afb2caSAndrew Geissler } 397d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG << "SubnetMask is Set"; 398d5afb2caSAndrew Geissler }, 399d5afb2caSAndrew Geissler "xyz.openbmc_project.Settings", 400d5afb2caSAndrew Geissler "/xyz/openbmc_project/network/hypervisor/" + ethIfaceId + "/ipv4/addr0", 401d5afb2caSAndrew Geissler "org.freedesktop.DBus.Properties", "Set", 402d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.IP", "PrefixLength", 403168e20c1SEd Tanous dbus::utility::DbusVariantType(subnet)); 404d5afb2caSAndrew Geissler } 405d5afb2caSAndrew Geissler 406d5afb2caSAndrew Geissler /** 407d5afb2caSAndrew Geissler * @brief Sets the Hypervisor Interface Gateway DBUS 408d5afb2caSAndrew Geissler * 409d5afb2caSAndrew Geissler * @param[in] aResp Shared pointer for generating response message. 410d5afb2caSAndrew Geissler * @param[in] gateway Gateway from the incoming request 411d5afb2caSAndrew Geissler * @param[in] ethIfaceId Hypervisor Interface Id 412d5afb2caSAndrew Geissler * 413d5afb2caSAndrew Geissler * @return None. 414d5afb2caSAndrew Geissler */ 4158d1b46d7Szhanghch05 inline void 4168d1b46d7Szhanghch05 setHypervisorIPv4Gateway(const std::shared_ptr<bmcweb::AsyncResp>& aResp, 417d5afb2caSAndrew Geissler const std::string& gateway) 418d5afb2caSAndrew Geissler { 419d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG 420d5afb2caSAndrew Geissler << "Setting the DefaultGateway to the last configured gateway"; 421d5afb2caSAndrew Geissler 422d5afb2caSAndrew Geissler crow::connections::systemBus->async_method_call( 4235e7e2dc5SEd Tanous [aResp](const boost::system::error_code& ec) { 424d5afb2caSAndrew Geissler if (ec) 425d5afb2caSAndrew Geissler { 426d5afb2caSAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 427d5afb2caSAndrew Geissler return; 428d5afb2caSAndrew Geissler } 429d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG << "Default Gateway is Set"; 430d5afb2caSAndrew Geissler }, 431d5afb2caSAndrew Geissler "xyz.openbmc_project.Settings", 432d5afb2caSAndrew Geissler "/xyz/openbmc_project/network/hypervisor", 433d5afb2caSAndrew Geissler "org.freedesktop.DBus.Properties", "Set", 434d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.SystemConfiguration", "DefaultGateway", 435168e20c1SEd Tanous dbus::utility::DbusVariantType(gateway)); 436d5afb2caSAndrew Geissler } 437d5afb2caSAndrew Geissler 438d5afb2caSAndrew Geissler /** 439d5afb2caSAndrew Geissler * @brief Creates a static IPv4 entry 440d5afb2caSAndrew Geissler * 441d5afb2caSAndrew Geissler * @param[in] ifaceId Id of interface upon which to create the IPv4 entry 442d5afb2caSAndrew Geissler * @param[in] prefixLength IPv4 prefix syntax for the subnet mask 443d5afb2caSAndrew Geissler * @param[in] gateway IPv4 address of this interfaces gateway 444d5afb2caSAndrew Geissler * @param[in] address IPv4 address to assign to this interface 445d5afb2caSAndrew Geissler * @param[io] asyncResp Response object that will be returned to client 446d5afb2caSAndrew Geissler * 447d5afb2caSAndrew Geissler * @return None 448d5afb2caSAndrew Geissler */ 4498d1b46d7Szhanghch05 inline void 4508d1b46d7Szhanghch05 createHypervisorIPv4(const std::string& ifaceId, uint8_t prefixLength, 4518d1b46d7Szhanghch05 const std::string& gateway, const std::string& address, 4528d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 453d5afb2caSAndrew Geissler { 454d5afb2caSAndrew Geissler setHypervisorIPv4Address(asyncResp, ifaceId, address); 455d5afb2caSAndrew Geissler setHypervisorIPv4Gateway(asyncResp, gateway); 456d5afb2caSAndrew Geissler setHypervisorIPv4Subnet(asyncResp, ifaceId, prefixLength); 457d5afb2caSAndrew Geissler } 458d5afb2caSAndrew Geissler 459d5afb2caSAndrew Geissler /** 460d5afb2caSAndrew Geissler * @brief Deletes given IPv4 interface 461d5afb2caSAndrew Geissler * 462d5afb2caSAndrew Geissler * @param[in] ifaceId Id of interface whose IP should be deleted 463d5afb2caSAndrew Geissler * @param[io] asyncResp Response object that will be returned to client 464d5afb2caSAndrew Geissler * 465d5afb2caSAndrew Geissler * @return None 466d5afb2caSAndrew Geissler */ 4678d1b46d7Szhanghch05 inline void 4688d1b46d7Szhanghch05 deleteHypervisorIPv4(const std::string& ifaceId, 4698d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 470d5afb2caSAndrew Geissler { 471d5afb2caSAndrew Geissler std::string address = "0.0.0.0"; 472d5afb2caSAndrew Geissler std::string gateway = "0.0.0.0"; 473d5afb2caSAndrew Geissler const uint8_t prefixLength = 0; 474d5afb2caSAndrew Geissler setHypervisorIPv4Address(asyncResp, ifaceId, address); 475d5afb2caSAndrew Geissler setHypervisorIPv4Gateway(asyncResp, gateway); 476d5afb2caSAndrew Geissler setHypervisorIPv4Subnet(asyncResp, ifaceId, prefixLength); 477d5afb2caSAndrew Geissler } 478d5afb2caSAndrew Geissler 4797e860f15SJohn Edward Broadbent inline void parseInterfaceData( 480d5afb2caSAndrew Geissler nlohmann::json& jsonResponse, const std::string& ifaceId, 481d5afb2caSAndrew Geissler const EthernetInterfaceData& ethData, 482d5afb2caSAndrew Geissler const boost::container::flat_set<IPv4AddressData>& ipv4Data) 483d5afb2caSAndrew Geissler { 484d5afb2caSAndrew Geissler jsonResponse["Id"] = ifaceId; 485d5afb2caSAndrew Geissler jsonResponse["@odata.id"] = 486eddfc437SWilly Tu crow::utility::urlFromPieces("redfish", "v1", "Systems", "hypervisor", 487eddfc437SWilly Tu "EthernetInterfaces", ifaceId); 488d5afb2caSAndrew Geissler jsonResponse["InterfaceEnabled"] = true; 48982695a5bSJiaqing Zhao jsonResponse["MACAddress"] = ethData.macAddress; 490d5afb2caSAndrew Geissler 49182695a5bSJiaqing Zhao jsonResponse["HostName"] = ethData.hostName; 492d5afb2caSAndrew Geissler jsonResponse["DHCPv4"]["DHCPEnabled"] = 49382695a5bSJiaqing Zhao translateDhcpEnabledToBool(ethData.dhcpEnabled, true); 494d5afb2caSAndrew Geissler 495d5afb2caSAndrew Geissler nlohmann::json& ipv4Array = jsonResponse["IPv4Addresses"]; 496d5afb2caSAndrew Geissler nlohmann::json& ipv4StaticArray = jsonResponse["IPv4StaticAddresses"]; 497d5afb2caSAndrew Geissler ipv4Array = nlohmann::json::array(); 498d5afb2caSAndrew Geissler ipv4StaticArray = nlohmann::json::array(); 4999eb808c1SEd Tanous for (const auto& ipv4Config : ipv4Data) 500d5afb2caSAndrew Geissler { 501d5afb2caSAndrew Geissler if (ipv4Config.isActive) 502d5afb2caSAndrew Geissler { 5031476687dSEd Tanous nlohmann::json::object_t ipv4; 5041476687dSEd Tanous ipv4["AddressOrigin"] = ipv4Config.origin; 5051476687dSEd Tanous ipv4["SubnetMask"] = ipv4Config.netmask; 5061476687dSEd Tanous ipv4["Address"] = ipv4Config.address; 5071476687dSEd Tanous ipv4["Gateway"] = ethData.defaultGateway; 508d5afb2caSAndrew Geissler 509d5afb2caSAndrew Geissler if (ipv4Config.origin == "Static") 510d5afb2caSAndrew Geissler { 5111476687dSEd Tanous ipv4StaticArray.push_back(ipv4); 512d5afb2caSAndrew Geissler } 5131476687dSEd Tanous ipv4Array.push_back(std::move(ipv4)); 514d5afb2caSAndrew Geissler } 515d5afb2caSAndrew Geissler } 516d5afb2caSAndrew Geissler } 517d5afb2caSAndrew Geissler 5187e860f15SJohn Edward Broadbent inline void setDHCPEnabled(const std::string& ifaceId, 5197e860f15SJohn Edward Broadbent const bool& ipv4DHCPEnabled, 5208d1b46d7Szhanghch05 const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 521d5afb2caSAndrew Geissler { 5227e860f15SJohn Edward Broadbent const std::string dhcp = getDhcpEnabledEnumeration(ipv4DHCPEnabled, false); 523d5afb2caSAndrew Geissler crow::connections::systemBus->async_method_call( 5245e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 525d5afb2caSAndrew Geissler if (ec) 526d5afb2caSAndrew Geissler { 527d5afb2caSAndrew Geissler BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 528d5afb2caSAndrew Geissler messages::internalError(asyncResp->res); 529d5afb2caSAndrew Geissler return; 530d5afb2caSAndrew Geissler } 531d5afb2caSAndrew Geissler }, 532d5afb2caSAndrew Geissler "xyz.openbmc_project.Settings", 533d5afb2caSAndrew Geissler "/xyz/openbmc_project/network/hypervisor/" + ifaceId, 534d5afb2caSAndrew Geissler "org.freedesktop.DBus.Properties", "Set", 535d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.EthernetInterface", "DHCPEnabled", 536168e20c1SEd Tanous dbus::utility::DbusVariantType{dhcp}); 537d5afb2caSAndrew Geissler 538d5afb2caSAndrew Geissler // Set the IPv4 address origin to the DHCP / Static as per the new value 539d5afb2caSAndrew Geissler // of the DHCPEnabled property 540d5afb2caSAndrew Geissler std::string origin; 541e05aec50SEd Tanous if (!ipv4DHCPEnabled) 542d5afb2caSAndrew Geissler { 543d5afb2caSAndrew Geissler origin = "xyz.openbmc_project.Network.IP.AddressOrigin.Static"; 544d5afb2caSAndrew Geissler } 545d5afb2caSAndrew Geissler else 546d5afb2caSAndrew Geissler { 547d5afb2caSAndrew Geissler // DHCPEnabled is set to true. Delete the current IPv4 settings 548d5afb2caSAndrew Geissler // to receive the new values from DHCP server. 549d5afb2caSAndrew Geissler deleteHypervisorIPv4(ifaceId, asyncResp); 550d5afb2caSAndrew Geissler origin = "xyz.openbmc_project.Network.IP.AddressOrigin.DHCP"; 551d5afb2caSAndrew Geissler } 552d5afb2caSAndrew Geissler crow::connections::systemBus->async_method_call( 5535e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 554d5afb2caSAndrew Geissler if (ec) 555d5afb2caSAndrew Geissler { 556d5afb2caSAndrew Geissler BMCWEB_LOG_ERROR << "DBUS response error " << ec; 557d5afb2caSAndrew Geissler messages::internalError(asyncResp->res); 558d5afb2caSAndrew Geissler return; 559d5afb2caSAndrew Geissler } 560d5afb2caSAndrew Geissler BMCWEB_LOG_DEBUG << "Hypervisor IPaddress Origin is Set"; 561d5afb2caSAndrew Geissler }, 562d5afb2caSAndrew Geissler "xyz.openbmc_project.Settings", 5637e860f15SJohn Edward Broadbent "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0", 564d5afb2caSAndrew Geissler "org.freedesktop.DBus.Properties", "Set", 565d5afb2caSAndrew Geissler "xyz.openbmc_project.Network.IP", "Origin", 566168e20c1SEd Tanous dbus::utility::DbusVariantType(origin)); 567d5afb2caSAndrew Geissler } 568d5afb2caSAndrew Geissler 5697e860f15SJohn Edward Broadbent inline void handleHypervisorIPv4StaticPatch( 5707e860f15SJohn Edward Broadbent const std::string& ifaceId, const nlohmann::json& input, 5717e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 572d5afb2caSAndrew Geissler { 5737e860f15SJohn Edward Broadbent if ((!input.is_array()) || input.empty()) 574d5afb2caSAndrew Geissler { 5757e860f15SJohn Edward Broadbent messages::propertyValueTypeError(asyncResp->res, input.dump(), 5767e860f15SJohn Edward Broadbent "IPv4StaticAddresses"); 577d5afb2caSAndrew Geissler return; 578d5afb2caSAndrew Geissler } 579d5afb2caSAndrew Geissler 5807e860f15SJohn Edward Broadbent // Hypervisor considers the first IP address in the array list 5817e860f15SJohn Edward Broadbent // as the Hypervisor's virtual management interface supports single IPv4 5827e860f15SJohn Edward Broadbent // address 5837e860f15SJohn Edward Broadbent const nlohmann::json& thisJson = input[0]; 5847e860f15SJohn Edward Broadbent 5857e860f15SJohn Edward Broadbent if (!thisJson.is_null() && !thisJson.empty()) 5867e860f15SJohn Edward Broadbent { 587f8fe53e7SEd Tanous // For the error string 588f8fe53e7SEd Tanous std::string pathString = "IPv4StaticAddresses/1"; 5897e860f15SJohn Edward Broadbent std::optional<std::string> address; 5907e860f15SJohn Edward Broadbent std::optional<std::string> subnetMask; 5917e860f15SJohn Edward Broadbent std::optional<std::string> gateway; 5927e860f15SJohn Edward Broadbent nlohmann::json thisJsonCopy = thisJson; 5937e860f15SJohn Edward Broadbent if (!json_util::readJson(thisJsonCopy, asyncResp->res, "Address", 5947e860f15SJohn Edward Broadbent address, "SubnetMask", subnetMask, "Gateway", 5957e860f15SJohn Edward Broadbent gateway)) 5967e860f15SJohn Edward Broadbent { 5977e860f15SJohn Edward Broadbent messages::propertyValueFormatError( 5987e860f15SJohn Edward Broadbent asyncResp->res, 5997e860f15SJohn Edward Broadbent thisJson.dump(2, ' ', true, 6007e860f15SJohn Edward Broadbent nlohmann::json::error_handler_t::replace), 6017e860f15SJohn Edward Broadbent pathString); 6027e860f15SJohn Edward Broadbent return; 6037e860f15SJohn Edward Broadbent } 6047e860f15SJohn Edward Broadbent 6057e860f15SJohn Edward Broadbent uint8_t prefixLength = 0; 6067e860f15SJohn Edward Broadbent bool errorInEntry = false; 6077e860f15SJohn Edward Broadbent if (address) 6087e860f15SJohn Edward Broadbent { 609033f1e4dSEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*address)) 6107e860f15SJohn Edward Broadbent { 6117e860f15SJohn Edward Broadbent messages::propertyValueFormatError(asyncResp->res, *address, 6127e860f15SJohn Edward Broadbent pathString + "/Address"); 6137e860f15SJohn Edward Broadbent errorInEntry = true; 6147e860f15SJohn Edward Broadbent } 6157e860f15SJohn Edward Broadbent } 6167e860f15SJohn Edward Broadbent else 6177e860f15SJohn Edward Broadbent { 6187e860f15SJohn Edward Broadbent messages::propertyMissing(asyncResp->res, pathString + "/Address"); 6197e860f15SJohn Edward Broadbent errorInEntry = true; 6207e860f15SJohn Edward Broadbent } 6217e860f15SJohn Edward Broadbent 6227e860f15SJohn Edward Broadbent if (subnetMask) 6237e860f15SJohn Edward Broadbent { 624033f1e4dSEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*subnetMask, 625033f1e4dSEd Tanous &prefixLength)) 6267e860f15SJohn Edward Broadbent { 6277e860f15SJohn Edward Broadbent messages::propertyValueFormatError(asyncResp->res, *subnetMask, 6287e860f15SJohn Edward Broadbent pathString + "/SubnetMask"); 6297e860f15SJohn Edward Broadbent errorInEntry = true; 6307e860f15SJohn Edward Broadbent } 6317e860f15SJohn Edward Broadbent } 6327e860f15SJohn Edward Broadbent else 6337e860f15SJohn Edward Broadbent { 6347e860f15SJohn Edward Broadbent messages::propertyMissing(asyncResp->res, 6357e860f15SJohn Edward Broadbent pathString + "/SubnetMask"); 6367e860f15SJohn Edward Broadbent errorInEntry = true; 6377e860f15SJohn Edward Broadbent } 6387e860f15SJohn Edward Broadbent 6397e860f15SJohn Edward Broadbent if (gateway) 6407e860f15SJohn Edward Broadbent { 641033f1e4dSEd Tanous if (!ip_util::ipv4VerifyIpAndGetBitcount(*gateway)) 6427e860f15SJohn Edward Broadbent { 6437e860f15SJohn Edward Broadbent messages::propertyValueFormatError(asyncResp->res, *gateway, 6447e860f15SJohn Edward Broadbent pathString + "/Gateway"); 6457e860f15SJohn Edward Broadbent errorInEntry = true; 6467e860f15SJohn Edward Broadbent } 6477e860f15SJohn Edward Broadbent } 6487e860f15SJohn Edward Broadbent else 6497e860f15SJohn Edward Broadbent { 6507e860f15SJohn Edward Broadbent messages::propertyMissing(asyncResp->res, pathString + "/Gateway"); 6517e860f15SJohn Edward Broadbent errorInEntry = true; 6527e860f15SJohn Edward Broadbent } 6537e860f15SJohn Edward Broadbent 6547e860f15SJohn Edward Broadbent if (errorInEntry) 6557e860f15SJohn Edward Broadbent { 6567e860f15SJohn Edward Broadbent return; 6577e860f15SJohn Edward Broadbent } 6587e860f15SJohn Edward Broadbent 6597e860f15SJohn Edward Broadbent BMCWEB_LOG_DEBUG << "Calling createHypervisorIPv4 on : " << ifaceId 6607e860f15SJohn Edward Broadbent << "," << *address; 6617e860f15SJohn Edward Broadbent createHypervisorIPv4(ifaceId, prefixLength, *gateway, *address, 6627e860f15SJohn Edward Broadbent asyncResp); 6637e860f15SJohn Edward Broadbent // Set the DHCPEnabled to false since the Static IPv4 is set 6647e860f15SJohn Edward Broadbent setDHCPEnabled(ifaceId, false, asyncResp); 6657e860f15SJohn Edward Broadbent } 6667e860f15SJohn Edward Broadbent else 6677e860f15SJohn Edward Broadbent { 6687e860f15SJohn Edward Broadbent if (thisJson.is_null()) 6697e860f15SJohn Edward Broadbent { 6707e860f15SJohn Edward Broadbent deleteHypervisorIPv4(ifaceId, asyncResp); 6717e860f15SJohn Edward Broadbent } 6727e860f15SJohn Edward Broadbent } 6737e860f15SJohn Edward Broadbent } 6747e860f15SJohn Edward Broadbent 67588a8a174SEd Tanous inline void handleHypervisorHostnamePatch( 67688a8a174SEd Tanous const std::string& hostName, 6777e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 6787e860f15SJohn Edward Broadbent { 6797e860f15SJohn Edward Broadbent if (!isHostnameValid(hostName)) 6807e860f15SJohn Edward Broadbent { 6817e860f15SJohn Edward Broadbent messages::propertyValueFormatError(asyncResp->res, hostName, 6827e860f15SJohn Edward Broadbent "HostName"); 6837e860f15SJohn Edward Broadbent return; 6847e860f15SJohn Edward Broadbent } 6857e860f15SJohn Edward Broadbent 6867e860f15SJohn Edward Broadbent asyncResp->res.jsonValue["HostName"] = hostName; 6877e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 6885e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 6897e860f15SJohn Edward Broadbent if (ec) 6907e860f15SJohn Edward Broadbent { 6917e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 6927e860f15SJohn Edward Broadbent } 6937e860f15SJohn Edward Broadbent }, 6947e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", 6957e860f15SJohn Edward Broadbent "/xyz/openbmc_project/network/hypervisor", 6967e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "Set", 6977e860f15SJohn Edward Broadbent "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 698168e20c1SEd Tanous dbus::utility::DbusVariantType(hostName)); 6997e860f15SJohn Edward Broadbent } 7007e860f15SJohn Edward Broadbent 7017e860f15SJohn Edward Broadbent inline void 7027e860f15SJohn Edward Broadbent setIPv4InterfaceEnabled(const std::string& ifaceId, const bool& isActive, 7037e860f15SJohn Edward Broadbent const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 7047e860f15SJohn Edward Broadbent { 7057e860f15SJohn Edward Broadbent crow::connections::systemBus->async_method_call( 7065e7e2dc5SEd Tanous [asyncResp](const boost::system::error_code& ec) { 7077e860f15SJohn Edward Broadbent if (ec) 7087e860f15SJohn Edward Broadbent { 7097e860f15SJohn Edward Broadbent BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 7107e860f15SJohn Edward Broadbent messages::internalError(asyncResp->res); 7117e860f15SJohn Edward Broadbent return; 7127e860f15SJohn Edward Broadbent } 7137e860f15SJohn Edward Broadbent }, 7147e860f15SJohn Edward Broadbent "xyz.openbmc_project.Settings", 7157e860f15SJohn Edward Broadbent "/xyz/openbmc_project/network/hypervisor/" + ifaceId + "/ipv4/addr0", 7167e860f15SJohn Edward Broadbent "org.freedesktop.DBus.Properties", "Set", 7177e860f15SJohn Edward Broadbent "xyz.openbmc_project.Object.Enable", "Enabled", 718168e20c1SEd Tanous dbus::utility::DbusVariantType(isActive)); 7197e860f15SJohn Edward Broadbent } 7207e860f15SJohn Edward Broadbent 721f40448e5SGunnar Mills inline void handleHypervisorEthernetInterfaceCollectionGet( 722f40448e5SGunnar Mills App& app, const crow::Request& req, 723f40448e5SGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 724f40448e5SGunnar Mills { 725f40448e5SGunnar Mills if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 726f40448e5SGunnar Mills { 727f40448e5SGunnar Mills return; 728f40448e5SGunnar Mills } 729f40448e5SGunnar Mills constexpr std::array<std::string_view, 1> interfaces = { 730f40448e5SGunnar Mills "xyz.openbmc_project.Network.EthernetInterface"}; 731f40448e5SGunnar Mills 732f40448e5SGunnar Mills dbus::utility::getSubTreePaths( 733f40448e5SGunnar Mills "/xyz/openbmc_project/network/hypervisor", 0, interfaces, 734f40448e5SGunnar Mills [asyncResp]( 735f40448e5SGunnar Mills const boost::system::error_code& error, 736f40448e5SGunnar Mills const dbus::utility::MapperGetSubTreePathsResponse& ifaceList) { 737f40448e5SGunnar Mills if (error) 738f40448e5SGunnar Mills { 739f40448e5SGunnar Mills messages::resourceNotFound(asyncResp->res, "System", "hypervisor"); 740f40448e5SGunnar Mills return; 741f40448e5SGunnar Mills } 742f40448e5SGunnar Mills asyncResp->res.jsonValue["@odata.type"] = 743f40448e5SGunnar Mills "#EthernetInterfaceCollection." 744f40448e5SGunnar Mills "EthernetInterfaceCollection"; 745f40448e5SGunnar Mills asyncResp->res.jsonValue["@odata.id"] = 746f40448e5SGunnar Mills "/redfish/v1/Systems/hypervisor/EthernetInterfaces"; 747f40448e5SGunnar Mills asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet " 748f40448e5SGunnar Mills "Interface Collection"; 749f40448e5SGunnar Mills asyncResp->res.jsonValue["Description"] = 750f40448e5SGunnar Mills "Collection of Virtual Management " 751f40448e5SGunnar Mills "Interfaces for the hypervisor"; 752f40448e5SGunnar Mills 753f40448e5SGunnar Mills nlohmann::json& ifaceArray = asyncResp->res.jsonValue["Members"]; 754f40448e5SGunnar Mills ifaceArray = nlohmann::json::array(); 755f40448e5SGunnar Mills for (const std::string& iface : ifaceList) 756f40448e5SGunnar Mills { 757f40448e5SGunnar Mills sdbusplus::message::object_path path(iface); 758f40448e5SGunnar Mills std::string name = path.filename(); 759f40448e5SGunnar Mills if (name.empty()) 760f40448e5SGunnar Mills { 761f40448e5SGunnar Mills continue; 762f40448e5SGunnar Mills } 763f40448e5SGunnar Mills nlohmann::json::object_t ethIface; 764f40448e5SGunnar Mills ethIface["@odata.id"] = crow::utility::urlFromPieces( 765f40448e5SGunnar Mills "redfish", "v1", "Systems", "hypervisor", "EthernetInterfaces", 766f40448e5SGunnar Mills name); 767f40448e5SGunnar Mills ifaceArray.push_back(std::move(ethIface)); 768f40448e5SGunnar Mills } 769f40448e5SGunnar Mills asyncResp->res.jsonValue["Members@odata.count"] = ifaceArray.size(); 770f40448e5SGunnar Mills }); 771f40448e5SGunnar Mills } 772f40448e5SGunnar Mills 773f40448e5SGunnar Mills inline void handleHypervisorEthernetInterfaceGet( 774f40448e5SGunnar Mills App& app, const crow::Request& req, 775f40448e5SGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, const std::string& id) 776f40448e5SGunnar Mills { 777f40448e5SGunnar Mills if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 778f40448e5SGunnar Mills { 779f40448e5SGunnar Mills return; 780f40448e5SGunnar Mills } 781f40448e5SGunnar Mills getHypervisorIfaceData( 782f40448e5SGunnar Mills id, [asyncResp, ifaceId{std::string(id)}]( 783f40448e5SGunnar Mills const bool& success, const EthernetInterfaceData& ethData, 784f40448e5SGunnar Mills const boost::container::flat_set<IPv4AddressData>& ipv4Data) { 785f40448e5SGunnar Mills if (!success) 786f40448e5SGunnar Mills { 787f40448e5SGunnar Mills messages::resourceNotFound(asyncResp->res, "EthernetInterface", 788f40448e5SGunnar Mills ifaceId); 789f40448e5SGunnar Mills return; 790f40448e5SGunnar Mills } 791f40448e5SGunnar Mills asyncResp->res.jsonValue["@odata.type"] = 792f40448e5SGunnar Mills "#EthernetInterface.v1_6_0.EthernetInterface"; 793f40448e5SGunnar Mills asyncResp->res.jsonValue["Name"] = "Hypervisor Ethernet Interface"; 794f40448e5SGunnar Mills asyncResp->res.jsonValue["Description"] = 795f40448e5SGunnar Mills "Hypervisor's Virtual Management Ethernet Interface"; 796f40448e5SGunnar Mills parseInterfaceData(asyncResp->res.jsonValue, ifaceId, ethData, 797f40448e5SGunnar Mills ipv4Data); 798f40448e5SGunnar Mills }); 799f40448e5SGunnar Mills } 800f40448e5SGunnar Mills 8018d8c30c3SGunnar Mills inline void handleHypervisorSystemGet( 8028d8c30c3SGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 8038d8c30c3SGunnar Mills { 8048d8c30c3SGunnar Mills sdbusplus::asio::getProperty<std::string>( 8058d8c30c3SGunnar Mills *crow::connections::systemBus, "xyz.openbmc_project.Settings", 8068d8c30c3SGunnar Mills "/xyz/openbmc_project/network/hypervisor", 8078d8c30c3SGunnar Mills "xyz.openbmc_project.Network.SystemConfiguration", "HostName", 8088d8c30c3SGunnar Mills [asyncResp](const boost::system::error_code& ec, 8098d8c30c3SGunnar Mills const std::string& /*hostName*/) { 8108d8c30c3SGunnar Mills if (ec) 8118d8c30c3SGunnar Mills { 8128d8c30c3SGunnar Mills messages::resourceNotFound(asyncResp->res, "System", "hypervisor"); 8138d8c30c3SGunnar Mills return; 8148d8c30c3SGunnar Mills } 8158d8c30c3SGunnar Mills BMCWEB_LOG_DEBUG << "Hypervisor is available"; 8168d8c30c3SGunnar Mills 8178d8c30c3SGunnar Mills asyncResp->res.jsonValue["@odata.type"] = 8188d8c30c3SGunnar Mills "#ComputerSystem.v1_6_0.ComputerSystem"; 8198d8c30c3SGunnar Mills asyncResp->res.jsonValue["@odata.id"] = 8208d8c30c3SGunnar Mills "/redfish/v1/Systems/hypervisor"; 8218d8c30c3SGunnar Mills asyncResp->res.jsonValue["Description"] = "Hypervisor"; 8228d8c30c3SGunnar Mills asyncResp->res.jsonValue["Name"] = "Hypervisor"; 8238d8c30c3SGunnar Mills asyncResp->res.jsonValue["Id"] = "hypervisor"; 8248d8c30c3SGunnar Mills asyncResp->res.jsonValue["SystemType"] = "OS"; 8258d8c30c3SGunnar Mills nlohmann::json::array_t managedBy; 8268d8c30c3SGunnar Mills nlohmann::json::object_t manager; 8278d8c30c3SGunnar Mills manager["@odata.id"] = "/redfish/v1/Managers/bmc"; 828*ad539545SPatrick Williams managedBy.emplace_back(std::move(manager)); 8298d8c30c3SGunnar Mills asyncResp->res.jsonValue["Links"]["ManagedBy"] = std::move(managedBy); 8308d8c30c3SGunnar Mills asyncResp->res.jsonValue["EthernetInterfaces"]["@odata.id"] = 8318d8c30c3SGunnar Mills "/redfish/v1/Systems/hypervisor/EthernetInterfaces"; 8328d8c30c3SGunnar Mills getHypervisorState(asyncResp); 8338d8c30c3SGunnar Mills getHypervisorActions(asyncResp); 8348d8c30c3SGunnar Mills // TODO: Add "SystemType" : "hypervisor" 8358d8c30c3SGunnar Mills }); 8368d8c30c3SGunnar Mills } 8378d8c30c3SGunnar Mills 838f40448e5SGunnar Mills inline void handleHypervisorEthernetInterfacePatch( 839f40448e5SGunnar Mills App& app, const crow::Request& req, 840f40448e5SGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp, 841f40448e5SGunnar Mills const std::string& ifaceId) 842f40448e5SGunnar Mills { 843f40448e5SGunnar Mills if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 844f40448e5SGunnar Mills { 845f40448e5SGunnar Mills return; 846f40448e5SGunnar Mills } 847f40448e5SGunnar Mills std::optional<std::string> hostName; 848f40448e5SGunnar Mills std::optional<std::vector<nlohmann::json>> ipv4StaticAddresses; 849f40448e5SGunnar Mills std::optional<nlohmann::json> ipv4Addresses; 850f40448e5SGunnar Mills std::optional<nlohmann::json> dhcpv4; 851f40448e5SGunnar Mills std::optional<bool> ipv4DHCPEnabled; 852f40448e5SGunnar Mills 853f40448e5SGunnar Mills if (!json_util::readJsonPatch(req, asyncResp->res, "HostName", hostName, 854f40448e5SGunnar Mills "IPv4StaticAddresses", ipv4StaticAddresses, 855f40448e5SGunnar Mills "IPv4Addresses", ipv4Addresses, "DHCPv4", 856f40448e5SGunnar Mills dhcpv4)) 857f40448e5SGunnar Mills { 858f40448e5SGunnar Mills return; 859f40448e5SGunnar Mills } 860f40448e5SGunnar Mills 861f40448e5SGunnar Mills if (ipv4Addresses) 862f40448e5SGunnar Mills { 863f40448e5SGunnar Mills messages::propertyNotWritable(asyncResp->res, "IPv4Addresses"); 864f40448e5SGunnar Mills return; 865f40448e5SGunnar Mills } 866f40448e5SGunnar Mills 867f40448e5SGunnar Mills if (dhcpv4) 868f40448e5SGunnar Mills { 869f40448e5SGunnar Mills if (!json_util::readJson(*dhcpv4, asyncResp->res, "DHCPEnabled", 870f40448e5SGunnar Mills ipv4DHCPEnabled)) 871f40448e5SGunnar Mills { 872f40448e5SGunnar Mills return; 873f40448e5SGunnar Mills } 874f40448e5SGunnar Mills } 875f40448e5SGunnar Mills 876f40448e5SGunnar Mills getHypervisorIfaceData( 877f40448e5SGunnar Mills ifaceId, 878f40448e5SGunnar Mills [asyncResp, ifaceId, hostName = std::move(hostName), 879f40448e5SGunnar Mills ipv4StaticAddresses = std::move(ipv4StaticAddresses), ipv4DHCPEnabled, 880f40448e5SGunnar Mills dhcpv4 = std::move(dhcpv4)]( 881f40448e5SGunnar Mills const bool& success, const EthernetInterfaceData& ethData, 882f40448e5SGunnar Mills const boost::container::flat_set<IPv4AddressData>&) { 883f40448e5SGunnar Mills if (!success) 884f40448e5SGunnar Mills { 885f40448e5SGunnar Mills messages::resourceNotFound(asyncResp->res, "EthernetInterface", 886f40448e5SGunnar Mills ifaceId); 887f40448e5SGunnar Mills return; 888f40448e5SGunnar Mills } 889f40448e5SGunnar Mills 890f40448e5SGunnar Mills if (ipv4StaticAddresses) 891f40448e5SGunnar Mills { 892f40448e5SGunnar Mills const nlohmann::json& ipv4Static = *ipv4StaticAddresses; 893f40448e5SGunnar Mills if (ipv4Static.begin() == ipv4Static.end()) 894f40448e5SGunnar Mills { 895f40448e5SGunnar Mills messages::propertyValueTypeError( 896f40448e5SGunnar Mills asyncResp->res, 897f40448e5SGunnar Mills ipv4Static.dump(2, ' ', true, 898f40448e5SGunnar Mills nlohmann::json::error_handler_t::replace), 899f40448e5SGunnar Mills "IPv4StaticAddresses"); 900f40448e5SGunnar Mills return; 901f40448e5SGunnar Mills } 902f40448e5SGunnar Mills 903f40448e5SGunnar Mills // One and only one hypervisor instance supported 904f40448e5SGunnar Mills if (ipv4Static.size() != 1) 905f40448e5SGunnar Mills { 906f40448e5SGunnar Mills messages::propertyValueFormatError( 907f40448e5SGunnar Mills asyncResp->res, 908f40448e5SGunnar Mills ipv4Static.dump(2, ' ', true, 909f40448e5SGunnar Mills nlohmann::json::error_handler_t::replace), 910f40448e5SGunnar Mills "IPv4StaticAddresses"); 911f40448e5SGunnar Mills return; 912f40448e5SGunnar Mills } 913f40448e5SGunnar Mills 914f40448e5SGunnar Mills const nlohmann::json& ipv4Json = ipv4Static[0]; 915f40448e5SGunnar Mills // Check if the param is 'null'. If its null, it means 916f40448e5SGunnar Mills // that user wants to delete the IP address. Deleting 917f40448e5SGunnar Mills // the IP address is allowed only if its statically 918f40448e5SGunnar Mills // configured. Deleting the address originated from DHCP 919f40448e5SGunnar Mills // is not allowed. 920f40448e5SGunnar Mills if ((ipv4Json.is_null()) && 921f40448e5SGunnar Mills (translateDhcpEnabledToBool(ethData.dhcpEnabled, true))) 922f40448e5SGunnar Mills { 923f40448e5SGunnar Mills BMCWEB_LOG_INFO << "Ignoring the delete on ipv4StaticAddresses " 924f40448e5SGunnar Mills "as the interface is DHCP enabled"; 925f40448e5SGunnar Mills } 926f40448e5SGunnar Mills else 927f40448e5SGunnar Mills { 928f40448e5SGunnar Mills handleHypervisorIPv4StaticPatch(ifaceId, ipv4Static, asyncResp); 929f40448e5SGunnar Mills } 930f40448e5SGunnar Mills } 931f40448e5SGunnar Mills 932f40448e5SGunnar Mills if (hostName) 933f40448e5SGunnar Mills { 934f40448e5SGunnar Mills handleHypervisorHostnamePatch(*hostName, asyncResp); 935f40448e5SGunnar Mills } 936f40448e5SGunnar Mills 937f40448e5SGunnar Mills if (dhcpv4) 938f40448e5SGunnar Mills { 939f40448e5SGunnar Mills setDHCPEnabled(ifaceId, *ipv4DHCPEnabled, asyncResp); 940f40448e5SGunnar Mills } 941f40448e5SGunnar Mills 942f40448e5SGunnar Mills // Set this interface to disabled/inactive. This will be set 943f40448e5SGunnar Mills // to enabled/active by the pldm once the hypervisor 944f40448e5SGunnar Mills // consumes the updated settings from the user. 945f40448e5SGunnar Mills setIPv4InterfaceEnabled(ifaceId, false, asyncResp); 946f40448e5SGunnar Mills }); 947f40448e5SGunnar Mills asyncResp->res.result(boost::beast::http::status::accepted); 948f40448e5SGunnar Mills } 949f40448e5SGunnar Mills 950a5d0cedbSGunnar Mills inline void handleHypervisorResetActionGet( 951a5d0cedbSGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 952a5d0cedbSGunnar Mills { 953a5d0cedbSGunnar Mills // Only return action info if hypervisor D-Bus object present 954a5d0cedbSGunnar Mills constexpr std::array<std::string_view, 1> interfaces = { 955a5d0cedbSGunnar Mills "xyz.openbmc_project.State.Host"}; 956a5d0cedbSGunnar Mills dbus::utility::getDbusObject( 957a5d0cedbSGunnar Mills "/xyz/openbmc_project/state/hypervisor0", interfaces, 958a5d0cedbSGunnar Mills [asyncResp]( 959a5d0cedbSGunnar Mills const boost::system::error_code& ec, 960a5d0cedbSGunnar Mills const std::vector<std::pair<std::string, std::vector<std::string>>>& 961a5d0cedbSGunnar Mills objInfo) { 962a5d0cedbSGunnar Mills if (ec) 963a5d0cedbSGunnar Mills { 964a5d0cedbSGunnar Mills BMCWEB_LOG_DEBUG << "DBUS response error " << ec; 965a5d0cedbSGunnar Mills 966a5d0cedbSGunnar Mills // No hypervisor objects found by mapper 967a5d0cedbSGunnar Mills if (ec.value() == boost::system::errc::io_error) 968a5d0cedbSGunnar Mills { 969a5d0cedbSGunnar Mills messages::resourceNotFound(asyncResp->res, "hypervisor", 970a5d0cedbSGunnar Mills "ResetActionInfo"); 971a5d0cedbSGunnar Mills return; 972a5d0cedbSGunnar Mills } 973a5d0cedbSGunnar Mills 974a5d0cedbSGunnar Mills messages::internalError(asyncResp->res); 975a5d0cedbSGunnar Mills return; 976a5d0cedbSGunnar Mills } 977a5d0cedbSGunnar Mills 978a5d0cedbSGunnar Mills // One and only one hypervisor instance supported 979a5d0cedbSGunnar Mills if (objInfo.size() != 1) 980a5d0cedbSGunnar Mills { 981a5d0cedbSGunnar Mills messages::internalError(asyncResp->res); 982a5d0cedbSGunnar Mills return; 983a5d0cedbSGunnar Mills } 984a5d0cedbSGunnar Mills 985a5d0cedbSGunnar Mills // The hypervisor object only support the ability to 986a5d0cedbSGunnar Mills // turn On The system object Action should be utilized 987a5d0cedbSGunnar Mills // for other operations 988a5d0cedbSGunnar Mills 989a5d0cedbSGunnar Mills asyncResp->res.jsonValue["@odata.type"] = 990a5d0cedbSGunnar Mills "#ActionInfo.v1_1_2.ActionInfo"; 991a5d0cedbSGunnar Mills asyncResp->res.jsonValue["@odata.id"] = 992a5d0cedbSGunnar Mills "/redfish/v1/Systems/hypervisor/ResetActionInfo"; 993a5d0cedbSGunnar Mills asyncResp->res.jsonValue["Name"] = "Reset Action Info"; 994a5d0cedbSGunnar Mills asyncResp->res.jsonValue["Id"] = "ResetActionInfo"; 995a5d0cedbSGunnar Mills nlohmann::json::array_t parameters; 996a5d0cedbSGunnar Mills nlohmann::json::object_t parameter; 997a5d0cedbSGunnar Mills parameter["Name"] = "ResetType"; 998a5d0cedbSGunnar Mills parameter["Required"] = true; 999a5d0cedbSGunnar Mills parameter["DataType"] = "String"; 1000a5d0cedbSGunnar Mills nlohmann::json::array_t allowed; 1001*ad539545SPatrick Williams allowed.emplace_back("On"); 1002a5d0cedbSGunnar Mills parameter["AllowableValues"] = std::move(allowed); 1003*ad539545SPatrick Williams parameters.emplace_back(std::move(parameter)); 1004a5d0cedbSGunnar Mills asyncResp->res.jsonValue["Parameters"] = std::move(parameters); 1005a5d0cedbSGunnar Mills }); 1006a5d0cedbSGunnar Mills } 1007a5d0cedbSGunnar Mills 1008a5d0cedbSGunnar Mills inline void handleHypervisorSystemResetPost( 1009a5d0cedbSGunnar Mills App& app, const crow::Request& req, 1010a5d0cedbSGunnar Mills const std::shared_ptr<bmcweb::AsyncResp>& asyncResp) 1011a5d0cedbSGunnar Mills { 1012a5d0cedbSGunnar Mills if (!redfish::setUpRedfishRoute(app, req, asyncResp)) 1013a5d0cedbSGunnar Mills { 1014a5d0cedbSGunnar Mills return; 1015a5d0cedbSGunnar Mills } 1016a5d0cedbSGunnar Mills std::optional<std::string> resetType; 1017a5d0cedbSGunnar Mills if (!json_util::readJsonAction(req, asyncResp->res, "ResetType", resetType)) 1018a5d0cedbSGunnar Mills { 1019a5d0cedbSGunnar Mills // readJson adds appropriate error to response 1020a5d0cedbSGunnar Mills return; 1021a5d0cedbSGunnar Mills } 1022a5d0cedbSGunnar Mills 1023a5d0cedbSGunnar Mills if (!resetType) 1024a5d0cedbSGunnar Mills { 1025a5d0cedbSGunnar Mills messages::actionParameterMissing(asyncResp->res, "ComputerSystem.Reset", 1026a5d0cedbSGunnar Mills "ResetType"); 1027a5d0cedbSGunnar Mills return; 1028a5d0cedbSGunnar Mills } 1029a5d0cedbSGunnar Mills 1030a5d0cedbSGunnar Mills // Hypervisor object only support On operation 1031a5d0cedbSGunnar Mills if (resetType != "On") 1032a5d0cedbSGunnar Mills { 1033a5d0cedbSGunnar Mills messages::propertyValueNotInList(asyncResp->res, *resetType, 1034a5d0cedbSGunnar Mills "ResetType"); 1035a5d0cedbSGunnar Mills return; 1036a5d0cedbSGunnar Mills } 1037a5d0cedbSGunnar Mills 1038a5d0cedbSGunnar Mills std::string command = "xyz.openbmc_project.State.Host.Transition.On"; 1039a5d0cedbSGunnar Mills 1040a5d0cedbSGunnar Mills crow::connections::systemBus->async_method_call( 1041a5d0cedbSGunnar Mills [asyncResp, resetType](const boost::system::error_code& ec) { 1042a5d0cedbSGunnar Mills if (ec) 1043a5d0cedbSGunnar Mills { 1044a5d0cedbSGunnar Mills BMCWEB_LOG_ERROR << "D-Bus responses error: " << ec; 1045a5d0cedbSGunnar Mills if (ec.value() == boost::asio::error::invalid_argument) 1046a5d0cedbSGunnar Mills { 1047a5d0cedbSGunnar Mills messages::actionParameterNotSupported(asyncResp->res, 1048a5d0cedbSGunnar Mills *resetType, "Reset"); 1049a5d0cedbSGunnar Mills return; 1050a5d0cedbSGunnar Mills } 1051a5d0cedbSGunnar Mills 1052a5d0cedbSGunnar Mills if (ec.value() == boost::asio::error::host_unreachable) 1053a5d0cedbSGunnar Mills { 1054a5d0cedbSGunnar Mills messages::resourceNotFound(asyncResp->res, "Actions", "Reset"); 1055a5d0cedbSGunnar Mills return; 1056a5d0cedbSGunnar Mills } 1057a5d0cedbSGunnar Mills 1058a5d0cedbSGunnar Mills messages::internalError(asyncResp->res); 1059a5d0cedbSGunnar Mills return; 1060a5d0cedbSGunnar Mills } 1061a5d0cedbSGunnar Mills messages::success(asyncResp->res); 1062a5d0cedbSGunnar Mills }, 1063a5d0cedbSGunnar Mills "xyz.openbmc_project.State.Hypervisor", 1064a5d0cedbSGunnar Mills "/xyz/openbmc_project/state/hypervisor0", 1065a5d0cedbSGunnar Mills "org.freedesktop.DBus.Properties", "Set", 1066a5d0cedbSGunnar Mills "xyz.openbmc_project.State.Host", "RequestedHostTransition", 1067a5d0cedbSGunnar Mills dbus::utility::DbusVariantType{std::move(command)}); 1068a5d0cedbSGunnar Mills } 1069a5d0cedbSGunnar Mills 10707e860f15SJohn Edward Broadbent inline void requestRoutesHypervisorSystems(App& app) 10717e860f15SJohn Edward Broadbent { 10727e860f15SJohn Edward Broadbent /** 10737e860f15SJohn Edward Broadbent * HypervisorInterfaceCollection class to handle the GET and PATCH on 10747e860f15SJohn Edward Broadbent * Hypervisor Interface 10757e860f15SJohn Edward Broadbent */ 10767e860f15SJohn Edward Broadbent 10777e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, "/redfish/v1/Systems/hypervisor/EthernetInterfaces/") 1078ed398213SEd Tanous .privileges(redfish::privileges::getEthernetInterfaceCollection) 1079f40448e5SGunnar Mills .methods(boost::beast::http::verb::get)(std::bind_front( 1080f40448e5SGunnar Mills handleHypervisorEthernetInterfaceCollectionGet, std::ref(app))); 10817e860f15SJohn Edward Broadbent 10827e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 10837e860f15SJohn Edward Broadbent "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/") 1084ed398213SEd Tanous .privileges(redfish::privileges::getEthernetInterface) 1085f40448e5SGunnar Mills .methods(boost::beast::http::verb::get)(std::bind_front( 1086f40448e5SGunnar Mills handleHypervisorEthernetInterfaceGet, std::ref(app))); 1087d5afb2caSAndrew Geissler 10887e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 10897e860f15SJohn Edward Broadbent "/redfish/v1/Systems/hypervisor/EthernetInterfaces/<str>/") 1090ed398213SEd Tanous .privileges(redfish::privileges::patchEthernetInterface) 1091f40448e5SGunnar Mills .methods(boost::beast::http::verb::patch)(std::bind_front( 1092f40448e5SGunnar Mills handleHypervisorEthernetInterfacePatch, std::ref(app))); 10934fbaf64aSAndrew Geissler 10947e860f15SJohn Edward Broadbent BMCWEB_ROUTE(app, 10954fbaf64aSAndrew Geissler "/redfish/v1/Systems/hypervisor/Actions/ComputerSystem.Reset/") 1096ed398213SEd Tanous .privileges(redfish::privileges::postComputerSystem) 10977e860f15SJohn Edward Broadbent .methods(boost::beast::http::verb::post)( 1098a5d0cedbSGunnar Mills std::bind_front(handleHypervisorSystemResetPost, std::ref(app))); 10994fbaf64aSAndrew Geissler } 110088a8a174SEd Tanous } // namespace redfish 1101