blob: d77f8b797f38ebc30e92d991269371955b3db3bd [file] [log] [blame]
Ratan Gupta1dc91782018-04-19 16:47:12 +05301#include "config.h"
Patrick Williams1334b7b2021-02-22 17:15:12 -06002
Ratan Gupta1dc91782018-04-19 16:47:12 +05303#include "snmp_conf_manager.hpp"
Patrick Williams1334b7b2021-02-22 17:15:12 -06004
Ratan Gupta212f53e2018-04-30 17:28:05 +05305#include "snmp_serialize.hpp"
Ratan Gupta213517b2018-04-28 13:41:09 +05306#include "snmp_util.hpp"
7#include "xyz/openbmc_project/Common/error.hpp"
8
Patrick Williams1334b7b2021-02-22 17:15:12 -06009#include <arpa/inet.h>
10
Ratan Gupta213517b2018-04-28 13:41:09 +053011#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta1dc91782018-04-19 16:47:12 +053012#include <phosphor-logging/log.hpp>
13
Ratan Gupta34d129a2021-12-04 21:04:51 +053014#include <filesystem>
Ratan Gupta1dc91782018-04-19 16:47:12 +053015
16namespace phosphor
17{
18namespace network
19{
20namespace snmp
21{
22
23using namespace phosphor::logging;
Ratan Gupta213517b2018-04-28 13:41:09 +053024using namespace sdbusplus::xyz::openbmc_project::Common::Error;
25using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Gupta1dc91782018-04-19 16:47:12 +053026
27ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) :
Patrick Williamsb9b4c7d2022-04-05 16:20:37 -050028 details::CreateIface(bus, objPath,
29 details::CreateIface::action::defer_emit),
Ratan Gupta212f53e2018-04-30 17:28:05 +053030 dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus),
31 objectPath(objPath)
Patrick Williams1334b7b2021-02-22 17:15:12 -060032{}
Ratan Gupta1dc91782018-04-19 16:47:12 +053033
Ratan Guptad84e3272018-09-06 16:52:52 +053034std::string ConfManager::client(std::string address, uint16_t port)
Ratan Gupta1dc91782018-04-19 16:47:12 +053035{
Ratan Gupta9c4fed62018-11-16 17:47:54 +053036 // will throw exception if it is already configured.
37 checkClientConfigured(address, port);
Ratan Guptaa7ff3852018-11-16 14:05:57 +053038
39 lastClientId++;
Ratan Gupta213517b2018-04-28 13:41:09 +053040 try
41 {
42 // just to check whether given address is valid or not.
43 resolveAddress(address);
44 }
Patrick Williamsc3600d82021-10-06 12:38:25 -050045 catch (const InternalFailure& e)
Ratan Gupta213517b2018-04-28 13:41:09 +053046 {
47 log<level::ERR>("Not a valid address"),
48 entry("ADDRESS=%s", address.c_str());
49 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"),
50 Argument::ARGUMENT_VALUE(address.c_str()));
51 }
Ratan Guptad84e3272018-09-06 16:52:52 +053052
Ratan Guptaa7ff3852018-11-16 14:05:57 +053053 // create the D-Bus object
Ratan Gupta34d129a2021-12-04 21:04:51 +053054 std::filesystem::path objPath;
Ratan Gupta213517b2018-04-28 13:41:09 +053055 objPath /= objectPath;
Ratan Guptaa7ff3852018-11-16 14:05:57 +053056 objPath /= std::to_string(lastClientId);
57
Ratan Gupta212f53e2018-04-30 17:28:05 +053058 auto client = std::make_unique<phosphor::network::snmp::Client>(
59 bus, objPath.string().c_str(), *this, address, port);
Ratan Gupta212f53e2018-04-30 17:28:05 +053060
Ratan Guptaa7ff3852018-11-16 14:05:57 +053061 // save the D-Bus object
62 serialize(lastClientId, *client, dbusPersistentLocation);
63
64 this->clients.emplace(lastClientId, std::move(client));
Ratan Guptad84e3272018-09-06 16:52:52 +053065 return objPath.string();
Ratan Gupta1dc91782018-04-19 16:47:12 +053066}
67
Ratan Gupta9c4fed62018-11-16 17:47:54 +053068void ConfManager::checkClientConfigured(const std::string& address,
69 uint16_t port)
70{
71 if (address.empty())
72 {
73 log<level::ERR>("Invalid address");
74 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"),
75 Argument::ARGUMENT_VALUE(address.c_str()));
76 }
77
78 for (const auto& val : clients)
79 {
80 if (val.second.get()->address() == address &&
81 val.second.get()->port() == port)
82 {
83 log<level::ERR>("Client already exist");
84 // TODO Add the error(Object already exist) in the D-Bus interface
85 // then make the change here,meanwhile send the Internal Failure.
86 elog<InvalidArgument>(
87 Argument::ARGUMENT_NAME("ADDRESS"),
88 Argument::ARGUMENT_VALUE("Client already exist."));
89 }
90 }
91}
92
Ratan Guptaa7ff3852018-11-16 14:05:57 +053093void ConfManager::deleteSNMPClient(Id id)
Ratan Gupta1dc91782018-04-19 16:47:12 +053094{
Ratan Guptaa7ff3852018-11-16 14:05:57 +053095 auto it = clients.find(id);
Ratan Gupta1dc91782018-04-19 16:47:12 +053096 if (it == clients.end())
97 {
98 log<level::ERR>("Unable to delete the snmp client.",
Ratan Guptaa7ff3852018-11-16 14:05:57 +053099 entry("ID=%d", id));
Ratan Gupta1dc91782018-04-19 16:47:12 +0530100 return;
101 }
Ratan Gupta212f53e2018-04-30 17:28:05 +0530102
103 std::error_code ec;
104 // remove the persistent file
105 fs::path fileName = dbusPersistentLocation;
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530106 fileName /= std::to_string(id);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530107
108 if (fs::exists(fileName))
109 {
110 if (!fs::remove(fileName, ec))
111 {
112 log<level::ERR>("Unable to delete the file",
113 entry("FILE=%s", fileName.c_str()),
114 entry("ERROR=%d", ec.value()));
115 }
116 }
117 else
118 {
119 log<level::ERR>("File doesn't exist",
120 entry("FILE=%s", fileName.c_str()));
121 }
122 // remove the D-Bus Object.
Ratan Gupta1dc91782018-04-19 16:47:12 +0530123 this->clients.erase(it);
124}
125
Ratan Gupta212f53e2018-04-30 17:28:05 +0530126void ConfManager::restoreClients()
127{
128 if (!fs::exists(dbusPersistentLocation) ||
129 fs::is_empty(dbusPersistentLocation))
130 {
131 return;
132 }
133
134 for (auto& confFile :
135 fs::recursive_directory_iterator(dbusPersistentLocation))
136 {
137 if (!fs::is_regular_file(confFile))
138 {
139 continue;
140 }
141
142 auto managerID = confFile.path().filename().string();
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530143 Id idNum = std::stol(managerID);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530144
145 fs::path objPath = objectPath;
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530146 objPath /= managerID;
Ratan Gupta212f53e2018-04-30 17:28:05 +0530147 auto manager =
148 std::make_unique<Client>(bus, objPath.string().c_str(), *this);
149 if (deserialize(confFile.path(), *manager))
150 {
151 manager->emit_object_added();
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530152 this->clients.emplace(idNum, std::move(manager));
153 if (idNum > lastClientId)
154 {
155 lastClientId = idNum;
156 }
Ratan Gupta212f53e2018-04-30 17:28:05 +0530157 }
158 }
159}
160
Ratan Gupta1dc91782018-04-19 16:47:12 +0530161} // namespace snmp
162} // namespace network
163} // namespace phosphor