Commit | Line | Data |
---|---|---|
b1be615b BS |
1 | /** @file |
2 | * @brief The updater class implementation. This class implements the updater logic. | |
3 | * | |
4 | * | |
5 | * | |
6 | * @copyright Intra2net AG | |
7 | * @license GPLv2 | |
8 | */ | |
9 | ||
4545a371 BS |
10 | #include "updater.h" |
11 | ||
e0080b78 BS |
12 | #include "serviceholder.h" |
13 | #include "dhs.h" | |
14 | #include "ods.h" | |
15 | ||
88a594e8 BS |
16 | #include <boost/foreach.hpp> |
17 | ||
e0080b78 BS |
18 | |
19 | // Following boost macros are needed for serialization of derived classes through a base class pointer (Service *). | |
20 | BOOST_CLASS_EXPORT_GUID(ODS, "ODS") | |
21 | BOOST_CLASS_EXPORT_GUID(DHS, "DHS") | |
22 | ||
23 | namespace fs = boost::filesystem; | |
24 | ||
8bca3c5d | 25 | using namespace std; |
527536b3 | 26 | |
b1be615b BS |
27 | /** |
28 | * Default constructor which initializes the member Conf. | |
29 | */ | |
4545a371 | 30 | Updater::Updater() |
019dc0d9 | 31 | : IPHelp(new IPHelper) |
4545a371 | 32 | { |
2e956a36 | 33 | // Initialize program wide Logger, at this point we don't know where to log and with which loglevel. |
88a594e8 | 34 | Logger::Ptr _log(new Logger); |
254bbf53 | 35 | Log = _log; |
0665b239 | 36 | _log.reset(); |
4545a371 | 37 | |
e0080b78 BS |
38 | // initialize Serviceholder |
39 | Serviceholder::Ptr _serviceholder(new Serviceholder(Log)); | |
40 | ServiceHolder = _serviceholder; | |
41 | _serviceholder.reset(); | |
42 | ||
254bbf53 | 43 | // initialize Config |
e0080b78 | 44 | Config::Ptr _config(new Config(Log,ServiceHolder)); |
254bbf53 | 45 | Conf = _config; |
0665b239 | 46 | _config.reset(); |
4545a371 BS |
47 | } |
48 | ||
527536b3 | 49 | |
b1be615b BS |
50 | /** |
51 | * Default destructor. | |
52 | */ | |
4545a371 BS |
53 | Updater::~Updater() |
54 | { | |
55 | } | |
56 | ||
527536b3 | 57 | |
efbde536 BS |
58 | |
59 | /** | |
60 | * Load config and initialize helper classes. | |
61 | * @param argc Number of arguments in array | |
62 | * @param argv Array with cmd options | |
63 | */ | |
64 | int Updater::load_config(int argc, char *argv[]) | |
65 | { | |
66 | // load the cmd options | |
67 | if ( init_config_from_cmd(argc,argv) != 0 ) | |
68 | return -1; | |
69 | ||
70 | // load the config and service files | |
71 | if ( init_config_from_files() != 0 ) | |
72 | return -1; | |
73 | ||
74 | // init all helper classes | |
75 | if ( init_helper_classes() != 0 ) | |
76 | return -1; | |
77 | ||
78 | return 0; | |
79 | } | |
80 | ||
81 | ||
82 | /** | |
83 | * Reloading the config. Delete all Service objects and then init new Service objects from config files. | |
84 | */ | |
85 | int Updater::reload_config() | |
86 | { | |
87 | // serialize all service objects | |
88 | if ( ServiceHolder->serialize_services() != 0 ) | |
89 | return -1; | |
90 | ||
91 | // delete all service objects | |
92 | ServiceHolder->delete_services(); | |
93 | ||
94 | // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options. | |
95 | Conf->delete_variables_map(); | |
96 | ||
97 | // load only config files | |
98 | if ( init_config_from_files() != 0 ) | |
99 | return -1; | |
100 | ||
101 | // init all helper classes | |
102 | if ( init_helper_classes() != 0 ) | |
103 | return -1; | |
104 | ||
105 | return 0; | |
106 | } | |
107 | ||
108 | ||
b1be615b | 109 | /** |
254bbf53 BS |
110 | * Parse the command line arguments and initialize corresponding options. |
111 | * @param argc Number command line arguments. | |
112 | * @param argv[] Array with arguments. | |
113 | * @return 0 if cmd options successfully parsed, 1 if usage or version. | |
38060291 | 114 | */ |
254bbf53 | 115 | int Updater::init_config_from_cmd(int argc, char *argv[]) |
38060291 BS |
116 | { |
117 | // Load the command line parameters | |
efbde536 | 118 | if( Conf->parse_cmd_line( argc, argv, HTTPHelp) != 0) |
667c672c | 119 | return -1; |
38060291 | 120 | |
59c8d63c BS |
121 | // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd. |
122 | init_log_facility(); | |
123 | ||
254bbf53 BS |
124 | // successful parsed |
125 | Log->print_cmd_parsed(); | |
38060291 BS |
126 | return 0; |
127 | } | |
128 | ||
129 | ||
130 | /** | |
254bbf53 BS |
131 | * Load the main config and the service definition files in config path. |
132 | * @return 0 if all is fine, | |
b1be615b | 133 | */ |
254bbf53 | 134 | int Updater::init_config_from_files() |
4545a371 | 135 | { |
254bbf53 | 136 | // Load the main and service config files in config path |
efbde536 | 137 | if ( Conf->load_config_from_files(HTTPHelp) != 0 ) |
667c672c | 138 | return -1; |
4545a371 | 139 | |
59c8d63c BS |
140 | // Re-init log facility, perhaps new config file options for logger are set. |
141 | // These config file options will only overwrite the cmd options if the SIGHUP (reload config) is caught. | |
142 | init_log_facility(); | |
143 | ||
27baf279 | 144 | // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them. |
e0080b78 | 145 | if ( ServiceHolder->deserialize_services() != 0 ) |
667c672c | 146 | return -1; |
27baf279 | 147 | |
254bbf53 | 148 | // successful loaded |
667c672c | 149 | Log->print_conf_files_parsed(); |
254bbf53 | 150 | return 0; |
4545a371 BS |
151 | } |
152 | ||
527536b3 | 153 | |
b1be615b | 154 | /** |
efbde536 BS |
155 | * Init all Helper classes |
156 | * @return | |
3434b35f | 157 | */ |
efbde536 | 158 | int Updater::init_helper_classes() |
3434b35f | 159 | { |
efbde536 BS |
160 | // Initialize IPHelper |
161 | if ( init_ip_helper() != 0 ) | |
162 | return -1; | |
3434b35f | 163 | |
efbde536 BS |
164 | // Initialize HTTPHelper |
165 | if ( init_http_helper() != 0 ) | |
166 | return -1; | |
3434b35f | 167 | |
efbde536 | 168 | return 0; |
3434b35f BS |
169 | } |
170 | ||
171 | ||
172 | /** | |
0665b239 BS |
173 | * Init the IPHelp member with needed values. |
174 | * @return 0 if all is fine, -1 otherwise. | |
175 | */ | |
176 | int Updater::init_ip_helper() | |
177 | { | |
019dc0d9 | 178 | // initialize IPHelper |
4eb87664 | 179 | IPHelper::Ptr _iphelp(new IPHelper(Log,Conf->get_webcheck_ip_url(),Conf->get_webcheck_ip_url_alt(),Conf->get_enable_ipv6(),Conf->get_proxy(),Conf->get_proxy_port())); |
019dc0d9 BS |
180 | IPHelp = _iphelp; |
181 | _iphelp.reset(); | |
0665b239 BS |
182 | |
183 | return 0; | |
184 | } | |
185 | ||
186 | ||
187 | /** | |
efbde536 BS |
188 | * Init the IPHelp member with needed values. |
189 | * @return 0 if all is fine, -1 otherwise. | |
c5675c01 | 190 | */ |
efbde536 | 191 | int Updater::init_http_helper() |
c5675c01 | 192 | { |
efbde536 BS |
193 | // initialize IPHelper |
194 | HTTPHelper::Ptr _httphelp(new HTTPHelper(Log,Conf->get_proxy(),Conf->get_proxy_port())); | |
195 | HTTPHelp = _httphelp; | |
196 | _httphelp.reset(); | |
27baf279 | 197 | |
efbde536 BS |
198 | return 0; |
199 | } | |
8bca3c5d | 200 | |
8bca3c5d | 201 | |
efbde536 BS |
202 | /** |
203 | * Getter for member Config. | |
204 | * @return Member Config. | |
205 | */ | |
206 | Config::Ptr Updater::get_config() const | |
207 | { | |
208 | return Conf; | |
209 | } | |
667c672c | 210 | |
efbde536 BS |
211 | |
212 | /** | |
213 | * Getter for member Logger. | |
214 | * @return Member Logger. | |
215 | */ | |
216 | Logger::Ptr Updater::get_logger() const | |
217 | { | |
218 | return Log; | |
8bca3c5d BS |
219 | } |
220 | ||
221 | ||
2bc1878a BS |
222 | /** |
223 | * Initialize the logging facility with loglevel and syslog. | |
224 | */ | |
8bca3c5d BS |
225 | void Updater::init_log_facility() |
226 | { | |
cbbdeb6c | 227 | Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level()); |
8bca3c5d | 228 | Log->print_init_log_facility(); |
c5675c01 BS |
229 | } |
230 | ||
231 | ||
232 | /** | |
b1be615b BS |
233 | * Update all configured services. |
234 | */ | |
4545a371 BS |
235 | void Updater::update_services() |
236 | { | |
e0080b78 | 237 | list<Service::Ptr> services = ServiceHolder->get_services(); |
4545a371 | 238 | |
0665b239 | 239 | string ip = IPHelp->get_actual_ip(); |
4545a371 | 240 | |
3c0cd271 | 241 | if ( !ip.empty() ) |
4545a371 | 242 | { |
3c0cd271 BS |
243 | BOOST_FOREACH(Service::Ptr &service, services ) |
244 | { | |
c3dea5dc BS |
245 | string dns_recheck_ip = ip; |
246 | int current_time = time(NULL); | |
247 | ||
248 | int lastupdated = 0; | |
249 | if ( service->get_last_updates()->size() > 0 ) | |
250 | lastupdated = service->get_last_updates()->front(); | |
251 | ||
4eb87664 | 252 | // If the dns cache ttl is expired, then get the actual ip of the dns record (this should be the IP in the last update) |
c3dea5dc | 253 | if ( (lastupdated != 0) && ((lastupdated + service->get_dns_cache_ttl()) < current_time) ) |
0541cd71 BS |
254 | { |
255 | Log->print_recheck_dns_entry(service->get_hostname(),lastupdated,service->get_dns_cache_ttl(),current_time); | |
256 | string _dns_recheck_ip = IPHelp->dns_query(service->get_hostname()); | |
257 | Log->print_cached_dns_entry(service->get_hostname(), _dns_recheck_ip, service->get_actual_ip()); | |
258 | if (!_dns_recheck_ip.empty()) | |
259 | dns_recheck_ip = _dns_recheck_ip; | |
260 | } | |
c3dea5dc | 261 | |
4eb87664 BS |
262 | // In case the local hosts IP (ip) differ from the IP set in the last update (actual_ip) or |
263 | // the IP of the dns record (dns_recheck_ip) differs from the IP of the local host (ip) | |
264 | // then perform an update. This implies that the update is not performed if actual_ip == dns_recheck_ip. | |
c3dea5dc BS |
265 | if ( (service->get_actual_ip() != ip) || (dns_recheck_ip != ip) ) |
266 | service->update(ip,current_time); | |
3c0cd271 | 267 | } |
4545a371 | 268 | } |
b1be615b | 269 | } |
e0080b78 BS |
270 | |
271 | ||
272 | /** | |
273 | * Getter for member ServiceHolder. | |
274 | * @return ServiceHolder | |
275 | */ | |
276 | Serviceholder::Ptr Updater::get_service_holder() const | |
277 | { | |
278 | return ServiceHolder; | |
279 | } |