blob: 52f467850b165afb6718633cc559395f11b839ac [file] [log] [blame]
Ratan Gupta1dc91782018-04-19 16:47:12 +05301#include "config.h"
2#include "snmp_conf_manager.hpp"
Ratan Gupta212f53e2018-04-30 17:28:05 +05303#include "snmp_serialize.hpp"
Ratan Gupta213517b2018-04-28 13:41:09 +05304#include "snmp_util.hpp"
5#include "xyz/openbmc_project/Common/error.hpp"
6
7#include <phosphor-logging/elog-errors.hpp>
Ratan Gupta1dc91782018-04-19 16:47:12 +05308#include <phosphor-logging/log.hpp>
9
10#include <experimental/filesystem>
11
Ratan Gupta213517b2018-04-28 13:41:09 +053012#include <arpa/inet.h>
13
Ratan Gupta1dc91782018-04-19 16:47:12 +053014namespace phosphor
15{
16namespace network
17{
18namespace snmp
19{
20
21using namespace phosphor::logging;
Ratan Gupta213517b2018-04-28 13:41:09 +053022using namespace sdbusplus::xyz::openbmc_project::Common::Error;
23using Argument = xyz::openbmc_project::Common::InvalidArgument;
Ratan Gupta1dc91782018-04-19 16:47:12 +053024
25ConfManager::ConfManager(sdbusplus::bus::bus& bus, const char* objPath) :
Ratan Gupta212f53e2018-04-30 17:28:05 +053026 details::CreateIface(bus, objPath, true),
27 dbusPersistentLocation(SNMP_CONF_PERSIST_PATH), bus(bus),
28 objectPath(objPath)
Ratan Gupta1dc91782018-04-19 16:47:12 +053029{
30}
31
Ratan Guptad84e3272018-09-06 16:52:52 +053032std::string ConfManager::client(std::string address, uint16_t port)
Ratan Gupta1dc91782018-04-19 16:47:12 +053033{
Ratan Gupta9c4fed62018-11-16 17:47:54 +053034 // will throw exception if it is already configured.
35 checkClientConfigured(address, port);
Ratan Guptaa7ff3852018-11-16 14:05:57 +053036
37 lastClientId++;
Ratan Gupta213517b2018-04-28 13:41:09 +053038 try
39 {
40 // just to check whether given address is valid or not.
41 resolveAddress(address);
42 }
43 catch (InternalFailure& e)
44 {
45 log<level::ERR>("Not a valid address"),
46 entry("ADDRESS=%s", address.c_str());
47 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Address"),
48 Argument::ARGUMENT_VALUE(address.c_str()));
49 }
Ratan Guptad84e3272018-09-06 16:52:52 +053050
Ratan Guptaa7ff3852018-11-16 14:05:57 +053051 // create the D-Bus object
Ratan Gupta213517b2018-04-28 13:41:09 +053052 std::experimental::filesystem::path objPath;
53 objPath /= objectPath;
Ratan Guptaa7ff3852018-11-16 14:05:57 +053054 objPath /= std::to_string(lastClientId);
55
Ratan Gupta212f53e2018-04-30 17:28:05 +053056 auto client = std::make_unique<phosphor::network::snmp::Client>(
57 bus, objPath.string().c_str(), *this, address, port);
Ratan Gupta212f53e2018-04-30 17:28:05 +053058
Ratan Guptaa7ff3852018-11-16 14:05:57 +053059 // save the D-Bus object
60 serialize(lastClientId, *client, dbusPersistentLocation);
61
62 this->clients.emplace(lastClientId, std::move(client));
Ratan Guptad84e3272018-09-06 16:52:52 +053063 return objPath.string();
Ratan Gupta1dc91782018-04-19 16:47:12 +053064}
65
Ratan Gupta9c4fed62018-11-16 17:47:54 +053066void ConfManager::checkClientConfigured(const std::string& address,
67 uint16_t port)
68{
69 if (address.empty())
70 {
71 log<level::ERR>("Invalid address");
72 elog<InvalidArgument>(Argument::ARGUMENT_NAME("ADDRESS"),
73 Argument::ARGUMENT_VALUE(address.c_str()));
74 }
75
76 for (const auto& val : clients)
77 {
78 if (val.second.get()->address() == address &&
79 val.second.get()->port() == port)
80 {
81 log<level::ERR>("Client already exist");
82 // TODO Add the error(Object already exist) in the D-Bus interface
83 // then make the change here,meanwhile send the Internal Failure.
84 elog<InvalidArgument>(
85 Argument::ARGUMENT_NAME("ADDRESS"),
86 Argument::ARGUMENT_VALUE("Client already exist."));
87 }
88 }
89}
90
Ratan Guptaa7ff3852018-11-16 14:05:57 +053091void ConfManager::deleteSNMPClient(Id id)
Ratan Gupta1dc91782018-04-19 16:47:12 +053092{
Ratan Guptaa7ff3852018-11-16 14:05:57 +053093 auto it = clients.find(id);
Ratan Gupta1dc91782018-04-19 16:47:12 +053094 if (it == clients.end())
95 {
96 log<level::ERR>("Unable to delete the snmp client.",
Ratan Guptaa7ff3852018-11-16 14:05:57 +053097 entry("ID=%d", id));
Ratan Gupta1dc91782018-04-19 16:47:12 +053098 return;
99 }
Ratan Gupta212f53e2018-04-30 17:28:05 +0530100
101 std::error_code ec;
102 // remove the persistent file
103 fs::path fileName = dbusPersistentLocation;
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530104 fileName /= std::to_string(id);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530105
106 if (fs::exists(fileName))
107 {
108 if (!fs::remove(fileName, ec))
109 {
110 log<level::ERR>("Unable to delete the file",
111 entry("FILE=%s", fileName.c_str()),
112 entry("ERROR=%d", ec.value()));
113 }
114 }
115 else
116 {
117 log<level::ERR>("File doesn't exist",
118 entry("FILE=%s", fileName.c_str()));
119 }
120 // remove the D-Bus Object.
Ratan Gupta1dc91782018-04-19 16:47:12 +0530121 this->clients.erase(it);
122}
123
Ratan Gupta212f53e2018-04-30 17:28:05 +0530124void ConfManager::restoreClients()
125{
126 if (!fs::exists(dbusPersistentLocation) ||
127 fs::is_empty(dbusPersistentLocation))
128 {
129 return;
130 }
131
132 for (auto& confFile :
133 fs::recursive_directory_iterator(dbusPersistentLocation))
134 {
135 if (!fs::is_regular_file(confFile))
136 {
137 continue;
138 }
139
140 auto managerID = confFile.path().filename().string();
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530141 Id idNum = std::stol(managerID);
Ratan Gupta212f53e2018-04-30 17:28:05 +0530142
143 fs::path objPath = objectPath;
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530144 objPath /= managerID;
Ratan Gupta212f53e2018-04-30 17:28:05 +0530145 auto manager =
146 std::make_unique<Client>(bus, objPath.string().c_str(), *this);
147 if (deserialize(confFile.path(), *manager))
148 {
149 manager->emit_object_added();
Ratan Guptaa7ff3852018-11-16 14:05:57 +0530150 this->clients.emplace(idNum, std::move(manager));
151 if (idNum > lastClientId)
152 {
153 lastClientId = idNum;
154 }
Ratan Gupta212f53e2018-04-30 17:28:05 +0530155 }
156 }
157}
158
Ratan Gupta1dc91782018-04-19 16:47:12 +0530159} // namespace snmp
160} // namespace network
161} // namespace phosphor