170141561SBorawski.Lukasz /* 270141561SBorawski.Lukasz // Copyright (c) 2018 Intel Corporation 370141561SBorawski.Lukasz // 470141561SBorawski.Lukasz // Licensed under the Apache License, Version 2.0 (the "License"); 570141561SBorawski.Lukasz // you may not use this file except in compliance with the License. 670141561SBorawski.Lukasz // You may obtain a copy of the License at 770141561SBorawski.Lukasz // 870141561SBorawski.Lukasz // http://www.apache.org/licenses/LICENSE-2.0 970141561SBorawski.Lukasz // 1070141561SBorawski.Lukasz // Unless required by applicable law or agreed to in writing, software 1170141561SBorawski.Lukasz // distributed under the License is distributed on an "AS IS" BASIS, 1270141561SBorawski.Lukasz // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1370141561SBorawski.Lukasz // See the License for the specific language governing permissions and 1470141561SBorawski.Lukasz // limitations under the License. 1570141561SBorawski.Lukasz */ 1670141561SBorawski.Lukasz #pragma once 1770141561SBorawski.Lukasz 183a8a0088SKowalski, Kamil #include "error_messages.hpp" 1970141561SBorawski.Lukasz #include "node.hpp" 2070141561SBorawski.Lukasz 21*1abe55efSEd Tanous namespace redfish 22*1abe55efSEd Tanous { 2370141561SBorawski.Lukasz 24*1abe55efSEd Tanous enum NetworkProtocolUnitStructFields 25*1abe55efSEd Tanous { 263a8a0088SKowalski, Kamil NET_PROTO_UNIT_NAME, 273a8a0088SKowalski, Kamil NET_PROTO_UNIT_DESC, 283a8a0088SKowalski, Kamil NET_PROTO_UNIT_LOAD_STATE, 293a8a0088SKowalski, Kamil NET_PROTO_UNIT_ACTIVE_STATE, 303a8a0088SKowalski, Kamil NET_PROTO_UNIT_SUB_STATE, 313a8a0088SKowalski, Kamil NET_PROTO_UNIT_DEVICE, 323a8a0088SKowalski, Kamil NET_PROTO_UNIT_OBJ_PATH, 333a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_0, 343a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_EMPTY, 353a8a0088SKowalski, Kamil NET_PROTO_UNIT_ALWAYS_ROOT_PATH 363a8a0088SKowalski, Kamil }; 373a8a0088SKowalski, Kamil 38*1abe55efSEd Tanous enum NetworkProtocolListenResponseElements 39*1abe55efSEd Tanous { 403a8a0088SKowalski, Kamil NET_PROTO_LISTEN_TYPE, 413a8a0088SKowalski, Kamil NET_PROTO_LISTEN_STREAM 423a8a0088SKowalski, Kamil }; 433a8a0088SKowalski, Kamil 443a8a0088SKowalski, Kamil /** 453a8a0088SKowalski, Kamil * @brief D-Bus Unit structure returned in array from ListUnits Method 463a8a0088SKowalski, Kamil */ 473a8a0088SKowalski, Kamil using UnitStruct = 483a8a0088SKowalski, Kamil std::tuple<std::string, std::string, std::string, std::string, std::string, 493a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path, uint32_t, 503a8a0088SKowalski, Kamil std::string, sdbusplus::message::object_path>; 513a8a0088SKowalski, Kamil 52*1abe55efSEd Tanous struct ServiceConfiguration 53*1abe55efSEd Tanous { 54865fbb75SEd Tanous const char* serviceName; 55865fbb75SEd Tanous const char* socketPath; 563a8a0088SKowalski, Kamil }; 573a8a0088SKowalski, Kamil 58865fbb75SEd Tanous const static boost::container::flat_map<const char*, ServiceConfiguration> 59865fbb75SEd Tanous protocolToDBus{ 60865fbb75SEd Tanous {"SSH", 61865fbb75SEd Tanous {"dropbear.service", 62865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/dropbear_2esocket"}}, 63865fbb75SEd Tanous {"HTTPS", 64865fbb75SEd Tanous {"phosphor-gevent.service", 65865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/phosphor_2dgevent_2esocket"}}, 66865fbb75SEd Tanous {"IPMI", 67865fbb75SEd Tanous {"phosphor-ipmi-net.service", 68865fbb75SEd Tanous "/org/freedesktop/systemd1/unit/phosphor_2dipmi_2dnet_2esocket"}}}; 693a8a0088SKowalski, Kamil 70*1abe55efSEd Tanous class NetworkProtocol : public Node 71*1abe55efSEd Tanous { 7270141561SBorawski.Lukasz public: 73*1abe55efSEd Tanous NetworkProtocol(CrowApp& app) : 74*1abe55efSEd Tanous Node(app, "/redfish/v1/Managers/openbmc/NetworkProtocol") 75*1abe55efSEd Tanous { 7670141561SBorawski.Lukasz Node::json["@odata.type"] = 7770141561SBorawski.Lukasz "#ManagerNetworkProtocol.v1_1_0.ManagerNetworkProtocol"; 78*1abe55efSEd Tanous Node::json["@odata.id"] = 79*1abe55efSEd Tanous "/redfish/v1/Managers/openbmc/NetworkProtocol"; 8070141561SBorawski.Lukasz Node::json["@odata.context"] = 81*1abe55efSEd Tanous "/redfish/v1/" 82*1abe55efSEd Tanous "$metadata#ManagerNetworkProtocol.ManagerNetworkProtocol"; 8370141561SBorawski.Lukasz Node::json["Id"] = "NetworkProtocol"; 8470141561SBorawski.Lukasz Node::json["Name"] = "Manager Network Protocol"; 8570141561SBorawski.Lukasz Node::json["Description"] = "Manager Network Service"; 8670141561SBorawski.Lukasz Node::json["Status"]["Health"] = "OK"; 8770141561SBorawski.Lukasz Node::json["Status"]["HealthRollup"] = "OK"; 8870141561SBorawski.Lukasz Node::json["Status"]["State"] = "Enabled"; 893ebd75f7SEd Tanous 90*1abe55efSEd Tanous for (auto& protocol : protocolToDBus) 91*1abe55efSEd Tanous { 923a8a0088SKowalski, Kamil Node::json[protocol.first]["ProtocolEnabled"] = false; 933a8a0088SKowalski, Kamil } 943a8a0088SKowalski, Kamil 954b1b8683SBorawski.Lukasz entityPrivileges = { 964b1b8683SBorawski.Lukasz {boost::beast::http::verb::get, {{"Login"}}}, 97e0d918bcSEd Tanous {boost::beast::http::verb::head, {{"Login"}}}, 98e0d918bcSEd Tanous {boost::beast::http::verb::patch, {{"ConfigureManager"}}}, 99e0d918bcSEd Tanous {boost::beast::http::verb::put, {{"ConfigureManager"}}}, 100e0d918bcSEd Tanous {boost::beast::http::verb::delete_, {{"ConfigureManager"}}}, 101e0d918bcSEd Tanous {boost::beast::http::verb::post, {{"ConfigureManager"}}}}; 10270141561SBorawski.Lukasz } 10370141561SBorawski.Lukasz 10470141561SBorawski.Lukasz private: 10555c7b7a2SEd Tanous void doGet(crow::Response& res, const crow::Request& req, 106*1abe55efSEd Tanous const std::vector<std::string>& params) override 107*1abe55efSEd Tanous { 1083a8a0088SKowalski, Kamil std::shared_ptr<AsyncResp> asyncResp = std::make_shared<AsyncResp>(res); 1093a8a0088SKowalski, Kamil 1103a8a0088SKowalski, Kamil getData(asyncResp); 11170141561SBorawski.Lukasz } 11270141561SBorawski.Lukasz 113*1abe55efSEd Tanous std::string getHostName() const 114*1abe55efSEd Tanous { 11570141561SBorawski.Lukasz std::string hostName; 11670141561SBorawski.Lukasz 11770141561SBorawski.Lukasz std::array<char, HOST_NAME_MAX> hostNameCStr; 118*1abe55efSEd Tanous if (gethostname(hostNameCStr.data(), hostNameCStr.size()) == 0) 119*1abe55efSEd Tanous { 12070141561SBorawski.Lukasz hostName = hostNameCStr.data(); 12170141561SBorawski.Lukasz } 12270141561SBorawski.Lukasz return hostName; 12370141561SBorawski.Lukasz } 12470141561SBorawski.Lukasz 125*1abe55efSEd Tanous void getData(const std::shared_ptr<AsyncResp>& asyncResp) 126*1abe55efSEd Tanous { 1273a8a0088SKowalski, Kamil Node::json["HostName"] = getHostName(); 1283a8a0088SKowalski, Kamil asyncResp->res.jsonValue = Node::json; 1293a8a0088SKowalski, Kamil 130865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 131865fbb75SEd Tanous [asyncResp](const boost::system::error_code ec, 1323a8a0088SKowalski, Kamil const std::vector<UnitStruct>& resp) { 133*1abe55efSEd Tanous if (ec) 134*1abe55efSEd Tanous { 1353a8a0088SKowalski, Kamil asyncResp->res.jsonValue = nlohmann::json::object(); 1363a8a0088SKowalski, Kamil messages::addMessageToErrorJson(asyncResp->res.jsonValue, 1373a8a0088SKowalski, Kamil messages::internalError()); 1383a8a0088SKowalski, Kamil asyncResp->res.result( 1393a8a0088SKowalski, Kamil boost::beast::http::status::internal_server_error); 140865fbb75SEd Tanous return; 1413a8a0088SKowalski, Kamil } 1423a8a0088SKowalski, Kamil 143*1abe55efSEd Tanous for (auto& unit : resp) 144*1abe55efSEd Tanous { 145*1abe55efSEd Tanous for (auto& kv : protocolToDBus) 146*1abe55efSEd Tanous { 1473a8a0088SKowalski, Kamil if (kv.second.serviceName == 148*1abe55efSEd Tanous std::get<NET_PROTO_UNIT_NAME>(unit)) 149*1abe55efSEd Tanous { 150865fbb75SEd Tanous continue; 15170141561SBorawski.Lukasz } 152865fbb75SEd Tanous const char* service = kv.first; 153865fbb75SEd Tanous const char* socketPath = kv.second.socketPath; 15470141561SBorawski.Lukasz 155865fbb75SEd Tanous asyncResp->res.jsonValue[service]["ProtocolEnabled"] = 156*1abe55efSEd Tanous std::get<NET_PROTO_UNIT_SUB_STATE>(unit) == 157*1abe55efSEd Tanous "running"; 158865fbb75SEd Tanous 159865fbb75SEd Tanous crow::connections::systemBus->async_method_call( 160*1abe55efSEd Tanous [asyncResp, service{std::string(service)}, 161*1abe55efSEd Tanous socketPath]( 162865fbb75SEd Tanous const boost::system::error_code ec, 163865fbb75SEd Tanous const sdbusplus::message::variant<std::vector< 164*1abe55efSEd Tanous std::tuple<std::string, std::string>>>& 165*1abe55efSEd Tanous resp) { 166*1abe55efSEd Tanous if (ec) 167*1abe55efSEd Tanous { 168*1abe55efSEd Tanous messages::addMessageToJson( 169*1abe55efSEd Tanous asyncResp->res.jsonValue, 1703a8a0088SKowalski, Kamil messages::internalError(), 1713a8a0088SKowalski, Kamil "/" + service); 172865fbb75SEd Tanous return; 1733a8a0088SKowalski, Kamil } 174*1abe55efSEd Tanous const std::vector<std::tuple< 175*1abe55efSEd Tanous std::string, std::string>>* responsePtr = 176*1abe55efSEd Tanous mapbox::getPtr<const std::vector< 177*1abe55efSEd Tanous std::tuple<std::string, std::string>>>( 178*1abe55efSEd Tanous resp); 179*1abe55efSEd Tanous if (responsePtr == nullptr || 180*1abe55efSEd Tanous responsePtr->size() < 1) 181*1abe55efSEd Tanous { 182865fbb75SEd Tanous return; 18370141561SBorawski.Lukasz } 18470141561SBorawski.Lukasz 185865fbb75SEd Tanous const std::string& listenStream = 186*1abe55efSEd Tanous std::get<NET_PROTO_LISTEN_STREAM>( 187*1abe55efSEd Tanous (*responsePtr)[0]); 188*1abe55efSEd Tanous std::size_t lastColonPos = 189*1abe55efSEd Tanous listenStream.rfind(":"); 190*1abe55efSEd Tanous if (lastColonPos == std::string::npos) 191*1abe55efSEd Tanous { 192865fbb75SEd Tanous // Not a port 193865fbb75SEd Tanous return; 194865fbb75SEd Tanous } 195*1abe55efSEd Tanous std::string portStr = 196*1abe55efSEd Tanous listenStream.substr(lastColonPos + 1); 197865fbb75SEd Tanous char* endPtr = nullptr; 198*1abe55efSEd Tanous // Use strtol instead of stroi to avoid 199*1abe55efSEd Tanous // exceptions 200*1abe55efSEd Tanous long port = 201*1abe55efSEd Tanous std::strtol(portStr.c_str(), &endPtr, 10); 202865fbb75SEd Tanous 203*1abe55efSEd Tanous if (*endPtr != '\0' || portStr.empty()) 204*1abe55efSEd Tanous { 205865fbb75SEd Tanous // Invalid value 206*1abe55efSEd Tanous asyncResp->res.jsonValue[service]["Port"] = 207*1abe55efSEd Tanous nullptr; 208*1abe55efSEd Tanous } 209*1abe55efSEd Tanous else 210*1abe55efSEd Tanous { 211865fbb75SEd Tanous // Everything OK 212*1abe55efSEd Tanous asyncResp->res.jsonValue[service]["Port"] = 213*1abe55efSEd Tanous port; 214865fbb75SEd Tanous } 215865fbb75SEd Tanous }, 216865fbb75SEd Tanous "org.freedesktop.systemd1", socketPath, 217865fbb75SEd Tanous "org.freedesktop.DBus.Properties", "Get", 218865fbb75SEd Tanous "org.freedesktop.systemd1.Socket", "Listen"); 219865fbb75SEd Tanous } 220865fbb75SEd Tanous } 221865fbb75SEd Tanous }, 222865fbb75SEd Tanous "org.freedesktop.systemd1", "/org/freedesktop/systemd1", 223865fbb75SEd Tanous "org.freedesktop.systemd1.Manager", "ListUnits"); 224865fbb75SEd Tanous } 22570141561SBorawski.Lukasz }; 22670141561SBorawski.Lukasz 22770141561SBorawski.Lukasz } // namespace redfish 228