#include "config.h" #include "snmp_conf_manager.hpp" #include "snmp_serialize.hpp" #include "snmp_util.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include #include #include #include namespace phosphor { namespace network { namespace snmp { using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; using Argument = xyz::openbmc_project::Common::InvalidArgument; ConfManager::ConfManager(sdbusplus::bus_t& bus, const char* objPath) : details::CreateIface(bus, objPath, details::CreateIface::action::defer_emit), dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus), objectPath(objPath) {} std::string ConfManager::client(std::string address, uint16_t port) { // will throw exception if it is already configured. checkClientConfigured(address, port); lastClientId++; try { // just to check whether given address is valid or not. resolveAddress(address); } catch (const InternalFailure& e) { lg2::error("{ADDRESS} is not a valid address", "ADDRESS", address); elog(Argument::ARGUMENT_NAME("Address"), Argument::ARGUMENT_VALUE(address.c_str())); } // create the D-Bus object std::filesystem::path objPath; objPath /= objectPath; objPath /= std::to_string(lastClientId); auto client = std::make_unique( bus, objPath.string().c_str(), *this, address, port); // save the D-Bus object serialize(lastClientId, *client, dbusPersistentLocation); this->clients.emplace(lastClientId, std::move(client)); return objPath.string(); } void ConfManager::checkClientConfigured(const std::string& address, uint16_t port) { if (address.empty()) { lg2::error("{ADDRESS} is not a valid address", "ADDRESS", address); elog(Argument::ARGUMENT_NAME("ADDRESS"), Argument::ARGUMENT_VALUE(address.c_str())); } for (const auto& val : clients) { if (val.second.get()->address() == address && val.second.get()->port() == port) { lg2::error("Client already exist"); // TODO Add the error(Object already exist) in the D-Bus interface // then make the change here,meanwhile send the Internal Failure. elog( Argument::ARGUMENT_NAME("ADDRESS"), Argument::ARGUMENT_VALUE("Client already exist.")); } } } void ConfManager::deleteSNMPClient(Id id) { auto it = clients.find(id); if (it == clients.end()) { lg2::error("Unable to delete the snmp client: {ID}", "ID", id); return; } std::error_code ec; // remove the persistent file fs::path fileName = dbusPersistentLocation; fileName /= std::to_string(id); if (fs::exists(fileName)) { if (!fs::remove(fileName, ec)) { lg2::error("Unable to delete {FILE}: {EC}", "FILE", fileName, "EC", ec.value()); } } else { lg2::error("{FILE} doesn't exist", "FILE", fileName); } // remove the D-Bus Object. this->clients.erase(it); } void ConfManager::restoreClients() { if (!fs::exists(dbusPersistentLocation) || fs::is_empty(dbusPersistentLocation)) { return; } for (auto& confFile : fs::recursive_directory_iterator(dbusPersistentLocation)) { if (!fs::is_regular_file(confFile)) { continue; } auto managerID = confFile.path().filename().string(); Id idNum = std::stol(managerID); fs::path objPath = objectPath; objPath /= managerID; auto manager = std::make_unique(bus, objPath.string().c_str(), *this); if (deserialize(confFile.path(), *manager)) { manager->emit_object_added(); this->clients.emplace(idNum, std::move(manager)); if (idNum > lastClientId) { lastClientId = idNum; } } } } } // namespace snmp } // namespace network } // namespace phosphor