1 #pragma once
2 
3 #include "xyz/openbmc_project/Network/Client/server.hpp"
4 
5 #include <phosphor-logging/log.hpp>
6 #include <sdbusplus/bus.hpp>
7 #include <sdbusplus/server/object.hpp>
8 
9 #include <string>
10 
11 namespace phosphor
12 {
13 namespace rsyslog_config
14 {
15 
16 using namespace phosphor::logging;
17 using NetworkClient = sdbusplus::xyz::openbmc_project::Network::server::Client;
18 using Iface = sdbusplus::server::object_t<NetworkClient>;
19 namespace sdbusRule = sdbusplus::bus::match::rules;
20 
21 /** @class Server
22  *  @brief Configuration for rsyslog server
23  *  @details A concrete implementation of the
24  *  xyz.openbmc_project.Network.Client API, in order to
25  *  provide remote rsyslog server's address and port.
26  */
27 class Server : public Iface
28 {
29   public:
30     Server() = delete;
31     Server(const Server&) = delete;
32     Server& operator=(const Server&) = delete;
33     Server(Server&&) = delete;
34     Server& operator=(Server&&) = delete;
35     virtual ~Server() = default;
36 
37     /** @brief Constructor to put object onto bus at a dbus path.
38      *  @param[in] bus - Bus to attach to.
39      *  @param[in] path - Path to attach at.
40      *  @param[in] filePath - rsyslog remote logging config file
41      */
Server(sdbusplus::bus_t & bus,const std::string & path,const char * filePath)42     Server(sdbusplus::bus_t& bus, const std::string& path,
43            const char* filePath) :
44         Iface(bus, path.c_str(), Iface::action::defer_emit),
45         configFilePath(filePath),
46         hostnameChange(
47             bus,
48             sdbusRule::propertiesChanged("/org/freedesktop/hostname1",
49                                          "org.freedesktop.hostname1"),
50             std::bind(std::mem_fn(&Server::hostnameChanged), this,
51                       std::placeholders::_1))
52     {
53         try
54         {
55             restore(configFilePath.c_str());
56         }
57         catch (const std::exception& e)
58         {
59             log<level::ERR>(e.what());
60         }
61 
62         emit_object_added();
63     }
64 
65     using NetworkClient::address;
66     using NetworkClient::port;
67     using NetworkClient::transportProtocol;
68 
69     /** @brief Override that updates rsyslog config file as well
70      *  @param[in] value - remote server address
71      *  @returns value of changed address
72      */
73     virtual std::string address(std::string value) override;
74 
75     /** @brief Override that updates rsyslog config file as well
76      *  @param[in] value - remote server port
77      *  @returns value of changed port
78      */
79     virtual uint16_t port(uint16_t value) override;
80 
81     /** @brief Restart rsyslog's systemd unit
82      */
83     virtual void restart();
84 
85     /** @brief Set protocol for rsyslog TCP or UDP.
86      *  @param[in] value - UDP/TCP.
87      *  @returns protocol value
88      */
89     virtual TransportProtocol
90         transportProtocol(TransportProtocol protocol) override;
91 
92   private:
93     /** @brief Update remote server address and port in
94      *         rsyslog config file.
95      *  @param[in] serverAddress - remote server address
96      *  @param[in] serverPort - remote server port
97      *  @param[in] serverTransportProtocol - remote server protocol TCP/UDP
98      *  @param[in] filePath - rsyslog config file path
99      */
100     void writeConfig(const std::string& serverAddress, uint16_t serverPort,
101                      TransportProtocol protocol, const char* filePath);
102 
103     /** @brief Checks if input IP address is valid (uses getaddrinfo)
104      *  @param[in] address - server address
105      *  @returns true if valid, false otherwise
106      */
107     bool addressValid(const std::string& address);
108 
109     /** @brief Populate existing config into D-Bus properties
110      *  @param[in] filePath - rsyslog config file path
111      */
112     void restore(const char* filePath);
113 
114     std::string configFilePath{};
115 
116     /** @brief React to hostname change
117      *  @param[in] msg - sdbusplus message
118      */
hostnameChanged(sdbusplus::message_t &)119     void hostnameChanged(sdbusplus::message_t& /*msg*/)
120     {
121         restart();
122     }
123 
124     sdbusplus::bus::match_t hostnameChange;
125 };
126 
127 } // namespace rsyslog_config
128 } // namespace phosphor
129