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. |
88a594e8 | 29 | Logger::Ptr _log(new Logger); |
4dfdba68 | 30 | Log.swap(_log); |
4545a371 | 31 | |
e0080b78 BS |
32 | // initialize Serviceholder |
33 | Serviceholder::Ptr _serviceholder(new Serviceholder(Log)); | |
4dfdba68 | 34 | ServiceHolder.swap(_serviceholder); |
e0080b78 | 35 | |
254bbf53 | 36 | // initialize Config |
e0080b78 | 37 | Config::Ptr _config(new Config(Log,ServiceHolder)); |
4dfdba68 | 38 | Conf.swap(_config); |
4545a371 BS |
39 | } |
40 | ||
527536b3 | 41 | |
b1be615b BS |
42 | /** |
43 | * Default destructor. | |
44 | */ | |
4545a371 BS |
45 | Updater::~Updater() |
46 | { | |
47 | } | |
48 | ||
527536b3 | 49 | |
efbde536 BS |
50 | |
51 | /** | |
52 | * Load config and initialize helper classes. | |
53 | * @param argc Number of arguments in array | |
54 | * @param argv Array with cmd options | |
55 | */ | |
56 | int Updater::load_config(int argc, char *argv[]) | |
57 | { | |
58 | // load the cmd options | |
59 | if ( init_config_from_cmd(argc,argv) != 0 ) | |
60 | return -1; | |
61 | ||
62 | // load the config and service files | |
63 | if ( init_config_from_files() != 0 ) | |
64 | return -1; | |
65 | ||
66 | // init all helper classes | |
67 | if ( init_helper_classes() != 0 ) | |
68 | return -1; | |
69 | ||
70 | return 0; | |
71 | } | |
72 | ||
73 | ||
74 | /** | |
75 | * Reloading the config. Delete all Service objects and then init new Service objects from config files. | |
76 | */ | |
77 | int Updater::reload_config() | |
78 | { | |
79 | // serialize all service objects | |
80 | if ( ServiceHolder->serialize_services() != 0 ) | |
81 | return -1; | |
82 | ||
83 | // delete all service objects | |
84 | ServiceHolder->delete_services(); | |
85 | ||
86 | // delete the actual Variables_map, perhaps with old cmd options which would overwrite new config file options. | |
87 | Conf->delete_variables_map(); | |
88 | ||
89 | // load only config files | |
90 | if ( init_config_from_files() != 0 ) | |
91 | return -1; | |
92 | ||
93 | // init all helper classes | |
94 | if ( init_helper_classes() != 0 ) | |
95 | return -1; | |
96 | ||
97 | return 0; | |
98 | } | |
99 | ||
100 | ||
b1be615b | 101 | /** |
254bbf53 BS |
102 | * Parse the command line arguments and initialize corresponding options. |
103 | * @param argc Number command line arguments. | |
104 | * @param argv[] Array with arguments. | |
105 | * @return 0 if cmd options successfully parsed, 1 if usage or version. | |
38060291 | 106 | */ |
254bbf53 | 107 | int Updater::init_config_from_cmd(int argc, char *argv[]) |
38060291 BS |
108 | { |
109 | // Load the command line parameters | |
e95a6634 | 110 | if( Conf->parse_cmd_line( argc, argv) != 0) |
667c672c | 111 | return -1; |
38060291 | 112 | |
59c8d63c BS |
113 | // If we have loaded the cmd options we need to init the log facility immediately in case debugging is enabled from cmd. |
114 | init_log_facility(); | |
115 | ||
254bbf53 BS |
116 | // successful parsed |
117 | Log->print_cmd_parsed(); | |
38060291 BS |
118 | return 0; |
119 | } | |
120 | ||
121 | ||
122 | /** | |
254bbf53 BS |
123 | * Load the main config and the service definition files in config path. |
124 | * @return 0 if all is fine, | |
b1be615b | 125 | */ |
254bbf53 | 126 | int Updater::init_config_from_files() |
4545a371 | 127 | { |
254bbf53 | 128 | // Load the main and service config files in config path |
e95a6634 | 129 | if ( Conf->load_config_from_files() != 0 ) |
667c672c | 130 | return -1; |
4545a371 | 131 | |
59c8d63c BS |
132 | // Re-init log facility, perhaps new config file options for logger are set. |
133 | // These config file options will only overwrite the cmd options if the SIGHUP (reload config) is caught. | |
134 | init_log_facility(); | |
135 | ||
27baf279 | 136 | // Here we are. All Service Objects should be initialized, so it is time to deserialize the old service objects and compare them. |
e0080b78 | 137 | if ( ServiceHolder->deserialize_services() != 0 ) |
667c672c | 138 | return -1; |
27baf279 | 139 | |
254bbf53 | 140 | // successful loaded |
667c672c | 141 | Log->print_conf_files_parsed(); |
254bbf53 | 142 | return 0; |
4545a371 BS |
143 | } |
144 | ||
527536b3 | 145 | |
b1be615b | 146 | /** |
efbde536 BS |
147 | * Init all Helper classes |
148 | * @return | |
3434b35f | 149 | */ |
efbde536 | 150 | int Updater::init_helper_classes() |
3434b35f | 151 | { |
efbde536 BS |
152 | // Initialize IPHelper |
153 | if ( init_ip_helper() != 0 ) | |
154 | return -1; | |
3434b35f | 155 | |
efbde536 | 156 | return 0; |
3434b35f BS |
157 | } |
158 | ||
159 | ||
160 | /** | |
0665b239 BS |
161 | * Init the IPHelp member with needed values. |
162 | * @return 0 if all is fine, -1 otherwise. | |
163 | */ | |
164 | int Updater::init_ip_helper() | |
165 | { | |
20399847 BS |
166 | // Try to get deserialized IPAddrHelper from ServiceHolder |
167 | IPAddrHelper::Ptr _ip_addr_help = ServiceHolder->get_ip_addr_helper(); | |
168 | if ( _ip_addr_help.use_count() != 0 ) | |
169 | { | |
170 | // Initialize IPHelper | |
171 | IPAddrHelper::Ptr ip_addr_help( 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() ) ); | |
172 | IPAddrHelp.swap(ip_addr_help); | |
173 | } | |
174 | else | |
175 | { | |
176 | // IPAddrHelper from ServiceHolder was not declared, so init oen with LastWebcheck 0 | |
177 | IPAddrHelper::Ptr ip_addr_help( new IPAddrHelper( Log, Conf->get_webcheck_ip_url(), Conf->get_webcheck_ip_url_alt(), Conf->get_webcheck_interval(), 0, Conf->get_enable_ipv6(), Conf->get_proxy(), Conf->get_proxy_port() ) ); | |
178 | IPAddrHelp.swap(ip_addr_help); | |
179 | } | |
180 | ||
181 | // Put the IPAddrHelper into ServiceHolder, so the LastWebcheck state will be serialized too. | |
182 | ServiceHolder->set_ip_addr_helper(IPAddrHelp); | |
0665b239 BS |
183 | |
184 | return 0; | |
185 | } | |
186 | ||
187 | ||
188 | /** | |
efbde536 BS |
189 | * Getter for member Config. |
190 | * @return Member Config. | |
191 | */ | |
192 | Config::Ptr Updater::get_config() const | |
193 | { | |
194 | return Conf; | |
195 | } | |
667c672c | 196 | |
efbde536 BS |
197 | |
198 | /** | |
199 | * Getter for member Logger. | |
200 | * @return Member Logger. | |
201 | */ | |
202 | Logger::Ptr Updater::get_logger() const | |
203 | { | |
204 | return Log; | |
8bca3c5d BS |
205 | } |
206 | ||
207 | ||
2bc1878a BS |
208 | /** |
209 | * Initialize the logging facility with loglevel and syslog. | |
210 | */ | |
8bca3c5d BS |
211 | void Updater::init_log_facility() |
212 | { | |
cbbdeb6c | 213 | Log->set_log_facility(Conf->get_loglevel(),Conf->get_syslog(),Conf->get_external_warning_log(),Conf->get_external_warning_level()); |
8bca3c5d | 214 | Log->print_init_log_facility(); |
c5675c01 BS |
215 | } |
216 | ||
217 | ||
218 | /** | |
b1be615b BS |
219 | * Update all configured services. |
220 | */ | |
4545a371 BS |
221 | void Updater::update_services() |
222 | { | |
1af7c124 | 223 | // Get all services from the ServiceHolder. |
e0080b78 | 224 | list<Service::Ptr> services = ServiceHolder->get_services(); |
4545a371 | 225 | |
1af7c124 BS |
226 | // Get the actual IP of this host. |
227 | string ip_host = IPAddrHelp->get_actual_ip(); | |
4545a371 | 228 | |
1af7c124 | 229 | if ( !ip_host.empty() ) |
4545a371 | 230 | { |
3c0cd271 BS |
231 | BOOST_FOREACH(Service::Ptr &service, services ) |
232 | { | |
1af7c124 BS |
233 | string ip_last_update = service->get_actual_ip(); |
234 | string hostname = service->get_hostname(); | |
235 | int lastupdated = 0; | |
c3dea5dc BS |
236 | int current_time = time(NULL); |
237 | ||
1af7c124 | 238 | // Try to get the lastupdated time of the actual service if there is one. |
c1b8cb79 BS |
239 | if ( service->get_last_updates().size() > 0 ) |
240 | lastupdated = service->get_last_updates().front(); | |
c3dea5dc | 241 | |
1af7c124 BS |
242 | Log->print_check_service_update(hostname, current_time, lastupdated); |
243 | ||
244 | // Do a DNS Query for the dynamic hostname. | |
245 | string ip_dns_recheck = IPAddrHelp->dns_query(hostname); | |
246 | ||
247 | Log->print_cached_dns_entry(hostname, ip_dns_recheck, ip_last_update, ip_host); | |
248 | ||
249 | // Test if the actual DNS-Record differs from the host's IP. | |
250 | 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 | } |
b1be615b | 292 | } |
e0080b78 BS |
293 | |
294 | ||
295 | /** | |
296 | * Getter for member ServiceHolder. | |
297 | * @return ServiceHolder | |
298 | */ | |
299 | Serviceholder::Ptr Updater::get_service_holder() const | |
300 | { | |
301 | return ServiceHolder; | |
302 | } |