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 | 12 | #include "serviceholder.h" |
e0080b78 | 13 | |
e0080b78 | 14 | |
ca5d6889 BS |
15 | #include <boost/foreach.hpp> |
16 | #include <boost/serialization/export.hpp> | |
b30f392d | 17 | |
e0080b78 | 18 | |
8bca3c5d | 19 | using namespace std; |
527536b3 | 20 | |
ca5d6889 | 21 | |
b1be615b BS |
22 | /** |
23 | * Default constructor which initializes the member Conf. | |
24 | */ | |
4545a371 | 25 | Updater::Updater() |
ad0e5016 | 26 | : IPAddrHelp(new IPAddrHelper) |
4545a371 | 27 | { |
2e956a36 | 28 | // Initialize program wide Logger, at this point we don't know where to log and with which loglevel. |
c3c84086 | 29 | Log = Logger::Ptr(new Logger); |
4545a371 | 30 | |
e0080b78 | 31 | // initialize Serviceholder |
c3c84086 | 32 | ServiceHolder = Serviceholder::Ptr(new Serviceholder(Log)); |
e0080b78 | 33 | |
254bbf53 | 34 | // initialize Config |
c3c84086 | 35 | Conf = Config::Ptr(new Config(Log,ServiceHolder)); |
4545a371 BS |
36 | } |
37 | ||
527536b3 | 38 | |
b1be615b BS |
39 | /** |
40 | * Default destructor. | |
41 | */ | |
4545a371 BS |
42 | Updater::~Updater() |
43 | { | |
44 | } | |
45 | ||
527536b3 | 46 | |
efbde536 BS |
47 | |
48 | /** | |
49 | * Load config and initialize helper classes. | |
50 | * @param argc Number of arguments in array | |
51 | * @param argv Array with cmd options | |
52 | */ | |
53 | int Updater::load_config(int argc, char *argv[]) | |
54 | { | |
55 | // load the cmd options | |
56 | if ( init_config_from_cmd(argc,argv) != 0 ) | |
57 | return -1; | |
58 | ||
59 | // load the config and service files | |
60 | if ( init_config_from_files() != 0 ) | |
61 | return -1; | |
62 | ||
63 | // init all helper classes | |
64 | if ( init_helper_classes() != 0 ) | |
65 | return -1; | |
66 | ||
67 | return 0; | |
68 | } | |
69 | ||
70 | ||
71 | /** | |
72 | * Reloading the config. Delete all Service objects and then init new Service objects from config files. | |
73 | */ | |
74 | int Updater::reload_config() | |
75 | { | |
76 | // serialize all service objects | |
77 | if ( ServiceHolder->serialize_services() != 0 ) | |
78 | return -1; | |
79 | ||
80 | // delete all service objects | |
81 | ServiceHolder->delete_services(); | |
82 | ||
83 | // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options. | |
84 | Conf->delete_variables_map(); | |
85 | ||
86 | // load only config files | |
87 | if ( init_config_from_files() != 0 ) | |
88 | return -1; | |
89 | ||
90 | // init all helper classes | |
91 | if ( init_helper_classes() != 0 ) | |
92 | return -1; | |
93 | ||
94 | return 0; | |
95 | } | |
96 | ||
97 | ||
b1be615b | 98 | /** |
254bbf53 BS |
99 | * Parse the command line arguments and initialize corresponding options. |
100 | * @param argc Number command line arguments. | |
101 | * @param argv[] Array with arguments. | |
102 | * @return 0 if cmd options successfully parsed, 1 if usage or version. | |
38060291 | 103 | */ |
08a5a621 | 104 | int Updater::init_config_from_cmd(int argc, char *argv[]) const |
38060291 BS |
105 | { |
106 | // Load the command line parameters | |
e95a6634 | 107 | if( Conf->parse_cmd_line( argc, argv) != 0) |
667c672c | 108 | return -1; |
38060291 | 109 | |
59c8d63c BS |
110 | // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd. |
111 | init_log_facility(); | |
112 | ||
254bbf53 BS |
113 | // successful parsed |
114 | Log->print_cmd_parsed(); | |
38060291 BS |
115 | return 0; |
116 | } | |
117 | ||
118 | ||
119 | /** | |
254bbf53 BS |
120 | * Load the main config and the service definition files in config path. |
121 | * @return 0 if all is fine, | |
b1be615b | 122 | */ |
08a5a621 | 123 | int Updater::init_config_from_files() const |
4545a371 | 124 | { |
254bbf53 | 125 | // Load the main and service config files in config path |
e95a6634 | 126 | if ( Conf->load_config_from_files() != 0 ) |
667c672c | 127 | return -1; |
4545a371 | 128 | |
59c8d63c BS |
129 | // Re-init log facility, perhaps new config file options for logger are set. |
130 | // These config file options will only overwrite the cmd options if the SIGHUP (reload config) is caught. | |
131 | init_log_facility(); | |
132 | ||
27baf279 | 133 | // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them. |
e0080b78 | 134 | if ( ServiceHolder->deserialize_services() != 0 ) |
667c672c | 135 | return -1; |
27baf279 | 136 | |
254bbf53 | 137 | // successful loaded |
667c672c | 138 | Log->print_conf_files_parsed(); |
254bbf53 | 139 | return 0; |
4545a371 BS |
140 | } |
141 | ||
527536b3 | 142 | |
b1be615b | 143 | /** |
efbde536 BS |
144 | * Init all Helper classes |
145 | * @return | |
3434b35f | 146 | */ |
efbde536 | 147 | int Updater::init_helper_classes() |
3434b35f | 148 | { |
efbde536 BS |
149 | // Initialize IPHelper |
150 | if ( init_ip_helper() != 0 ) | |
151 | return -1; | |
3434b35f | 152 | |
efbde536 | 153 | return 0; |
3434b35f BS |
154 | } |
155 | ||
156 | ||
157 | /** | |
0665b239 BS |
158 | * Init the IPHelp member with needed values. |
159 | * @return 0 if all is fine, -1 otherwise. | |
160 | */ | |
161 | int Updater::init_ip_helper() | |
162 | { | |
20399847 BS |
163 | // Try to get deserialized IPAddrHelper from ServiceHolder |
164 | IPAddrHelper::Ptr _ip_addr_help = ServiceHolder->get_ip_addr_helper(); | |
165 | if ( _ip_addr_help.use_count() != 0 ) | |
166 | { | |
167 | // Initialize IPHelper | |
c3c84086 | 168 | IPAddrHelp = IPAddrHelper::Ptr( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), _ip_addr_help->get_last_webcheck(), Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) ); |
20399847 BS |
169 | } |
170 | else | |
171 | { | |
172 | // IPAddrHelper from ServiceHolder was not declared, so init oen with LastWebcheck 0 | |
08a5a621 | 173 | IPAddrHelp = IPAddrHelper::Ptr( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), (size_t)0, Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) ); |
20399847 BS |
174 | } |
175 | ||
176 | // Put the IPAddrHelper into ServiceHolder, so the LastWebcheck state will be serialized too. | |
177 | ServiceHolder->set_ip_addr_helper(IPAddrHelp); | |
0665b239 BS |
178 | |
179 | return 0; | |
180 | } | |
181 | ||
182 | ||
183 | /** | |
efbde536 BS |
184 | * Getter for member Config. |
185 | * @return Member Config. | |
186 | */ | |
187 | Config::Ptr Updater::get_config() const | |
188 | { | |
189 | return Conf; | |
190 | } | |
667c672c | 191 | |
efbde536 BS |
192 | |
193 | /** | |
194 | * Getter for member Logger. | |
195 | * @return Member Logger. | |
196 | */ | |
197 | Logger::Ptr Updater::get_logger() const | |
198 | { | |
199 | return Log; | |
8bca3c5d BS |
200 | } |
201 | ||
202 | ||
2bc1878a BS |
203 | /** |
204 | * Initialize the logging facility with loglevel and syslog. | |
205 | */ | |
c730deea | 206 | void Updater::init_log_facility() const |
8bca3c5d | 207 | { |
cbbdeb6c | 208 | Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level()); |
8bca3c5d | 209 | Log->print_init_log_facility(); |
c5675c01 BS |
210 | } |
211 | ||
212 | ||
213 | /** | |
b1be615b BS |
214 | * Update all configured services. |
215 | */ | |
c730deea | 216 | void Updater::update_services() const |
4545a371 | 217 | { |
1af7c124 | 218 | // Get all services from the ServiceHolder. |
e0080b78 | 219 | list<Service::Ptr> services = ServiceHolder->get_services(); |
4545a371 | 220 | |
1af7c124 | 221 | // Get the actual IP of this host. |
46fffdd6 | 222 | string ip_host = IPAddrHelp->get_actual_ip(Conf->get_webcheck_enabled()); |
4545a371 | 223 | |
1af7c124 | 224 | if ( !ip_host.empty() ) |
4545a371 | 225 | { |
3c0cd271 BS |
226 | BOOST_FOREACH(Service::Ptr &service, services ) |
227 | { | |
1af7c124 BS |
228 | string ip_last_update = service->get_actual_ip(); |
229 | string hostname = service->get_hostname(); | |
c730deea BS |
230 | time_t lastupdated = 0; |
231 | time_t current_time = time(NULL); | |
c3dea5dc | 232 | |
1af7c124 | 233 | // Try to get the lastupdated time of the actual service if there is one. |
c1b8cb79 | 234 | if ( service->get_last_updates().size() > 0 ) |
08a5a621 | 235 | lastupdated = service->get_last_updates().front(); /*lint !e1793 */ |
c3dea5dc | 236 | |
1af7c124 BS |
237 | Log->print_check_service_update(hostname, current_time, lastupdated); |
238 | ||
239 | // Do a DNS Query for the dynamic hostname. | |
240 | string ip_dns_recheck = IPAddrHelp->dns_query(hostname); | |
241 | ||
242 | Log->print_cached_dns_entry(hostname, ip_dns_recheck, ip_last_update, ip_host); | |
243 | ||
a7c1e271 BS |
244 | // Test if the DNS-Record could not be found. |
245 | if ( ip_dns_recheck.empty() ) | |
246 | { | |
247 | // Next in BOOST_FOREACH | |
248 | } | |
1af7c124 | 249 | // Test if the actual DNS-Record differs from the host's IP. |
a7c1e271 | 250 | else if ( ip_host != ip_dns_recheck ) |
0541cd71 | 251 | { |
1af7c124 BS |
252 | // Check if the service will be updated for the first time. |
253 | if ( lastupdated == 0 ) | |
254 | { | |
255 | // Update for the firt time. | |
256 | Log->print_update_service_firttime(hostname, ip_dns_recheck, ip_host); | |
257 | service->update(ip_host,current_time); | |
258 | } | |
259 | else | |
260 | { | |
261 | // We already have updated, check if the IP set in last update differs from the actual host's ip. | |
262 | if ( ip_last_update != ip_host ) | |
263 | { | |
264 | // Update | |
265 | Log->print_update_service(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated); | |
266 | service->update(ip_host,current_time); | |
267 | } | |
268 | else | |
269 | { | |
270 | int dns_cache_ttl = service->get_dns_cache_ttl(); | |
271 | // Check if DNS Cache TTL is expired, if so, then update the same IP again. | |
272 | if ( (lastupdated + dns_cache_ttl) < current_time ) | |
273 | { | |
274 | // Update | |
275 | Log->print_update_service_ttl_expired(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time); | |
276 | service->update(ip_host,current_time); | |
277 | } | |
278 | else | |
279 | { | |
280 | // DNS cache TTL isn't expired | |
281 | Log->print_update_service_ttl_not_expired(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated, dns_cache_ttl, current_time); | |
282 | } | |
283 | } | |
284 | } | |
285 | } | |
286 | else | |
287 | { | |
288 | Log->print_no_update_needed(hostname, ip_dns_recheck, ip_last_update, ip_host, lastupdated); | |
0541cd71 | 289 | } |
3c0cd271 | 290 | } |
4545a371 | 291 | } |
1d2e2f56 BS |
292 | else |
293 | { | |
294 | Log->print_no_wan_ip(); | |
295 | } | |
b1be615b | 296 | } |
e0080b78 BS |
297 | |
298 | ||
299 | /** | |
300 | * Getter for member ServiceHolder. | |
301 | * @return ServiceHolder | |
302 | */ | |
303 | Serviceholder::Ptr Updater::get_service_holder() const | |
304 | { | |
305 | return ServiceHolder; | |
306 | } |