added option min-time-between-resolves-option and tests for it
[pingcheck] / src / config / configurationoptions.cpp
CommitLineData
aab6eaa1
GMF
1/*
2 The software in this package is distributed under the GNU General
3 Public License version 2 (with a special exception described below).
4
5 A copy of GNU General Public License (GPL) is included in this distribution,
6 in the file COPYING.GPL.
7
8 As a special exception, if other files instantiate templates or use macros
9 or inline functions from this file, or you compile this file and link it
10 with other works to produce a work based on this file, this file
11 does not by itself cause the resulting work to be covered
12 by the GNU General Public License.
13
14 However the source code for this file must still be made available
15 in accordance with section (3) of the GNU General Public License.
16
17 This exception does not invalidate any other reasons why a work based
18 on this file might be covered by the GNU General Public License.
19 */
20
21#include "config/configurationoptions.h"
22
23#include <iostream>
24
aab6eaa1
GMF
25#include <boost/foreach.hpp>
26
27#include <logfunc.hpp>
28
780b0bca 29#include "boost_assert_handler.h"
6c5bdffd
GMF
30#include "config/option/configfileoption.h"
31#include "config/option/daemonoption.h"
5596767b 32#include "config/option/hostsdownlimitoption.h"
6c5bdffd
GMF
33#include "config/option/hostnameoption.h"
34#include "config/option/hostportoption.h"
35#include "config/option/hostpingprotocoloption.h"
36#include "config/option/hostpingintervaloption.h"
74dd30e1 37#include "config/option/hostsourcenetworkinterfaceoption.h"
6c5bdffd
GMF
38#include "config/option/linkdownintervaloption.h"
39#include "config/option/linkupintervaloption.h"
2c40f493 40#include "config/option/logleveloption.h"
5ba17410 41#include "config/option/logoutputoption.h"
fda777ea 42#include "config/option/logfileoption.h"
6c5bdffd
GMF
43#include "config/option/nameserveroption.h"
44#include "config/option/pingfaillimitoption.h"
45#include "config/option/sourcenetworkinterfaceoption.h"
46#include "config/option/statusnotifiercmdoption.h"
47#include "config/option/versionoption.h"
096b06ef 48#include "config/option/ratiorandomhostsoption.h"
079d19ab
CH
49#include "config/option/pingreplytimeoutoption.h"
50#include "config/option/maxaddressresolutionattemptsoption.h"
51#include "config/option/resolvedipttlthresholdoption.h"
f833126b 52#include "config/option/mintimebetweenresolvesoption.h"
a901aed6 53#include "config/option/dnscachefileoption.h"
6c5bdffd 54
aab6eaa1 55using namespace std;
6c5bdffd 56using boost::program_options::option_description;
aab6eaa1
GMF
57using boost::program_options::options_description;
58using boost::program_options::value;
59using boost::program_options::variables_map;
6c5bdffd 60using boost::shared_ptr;
aab6eaa1
GMF
61using I2n::Logger::GlobalLogger;
62
63//-----------------------------------------------------------------------------
64// ConfigurationOptions
65//-----------------------------------------------------------------------------
66
67/**
68 * @brief Default constructor.
69 */
70ConfigurationOptions::ConfigurationOptions() :
6c5bdffd
GMF
71 GenericOptions(),
72 ConfigOptions(),
73 HostOptions(),
aab6eaa1 74 HelpCmdStr( "help" ),
6c5bdffd 75 HelpCmdDesc( "Print this help and exit." )
aab6eaa1 76{
6c5bdffd
GMF
77 ConfigurationOptionItem config_file( new ConfigFileOption );
78 GenericOptions.push_back( config_file );
79
80 ConfigurationOptionItem daemon( new DaemonOption );
81 GenericOptions.push_back( daemon );
82
83 ConfigurationOptionItem version( new VersionOption );
84 GenericOptions.push_back( version );
85
2c40f493
GMF
86 ConfigurationOptionItem log_level( new LogLevelOption );
87 GenericOptions.push_back( log_level );
88
5ba17410
GMF
89 ConfigurationOptionItem log_output( new LogOutputOption );
90 GenericOptions.push_back( log_output );
91
fda777ea
CH
92 ConfigurationOptionItem log_file( new LogFileOption );
93 GenericOptions.push_back( log_file );
94
5596767b
GMF
95 ConfigurationOptionItem hosts_down_limit( new HostsDownLimitOption );
96 ConfigOptions.push_back( hosts_down_limit );
6c5bdffd
GMF
97
98 ConfigurationOptionItem link_down_interval( new LinkDownIntervalOption );
99 ConfigOptions.push_back( link_down_interval );
100
101 ConfigurationOptionItem link_up_interval( new LinkUpIntervalOption );
102 ConfigOptions.push_back( link_up_interval );
103
104 ConfigurationOptionItem nameserver( new NameserverOption );
105 ConfigOptions.push_back( nameserver );
106
107 ConfigurationOptionItem ping_fail_limit( new PingFailLimitOption );
108 ConfigOptions.push_back( ping_fail_limit );
109
110 ConfigurationOptionItem source_network_interface( new SourceNetworkInterfaceOption );
111 ConfigOptions.push_back( source_network_interface );
112
113 ConfigurationOptionItem status_notifier_cmd( new StatusNotifierCmdOption );
114 ConfigOptions.push_back( status_notifier_cmd );
115
079d19ab
CH
116 ConfigurationOptionItem ping_reply_timeout( new PingReplyTimeoutOption );
117 ConfigOptions.push_back( ping_reply_timeout );
118
119 ConfigurationOptionItem max_address_resolution_attempts( new MaxAddressResolutionAttemptsOption );
120 ConfigOptions.push_back( max_address_resolution_attempts );
121
122 ConfigurationOptionItem resolved_ip_ttl_threshold( new ResolvedIpTtlThresholdOption );
123 ConfigOptions.push_back( resolved_ip_ttl_threshold );
124
f833126b
CH
125 ConfigurationOptionItem min_time_between_resolves( new MinTimeBetweenResolvesOption );
126 ConfigOptions.push_back( min_time_between_resolves );
127
096b06ef
CH
128 ConfigurationOptionItem ratio_random_hosts( new RatioRandomHostsOption );
129 ConfigOptions.push_back( ratio_random_hosts );
130
a901aed6
CH
131 ConfigurationOptionItem dns_cache_file( new DnsCacheFileOption );
132 ConfigOptions.push_back( dns_cache_file );
133
6c5bdffd
GMF
134 HostConfigurationOptionItem host_name( new HostNameOption );
135 HostOptions.push_back( host_name );
136
137 HostConfigurationOptionItem host_port( new HostPortOption );
138 HostOptions.push_back( host_port );
139
74dd30e1
GMF
140 HostConfigurationOptionItem host_source_network_interface( new HostSourceNetworkInterfaceOption );
141 HostOptions.push_back( host_source_network_interface );
142
6c5bdffd
GMF
143 HostConfigurationOptionItem host_protocol( new HostPingProtocolOption );
144 HostOptions.push_back( host_protocol );
145
146 HostConfigurationOptionItem host_interval( new HostPingIntervalOption );
147 HostOptions.push_back( host_interval );
aab6eaa1
GMF
148}
149
150/**
151 * @brief Destructor.
152 */
153ConfigurationOptions::~ConfigurationOptions()
154{
155}
156
157/**
6c5bdffd 158 * @return The options which are common to all kinds of applications.
aab6eaa1
GMF
159 */
160options_description ConfigurationOptions::get_generic_options() const
161{
162 options_description options( "Generic options" );
6c5bdffd 163
aab6eaa1
GMF
164 options.add_options()
165 ( HelpCmdStr.c_str(), HelpCmdDesc.c_str() )
aab6eaa1
GMF
166 ;
167
6c5bdffd
GMF
168 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
169 {
170 // Do not pass the the underlying boost::program_options::option_description
171 // object from ConfigurationOption to the
172 // boost::program_options::options_description::add() method, because it
173 // deletes the boost::program_options::option_description, causing
174 // multiple freed when ConfigurationOption try to delete it.
175 option_description option = generic_option->get_option_description();
176 shared_ptr< option_description > ptr( new option_description( option ) );
177 options.add( ptr );
178 }
179
aab6eaa1
GMF
180 return options;
181}
182
183/**
6c5bdffd 184 * @return The options which are specific to this application.
aab6eaa1
GMF
185 */
186options_description ConfigurationOptions::get_configuration_options() const
187{
188 options_description options( "Configuration" );
6c5bdffd
GMF
189
190 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
191 {
192 option_description option = configuration_option->get_option_description();
193 shared_ptr< option_description > ptr( new option_description( option ) );
194 options.add( ptr );
195 }
196
197 BOOST_FOREACH( ConfigurationOptionItem host_option, HostOptions )
198 {
199 option_description option = host_option->get_option_description();
200 shared_ptr< option_description > ptr( new option_description( option ) );
201 options.add( ptr );
202 }
aab6eaa1
GMF
203
204 return options;
205}
206
207/**
6c5bdffd 208 * @brief Parse the options common to all kinds of applications.
aab6eaa1 209 *
6c5bdffd
GMF
210 * @param vm The input @c boost::program_options::variables_map.
211 * @param configuration The output @c Configuration filled with the parsed
212 * generic options.
aab6eaa1 213 *
6c5bdffd
GMF
214 * @return @c true if it was parsed at least one option, or @c false if there
215 * were no options available in this category.
aab6eaa1
GMF
216 */
217bool ConfigurationOptions::parse_generic_options(
218 const variables_map& vm,
219 Configuration *configuration
220)
221{
10af47fc
GMF
222 BOOST_ASSERT(configuration != NULL);
223
aab6eaa1 224 // help
6c5bdffd 225 if ( vm.count( HelpCmdStr ) > 0 )
aab6eaa1
GMF
226 {
227 options_description generic = get_generic_options();
228 options_description config = get_configuration_options();
229
230 options_description visible_options( "Allowed options" );
231 visible_options.add( generic ).add( config );
232
6c5bdffd 233 // TODO GlobalOutput::print( help )
aab6eaa1
GMF
234 cout << visible_options << endl;
235 return true;
236 }
237
6c5bdffd 238 BOOST_FOREACH( ConfigurationOptionItem generic_option, GenericOptions )
aab6eaa1 239 {
d3384e36 240 generic_option->parse( vm, configuration );
aab6eaa1
GMF
241 }
242
aab6eaa1
GMF
243 return false;
244}
245
246/**
6c5bdffd 247 * @brief Parse the options specific to this application.
aab6eaa1 248 *
6c5bdffd
GMF
249 * @param vm The input @c boost::program_options::variables_map.
250 * @param configuration The output @c Configuration filled with the parsed
251 * configuration options.
aab6eaa1 252 *
6c5bdffd
GMF
253 * @return @c true if it was parsed at least one option, or @c false if there
254 * were no options available in this category.
aab6eaa1
GMF
255 */
256bool ConfigurationOptions::parse_configuration_options(
257 const variables_map &vm,
258 Configuration *configuration
259)
260{
10af47fc
GMF
261 BOOST_ASSERT(configuration != NULL);
262
6c5bdffd 263 BOOST_FOREACH( ConfigurationOptionItem configuration_option, ConfigOptions )
aab6eaa1 264 {
d3384e36 265 configuration_option->parse( vm, configuration );
aab6eaa1
GMF
266 }
267
10af47fc
GMF
268 bool hosts_parsed = parse_hosts_options(vm, configuration);
269
270 return hosts_parsed;
271}
272
273/**
274 * @brief Parse the hosts section options.
275 *
276 * @param vm The input @c boost::program_options::variables_map.
277 * @param configuration The output @c Configuration filled with the parsed
278 * hosts options.
279 *
280 * @return @c true if the hosts were parsed correctly, or @c false otherwise.
281 */
282bool ConfigurationOptions::parse_hosts_options(
283 const variables_map &vm,
284 Configuration *configuration
285)
286{
287 BOOST_ASSERT(configuration != NULL);
288
6c5bdffd 289 size_t host_down_limit_count = static_cast<size_t>( configuration->get_hosts_down_limit() );
aab6eaa1 290
6c5bdffd 291 BOOST_FOREACH( HostConfigurationOptionItem host_option, HostOptions )
c9e981f6 292 {
6c5bdffd 293 bool parsed = host_option->parse( vm, configuration );
d3384e36 294 if ( parsed )
c9e981f6 295 {
6c5bdffd
GMF
296 // The set_hosts_count() method is called in parse() method, that is
297 // why we must parse before check the number of host options
298 size_t hosts_parsed_count = host_option->get_hosts_count();
299 bool have_minimum_hosts = ( host_down_limit_count <= hosts_parsed_count );
300 // Ensure we have all options for each host
301 if ( !have_minimum_hosts ) {
302 // TODO GlobalOutput::print()
303 GlobalLogger.error() << "Could not parse configuration file." <<
304 " Missing an entry for one of the hosts." << endl;
305 // TODO Assume default value for a missing option
306 return false;
307 }
308
309 BOOST_ASSERT( hosts_parsed_count >= static_cast<size_t>( host_down_limit_count ) );
c9e981f6 310 }
c9e981f6
GMF
311 }
312
aab6eaa1
GMF
313 return true;
314}
315
316/**
317 * @return which options must abort the application. Like the --version.
aab6eaa1
GMF
318 */
319bool ConfigurationOptions::halt_on_generic_options( const variables_map &vm ) const
320{
6c5bdffd
GMF
321 VersionOption v;
322
aab6eaa1 323 bool is_help = ( vm.count( HelpCmdStr ) > 0 );
6c5bdffd 324 bool is_version = ( vm.count( v.get_command_string() ) > 0 );
aab6eaa1
GMF
325 bool terminate_app = is_help || is_version;
326
327 return terminate_app;
328}